]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'pinctrl/for-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Mon, 2 Dec 2013 04:42:13 +0000 (15:42 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Mon, 2 Dec 2013 04:42:13 +0000 (15:42 +1100)
2160 files changed:
CREDITS
Documentation/Changes
Documentation/DocBook/device-drivers.tmpl
Documentation/DocBook/media/v4l/vidioc-expbuf.xml
Documentation/acpi/namespace.txt
Documentation/block/biodoc.txt
Documentation/block/biovecs.txt [new file with mode: 0644]
Documentation/cgroups/cgroups.txt
Documentation/device-mapper/cache.txt
Documentation/devicetree/bindings/arm/cpus.txt
Documentation/devicetree/bindings/clock/imx5-clock.txt
Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
Documentation/devicetree/bindings/i2c/i2c-omap.txt
Documentation/devicetree/bindings/iio/light/tsl2563.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/magnetometer/hmc5843.txt [new file with mode: 0644]
Documentation/devicetree/bindings/input/gpio-beeper.txt [new file with mode: 0644]
Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt [new file with mode: 0644]
Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/marvell,dove-pmu-intc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/leds/tca6507.txt
Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
Documentation/devicetree/bindings/mmc/ti-omap.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/gpmi-nand.txt
Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
Documentation/devicetree/bindings/rng/qcom,prng.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/bcm2835-i2s.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/cs42l52.txt [new file with mode: 0644]
Documentation/devicetree/bindings/tty/serial/renesas,sci-serial.txt [new file with mode: 0644]
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
Documentation/driver-model/devres.txt
Documentation/gpio/board.txt [new file with mode: 0644]
Documentation/gpio/consumer.txt [new file with mode: 0644]
Documentation/gpio/driver.txt [new file with mode: 0644]
Documentation/gpio/gpio-legacy.txt [moved from Documentation/gpio.txt with 100% similarity]
Documentation/gpio/gpio.txt [new file with mode: 0644]
Documentation/gpio/sysfs.txt [new file with mode: 0644]
Documentation/hwmon/it87
Documentation/kernel-parameters.txt
Documentation/kmsg/s390/zcrypt [new file with mode: 0644]
Documentation/memory-barriers.txt
Documentation/mic/mpssd/mpssd.c
Documentation/mtd/nand/pxa3xx-nand.txt [new file with mode: 0644]
Documentation/robust-futex-ABI.txt
Documentation/x86/x86_64/mm.txt
Documentation/zorro.txt
MAINTAINERS
Makefile
arch/arc/Kconfig
arch/arc/include/asm/smp.h
arch/arc/include/uapi/asm/unistd.h
arch/arc/kernel/perf_event.c
arch/arc/kernel/smp.c
arch/arc/plat-arcfpga/smp.c
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/arm-soc-for-next-contents.txt [new file with mode: 0644]
arch/arm/boot/compressed/Makefile
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-base0033.dts
arch/arm/boot/dts/am335x-igep0033.dtsi
arch/arm/boot/dts/armada-370-db.dts
arch/arm/boot/dts/armada-370-mirabox.dts
arch/arm/boot/dts/armada-370-netgear-rn102.dts
arch/arm/boot/dts/armada-370-netgear-rn104.dts
arch/arm/boot/dts/armada-370-xp.dtsi
arch/arm/boot/dts/armada-xp-gp.dts
arch/arm/boot/dts/armada-xp-mv78230.dtsi
arch/arm/boot/dts/armada-xp-mv78260.dtsi
arch/arm/boot/dts/armada-xp-netgear-rn2120.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
arch/arm/boot/dts/at91sam9260.dtsi
arch/arm/boot/dts/at91sam9263.dtsi
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9n12.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/cros5250-common.dtsi
arch/arm/boot/dts/dove-cubox.dts
arch/arm/boot/dts/dove.dtsi
arch/arm/boot/dts/emev2-kzm9d.dts
arch/arm/boot/dts/emev2.dtsi
arch/arm/boot/dts/exynos5.dtsi
arch/arm/boot/dts/exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-smdk5250.dts
arch/arm/boot/dts/exynos5250-snow.dts
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5420-smdk5420.dts
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/imx23-evk.dts
arch/arm/boot/dts/imx23-olinuxino.dts
arch/arm/boot/dts/imx23-stmp378x_devb.dts
arch/arm/boot/dts/imx25-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/imx25-pingrp.h [new file with mode: 0644]
arch/arm/boot/dts/imx25.dtsi
arch/arm/boot/dts/imx27-apf27.dts
arch/arm/boot/dts/imx27-apf27dev.dts
arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts
arch/arm/boot/dts/imx27-phytec-phycard-s-som.dts
arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts
arch/arm/boot/dts/imx27-phytec-phycore-som.dts
arch/arm/boot/dts/imx27-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/imx27-pingrp.h [new file with mode: 0644]
arch/arm/boot/dts/imx27.dtsi
arch/arm/boot/dts/imx28-apf28dev.dts
arch/arm/boot/dts/imx28-apx4devkit.dts
arch/arm/boot/dts/imx28-cfa10036.dts
arch/arm/boot/dts/imx28-cfa10037.dts
arch/arm/boot/dts/imx28-cfa10049.dts
arch/arm/boot/dts/imx28-cfa10057.dts
arch/arm/boot/dts/imx28-cfa10058.dts
arch/arm/boot/dts/imx28-duckbill.dts [new file with mode: 0644]
arch/arm/boot/dts/imx28-evk.dts
arch/arm/boot/dts/imx28-m28cu3.dts
arch/arm/boot/dts/imx28-m28evk.dts
arch/arm/boot/dts/imx28-sps1.dts
arch/arm/boot/dts/imx28-tx28.dts
arch/arm/boot/dts/imx28.dtsi
arch/arm/boot/dts/imx50-evk.dts [new file with mode: 0644]
arch/arm/boot/dts/imx50-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/imx50-pingrp.h [new file with mode: 0644]
arch/arm/boot/dts/imx50.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx51-apf51.dts
arch/arm/boot/dts/imx51-apf51dev.dts
arch/arm/boot/dts/imx51-babbage.dts
arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts [new file with mode: 0644]
arch/arm/boot/dts/imx51-pingrp.h [new file with mode: 0644]
arch/arm/boot/dts/imx51.dtsi
arch/arm/boot/dts/imx53-ard.dts
arch/arm/boot/dts/imx53-evk.dts
arch/arm/boot/dts/imx53-m53evk.dts
arch/arm/boot/dts/imx53-mba53.dts
arch/arm/boot/dts/imx53-pingrp.h [new file with mode: 0644]
arch/arm/boot/dts/imx53-qsb.dts
arch/arm/boot/dts/imx53-smd.dts
arch/arm/boot/dts/imx53-tqma53.dtsi
arch/arm/boot/dts/imx53-tx53.dtsi
arch/arm/boot/dts/imx53-voipac-bsb.dts [new file with mode: 0644]
arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx53.dtsi
arch/arm/boot/dts/imx6dl-gw51xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw52xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw53xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw54xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-pinfunc.h
arch/arm/boot/dts/imx6dl.dtsi
arch/arm/boot/dts/imx6q-arm2.dts
arch/arm/boot/dts/imx6q-cm-fx6.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw51xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw52xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw53xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw5400-a.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw54xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
arch/arm/boot/dts/imx6q-pinfunc.h
arch/arm/boot/dts/imx6q-sabrelite.dts
arch/arm/boot/dts/imx6q-sbc6x.dts
arch/arm/boot/dts/imx6q-udoo.dts
arch/arm/boot/dts/imx6q.dtsi
arch/arm/boot/dts/imx6qdl-gw51xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw52xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw53xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw54xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-pingrp.h [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
arch/arm/boot/dts/imx6qdl-sabresd.dtsi
arch/arm/boot/dts/imx6qdl-wandboard.dtsi
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/imx6sl-evk.dts
arch/arm/boot/dts/imx6sl-pingrp.h [new file with mode: 0644]
arch/arm/boot/dts/imx6sl.dtsi
arch/arm/boot/dts/kirkwood-6281.dtsi
arch/arm/boot/dts/kirkwood-6282.dtsi
arch/arm/boot/dts/kirkwood-dns320.dts
arch/arm/boot/dts/kirkwood-dns325.dts
arch/arm/boot/dts/kirkwood-dockstar.dts
arch/arm/boot/dts/kirkwood-goflexnet.dts
arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
arch/arm/boot/dts/kirkwood-ib62x0.dts
arch/arm/boot/dts/kirkwood-iconnect.dts
arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
arch/arm/boot/dts/kirkwood-lsxl.dtsi
arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ns2lite.dts
arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts
arch/arm/boot/dts/kirkwood-sheevaplug.dts
arch/arm/boot/dts/kizbox.dts
arch/arm/boot/dts/omap-zoom-common.dtsi
arch/arm/boot/dts/omap2.dtsi
arch/arm/boot/dts/omap2420.dtsi
arch/arm/boot/dts/omap2430.dtsi
arch/arm/boot/dts/omap3-beagle-xm.dts
arch/arm/boot/dts/omap3-beagle.dts
arch/arm/boot/dts/omap3-igep.dtsi
arch/arm/boot/dts/omap3-igep0020.dts
arch/arm/boot/dts/omap3-igep0030.dts
arch/arm/boot/dts/omap3-n900.dts
arch/arm/boot/dts/omap3.dtsi
arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
arch/arm/boot/dts/r7s72100-genmai.dts
arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts
arch/arm/boot/dts/r8a73a4-ape6evm.dts
arch/arm/boot/dts/r8a73a4.dtsi
arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts
arch/arm/boot/dts/r8a7740-armadillo800eva.dts
arch/arm/boot/dts/r8a7740.dtsi
arch/arm/boot/dts/r8a7778-bockw-reference.dts
arch/arm/boot/dts/r8a7778-bockw.dts
arch/arm/boot/dts/r8a7778.dtsi
arch/arm/boot/dts/r8a7779-marzen-reference.dts
arch/arm/boot/dts/r8a7779-marzen.dts
arch/arm/boot/dts/r8a7779.dtsi
arch/arm/boot/dts/r8a7790-lager-reference.dts
arch/arm/boot/dts/r8a7790-lager.dts
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791-koelsch-reference.dts [new file with mode: 0644]
arch/arm/boot/dts/r8a7791-koelsch.dts
arch/arm/boot/dts/r8a7791.dtsi
arch/arm/boot/dts/sama5d3.dtsi
arch/arm/boot/dts/sh7372-mackerel.dts
arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
arch/arm/boot/dts/sh73a0-kzm9g.dts
arch/arm/boot/dts/sh73a0.dtsi
arch/arm/configs/ape6evm_defconfig
arch/arm/configs/armadillo800eva_defconfig
arch/arm/configs/bockw_defconfig
arch/arm/configs/genmai_defconfig [new file with mode: 0644]
arch/arm/configs/imx_v4_v5_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/kirkwood_defconfig
arch/arm/configs/koelsch_defconfig
arch/arm/configs/kzm9d_defconfig
arch/arm/configs/kzm9g_defconfig
arch/arm/configs/lager_defconfig
arch/arm/configs/mackerel_defconfig
arch/arm/configs/marzen_defconfig
arch/arm/configs/mvebu_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/include/asm/cacheflush.h
arch/arm/include/asm/io.h
arch/arm/include/asm/mach/map.h
arch/arm/include/asm/pgtable-2level.h
arch/arm/include/asm/pgtable-3level.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/xen/page.h
arch/arm/include/debug/imx-uart.h
arch/arm/kernel/entry-v7m.S
arch/arm/kernel/etm.c
arch/arm/kernel/machine_kexec.c
arch/arm/kernel/relocate_kernel.S
arch/arm/kernel/sigreturn_codes.S
arch/arm/kernel/tcm.c
arch/arm/kernel/traps.c
arch/arm/lib/backtrace.S
arch/arm/lib/delay-loop.S
arch/arm/mach-at91/at91rm9200_time.c
arch/arm/mach-at91/setup.c
arch/arm/mach-dove/common.c
arch/arm/mach-ep93xx/Kconfig
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ep93xx/include/mach/platform.h
arch/arm/mach-footbridge/common.c
arch/arm/mach-footbridge/dc21285.c
arch/arm/mach-footbridge/ebsa285.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/avic.c
arch/arm/mach-imx/clk-imx51-imx53.c
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/clk-imx6sl.c
arch/arm/mach-imx/clk-vf610.c
arch/arm/mach-imx/common.h
arch/arm/mach-imx/irq-common.h
arch/arm/mach-imx/mach-cpuimx35.c
arch/arm/mach-imx/mach-cpuimx51sd.c
arch/arm/mach-imx/mach-imx50.c [new file with mode: 0644]
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mm-imx5.c
arch/arm/mach-kirkwood/board-dt.c
arch/arm/mach-mvebu/coherency.c
arch/arm/mach-mvebu/coherency.h
arch/arm/mach-mvebu/common.h
arch/arm/mach-mvebu/hotplug.c
arch/arm/mach-mvebu/platsmp.c
arch/arm/mach-mvebu/pmsu.c
arch/arm/mach-mvebu/system-controller.c
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/dss-common.c
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/omap-secure.h
arch/arm/mach-omap2/omap4-common.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/prm44xx_54xx.h
arch/arm/mach-orion5x/board-dt.c
arch/arm/mach-orion5x/common.c
arch/arm/mach-orion5x/db88f5281-setup.c
arch/arm/mach-orion5x/irq.c
arch/arm/mach-orion5x/pci.c
arch/arm/mach-orion5x/rd88f5182-setup.c
arch/arm/mach-orion5x/terastation_pro2-setup.c
arch/arm/mach-orion5x/ts209-setup.c
arch/arm/mach-orion5x/ts78xx-setup.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/Makefile.boot
arch/arm/mach-shmobile/board-ape6evm.c
arch/arm/mach-shmobile/board-bockw-reference.c
arch/arm/mach-shmobile/board-kzm9d.c [deleted file]
arch/arm/mach-shmobile/board-lager-reference.c
arch/arm/mach-shmobile/board-lager.c
arch/arm/mach-shmobile/board-marzen.c
arch/arm/mach-shmobile/clock-r7s72100.c
arch/arm/mach-shmobile/clock-r8a73a4.c
arch/arm/mach-shmobile/clock-r8a7740.c
arch/arm/mach-shmobile/clock-r8a7778.c
arch/arm/mach-shmobile/clock-r8a7779.c
arch/arm/mach-shmobile/clock-r8a7790.c
arch/arm/mach-shmobile/clock-r8a7791.c
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-shmobile/clock-sh73a0.c
arch/arm/mach-shmobile/include/mach/emev2.h
arch/arm/mach-shmobile/include/mach/r8a7779.h
arch/arm/mach-shmobile/include/mach/r8a7791.h
arch/arm/mach-shmobile/setup-emev2.c
arch/arm/mach-shmobile/setup-r7s72100.c
arch/arm/mach-shmobile/setup-r8a73a4.c
arch/arm/mach-shmobile/setup-r8a7779.c
arch/arm/mach-shmobile/setup-r8a7790.c
arch/arm/mach-shmobile/setup-r8a7791.c
arch/arm/mach-shmobile/setup-sh73a0.c
arch/arm/mach-tegra/fuse.c
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-ux500/setup.h
arch/arm/mach-vexpress/spc.c
arch/arm/mach-vexpress/spc.h
arch/arm/mach-vexpress/tc2_pm.c
arch/arm/mm/Makefile
arch/arm/mm/cache-v7.S
arch/arm/mm/dma-mapping.c
arch/arm/mm/dump.c [new file with mode: 0644]
arch/arm/mm/ioremap.c
arch/arm/mm/mmap.c
arch/arm/mm/mmu.c
arch/arm/mm/pgd.c
arch/arm/plat-omap/include/plat/dmtimer.h
arch/arm/plat-orion/common.c
arch/arm/plat-orion/time.c
arch/arm/plat-samsung/s5p-irq-eint.c
arch/arm/xen/p2m.c
arch/arm64/boot/dts/foundation-v8.dts
arch/arm64/include/asm/irqflags.h
arch/arm64/include/asm/pgtable.h
arch/arm64/kernel/debug-monitors.c
arch/arm64/kernel/entry.S
arch/arm64/kernel/ptrace.c
arch/arm64/kernel/setup.c
arch/arm64/kernel/smp.c
arch/c6x/include/asm/cache.h
arch/ia64/hp/common/aml_nfw.c
arch/m68k/amiga/chipram.c
arch/m68k/amiga/config.c
arch/m68k/amiga/platform.c
arch/m68k/apollo/config.c
arch/m68k/atari/config.c
arch/m68k/bvme6000/config.c
arch/m68k/configs/amiga_defconfig
arch/m68k/configs/apollo_defconfig
arch/m68k/configs/atari_defconfig
arch/m68k/configs/bvme6000_defconfig
arch/m68k/configs/hp300_defconfig
arch/m68k/configs/m5208evb_defconfig
arch/m68k/configs/m5249evb_defconfig
arch/m68k/configs/m5272c3_defconfig
arch/m68k/configs/m5275evb_defconfig
arch/m68k/configs/m5307c3_defconfig
arch/m68k/configs/m5407c3_defconfig
arch/m68k/configs/mac_defconfig
arch/m68k/configs/multi_defconfig
arch/m68k/configs/mvme147_defconfig
arch/m68k/configs/mvme16x_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/configs/sun3_defconfig
arch/m68k/configs/sun3x_defconfig
arch/m68k/emu/natfeat.c
arch/m68k/emu/nfblock.c
arch/m68k/hp300/config.c
arch/m68k/include/asm/amigahw.h
arch/m68k/include/asm/apollohw.h
arch/m68k/include/asm/atarihw.h
arch/m68k/include/asm/bootinfo.h
arch/m68k/include/asm/hp300hw.h
arch/m68k/include/asm/macintosh.h
arch/m68k/include/asm/mvme16xhw.h
arch/m68k/include/asm/setup.h
arch/m68k/include/asm/timex.h
arch/m68k/include/uapi/asm/Kbuild
arch/m68k/include/uapi/asm/bootinfo-amiga.h [new file with mode: 0644]
arch/m68k/include/uapi/asm/bootinfo-apollo.h [new file with mode: 0644]
arch/m68k/include/uapi/asm/bootinfo-atari.h [new file with mode: 0644]
arch/m68k/include/uapi/asm/bootinfo-hp300.h [new file with mode: 0644]
arch/m68k/include/uapi/asm/bootinfo-mac.h [new file with mode: 0644]
arch/m68k/include/uapi/asm/bootinfo-q40.h [new file with mode: 0644]
arch/m68k/include/uapi/asm/bootinfo-vme.h [new file with mode: 0644]
arch/m68k/include/uapi/asm/bootinfo.h [new file with mode: 0644]
arch/m68k/include/uapi/asm/setup.h
arch/m68k/kernel/head.S
arch/m68k/kernel/setup_mm.c
arch/m68k/kernel/time.c
arch/m68k/mac/config.c
arch/m68k/mac/iop.c
arch/m68k/mac/misc.c
arch/m68k/mac/oss.c
arch/m68k/mac/psc.c
arch/m68k/mac/via.c
arch/m68k/mm/init.c
arch/m68k/mm/motorola.c
arch/m68k/mvme147/config.c
arch/m68k/mvme16x/config.c
arch/m68k/q40/config.c
arch/m68k/sun3/dvma.c
arch/m68k/sun3/mmu_emu.c
arch/m68k/sun3/sun3dvma.c
arch/m68k/sun3x/prom.c
arch/metag/kernel/dma.c
arch/metag/kernel/smp.c
arch/microblaze/Makefile
arch/microblaze/include/asm/sections.h
arch/microblaze/kernel/setup.c
arch/mips/ar7/setup.c
arch/mips/emma/markeins/setup.c
arch/mips/lasat/picvue_proc.c
arch/mips/netlogic/xlp/setup.c
arch/mips/netlogic/xlr/setup.c
arch/mips/sibyte/swarm/setup.c
arch/openrisc/kernel/entry.S
arch/openrisc/kernel/signal.c
arch/parisc/configs/c8000_defconfig
arch/parisc/configs/generic-64bit_defconfig
arch/parisc/include/asm/serial.h
arch/parisc/kernel/hardware.c
arch/parisc/kernel/head.S
arch/parisc/kernel/sys_parisc.c
arch/parisc/kernel/unwind.c
arch/parisc/kernel/vmlinux.lds.S
arch/parisc/mm/init.c
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/dts/xcalibur1501.dts
arch/powerpc/boot/dts/xpedite5301.dts
arch/powerpc/boot/dts/xpedite5330.dts
arch/powerpc/boot/dts/xpedite5370.dts
arch/powerpc/boot/util.S
arch/powerpc/include/asm/pgalloc-64.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/setup.h
arch/powerpc/include/asm/timex.h
arch/powerpc/include/asm/uprobes.h
arch/powerpc/kernel/machine_kexec.c
arch/powerpc/kernel/nvram_64.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/uprobes.c
arch/powerpc/kernel/vdso32/gettimeofday.S
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/mm/hugetlbpage-book3e.c
arch/powerpc/mm/tlb_nohash.c
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/axonram.c
arch/s390/Kconfig
arch/s390/crypto/aes_s390.c
arch/s390/include/asm/page.h
arch/s390/include/asm/vdso.h
arch/s390/include/uapi/asm/zcrypt.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/compat_signal.c
arch/s390/kernel/pgm_check.S
arch/s390/kernel/signal.c
arch/s390/kernel/time.c
arch/s390/kernel/vdso32/clock_gettime.S
arch/s390/kernel/vdso32/gettimeofday.S
arch/s390/kernel/vdso64/clock_gettime.S
arch/s390/kernel/vdso64/gettimeofday.S
arch/s390/lib/uaccess_pt.c
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/include/asm/hw_breakpoint.h
arch/sh/include/cpu-common/cpu/ubc.h [new file with mode: 0644]
arch/sh/include/cpu-sh2a/cpu/ubc.h [new file with mode: 0644]
arch/sh/kernel/cpu/sh2a/Makefile
arch/sh/kernel/cpu/sh2a/ubc.c [new file with mode: 0644]
arch/sh/kernel/hw_breakpoint.c
arch/tile/include/asm/sections.h
arch/tile/kernel/vmlinux.lds.S
arch/tile/mm/init.c
arch/x86/Kconfig
arch/x86/boot/Makefile
arch/x86/boot/boot.h
arch/x86/boot/compressed/Makefile
arch/x86/boot/compressed/aslr.c [new file with mode: 0644]
arch/x86/boot/compressed/cmdline.c
arch/x86/boot/compressed/cpuflags.c [new file with mode: 0644]
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S
arch/x86/boot/compressed/misc.c
arch/x86/boot/compressed/misc.h
arch/x86/boot/cpucheck.c
arch/x86/boot/cpuflags.c [new file with mode: 0644]
arch/x86/boot/cpuflags.h [new file with mode: 0644]
arch/x86/crypto/Makefile
arch/x86/crypto/aesni-intel_glue.c
arch/x86/crypto/camellia_aesni_avx2_glue.c
arch/x86/crypto/camellia_aesni_avx_glue.c
arch/x86/crypto/cast5_avx_glue.c
arch/x86/crypto/cast6_avx_glue.c
arch/x86/crypto/serpent_avx2_glue.c
arch/x86/crypto/serpent_avx_glue.c
arch/x86/crypto/serpent_sse2_glue.c
arch/x86/crypto/sha256_ssse3_glue.c
arch/x86/crypto/twofish_avx_glue.c
arch/x86/include/asm/archrandom.h
arch/x86/include/asm/efi.h
arch/x86/include/asm/page.h
arch/x86/include/asm/page_32.h
arch/x86/include/asm/page_64_types.h
arch/x86/include/asm/pgtable-2level.h
arch/x86/include/asm/pgtable_64_types.h
arch/x86/include/asm/pgtable_types.h
arch/x86/include/asm/simd.h [new file with mode: 0644]
arch/x86/include/asm/trace/irq_vectors.h
arch/x86/kernel/apic/apic_flat_64.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/cpu/perf_event_intel_rapl.c [new file with mode: 0644]
arch/x86/kernel/cpu/rdrand.c
arch/x86/kernel/setup.c
arch/x86/lib/copy_user_64.S
arch/x86/mm/hugetlbpage.c
arch/x86/mm/init_32.c
arch/x86/mm/pageattr.c
arch/x86/pci/mmconfig_32.c
arch/x86/platform/efi/early_printk.c
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/efi_32.c
arch/x86/platform/efi/efi_64.c
arch/x86/platform/efi/efi_stub_64.S
arch/x86/platform/olpc/olpc-xo15-sci.c
arch/x86/tools/relocs.c
arch/xtensa/Kconfig
arch/xtensa/include/asm/Kbuild
arch/xtensa/include/asm/barrier.h
arch/xtensa/include/asm/bitops.h
arch/xtensa/include/asm/cacheflush.h
arch/xtensa/include/asm/delay.h
arch/xtensa/include/asm/ftrace.h
arch/xtensa/include/asm/futex.h [new file with mode: 0644]
arch/xtensa/include/asm/irq.h
arch/xtensa/include/asm/mmu.h
arch/xtensa/include/asm/mmu_context.h
arch/xtensa/include/asm/mxregs.h [new file with mode: 0644]
arch/xtensa/include/asm/processor.h
arch/xtensa/include/asm/ptrace.h
arch/xtensa/include/asm/smp.h
arch/xtensa/include/asm/spinlock.h
arch/xtensa/include/asm/spinlock_types.h [new file with mode: 0644]
arch/xtensa/include/asm/timex.h
arch/xtensa/include/asm/tlbflush.h
arch/xtensa/include/asm/traps.h
arch/xtensa/include/asm/vectors.h
arch/xtensa/kernel/Makefile
arch/xtensa/kernel/head.S
arch/xtensa/kernel/irq.c
arch/xtensa/kernel/mxhead.S [new file with mode: 0644]
arch/xtensa/kernel/setup.c
arch/xtensa/kernel/smp.c [new file with mode: 0644]
arch/xtensa/kernel/time.c
arch/xtensa/kernel/traps.c
arch/xtensa/kernel/vmlinux.lds.S
arch/xtensa/mm/cache.c
arch/xtensa/mm/fault.c
arch/xtensa/mm/misc.S
arch/xtensa/mm/mmu.c
arch/xtensa/mm/tlb.c
arch/xtensa/platforms/iss/network.c
arch/xtensa/platforms/xtfpga/include/platform/hardware.h
arch/xtensa/variants/s6000/include/variant/irq.h
block/blk-core.c
block/blk-flush.c
block/blk-integrity.c
block/blk-lib.c
block/blk-map.c
block/blk-merge.c
block/blk-mq.c
block/blk-throttle.c
block/elevator.c
crypto/Kconfig
crypto/Makefile
crypto/ablk_helper.c [moved from arch/x86/crypto/ablk_helper.c with 95% similarity]
crypto/ablkcipher.c
crypto/algif_hash.c
crypto/algif_skcipher.c
crypto/ansi_cprng.c
crypto/asymmetric_keys/rsa.c
crypto/asymmetric_keys/x509_public_key.c
crypto/authenc.c
crypto/authencesn.c
crypto/ccm.c
crypto/gcm.c
crypto/memneq.c [new file with mode: 0644]
crypto/tcrypt.c
crypto/testmgr.c
drivers/Makefile
drivers/acpi/ac.c
drivers/acpi/acpi_extlog.c
drivers/acpi/acpi_lpss.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/acpi_pad.c
drivers/acpi/acpi_processor.c
drivers/acpi/acpica/acresrc.h
drivers/acpi/acpica/nsalloc.c
drivers/acpi/acpica/nsutils.c
drivers/acpi/acpica/rscalc.c
drivers/acpi/acpica/rscreate.c
drivers/acpi/acpica/rsutils.c
drivers/acpi/acpica/utdebug.c
drivers/acpi/apei/einj.c
drivers/acpi/battery.c
drivers/acpi/blacklist.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/container.c
drivers/acpi/custom_method.c
drivers/acpi/debugfs.c
drivers/acpi/device_pm.c
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/event.c
drivers/acpi/fan.c
drivers/acpi/glue.c
drivers/acpi/hed.c
drivers/acpi/internal.h
drivers/acpi/numa.c
drivers/acpi/nvs.c
drivers/acpi/osl.c
drivers/acpi/pci_irq.c
drivers/acpi/pci_link.c
drivers/acpi/pci_root.c
drivers/acpi/power.c
drivers/acpi/proc.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_perflib.c
drivers/acpi/processor_thermal.c
drivers/acpi/processor_throttling.c
drivers/acpi/sbshc.c
drivers/acpi/scan.c
drivers/acpi/sleep.c
drivers/acpi/sysfs.c
drivers/acpi/thermal.c
drivers/acpi/utils.c
drivers/acpi/video.c
drivers/acpi/wakeup.c
drivers/ata/ahci.c
drivers/ata/ahci_platform.c
drivers/ata/ata_generic.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata-zpodd.c
drivers/ata/pata_acpi.c
drivers/ata/pata_arasan_cf.c
drivers/ata/sata_rcar.c
drivers/base/power/main.c
drivers/base/regmap/regmap-mmio.c
drivers/base/regmap/regmap.c
drivers/block/aoe/aoe.h
drivers/block/aoe/aoecmd.c
drivers/block/brd.c
drivers/block/drbd/drbd_actlog.c
drivers/block/drbd/drbd_bitmap.c
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_req.c
drivers/block/drbd/drbd_req.h
drivers/block/drbd/drbd_worker.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/nbd.c
drivers/block/nvme-core.c
drivers/block/pktcdvd.c
drivers/block/ps3disk.c
drivers/block/ps3vram.c
drivers/block/rbd.c
drivers/block/rsxx/dev.c
drivers/block/rsxx/dma.c
drivers/block/umem.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkfront.c
drivers/block/z2ram.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btmrvl_drv.h
drivers/bluetooth/btmrvl_main.c
drivers/bluetooth/btmrvl_sdio.c
drivers/bluetooth/btmrvl_sdio.h
drivers/bluetooth/btusb.c
drivers/bus/mvebu-mbus.c
drivers/char/Makefile
drivers/char/agp/Kconfig
drivers/char/agp/Makefile
drivers/char/agp/intel-agp.c
drivers/char/agp/intel-gtt.c
drivers/char/hpet.c
drivers/char/hw_random/Kconfig
drivers/char/hw_random/Makefile
drivers/char/hw_random/msm-rng.c [new file with mode: 0644]
drivers/char/hw_random/omap3-rom-rng.c [new file with mode: 0644]
drivers/char/hw_random/pseries-rng.c
drivers/char/hw_random/via-rng.c
drivers/char/tpm/tpm_acpi.c
drivers/char/tpm/tpm_ppi.c
drivers/clk/mvebu/Kconfig
drivers/clk/mvebu/Makefile
drivers/clk/mvebu/clk-corediv.c [new file with mode: 0644]
drivers/clk/mvebu/clk-cpu.c
drivers/clocksource/Kconfig
drivers/clocksource/sh_mtu2.c
drivers/clocksource/sh_tmu.c
drivers/cpufreq/cpufreq-cpu0.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/exynos4210-cpufreq.c
drivers/cpufreq/exynos4x12-cpufreq.c
drivers/cpufreq/exynos5250-cpufreq.c
drivers/cpufreq/spear-cpufreq.c
drivers/cpufreq/tegra-cpufreq.c
drivers/crypto/caam/Kconfig
drivers/crypto/caam/Makefile
drivers/crypto/caam/caamalg.c
drivers/crypto/caam/caamhash.c
drivers/crypto/caam/caamrng.c
drivers/crypto/caam/ctrl.c
drivers/crypto/caam/desc.h
drivers/crypto/caam/intern.h
drivers/crypto/caam/jr.c
drivers/crypto/caam/jr.h
drivers/crypto/caam/regs.h
drivers/crypto/caam/sg_sw_sec4.h
drivers/crypto/dcp.c
drivers/crypto/ixp4xx_crypto.c
drivers/crypto/mv_cesa.c
drivers/crypto/omap-aes.c
drivers/crypto/omap-sham.c
drivers/crypto/picoxcell_crypto.c
drivers/crypto/sahara.c
drivers/crypto/talitos.c
drivers/crypto/tegra-aes.c
drivers/dma/amba-pl08x.c
drivers/dma/imx-sdma.c
drivers/dma/mmp_pdma.c
drivers/dma/mmp_tdma.c
drivers/dma/pl330.c
drivers/dma/s3c24xx-dma.c
drivers/dma/sh/rcar-hpbdma.c
drivers/edac/mpc85xx_edac.c
drivers/edac/mpc85xx_edac.h
drivers/extcon/extcon-arizona.c
drivers/extcon/extcon-class.c
drivers/firewire/sbp2.c
drivers/firmware/efi/efi-pstore.c
drivers/firmware/efi/efivars.c
drivers/firmware/efi/vars.c
drivers/gpio/gpio-bcm-kona.c
drivers/gpio/gpio-msm-v2.c
drivers/gpio/gpio-mvebu.c
drivers/gpio/gpio-pl061.c
drivers/gpio/gpio-rcar.c
drivers/gpio/gpio-tb10x.c
drivers/gpio/gpio-twl4030.c
drivers/gpio/gpio-ucb1400.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/i915/Kconfig
drivers/gpu/drm/i915/dvo_ns2501.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_dmabuf.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/i915_sysfs.c
drivers/gpu/drm/i915/i915_ums.c
drivers/gpu/drm/i915/intel_acpi.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_opregion.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_sideband.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/i915/intel_uncore.c
drivers/gpu/drm/nouveau/nouveau_acpi.c
drivers/gpu/drm/nouveau/nouveau_hwmon.c
drivers/gpu/drm/qxl/qxl_release.c
drivers/gpu/drm/radeon/radeon_acpi.c
drivers/hid/Kconfig
drivers/hid/hid-appleir.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-kye.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-sony.c
drivers/hid/hid-wiimote-core.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/uhid.c
drivers/hid/usbhid/usbkbd.c
drivers/hv/vmbus_drv.c
drivers/hwmon/Kconfig
drivers/hwmon/acpi_power_meter.c
drivers/hwmon/asus_atk0110.c
drivers/hwmon/it87.c
drivers/hwmon/lm90.c
drivers/i2c/busses/i2c-bcm-kona.c
drivers/i2c/busses/i2c-bcm2835.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-diolan-u2c.c
drivers/i2c/busses/i2c-omap.c
drivers/ide/buddha.c
drivers/ide/ide-acpi.c
drivers/idle/intel_idle.c
drivers/iio/accel/hid-sensor-accel-3d.c
drivers/iio/accel/kxsd9.c
drivers/iio/adc/at91_adc.c
drivers/iio/adc/mcp3422.c
drivers/iio/adc/ti_am335x_adc.c
drivers/iio/adc/viperboard_adc.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.h
drivers/iio/dac/ad5421.c
drivers/iio/dac/ad5755.c
drivers/iio/gyro/adis16130.c
drivers/iio/gyro/adxrs450.c
drivers/iio/gyro/hid-sensor-gyro-3d.c
drivers/iio/industrialio-core.c
drivers/iio/industrialio-event.c
drivers/iio/industrialio-trigger.c
drivers/iio/light/Kconfig
drivers/iio/light/hid-sensor-als.c
drivers/iio/light/tsl2563.c
drivers/iio/light/vcnl4000.c
drivers/iio/magnetometer/Kconfig
drivers/iio/magnetometer/hid-sensor-magn-3d.c
drivers/iio/magnetometer/mag3110.c
drivers/iio/pressure/Kconfig
drivers/iio/pressure/Makefile
drivers/iio/pressure/mpl3115.c [new file with mode: 0644]
drivers/input/keyboard/adp5588-keys.c
drivers/input/keyboard/adp5589-keys.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/atlas_btns.c
drivers/input/misc/gpio-beeper.c [new file with mode: 0644]
drivers/input/misc/hp_sdc_rtc.c
drivers/input/misc/pcf8574_keypad.c
drivers/input/misc/twl4030-pwrbutton.c
drivers/input/serio/ambakmi.c
drivers/input/serio/pcips2.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/tablet/wacom_wac.h
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/atmel-wm97xx.c
drivers/input/touchscreen/cyttsp4_core.c
drivers/input/touchscreen/sur40.c [new file with mode: 0644]
drivers/input/touchscreen/tsc2007.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/intel_irq_remapping.c
drivers/irqchip/Kconfig
drivers/irqchip/Makefile
drivers/irqchip/exynos-combiner.c
drivers/irqchip/irq-dove.c [new file with mode: 0644]
drivers/irqchip/irq-gic.c
drivers/irqchip/irq-renesas-intc-irqpin.c
drivers/irqchip/irq-xtensa-mx.c [new file with mode: 0644]
drivers/irqchip/irq-xtensa-pic.c [new file with mode: 0644]
drivers/leds/leds-tca6507.c
drivers/macintosh/Makefile
drivers/md/bcache/bcache.h
drivers/md/bcache/btree.c
drivers/md/bcache/debug.c
drivers/md/bcache/io.c
drivers/md/bcache/journal.c
drivers/md/bcache/movinggc.c
drivers/md/bcache/request.c
drivers/md/bcache/super.c
drivers/md/bcache/util.c
drivers/md/bcache/writeback.c
drivers/md/bcache/writeback.h
drivers/md/dm-bio-record.h
drivers/md/dm-bufio.c
drivers/md/dm-cache-policy-mq.c
drivers/md/dm-cache-target.c
drivers/md/dm-crypt.c
drivers/md/dm-delay.c
drivers/md/dm-flakey.c
drivers/md/dm-io.c
drivers/md/dm-linear.c
drivers/md/dm-raid1.c
drivers/md/dm-region-hash.c
drivers/md/dm-snap.c
drivers/md/dm-stripe.c
drivers/md/dm-switch.c
drivers/md/dm-thin.c
drivers/md/dm-verity.c
drivers/md/dm.c
drivers/md/faulty.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/common/siano/smscoreapi.h
drivers/media/common/siano/smsdvb.h
drivers/media/dvb-core/dvb_demux.c
drivers/media/dvb-frontends/cxd2820r_c.c
drivers/media/dvb-frontends/dib8000.c
drivers/media/dvb-frontends/drxk_hard.c
drivers/media/i2c/adv7183_regs.h
drivers/media/i2c/adv7604.c
drivers/media/i2c/adv7842.c
drivers/media/i2c/ir-kbd-i2c.c
drivers/media/i2c/m5mols/m5mols_controls.c
drivers/media/i2c/s5c73m3/s5c73m3-core.c
drivers/media/i2c/s5c73m3/s5c73m3.h
drivers/media/i2c/saa7115.c
drivers/media/i2c/soc_camera/ov5642.c
drivers/media/i2c/ths7303.c
drivers/media/i2c/wm8775.c
drivers/media/pci/bt8xx/bttv-driver.c
drivers/media/pci/cx18/cx18-driver.h
drivers/media/pci/cx23885/cx23885-417.c
drivers/media/pci/pluto2/pluto2.c
drivers/media/pci/saa7164/saa7164-core.c
drivers/media/platform/coda.c
drivers/media/platform/exynos4-is/fimc-core.c
drivers/media/platform/exynos4-is/media-dev.c
drivers/media/platform/marvell-ccic/mmp-driver.c
drivers/media/platform/omap3isp/isp.c
drivers/media/platform/s5p-mfc/regs-mfc.h
drivers/media/platform/s5p-mfc/s5p_mfc.c
drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
drivers/media/platform/s5p-tv/mixer.h
drivers/media/platform/s5p-tv/mixer_video.c
drivers/media/platform/soc_camera/omap1_camera.c
drivers/media/platform/vivi.c
drivers/media/platform/vsp1/vsp1_drv.c
drivers/media/platform/vsp1/vsp1_video.c
drivers/media/radio/radio-shark.c
drivers/media/radio/radio-shark2.c
drivers/media/radio/radio-si476x.c
drivers/media/radio/radio-tea5764.c
drivers/media/radio/tef6862.c
drivers/media/rc/imon.c
drivers/media/rc/redrat3.c
drivers/media/tuners/mt2063.c
drivers/media/tuners/tuner-xc2028-types.h
drivers/media/usb/cx231xx/cx231xx-cards.c
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/media/usb/dvb-usb-v2/mxl111sf.c
drivers/media/usb/dvb-usb/technisat-usb2.c
drivers/media/usb/em28xx/em28xx-video.c
drivers/media/usb/gspca/gl860/gl860.c
drivers/media/usb/gspca/pac207.c
drivers/media/usb/gspca/pac7302.c
drivers/media/usb/gspca/stk1135.c
drivers/media/usb/gspca/stv0680.c
drivers/media/usb/gspca/sunplus.c
drivers/media/usb/gspca/zc3xx.c
drivers/media/usb/pwc/pwc-if.c
drivers/media/usb/usbtv/usbtv.c
drivers/media/usb/uvc/uvc_video.c
drivers/media/v4l2-core/v4l2-ctrls.c
drivers/media/v4l2-core/videobuf2-core.c
drivers/media/v4l2-core/videobuf2-dma-contig.c
drivers/message/fusion/mptsas.c
drivers/mfd/88pm800.c
drivers/mfd/88pm805.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/ab8500-core.c
drivers/mfd/ab8500-debugfs.c
drivers/mfd/arizona-core.c
drivers/mfd/as3722.c
drivers/mfd/asic3.c
drivers/mfd/cros_ec.c
drivers/mfd/cros_ec_i2c.c
drivers/mfd/cros_ec_spi.c
drivers/mfd/da9052-core.c
drivers/mfd/da9055-core.c
drivers/mfd/da9063-core.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/htc-pasic3.c
drivers/mfd/intel_msic.c
drivers/mfd/jz4740-adc.c
drivers/mfd/lp8788.c
drivers/mfd/lpc_ich.c
drivers/mfd/max14577.c [new file with mode: 0644]
drivers/mfd/max77686.c
drivers/mfd/max77693.c
drivers/mfd/max8907.c
drivers/mfd/max8925-core.c
drivers/mfd/max8997.c
drivers/mfd/max8998.c
drivers/mfd/mc13xxx-spi.c
drivers/mfd/omap-usb-host.c
drivers/mfd/omap-usb-tll.c
drivers/mfd/rc5t583.c
drivers/mfd/rdc321x-southbridge.c
drivers/mfd/retu-mfd.c
drivers/mfd/sec-core.c
drivers/mfd/sec-irq.c
drivers/mfd/stmpe.c
drivers/mfd/stmpe.h
drivers/mfd/tc3589x.c
drivers/mfd/tc6387xb.c
drivers/mfd/ti-ssp.c
drivers/mfd/timberdale.c
drivers/mfd/tps6507x.c
drivers/mfd/tps65090.c
drivers/mfd/tps65217.c
drivers/mfd/tps6586x.c
drivers/mfd/tps65910.c
drivers/mfd/tps65912-core.c
drivers/mfd/tps80031.c
drivers/mfd/viperboard.c
drivers/mfd/vx855.c
drivers/mfd/wm5110-tables.c
drivers/mfd/wm831x-core.c
drivers/mfd/wm8994-core.c
drivers/misc/mei/client.c
drivers/misc/mei/init.c
drivers/misc/mei/interrupt.c
drivers/misc/mei/mei_dev.h
drivers/misc/mei/nfc.c
drivers/misc/mei/pci-me.c
drivers/misc/mic/card/mic_virtio.c
drivers/misc/mic/card/mic_virtio.h
drivers/misc/mic/host/mic_boot.c
drivers/misc/mic/host/mic_virtio.c
drivers/misc/mic/host/mic_x100.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/host/mmci.c
drivers/mmc/host/omap.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/ms02-nv.c
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/maps/sun_uflash.c
drivers/mtd/mtdpart.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/gpmi-nand/gpmi-lib.c
drivers/mtd/nand/gpmi-nand/gpmi-nand.c
drivers/mtd/nand/gpmi-nand/gpmi-nand.h
drivers/mtd/nand/mpc5121_nfc.c
drivers/mtd/nand/pasemi_nand.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/ofpart.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_options.c
drivers/net/bonding/bond_sysfs.c
drivers/net/bonding/bonding.h
drivers/net/can/c_can/c_can.c
drivers/net/can/flexcan.c
drivers/net/can/sja1000/sja1000.c
drivers/net/ethernet/8390/hydra.c
drivers/net/ethernet/8390/zorro8390.c
drivers/net/ethernet/amd/a2065.c
drivers/net/ethernet/amd/ariadne.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/intel/e1000/e1000.h
drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/intel/igb/igb_ethtool.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
drivers/net/ethernet/natsemi/macsonic.c
drivers/net/ethernet/realtek/8139cp.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/sfc/mcdi.h
drivers/net/ethernet/sfc/mcdi_mon.c
drivers/net/ethernet/smsc/smc91x.h
drivers/net/ethernet/via/via-velocity.c
drivers/net/macvtap.c
drivers/net/phy/vitesse.c
drivers/net/team/team.c
drivers/net/virtio_net.c
drivers/net/wireless/brcm80211/Kconfig
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/xen-netback/netback.c
drivers/ntb/ntb_hw.c
drivers/ntb/ntb_hw.h
drivers/ntb/ntb_regs.h
drivers/ntb/ntb_transport.c
drivers/parport/parport_mfc3.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_ibm.c
drivers/pci/hotplug/pciehp.h
drivers/pci/ioapic.c
drivers/pci/pci-acpi.c
drivers/pci/pci-driver.c
drivers/pci/pci-label.c
drivers/pci/quirks.c
drivers/pci/remove.c
drivers/pinctrl/pinctrl-baytrail.c
drivers/platform/Kconfig
drivers/platform/Makefile
drivers/platform/chrome/Kconfig [new file with mode: 0644]
drivers/platform/chrome/Makefile [new file with mode: 0644]
drivers/platform/chrome/chromeos_laptop.c [moved from drivers/platform/x86/chromeos_laptop.c with 57% similarity]
drivers/platform/chrome/chromeos_pstore.c [new file with mode: 0644]
drivers/platform/x86/Kconfig
drivers/platform/x86/Makefile
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/asus-laptop.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/classmate-laptop.c
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/dell-wmi-aio.c
drivers/platform/x86/dell-wmi.c
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/eeepc-wmi.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/hp_accel.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel-rst.c
drivers/platform/x86/intel-smartconnect.c
drivers/platform/x86/intel_menlow.c
drivers/platform/x86/intel_mid_powerbtn.c
drivers/platform/x86/intel_oaktrail.c
drivers/platform/x86/intel_scu_ipc.c
drivers/platform/x86/mxm-wmi.c
drivers/platform/x86/panasonic-laptop.c
drivers/platform/x86/pvpanic.c
drivers/platform/x86/samsung-q10.c
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/tc1100-wmi.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/topstar-laptop.c
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/toshiba_bluetooth.c
drivers/platform/x86/wmi.c
drivers/platform/x86/xo15-ebook.c
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpacpi/pnpacpi.h
drivers/power/Kconfig
drivers/power/power_supply_core.c
drivers/regulator/arizona-micsupp.c
drivers/regulator/as3722-regulator.c
drivers/regulator/core.c
drivers/regulator/gpio-regulator.c
drivers/regulator/lp3971.c
drivers/regulator/lp3972.c
drivers/regulator/pfuze100-regulator.c
drivers/regulator/tps51632-regulator.c
drivers/s390/block/dasd_diag.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_fba.c
drivers/s390/block/dcssblk.c
drivers/s390/block/scm_blk.c
drivers/s390/block/scm_blk_cluster.c
drivers/s390/block/xpram.c
drivers/s390/cio/blacklist.c
drivers/s390/cio/chsc.c
drivers/s390/cio/css.c
drivers/s390/cio/css.h
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_api.h
drivers/s390/crypto/zcrypt_cex4.c
drivers/s390/crypto/zcrypt_error.h
drivers/s390/crypto/zcrypt_msgtype50.c
drivers/s390/crypto/zcrypt_msgtype6.c
drivers/s390/crypto/zcrypt_msgtype6.h
drivers/s390/crypto/zcrypt_pcica.c
drivers/s390/crypto/zcrypt_pcicc.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-sas.c
drivers/scsi/3w-xxxx.c
drivers/scsi/a2091.c
drivers/scsi/a3000.c
drivers/scsi/a4000t.c
drivers/scsi/aacraid/linit.c
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/gdth.c
drivers/scsi/gvp11.c
drivers/scsi/hosts.c
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h
drivers/scsi/ipr.c
drivers/scsi/ips.c
drivers/scsi/libsas/sas_ata.c
drivers/scsi/libsas/sas_expander.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/mpt2sas/mpt2sas_transport.c
drivers/scsi/mpt3sas/mpt3sas_transport.c
drivers/scsi/osd/osd_initiator.c
drivers/scsi/pmcraid.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_bsg.c
drivers/scsi/qla2xxx/qla_bsg.h
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_mr.c
drivers/scsi/qla2xxx/qla_mr.h
drivers/scsi/qla2xxx/qla_nx.c
drivers/scsi/qla2xxx/qla_nx2.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/qla4xxx/ql4_def.h
drivers/scsi/qla4xxx/ql4_fw.h
drivers/scsi/qla4xxx/ql4_glbl.h
drivers/scsi/qla4xxx/ql4_isr.c
drivers/scsi/qla4xxx/ql4_mbx.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/qla4xxx/ql4_version.h
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_pm.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sd.c
drivers/scsi/sd_dif.c
drivers/scsi/sr.c
drivers/scsi/storvsc_drv.c
drivers/scsi/zorro7xx.c
drivers/sfi/sfi_acpi.c
drivers/spi/Kconfig
drivers/spi/spi-bcm2835.c
drivers/spi/spi-bcm63xx.c
drivers/spi/spi-davinci.c
drivers/spi/spi-gpio.c
drivers/spi/spi-mpc512x-psc.c
drivers/spi/spi-mxs.c
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-rspi.c
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-ti-qspi.c
drivers/spi/spi-txx9.c
drivers/spi/spi.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/android/alarm-dev.c
drivers/staging/android/sync.h
drivers/staging/bcm/Bcmchar.c
drivers/staging/bcm/DDRInit.c
drivers/staging/btmtk_usb/btmtk_usb.c
drivers/staging/ced1401/ced_ioc.c
drivers/staging/comedi/Makefile
drivers/staging/comedi/comedi_buf.c
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/comedi_internal.h
drivers/staging/comedi/comedidev.h
drivers/staging/comedi/drivers.c
drivers/staging/comedi/drivers/Makefile
drivers/staging/comedi/drivers/amplc_dio200_common.c
drivers/staging/comedi/drivers/amplc_pci224.c
drivers/staging/comedi/drivers/amplc_pci230.c
drivers/staging/comedi/drivers/c6xdigio.c
drivers/staging/comedi/drivers/cb_pcidas64.c
drivers/staging/comedi/drivers/cb_pcimdas.c
drivers/staging/comedi/drivers/das6402.c
drivers/staging/comedi/drivers/dmm32at.c
drivers/staging/comedi/drivers/dt2801.c
drivers/staging/comedi/drivers/dt2814.c
drivers/staging/comedi/drivers/dt282x.c
drivers/staging/comedi/drivers/dt3000.c
drivers/staging/comedi/drivers/dyna_pci10xx.c
drivers/staging/comedi/drivers/fl512.c
drivers/staging/comedi/drivers/gsc_hpdi.c
drivers/staging/comedi/drivers/mite.c
drivers/staging/comedi/drivers/mite.h
drivers/staging/comedi/drivers/ni_65xx.c
drivers/staging/comedi/drivers/ni_at_a2150.c
drivers/staging/comedi/drivers/ni_atmio.c
drivers/staging/comedi/drivers/ni_mio_common.c
drivers/staging/comedi/drivers/ni_mio_cs.c
drivers/staging/comedi/drivers/ni_pcidio.c
drivers/staging/comedi/drivers/ni_pcimio.c
drivers/staging/comedi/drivers/pcl730.c
drivers/staging/comedi/drivers/pcl816.c
drivers/staging/comedi/drivers/pcl818.c
drivers/staging/comedi/drivers/pcmmio.c
drivers/staging/comedi/drivers/s626.c
drivers/staging/comedi/drivers/unioxx5.c
drivers/staging/comedi/drivers/vmk80xx.c
drivers/staging/comedi/kcomedilib/Makefile
drivers/staging/comedi/kcomedilib/kcomedilib_main.c
drivers/staging/comedi/proc.c
drivers/staging/comedi/range.c
drivers/staging/crystalhd/crystalhd_cmds.c
drivers/staging/cxt1e1/comet.c
drivers/staging/cxt1e1/comet.h
drivers/staging/cxt1e1/functions.c
drivers/staging/cxt1e1/musycc.c
drivers/staging/cxt1e1/pmcc4_drv.c
drivers/staging/cxt1e1/pmcc4_private.h
drivers/staging/cxt1e1/sbeid.c
drivers/staging/dgrp/dgrp_net_ops.c
drivers/staging/dwc2/core.c
drivers/staging/dwc2/core.h
drivers/staging/dwc2/core_intr.c
drivers/staging/dwc2/hcd.c
drivers/staging/dwc2/hcd.h
drivers/staging/dwc2/hcd_ddma.c
drivers/staging/dwc2/hcd_intr.c
drivers/staging/dwc2/hcd_queue.c
drivers/staging/dwc2/platform.c
drivers/staging/ft1000/ft1000-pcmcia/boot.h
drivers/staging/ft1000/ft1000-usb/ft1000_download.c
drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
drivers/staging/ft1000/ft1000-usb/ft1000_usb.c
drivers/staging/ft1000/ft1000-usb/ft1000_usb.h
drivers/staging/gdm724x/gdm_lte.c
drivers/staging/gdm724x/gdm_mux.c
drivers/staging/gdm724x/gdm_usb.c
drivers/staging/iio/accel/adis16220_core.c
drivers/staging/iio/adc/ad7816.c
drivers/staging/iio/adc/lpc32xx_adc.c
drivers/staging/iio/addac/adt7316-i2c.c
drivers/staging/iio/addac/adt7316-spi.c
drivers/staging/iio/addac/adt7316.c
drivers/staging/iio/addac/adt7316.h
drivers/staging/iio/gyro/adis16060_core.c
drivers/staging/iio/light/isl29018.c
drivers/staging/iio/magnetometer/Kconfig
drivers/staging/iio/magnetometer/hmc5843.c
drivers/staging/iio/resolver/ad2s1200.c
drivers/staging/imx-drm/Makefile
drivers/staging/imx-drm/imx-drm-core.c
drivers/staging/imx-drm/imx-ldb.c
drivers/staging/keucr/smil.h
drivers/staging/keucr/smilmain.c
drivers/staging/keucr/smilsub.c
drivers/staging/keucr/smscsi.c
drivers/staging/lustre/include/linux/libcfs/curproc.h
drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h
drivers/staging/lustre/include/linux/libcfs/linux/kp30.h
drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h
drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h [deleted file]
drivers/staging/lustre/include/linux/lnet/types.h
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c
drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c
drivers/staging/lustre/lnet/lnet/acceptor.c
drivers/staging/lustre/lnet/lnet/api-ni.c
drivers/staging/lustre/lnet/lnet/lib-move.c
drivers/staging/lustre/lnet/lnet/lib-ptl.c
drivers/staging/lustre/lnet/lnet/module.c
drivers/staging/lustre/lnet/lnet/router.c
drivers/staging/lustre/lnet/lnet/router_proc.c
drivers/staging/lustre/lnet/selftest/brw_test.c
drivers/staging/lustre/lnet/selftest/conctl.c
drivers/staging/lustre/lnet/selftest/conrpc.c
drivers/staging/lustre/lnet/selftest/console.c
drivers/staging/lustre/lnet/selftest/console.h
drivers/staging/lustre/lnet/selftest/framework.c
drivers/staging/lustre/lnet/selftest/ping_test.c
drivers/staging/lustre/lustre/fld/fld_request.c
drivers/staging/lustre/lustre/include/cl_object.h
drivers/staging/lustre/lustre/include/linux/lustre_intent.h
drivers/staging/lustre/lustre/include/lu_object.h
drivers/staging/lustre/lustre/include/lu_target.h [deleted file]
drivers/staging/lustre/lustre/include/lustre/liblustreapi.h [deleted file]
drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
drivers/staging/lustre/lustre/include/lustre/lustre_user.h
drivers/staging/lustre/lustre/include/lustre/lustreapi.h [deleted file]
drivers/staging/lustre/lustre/include/lustre_disk.h
drivers/staging/lustre/lustre/include/lustre_dlm_flags.h
drivers/staging/lustre/lustre/include/lustre_lib.h
drivers/staging/lustre/lustre/include/lustre_net.h
drivers/staging/lustre/lustre/include/lustre_req_layout.h
drivers/staging/lustre/lustre/include/obd_support.h
drivers/staging/lustre/lustre/lclient/lcommon_cl.c
drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
drivers/staging/lustre/lustre/ldlm/ldlm_request.c
drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
drivers/staging/lustre/lustre/libcfs/debug.c
drivers/staging/lustre/lustre/libcfs/hash.c
drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c
drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
drivers/staging/lustre/lustre/libcfs/lwt.c [deleted file]
drivers/staging/lustre/lustre/libcfs/module.c
drivers/staging/lustre/lustre/libcfs/nidstrings.c
drivers/staging/lustre/lustre/libcfs/tracefile.c
drivers/staging/lustre/lustre/llite/file.c
drivers/staging/lustre/lustre/llite/llite_internal.h
drivers/staging/lustre/lustre/llite/llite_lib.c
drivers/staging/lustre/lustre/llite/lloop.c
drivers/staging/lustre/lustre/llite/namei.c
drivers/staging/lustre/lustre/llite/vvp_io.c
drivers/staging/lustre/lustre/lov/lov_io.c
drivers/staging/lustre/lustre/lov/lov_pack.c
drivers/staging/lustre/lustre/lov/lproc_lov.c
drivers/staging/lustre/lustre/lvfs/fsfilt_ext3.c [deleted file]
drivers/staging/lustre/lustre/mdc/mdc_internal.h
drivers/staging/lustre/lustre/mdc/mdc_lib.c
drivers/staging/lustre/lustre/mdc/mdc_locks.c
drivers/staging/lustre/lustre/mdc/mdc_request.c
drivers/staging/lustre/lustre/mgc/mgc_request.c
drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
drivers/staging/lustre/lustre/obdclass/llog.c
drivers/staging/lustre/lustre/obdclass/local_storage.c
drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
drivers/staging/lustre/lustre/obdclass/lu_object.c
drivers/staging/lustre/lustre/obdecho/echo_client.c
drivers/staging/lustre/lustre/osc/osc_request.c
drivers/staging/lustre/lustre/ptlrpc/Makefile
drivers/staging/lustre/lustre/ptlrpc/client.c
drivers/staging/lustre/lustre/ptlrpc/events.c
drivers/staging/lustre/lustre/ptlrpc/gss/gss_asn1.h
drivers/staging/lustre/lustre/ptlrpc/gss/gss_err.h
drivers/staging/lustre/lustre/ptlrpc/gss/gss_keyring.c
drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5_mech.c
drivers/staging/lustre/lustre/ptlrpc/gss/sec_gss.c
drivers/staging/lustre/lustre/ptlrpc/import.c
drivers/staging/lustre/lustre/ptlrpc/layout.c
drivers/staging/lustre/lustre/ptlrpc/llog_client.c
drivers/staging/lustre/lustre/ptlrpc/llog_server.c [deleted file]
drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
drivers/staging/lustre/lustre/ptlrpc/niobuf.c
drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
drivers/staging/lustre/lustre/ptlrpc/pinger.c
drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c
drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
drivers/staging/lustre/lustre/ptlrpc/service.c
drivers/staging/lustre/lustre/ptlrpc/wiretest.c
drivers/staging/media/davinci_vpfe/dm365_ipipe.c
drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c
drivers/staging/media/go7007/go7007-fw.c
drivers/staging/media/go7007/go7007-usb.c
drivers/staging/media/go7007/saa7134-go7007.c
drivers/staging/media/lirc/lirc_igorplugusb.c
drivers/staging/media/lirc/lirc_imon.c
drivers/staging/media/lirc/lirc_serial.c
drivers/staging/media/lirc/lirc_zilog.c
drivers/staging/nvec/nvec.c
drivers/staging/olpc_dcon/olpc_dcon.c
drivers/staging/ozwpan/ozeltbuf.c
drivers/staging/ozwpan/ozproto.c
drivers/staging/quickstart/quickstart.c
drivers/staging/rtl8187se/ieee80211/dot11d.c
drivers/staging/rtl8187se/ieee80211/dot11d.h
drivers/staging/rtl8187se/ieee80211/ieee80211.h
drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
drivers/staging/rtl8187se/r8180.h
drivers/staging/rtl8187se/r8180_core.c
drivers/staging/rtl8187se/r8180_dm.h
drivers/staging/rtl8187se/r8180_rtl8225.h
drivers/staging/rtl8187se/r8180_wx.c
drivers/staging/rtl8187se/r8185b_init.c
drivers/staging/rtl8188eu/core/rtw_ap.c
drivers/staging/rtl8188eu/core/rtw_io.c
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
drivers/staging/rtl8188eu/core/rtw_xmit.c
drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
drivers/staging/rtl8188eu/os_dep/osdep_service.c
drivers/staging/rtl8188eu/os_dep/usb_intf.c
drivers/staging/rtl8192e/dot11d.c
drivers/staging/rtl8192e/dot11d.h
drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
drivers/staging/rtl8192e/rtl8192e/rtl_core.c
drivers/staging/rtl8192e/rtl8192e/rtl_core.h
drivers/staging/rtl8192e/rtl819x_BAProc.c
drivers/staging/rtl8192e/rtllib_crypt_ccmp.c
drivers/staging/rtl8192e/rtllib_crypt_tkip.c
drivers/staging/rtl8192e/rtllib_crypt_wep.c
drivers/staging/rtl8192e/rtllib_module.c
drivers/staging/rtl8192e/rtllib_rx.c
drivers/staging/rtl8192e/rtllib_softmac.c
drivers/staging/rtl8192e/rtllib_tx.c
drivers/staging/rtl8712/rtl871x_mlme.c
drivers/staging/rts5208/Kconfig [new file with mode: 0644]
drivers/staging/rts5208/Makefile [new file with mode: 0644]
drivers/staging/rts5208/TODO [new file with mode: 0644]
drivers/staging/rts5208/debug.h [new file with mode: 0644]
drivers/staging/rts5208/general.c [new file with mode: 0644]
drivers/staging/rts5208/general.h [new file with mode: 0644]
drivers/staging/rts5208/ms.c [new file with mode: 0644]
drivers/staging/rts5208/ms.h [new file with mode: 0644]
drivers/staging/rts5208/rtsx.c [new file with mode: 0644]
drivers/staging/rts5208/rtsx.h [new file with mode: 0644]
drivers/staging/rts5208/rtsx_card.c [new file with mode: 0644]
drivers/staging/rts5208/rtsx_card.h [new file with mode: 0644]
drivers/staging/rts5208/rtsx_chip.c [new file with mode: 0644]
drivers/staging/rts5208/rtsx_chip.h [new file with mode: 0644]
drivers/staging/rts5208/rtsx_scsi.c [new file with mode: 0644]
drivers/staging/rts5208/rtsx_scsi.h [new file with mode: 0644]
drivers/staging/rts5208/rtsx_sys.h [new file with mode: 0644]
drivers/staging/rts5208/rtsx_transport.c [new file with mode: 0644]
drivers/staging/rts5208/rtsx_transport.h [new file with mode: 0644]
drivers/staging/rts5208/sd.c [new file with mode: 0644]
drivers/staging/rts5208/sd.h [new file with mode: 0644]
drivers/staging/rts5208/spi.c [new file with mode: 0644]
drivers/staging/rts5208/spi.h [new file with mode: 0644]
drivers/staging/rts5208/trace.h [new file with mode: 0644]
drivers/staging/rts5208/xd.c [new file with mode: 0644]
drivers/staging/rts5208/xd.h [new file with mode: 0644]
drivers/staging/silicom/bypasslib/bypass.c
drivers/staging/speakup/main.c
drivers/staging/speakup/serialio.c
drivers/staging/speakup/serialio.h
drivers/staging/tidspbridge/Kconfig
drivers/staging/tidspbridge/pmgr/cmm.c
drivers/staging/tidspbridge/pmgr/dbll.c
drivers/staging/tidspbridge/pmgr/dev.c
drivers/staging/tidspbridge/pmgr/dmm.c
drivers/staging/tidspbridge/pmgr/dspapi.c
drivers/staging/usbip/stub_rx.c
drivers/staging/usbip/usbip_common.c
drivers/staging/usbip/vhci_hcd.c
drivers/staging/vt6655/baseband.c
drivers/staging/vt6655/bssdb.c
drivers/staging/vt6655/card.c
drivers/staging/vt6655/channel.c
drivers/staging/vt6655/datarate.c
drivers/staging/vt6655/device_main.c
drivers/staging/vt6655/dpc.c
drivers/staging/vt6655/hostap.c
drivers/staging/vt6655/iwctl.c
drivers/staging/vt6655/key.c
drivers/staging/vt6655/mac.c
drivers/staging/vt6655/power.c
drivers/staging/vt6655/rf.c
drivers/staging/vt6655/rxtx.c
drivers/staging/vt6655/vntwifi.c
drivers/staging/vt6655/wcmd.c
drivers/staging/vt6655/wctl.c
drivers/staging/vt6655/wmgr.c
drivers/staging/vt6655/wpa.c
drivers/staging/vt6655/wpa2.c
drivers/staging/vt6655/wpactl.c
drivers/staging/vt6656/aes_ccmp.c
drivers/staging/vt6656/baseband.c
drivers/staging/vt6656/bssdb.c
drivers/staging/vt6656/card.c
drivers/staging/vt6656/channel.c
drivers/staging/vt6656/datarate.c
drivers/staging/vt6656/desc.h
drivers/staging/vt6656/device.h
drivers/staging/vt6656/dpc.c
drivers/staging/vt6656/hostap.c
drivers/staging/vt6656/main_usb.c
drivers/staging/vt6656/rf.c
drivers/staging/vt6656/rndis.h
drivers/staging/vt6656/rxtx.c
drivers/staging/vt6656/rxtx.h
drivers/staging/vt6656/tkip.c
drivers/staging/vt6656/wcmd.c
drivers/staging/vt6656/wmgr.c
drivers/staging/vt6656/wpa.c
drivers/staging/vt6656/wpa2.c
drivers/staging/winbond/mds.c
drivers/staging/wlags49_h2/sta_h25.c
drivers/staging/wlan-ng/cfg80211.c
drivers/staging/wlan-ng/hfa384x.h
drivers/staging/wlan-ng/prism2mgmt.c
drivers/staging/wlan-ng/prism2mgmt.h
drivers/staging/wlan-ng/prism2mib.c
drivers/staging/wlan-ng/prism2sta.c
drivers/staging/zram/zram_drv.c
drivers/staging/zsmalloc/zsmalloc-main.c
drivers/target/target_core_iblock.c
drivers/tty/amiserial.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/Kconfig
drivers/tty/serial/pmac_zilog.c
drivers/tty/serial/sh-sci.c
drivers/tty/tty_io.c
drivers/usb/core/usb-acpi.c
drivers/usb/dwc3/ep0.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/composite.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/r8a66597-udc.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/storage_common.h
drivers/usb/gadget/tcm_usb_gadget.c
drivers/usb/gadget/zero.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_cppi41.c
drivers/usb/musb/musb_gadget.c
drivers/usb/phy/phy-am335x.c
drivers/usb/phy/phy-generic.c
drivers/usb/phy/phy-generic.h
drivers/usb/phy/phy-mxs-usb.c
drivers/usb/phy/phy-rcar-gen2-usb.c
drivers/usb/serial/generic.c
drivers/video/amifb.c
drivers/video/cirrusfb.c
drivers/video/macfb.c
drivers/video/valkyriefb.c
drivers/watchdog/at91sam9_wdt.c
drivers/watchdog/bcm2835_wdt.c
drivers/watchdog/ep93xx_wdt.c
drivers/watchdog/ie6xx_wdt.c
drivers/watchdog/jz4740_wdt.c
drivers/watchdog/kempld_wdt.c
drivers/watchdog/max63xx_wdt.c
drivers/watchdog/orion_wdt.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/rt2880_wdt.c
drivers/watchdog/shwdt.c
drivers/watchdog/softdog.c
drivers/watchdog/stmp3xxx_rtc_wdt.c
drivers/watchdog/txx9wdt.c
drivers/watchdog/ux500_wdt.c
drivers/xen/grant-table.c
drivers/xen/swiotlb-xen.c
drivers/xen/xen-acpi-cpuhotplug.c
drivers/xen/xen-acpi-memhotplug.c
drivers/xen/xen-acpi-pad.c
drivers/xen/xen-acpi-processor.c
drivers/zorro/Makefile
drivers/zorro/names.c
drivers/zorro/proc.c
drivers/zorro/zorro-driver.c
drivers/zorro/zorro-sysfs.c
drivers/zorro/zorro.c
drivers/zorro/zorro.h
fs/9p/cache.c
fs/9p/vfs_file.c
fs/9p/vfs_inode.c
fs/9p/vfs_inode_dotl.c
fs/9p/xattr.c
fs/Makefile
fs/affs/Changes
fs/bio-integrity.c
fs/bio.c
fs/btrfs/check-integrity.c
fs/btrfs/check-integrity.h
fs/btrfs/compression.c
fs/btrfs/disk-io.c
fs/btrfs/extent_io.c
fs/btrfs/file-item.c
fs/btrfs/inode.c
fs/btrfs/raid56.c
fs/btrfs/scrub.c
fs/btrfs/volumes.c
fs/buffer.c
fs/ceph/addr.c
fs/ceph/cache.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/super.c
fs/ceph/super.h
fs/cifs/cifs_unicode.c
fs/cifs/cifsglob.h
fs/cifs/ioctl.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smb2proto.h
fs/cifs/smbfsctl.h
fs/direct-io.c
fs/ext4/page-io.c
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/gc.c
fs/f2fs/node.c
fs/f2fs/recovery.c
fs/f2fs/segment.c
fs/f2fs/segment.h
fs/f2fs/super.c
fs/fscache/page.c
fs/gfs2/aops.c
fs/gfs2/incore.h
fs/gfs2/lops.c
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c
fs/gfs2/rgrp.c
fs/hfsplus/wrapper.c
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_metapage.c
fs/kernfs/Makefile [new file with mode: 0644]
fs/kernfs/dir.c [new file with mode: 0644]
fs/kernfs/file.c [new file with mode: 0644]
fs/kernfs/inode.c [moved from fs/sysfs/inode.c with 89% similarity]
fs/kernfs/kernfs-internal.h [new file with mode: 0644]
fs/kernfs/mount.c [new file with mode: 0644]
fs/kernfs/symlink.c [new file with mode: 0644]
fs/logfs/dev_bdev.c
fs/logfs/dev_mtd.c
fs/logfs/super.c
fs/mpage.c
fs/namei.c
fs/namespace.c
fs/nfs/blocklayout/blocklayout.c
fs/nfs/blocklayout/blocklayout.h
fs/nfs/dns_resolve.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c
fs/nilfs2/segbuf.c
fs/ocfs2/cluster/heartbeat.c
fs/squashfs/file_direct.c
fs/sysfs/Makefile
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/group.c
fs/sysfs/mount.c
fs/sysfs/symlink.c
fs/sysfs/sysfs.h
fs/xfs/xfs_aops.c
fs/xfs/xfs_buf.c
include/acpi/acconfig.h
include/acpi/acpi_bus.h
include/acpi/acpi_drivers.h
include/acpi/acpixf.h
include/asm-generic/simd.h [new file with mode: 0644]
include/crypto/ablk_helper.h [moved from arch/x86/include/asm/crypto/ablk_helper.h with 100% similarity]
include/crypto/algapi.h
include/crypto/authenc.h
include/crypto/scatterwalk.h
include/dt-bindings/clock/imx5-clock.h [new file with mode: 0644]
include/dt-bindings/clock/imx6sl-clock.h
include/dt-bindings/clock/vf610-clock.h
include/linux/acpi.h
include/linux/acpi_io.h
include/linux/bio.h
include/linux/blk_types.h
include/linux/blkdev.h
include/linux/ceph/messenger.h
include/linux/cgroup.h
include/linux/cpufreq.h
include/linux/dm-io.h
include/linux/efi.h
include/linux/f2fs_fs.h
include/linux/ftrace_event.h
include/linux/gpio/driver.h
include/linux/hid-sensor-hub.h
include/linux/hid-sensor-ids.h
include/linux/i2c/tsc2007.h
include/linux/ide.h
include/linux/iio/iio.h
include/linux/irqchip/xtensa-mx.h [new file with mode: 0644]
include/linux/irqchip/xtensa-pic.h [new file with mode: 0644]
include/linux/irqreturn.h
include/linux/iscsi_ibft.h
include/linux/kernel.h
include/linux/kernfs.h [new file with mode: 0644]
include/linux/mfd/arizona/registers.h
include/linux/mfd/max14577-private.h [new file with mode: 0644]
include/linux/mfd/max14577.h [new file with mode: 0644]
include/linux/mtd/partitions.h
include/linux/nfs4.h
include/linux/nfs_fs.h
include/linux/padata.h
include/linux/pci_hotplug.h
include/linux/perf_event.h
include/linux/platform_data/dma-imx-sdma.h
include/linux/platform_data/dma-imx.h
include/linux/platform_data/mtd-nand-pxa3xx.h
include/linux/power_supply.h
include/linux/sched.h
include/linux/serial_sci.h
include/linux/sfi_acpi.h
include/linux/slab.h
include/linux/sysfs.h
include/linux/tboot.h
include/linux/tegra-powergate.h
include/linux/tracepoint.h
include/linux/uprobes.h
include/linux/vmpressure.h
include/linux/zorro.h
include/media/videobuf2-core.h
include/net/ip.h
include/net/ipv6.h
include/net/ping.h
include/net/sctp/structs.h
include/scsi/iscsi_if.h
include/scsi/scsi_host.h
include/scsi/scsi_transport_iscsi.h
include/sound/cs42l52.h
include/sound/dmaengine_pcm.h
include/sound/rcar_snd.h
include/sound/soc-dai.h
include/sound/soc-dapm.h
include/sound/soc.h
include/trace/events/bcache.h
include/trace/events/block.h
include/trace/events/f2fs.h
include/trace/ftrace.h
include/uapi/drm/i915_drm.h
include/uapi/linux/Kbuild
include/uapi/linux/genetlink.h
include/uapi/linux/if_link.h
include/uapi/linux/input.h
include/uapi/linux/mic_common.h
include/uapi/linux/netlink_diag.h
include/uapi/linux/packet_diag.h
include/uapi/linux/unix_diag.h
include/uapi/linux/zorro.h [new file with mode: 0644]
include/uapi/linux/zorro_ids.h [moved from include/linux/zorro_ids.h with 100% similarity]
init/Kconfig
kernel/cgroup.c
kernel/cpuset.c
kernel/events/core.c
kernel/events/uprobes.c
kernel/extable.c
kernel/fork.c
kernel/irq/pm.c
kernel/locking/lockdep.c
kernel/padata.c
kernel/panic.c
kernel/power/block_io.c
kernel/power/hibernate.c
kernel/rcu/tree_plugin.h
kernel/sched/core.c
kernel/sched/fair.c
kernel/sched/sched.h
kernel/softirq.c
kernel/time/tick-common.c
kernel/time/tick-sched.c
kernel/time/timekeeping.c
kernel/timer.c
kernel/trace/blktrace.c
kernel/trace/ftrace.c
kernel/trace/trace_event_perf.c
kernel/workqueue.c
lib/Kconfig.debug
lib/kobject.c
lib/lockref.c
mm/bounce.c
mm/memcontrol.c
mm/page_io.c
mm/vmpressure.c
net/9p/client.c
net/9p/trans_fd.c
net/9p/trans_virtio.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c
net/bluetooth/smp.c
net/ceph/messenger.c
net/compat.c
net/hsr/hsr_framereg.c
net/hsr/hsr_netlink.c
net/ipv4/ip_sockglue.c
net/ipv4/ping.c
net/ipv4/protocol.c
net/ipv4/raw.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_memcontrol.c
net/ipv4/tcp_offload.c
net/ipv4/udp.c
net/ipv6/datagram.c
net/ipv6/ip6_output.c
net/ipv6/ping.c
net/ipv6/protocol.c
net/ipv6/raw.c
net/ipv6/sit.c
net/ipv6/tcpv6_offload.c
net/ipv6/udp.c
net/l2tp/l2tp_ip6.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mlme.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/spectmgmt.c
net/mac80211/util.c
net/netlink/genetlink.c
net/packet/af_packet.c
net/sched/sch_netem.c
net/sched/sch_tbf.c
net/sctp/output.c
net/sctp/outqueue.c
net/socket.c
net/wireless/core.c
net/wireless/ibss.c
net/wireless/nl80211.c
scripts/package/builddeb
scripts/sortextable.c
security/integrity/digsig.c
security/integrity/ima/Kconfig
security/integrity/ima/ima.h
security/integrity/ima/ima_api.c
security/integrity/ima/ima_appraise.c
security/integrity/ima/ima_crypto.c
security/integrity/ima/ima_fs.c
security/integrity/ima/ima_template.c
security/integrity/ima/ima_template_lib.c
security/integrity/integrity.h
sound/firewire/amdtp.c
sound/firewire/dice.c
sound/pci/Kconfig
sound/pci/cs46xx/cs46xx.h
sound/pci/cs46xx/cs46xx_image.h [deleted file]
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs46xx/imgs/cwc4630.h [deleted file]
sound/pci/cs46xx/imgs/cwcasync.h [deleted file]
sound/pci/cs46xx/imgs/cwcbinhack.h [deleted file]
sound/pci/cs46xx/imgs/cwcdma.asp [deleted file]
sound/pci/cs46xx/imgs/cwcdma.h [deleted file]
sound/pci/cs46xx/imgs/cwcsnoop.h [deleted file]
sound/pci/hda/Makefile
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/atmel/sam9x5_wm8731.c
sound/soc/bcm/Kconfig [new file with mode: 0644]
sound/soc/bcm/Makefile [new file with mode: 0644]
sound/soc/bcm/bcm2835-i2s.c [new file with mode: 0644]
sound/soc/codecs/Kconfig
sound/soc/codecs/ad193x.c
sound/soc/codecs/adav80x.c
sound/soc/codecs/ak4641.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/arizona.c
sound/soc/codecs/arizona.h
sound/soc/codecs/cs4271.c
sound/soc/codecs/cs42l52.c
sound/soc/codecs/da7210.c
sound/soc/codecs/hdmi.c
sound/soc/codecs/ssm2602.c
sound/soc/codecs/uda1380.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8510.c
sound/soc/codecs/wm8523.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8728.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8741.c
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8776.c
sound/soc/codecs/wm8804.c
sound/soc/codecs/wm8900.c
sound/soc/codecs/wm8940.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8974.c
sound/soc/codecs/wm8985.c
sound/soc/codecs/wm8988.c
sound/soc/codecs/wm8990.c
sound/soc/codecs/wm8990.h
sound/soc/codecs/wm8991.c
sound/soc/codecs/wm8991.h
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8995.c
sound/soc/codecs/wm9081.c
sound/soc/codecs/wm_adsp.c
sound/soc/fsl/fsl_ssi.c
sound/soc/intel/Kconfig [moved from sound/soc/mid-x86/Kconfig with 100% similarity]
sound/soc/intel/Makefile [moved from sound/soc/mid-x86/Makefile with 100% similarity]
sound/soc/intel/mfld_machine.c [moved from sound/soc/mid-x86/mfld_machine.c with 100% similarity]
sound/soc/intel/sst_dsp.h [moved from sound/soc/mid-x86/sst_dsp.h with 100% similarity]
sound/soc/intel/sst_platform.c [moved from sound/soc/mid-x86/sst_platform.c with 100% similarity]
sound/soc/intel/sst_platform.h [moved from sound/soc/mid-x86/sst_platform.h with 100% similarity]
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/omap/mcbsp.c
sound/soc/omap/omap-dmic.c
sound/soc/omap/omap-mcpdm.c
sound/soc/sh/Kconfig
sound/soc/sh/rcar/gen.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/ssi.c
sound/soc/soc-core.c
sound/soc/soc-devres.c
sound/soc/soc-io.c
sound/soc/soc-pcm.c
sound/soc/spear/spear_pcm.c
sound/soc/ux500/mop500.c
sound/soc/ux500/ux500_msp_dai.c
sound/soc/ux500/ux500_msp_i2s.c
sound/soc/ux500/ux500_pcm.c
sound/usb/endpoint.c
tools/lib/lockdep/Makefile [new file with mode: 0644]
tools/lib/lockdep/common.c [new file with mode: 0644]
tools/lib/lockdep/include/liblockdep/common.h [new file with mode: 0644]
tools/lib/lockdep/include/liblockdep/mutex.h [new file with mode: 0644]
tools/lib/lockdep/include/liblockdep/rwlock.h [new file with mode: 0644]
tools/lib/lockdep/lockdep [new file with mode: 0755]
tools/lib/lockdep/lockdep.c [new file with mode: 0644]
tools/lib/lockdep/lockdep_internals.h [new file with mode: 0644]
tools/lib/lockdep/lockdep_states.h [new file with mode: 0644]
tools/lib/lockdep/preload.c [new file with mode: 0644]
tools/lib/lockdep/rbtree.c [new file with mode: 0644]
tools/lib/lockdep/run_tests.sh [new file with mode: 0644]
tools/lib/lockdep/tests/AA.c [new file with mode: 0644]
tools/lib/lockdep/tests/ABBA.c [new file with mode: 0644]
tools/lib/lockdep/tests/ABBCCA.c [new file with mode: 0644]
tools/lib/lockdep/tests/ABBCCDDA.c [new file with mode: 0644]
tools/lib/lockdep/tests/ABCABC.c [new file with mode: 0644]
tools/lib/lockdep/tests/ABCDBCDA.c [new file with mode: 0644]
tools/lib/lockdep/tests/ABCDBDDA.c [new file with mode: 0644]
tools/lib/lockdep/tests/WW.c [new file with mode: 0644]
tools/lib/lockdep/tests/common.h [new file with mode: 0644]
tools/lib/lockdep/tests/unlock_balance.c [new file with mode: 0644]
tools/lib/lockdep/uinclude/asm/hweight.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/asm/sections.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/bitops.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/compiler.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/debug_locks.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/delay.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/export.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/ftrace.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/gfp.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/hardirq.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/hash.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/interrupt.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/irqflags.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/kallsyms.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/kern_levels.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/kernel.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/kmemcheck.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/linkage.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/list.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/lockdep.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/module.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/mutex.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/poison.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/prefetch.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/proc_fs.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/rbtree.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/rbtree_augmented.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/rcu.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/seq_file.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/spinlock.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/stacktrace.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/stringify.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/types.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/trace/events/lock.h [new file with mode: 0644]
tools/lib/traceevent/event-parse.c
tools/perf/Documentation/perf-record.txt
tools/perf/Documentation/perf-script.txt
tools/perf/Documentation/perf-timechart.txt
tools/perf/Documentation/perf-top.txt
tools/perf/Makefile
tools/perf/Makefile.perf
tools/perf/builtin-record.c
tools/perf/builtin-script.c
tools/perf/builtin-stat.c
tools/perf/builtin-timechart.c
tools/perf/builtin-top.c
tools/perf/builtin-trace.c
tools/perf/perf-completion.sh [moved from tools/perf/bash_completion with 65% similarity]
tools/perf/perf.h
tools/perf/tests/attr/test-record-no-inherit
tools/perf/util/event.c
tools/perf/util/evlist.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/header.c
tools/perf/util/parse-events.c
tools/perf/util/parse-options.c
tools/perf/util/parse-options.h
tools/perf/util/pmu.c
tools/perf/util/pmu.h
tools/perf/util/session.c
tools/perf/util/svghelper.c
tools/perf/util/svghelper.h
tools/perf/util/symbol.c
tools/perf/util/symbol.h
tools/perf/util/target.c
tools/perf/util/target.h
tools/perf/util/thread.c
tools/perf/util/thread.h
tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c
tools/power/cpupower/man/cpupower-idle-info.1
tools/power/cpupower/man/cpupower-idle-set.1 [new file with mode: 0644]
tools/power/cpupower/utils/helpers/sysfs.c

diff --git a/CREDITS b/CREDITS
index 4fc997d58ab2640a4b94fdcb1f363935f8a13395..4c7738f493570eb9d0c70e6db67c527bcbe6e691 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -655,6 +655,11 @@ S: Stanford University
 S: Stanford, California 94305
 S: USA
 
+N: Carlos Chinea
+E: carlos.chinea@nokia.com
+E: cch.devel@gmail.com
+D: Author of HSI Subsystem
+
 N: Randolph Chung
 E: tausq@debian.org
 D: Linux/PA-RISC hacker
index b1758088527339466c5d5eb8be6151eabe02952d..07c75d18154e7608f9368caaf6fbbca2baa6aafd 100644 (file)
@@ -196,13 +196,6 @@ chmod 0644 /dev/cpu/microcode
 as root before you can use this.  You'll probably also want to
 get the user-space microcode_ctl utility to use with this.
 
-Powertweak
-----------
-
-If you are running v0.1.17 or earlier, you should upgrade to
-version v0.99.0 or higher. Running old versions may cause problems
-with programs using shared memory.
-
 udev
 ----
 udev is a userspace application for populating /dev dynamically with
@@ -366,10 +359,6 @@ Intel P6 microcode
 ------------------
 o  <http://www.urbanmyth.org/microcode/>
 
-Powertweak
-----------
-o  <http://powertweak.sourceforge.net/>
-
 udev
 ----
 o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
index 6c9d9d37c83a30e24cce3ed25abf484e1bbd18f1..f5170082bdb3738eb409d67dfedd2851b683d2b6 100644 (file)
@@ -58,7 +58,7 @@
      </sect1>
      <sect1><title>Wait queues and Wake events</title>
 !Iinclude/linux/wait.h
-!Ekernel/wait.c
+!Ekernel/sched/wait.c
      </sect1>
      <sect1><title>High-resolution timers</title>
 !Iinclude/linux/ktime.h
index e287c8fc803b437ce34550ba88777183f66ca0cc..4165e7bfa4ff7560c0283213e53a54b1575ab2e8 100644 (file)
@@ -73,7 +73,8 @@ range from zero to the maximal number of valid planes for the currently active
 format. For the single-planar API, applications must set <structfield> plane
 </structfield> to zero.  Additional flags may be posted in the <structfield>
 flags </structfield> field.  Refer to a manual for open() for details.
-Currently only O_CLOEXEC is supported.  All other fields must be set to zero.
+Currently only O_CLOEXEC, O_RDONLY, O_WRONLY, and O_RDWR are supported.  All
+other fields must be set to zero.
 In the case of multi-planar API, every plane is exported separately using
 multiple <constant> VIDIOC_EXPBUF </constant> calls. </para>
 
@@ -170,8 +171,9 @@ multi-planar API. Otherwise this value must be set to zero. </entry>
            <entry>__u32</entry>
            <entry><structfield>flags</structfield></entry>
            <entry>Flags for the newly created file, currently only <constant>
-O_CLOEXEC </constant> is supported, refer to the manual of open() for more
-details.</entry>
+O_CLOEXEC </constant>, <constant>O_RDONLY</constant>, <constant>O_WRONLY
+</constant>, and <constant>O_RDWR</constant> are supported, refer to the manual
+of open() for more details.</entry>
          </row>
          <row>
            <entry>__s32</entry>
index 260f6a3661faff625aabda6bc3dc6ba9eda84012..1860cb3865c6b26474a2d07d3944a9858a9f07c6 100644 (file)
@@ -235,10 +235,6 @@ Wysocki <rafael.j.wysocki@intel.com>.
       named object's type in the second column).  In that case the object's
       directory in sysfs will contain the 'path' attribute whose value is
       the full path to the node from the namespace root.
-      struct acpi_device objects are created for the ACPI namespace nodes
-      whose _STA control methods return PRESENT or FUNCTIONING.  The power
-      resource nodes or nodes without _STA are assumed to be both PRESENT
-      and FUNCTIONING.
    F:
       The struct acpi_device object is created for a fixed hardware
       feature (as indicated by the fixed feature flag's name in the second
@@ -340,7 +336,7 @@ Wysocki <rafael.j.wysocki@intel.com>.
      | +-------------+-------+----------------+
      |   |
      |   | +- - - - - - - +- - - - - - +- - - - - - - -+
-     |   +-| PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: |
+     |   +-| PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: |
      |   | +- - - - - - - +- - - - - - +- - - - - - - -+
      |   |
      |   | +------------+------------+-----------------------+
@@ -390,6 +386,3 @@ Wysocki <rafael.j.wysocki@intel.com>.
             attribute (as described earlier in this document).
    NOTE: N/A indicates the device object does not have the 'path' or the
          'modalias' attribute.
-   NOTE: The PNP0C0D device listed above is highlighted (marked by "*")
-         to indicate it will be created only when its _STA methods return
-         PRESENT or FUNCTIONING.
index 8df5e8e6dceba06846042d0c6155fd4e986addd8..2101e718670d0248110caa4320e51e83c715fad2 100644 (file)
@@ -447,14 +447,13 @@ struct bio_vec {
  * main unit of I/O for the block layer and lower layers (ie drivers)
  */
 struct bio {
-       sector_t            bi_sector;
        struct bio          *bi_next;    /* request queue link */
        struct block_device *bi_bdev;   /* target device */
        unsigned long       bi_flags;    /* status, command, etc */
        unsigned long       bi_rw;       /* low bits: r/w, high: priority */
 
        unsigned int    bi_vcnt;     /* how may bio_vec's */
-       unsigned int    bi_idx;         /* current index into bio_vec array */
+       struct bvec_iter        bi_iter;        /* current index into bio_vec array */
 
        unsigned int    bi_size;     /* total size in bytes */
        unsigned short  bi_phys_segments; /* segments after physaddr coalesce*/
@@ -480,7 +479,7 @@ With this multipage bio design:
 - Code that traverses the req list can find all the segments of a bio
   by using rq_for_each_segment.  This handles the fact that a request
   has multiple bios, each of which can have multiple segments.
-- Drivers which can't process a large bio in one shot can use the bi_idx
+- Drivers which can't process a large bio in one shot can use the bi_iter
   field to keep track of the next bio_vec entry to process.
   (e.g a 1MB bio_vec needs to be handled in max 128kB chunks for IDE)
   [TBD: Should preferably also have a bi_voffset and bi_vlen to avoid modifying
@@ -589,7 +588,7 @@ driver should not modify these values. The block layer sets up the
 nr_sectors and current_nr_sectors fields (based on the corresponding
 hard_xxx values and the number of bytes transferred) and updates it on
 every transfer that invokes end_that_request_first. It does the same for the
-buffer, bio, bio->bi_idx fields too.
+buffer, bio, bio->bi_iter fields too.
 
 The buffer field is just a virtual address mapping of the current segment
 of the i/o buffer in cases where the buffer resides in low-memory. For high
diff --git a/Documentation/block/biovecs.txt b/Documentation/block/biovecs.txt
new file mode 100644 (file)
index 0000000..74a32ad
--- /dev/null
@@ -0,0 +1,111 @@
+
+Immutable biovecs and biovec iterators:
+=======================================
+
+Kent Overstreet <kmo@daterainc.com>
+
+As of 3.13, biovecs should never be modified after a bio has been submitted.
+Instead, we have a new struct bvec_iter which represents a range of a biovec -
+the iterator will be modified as the bio is completed, not the biovec.
+
+More specifically, old code that needed to partially complete a bio would
+update bi_sector and bi_size, and advance bi_idx to the next biovec. If it
+ended up partway through a biovec, it would increment bv_offset and decrement
+bv_len by the number of bytes completed in that biovec.
+
+In the new scheme of things, everything that must be mutated in order to
+partially complete a bio is segregated into struct bvec_iter: bi_sector,
+bi_size and bi_idx have been moved there; and instead of modifying bv_offset
+and bv_len, struct bvec_iter has bi_bvec_done, which represents the number of
+bytes completed in the current bvec.
+
+There are a bunch of new helper macros for hiding the gory details - in
+particular, presenting the illusion of partially completed biovecs so that
+normal code doesn't have to deal with bi_bvec_done.
+
+ * Driver code should no longer refer to biovecs directly; we now have
+   bio_iovec() and bio_iovec_iter() macros that return literal struct biovecs,
+   constructed from the raw biovecs but taking into account bi_bvec_done and
+   bi_size.
+
+   bio_for_each_segment() has been updated to take a bvec_iter argument
+   instead of an integer (that corresponded to bi_idx); for a lot of code the
+   conversion just required changing the types of the arguments to
+   bio_for_each_segment().
+
+ * Advancing a bvec_iter is done with bio_advance_iter(); bio_advance() is a
+   wrapper around bio_advance_iter() that operates on bio->bi_iter, and also
+   advances the bio integrity's iter if present.
+
+   There is a lower level advance function - bvec_iter_advance() - which takes
+   a pointer to a biovec, not a bio; this is used by the bio integrity code.
+
+What's all this get us?
+=======================
+
+Having a real iterator, and making biovecs immutable, has a number of
+advantages:
+
+ * Before, iterating over bios was very awkward when you weren't processing
+   exactly one bvec at a time - for example, bio_copy_data() in fs/bio.c,
+   which copies the contents of one bio into another. Because the biovecs
+   wouldn't necessarily be the same size, the old code was tricky convoluted -
+   it had to walk two different bios at the same time, keeping both bi_idx and
+   and offset into the current biovec for each.
+
+   The new code is much more straightforward - have a look. This sort of
+   pattern comes up in a lot of places; a lot of drivers were essentially open
+   coding bvec iterators before, and having common implementation considerably
+   simplifies a lot of code.
+
+ * Before, any code that might need to use the biovec after the bio had been
+   completed (perhaps to copy the data somewhere else, or perhaps to resubmit
+   it somewhere else if there was an error) had to save the entire bvec array
+   - again, this was being done in a fair number of places.
+
+ * Biovecs can be shared between multiple bios - a bvec iter can represent an
+   arbitrary range of an existing biovec, both starting and ending midway
+   through biovecs. This is what enables efficient splitting of arbitrary
+   bios. Note that this means we _only_ use bi_size to determine when we've
+   reached the end of a bio, not bi_vcnt - and the bio_iovec() macro takes
+   bi_size into account when constructing biovecs.
+
+ * Splitting bios is now much simpler. The old bio_split() didn't even work on
+   bios with more than a single bvec! Now, we can efficiently split arbitrary
+   size bios - because the new bio can share the old bio's biovec.
+
+   Care must be taken to ensure the biovec isn't freed while the split bio is
+   still using it, in case the original bio completes first, though. Using
+   bio_chain() when splitting bios helps with this.
+
+ * Submitting partially completed bios is now perfectly fine - this comes up
+   occasionally in stacking block drivers and various code (e.g. md and
+   bcache) had some ugly workarounds for this.
+
+   It used to be the case that submitting a partially completed bio would work
+   fine to _most_ devices, but since accessing the raw bvec array was the
+   norm, not all drivers would respect bi_idx and those would break. Now,
+   since all drivers _must_ go through the bvec iterator - and have been
+   audited to make sure they are - submitting partially completed bios is
+   perfectly fine.
+
+Other implications:
+===================
+
+ * Almost all usage of bi_idx is now incorrect and has been removed; instead,
+   where previously you would have used bi_idx you'd now use a bvec_iter,
+   probably passing it to one of the helper macros.
+
+   I.e. instead of using bio_iovec_idx() (or bio->bi_iovec[bio->bi_idx]), you
+   now use bio_iter_iovec(), which takes a bvec_iter and returns a
+   literal struct bio_vec - constructed on the fly from the raw biovec but
+   taking into account bi_bvec_done (and bi_size).
+
+ * bi_vcnt can't be trusted or relied upon by driver code - i.e. anything that
+   doesn't actually own the bio. The reason is twofold: firstly, it's not
+   actually needed for iterating over the bio anymore - we only use bi_size.
+   Secondly, when cloning a bio and reusing (a portion of) the original bio's
+   biovec, in order to calculate bi_vcnt for the new bio we'd have to iterate
+   over all the biovecs in the new bio - which is silly as it's not needed.
+
+   So, don't use bi_vcnt anymore.
index 638bf17ff86965a561b5cc258451ea53bd752f1a..821de56d15802c3e41a18d4aac41dbb64f272832 100644 (file)
@@ -24,7 +24,6 @@ CONTENTS:
   2.1 Basic Usage
   2.2 Attaching processes
   2.3 Mounting hierarchies by name
-  2.4 Notification API
 3. Kernel API
   3.1 Overview
   3.2 Synchronization
@@ -472,25 +471,6 @@ you give a subsystem a name.
 The name of the subsystem appears as part of the hierarchy description
 in /proc/mounts and /proc/<pid>/cgroups.
 
-2.4 Notification API
---------------------
-
-There is mechanism which allows to get notifications about changing
-status of a cgroup.
-
-To register a new notification handler you need to:
- - create a file descriptor for event notification using eventfd(2);
- - open a control file to be monitored (e.g. memory.usage_in_bytes);
- - write "<event_fd> <control_fd> <args>" to cgroup.event_control.
-   Interpretation of args is defined by control file implementation;
-
-eventfd will be woken up by control file implementation or when the
-cgroup is removed.
-
-To unregister a notification handler just close eventfd.
-
-NOTE: Support of notifications should be implemented for the control
-file. See documentation for the subsystem.
 
 3. Kernel API
 =============
index 274752f8bdf963b0f1757f2df446f6c5a503c6a5..719320b5ed3f36f476bd019781b774c3b4b8ace6 100644 (file)
@@ -266,10 +266,12 @@ E.g.
 Invalidation is removing an entry from the cache without writing it
 back.  Cache blocks can be invalidated via the invalidate_cblocks
 message, which takes an arbitrary number of cblock ranges.  Each cblock
-must be expressed as a decimal value, in the future a variant message
-that takes cblock ranges expressed in hexidecimal may be needed to
-better support efficient invalidation of larger caches.  The cache must
-be in passthrough mode when invalidate_cblocks is used.
+range's end value is "one past the end", meaning 5-10 expresses a range
+of values from 5 to 9.  Each cblock must be expressed as a decimal
+value, in the future a variant message that takes cblock ranges
+expressed in hexidecimal may be needed to better support efficient
+invalidation of larger caches.  The cache must be in passthrough mode
+when invalidate_cblocks is used.
 
    invalidate_cblocks [<cblock>|<cblock begin>-<cblock end>]*
 
index 91304353eea45193606d1df7925b4e45e7484f74..632015f8314ff785d237d0fddee601b932ee95b4 100644 (file)
@@ -191,6 +191,14 @@ nodes to be present and contain the properties described below.
                          property identifying a 64-bit zero-initialised
                          memory location.
 
+       - lpae
+               Usage: Indicates that the CPU can use the LPAE extensions to
+                      address more than 32 bit physical memory.
+               Value type: <empty>
+               Definition:
+                       # On ARMv7 systems this boolean property is used
+                         to indicate LPAE feature capability.
+
 Example 1 (dual-cluster big.LITTLE system 32-bit):
 
        cpus {
index 4c029a8739d3abae79c08ea1e100fc9b91efe642..cadc4d29ada6663716c5135f78adcc3df902ee8e 100644 (file)
@@ -7,197 +7,8 @@ Required properties:
 - #clock-cells: Should be <1>
 
 The clock consumer should specify the desired clock by having the clock
-ID in its "clocks" phandle cell.  The following is a full list of i.MX5
-clocks and IDs.
-
-       Clock                   ID
-       ---------------------------
-       dummy                   0
-       ckil                    1
-       osc                     2
-       ckih1                   3
-       ckih2                   4
-       ahb                     5
-       ipg                     6
-       axi_a                   7
-       axi_b                   8
-       uart_pred               9
-       uart_root               10
-       esdhc_a_pred            11
-       esdhc_b_pred            12
-       esdhc_c_s               13
-       esdhc_d_s               14
-       emi_sel                 15
-       emi_slow_podf           16
-       nfc_podf                17
-       ecspi_pred              18
-       ecspi_podf              19
-       usboh3_pred             20
-       usboh3_podf             21
-       usb_phy_pred            22
-       usb_phy_podf            23
-       cpu_podf                24
-       di_pred                 25
-       tve_s                   27
-       uart1_ipg_gate          28
-       uart1_per_gate          29
-       uart2_ipg_gate          30
-       uart2_per_gate          31
-       uart3_ipg_gate          32
-       uart3_per_gate          33
-       i2c1_gate               34
-       i2c2_gate               35
-       gpt_ipg_gate            36
-       pwm1_ipg_gate           37
-       pwm1_hf_gate            38
-       pwm2_ipg_gate           39
-       pwm2_hf_gate            40
-       gpt_hf_gate             41
-       fec_gate                42
-       usboh3_per_gate         43
-       esdhc1_ipg_gate         44
-       esdhc2_ipg_gate         45
-       esdhc3_ipg_gate         46
-       esdhc4_ipg_gate         47
-       ssi1_ipg_gate           48
-       ssi2_ipg_gate           49
-       ssi3_ipg_gate           50
-       ecspi1_ipg_gate         51
-       ecspi1_per_gate         52
-       ecspi2_ipg_gate         53
-       ecspi2_per_gate         54
-       cspi_ipg_gate           55
-       sdma_gate               56
-       emi_slow_gate           57
-       ipu_s                   58
-       ipu_gate                59
-       nfc_gate                60
-       ipu_di1_gate            61
-       vpu_s                   62
-       vpu_gate                63
-       vpu_reference_gate      64
-       uart4_ipg_gate          65
-       uart4_per_gate          66
-       uart5_ipg_gate          67
-       uart5_per_gate          68
-       tve_gate                69
-       tve_pred                70
-       esdhc1_per_gate         71
-       esdhc2_per_gate         72
-       esdhc3_per_gate         73
-       esdhc4_per_gate         74
-       usb_phy_gate            75
-       hsi2c_gate              76
-       mipi_hsc1_gate          77
-       mipi_hsc2_gate          78
-       mipi_esc_gate           79
-       mipi_hsp_gate           80
-       ldb_di1_div_3_5         81
-       ldb_di1_div             82
-       ldb_di0_div_3_5         83
-       ldb_di0_div             84
-       ldb_di1_gate            85
-       can2_serial_gate        86
-       can2_ipg_gate           87
-       i2c3_gate               88
-       lp_apm                  89
-       periph_apm              90
-       main_bus                91
-       ahb_max                 92
-       aips_tz1                93
-       aips_tz2                94
-       tmax1                   95
-       tmax2                   96
-       tmax3                   97
-       spba                    98
-       uart_sel                99
-       esdhc_a_sel             100
-       esdhc_b_sel             101
-       esdhc_a_podf            102
-       esdhc_b_podf            103
-       ecspi_sel               104
-       usboh3_sel              105
-       usb_phy_sel             106
-       iim_gate                107
-       usboh3_gate             108
-       emi_fast_gate           109
-       ipu_di0_gate            110
-       gpc_dvfs                111
-       pll1_sw                 112
-       pll2_sw                 113
-       pll3_sw                 114
-       ipu_di0_sel             115
-       ipu_di1_sel             116
-       tve_ext_sel             117
-       mx51_mipi               118
-       pll4_sw                 119
-       ldb_di1_sel             120
-       di_pll4_podf            121
-       ldb_di0_sel             122
-       ldb_di0_gate            123
-       usb_phy1_gate           124
-       usb_phy2_gate           125
-       per_lp_apm              126
-       per_pred1               127
-       per_pred2               128
-       per_podf                129
-       per_root                130
-       ssi_apm                 131
-       ssi1_root_sel           132
-       ssi2_root_sel           133
-       ssi3_root_sel           134
-       ssi_ext1_sel            135
-       ssi_ext2_sel            136
-       ssi_ext1_com_sel        137
-       ssi_ext2_com_sel        138
-       ssi1_root_pred          139
-       ssi1_root_podf          140
-       ssi2_root_pred          141
-       ssi2_root_podf          142
-       ssi_ext1_pred           143
-       ssi_ext1_podf           144
-       ssi_ext2_pred           145
-       ssi_ext2_podf           146
-       ssi1_root_gate          147
-       ssi2_root_gate          148
-       ssi3_root_gate          149
-       ssi_ext1_gate           150
-       ssi_ext2_gate           151
-       epit1_ipg_gate          152
-       epit1_hf_gate           153
-       epit2_ipg_gate          154
-       epit2_hf_gate           155
-       can_sel                 156
-       can1_serial_gate        157
-       can1_ipg_gate           158
-       owire_gate              159
-       gpu3d_s                 160
-       gpu2d_s                 161
-       gpu3d_gate              162
-       gpu2d_gate              163
-       garb_gate               164
-       cko1_sel                165
-       cko1_podf               166
-       cko1                    167
-       cko2_sel                168
-       cko2_podf               169
-       cko2                    170
-       srtc_gate               171
-       pata_gate               172
-       sata_gate               173
-       spdif_xtal_sel          174
-       spdif0_sel              175
-       spdif1_sel              176
-       spdif0_pred             177
-       spdif0_podf             178
-       spdif1_pred             179
-       spdif1_podf             180
-       spdif0_com_sel          181
-       spdif1_com_sel          182
-       spdif0_gate             183
-       spdif1_gate             184
-       spdif_ipg_gate          185
-       ocram                   186
+ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx5-clock.h
+for the full list of i.MX5 clock IDs.
 
 Examples (for mx53):
 
@@ -212,7 +23,7 @@ can1: can@53fc8000 {
        compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
        reg = <0x53fc8000 0x4000>;
        interrupts = <82>;
-       clocks = <&clks 158>, <&clks 157>;
+       clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, <&clks IMX5_CLK_CAN1_SERIAL_GATE>;
        clock-names = "ipg", "per";
        status = "disabled";
 };
index 4fa814d3832124adb80f29ee777849739acbb7e4..68b83ecc385007216d391f1a0edf06527dad5fb9 100644 (file)
@@ -42,6 +42,7 @@ The full ID of peripheral types can be found below.
        19      IPU Memory
        20      ASRC
        21      ESAI
+       22      SSI Dual FIFO   (needs firmware ver >= 2)
 
 The third cell specifies the transfer priority as below.
 
index 56564aa4b444addcf9b770bfd4dbe6476f2b3d4d..7e49839d41249ca5168b0de1ea02781a2798486d 100644 (file)
@@ -1,7 +1,8 @@
 I2C for OMAP platforms
 
 Required properties :
-- compatible : Must be "ti,omap3-i2c" or "ti,omap4-i2c"
+- compatible : Must be "ti,omap2420-i2c", "ti,omap2430-i2c", "ti,omap3-i2c"
+  or "ti,omap4-i2c"
 - ti,hwmods : Must be "i2c<n>", n being the instance number (1-based)
 - #address-cells = <1>;
 - #size-cells = <0>;
diff --git a/Documentation/devicetree/bindings/iio/light/tsl2563.txt b/Documentation/devicetree/bindings/iio/light/tsl2563.txt
new file mode 100644 (file)
index 0000000..f91e809
--- /dev/null
@@ -0,0 +1,19 @@
+* AMS TAOS TSL2563 ambient light sensor
+
+Required properties:
+
+  - compatible : should be "amstaos,tsl2563"
+  - reg : the I2C address of the sensor
+
+Optional properties:
+
+  - amstaos,cover-comp-gain : integer used as multiplier for gain
+                              compensation (default = 1)
+
+Example:
+
+tsl2563@29 {
+       compatible = "amstaos,tsl2563";
+       reg = <0x29>;
+       amstaos,cover-comp-gain = <16>;
+};
diff --git a/Documentation/devicetree/bindings/iio/magnetometer/hmc5843.txt b/Documentation/devicetree/bindings/iio/magnetometer/hmc5843.txt
new file mode 100644 (file)
index 0000000..90d5f34
--- /dev/null
@@ -0,0 +1,17 @@
+* Honeywell HMC5843 magnetometer sensor
+
+Required properties:
+
+  - compatible : should be "honeywell,hmc5843"
+  - reg : the I2C address of the magnetometer - typically 0x1e
+
+Optional properties:
+
+  - gpios : should be device tree identifier of the magnetometer DRDY pin
+
+Example:
+
+hmc5843@1e {
+        compatible = "honeywell,hmc5843"
+        reg = <0x1e>;
+};
diff --git a/Documentation/devicetree/bindings/input/gpio-beeper.txt b/Documentation/devicetree/bindings/input/gpio-beeper.txt
new file mode 100644 (file)
index 0000000..a5086e3
--- /dev/null
@@ -0,0 +1,13 @@
+* GPIO beeper device tree bindings
+
+Register a beeper connected to GPIO pin.
+
+Required properties:
+- compatible:  Should be "gpio-beeper".
+- gpios:       From common gpio binding; gpio connection to beeper enable pin.
+
+Example:
+       beeper: beeper {
+               compatible = "gpio-beeper";
+               gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+       };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
new file mode 100644 (file)
index 0000000..ec365e1
--- /dev/null
@@ -0,0 +1,41 @@
+* Texas Instruments tsc2007 touchscreen controller
+
+Required properties:
+- compatible: must be "ti,tsc2007".
+- reg: I2C address of the chip.
+- ti,x-plate-ohms: X-plate resistance in ohms.
+
+Optional properties:
+- gpios: the interrupt gpio the chip is connected to (trough the penirq pin).
+  The penirq pin goes to low when the panel is touched.
+  (see GPIO binding[1] for more details).
+- interrupt-parent: the phandle for the gpio controller
+  (see interrupt binding[0]).
+- interrupts: (gpio) interrupt to which the chip is connected
+  (see interrupt binding[0]).
+- ti,max-rt: maximum pressure.
+- ti,fuzzx: specifies the absolute input fuzz x value.
+  If set, it will permit noise in the data up to +- the value given to the fuzz
+  parameter, that is used to filter noise from the event stream.
+- ti,fuzzy: specifies the absolute input fuzz y value.
+- ti,fuzzz: specifies the absolute input fuzz z value.
+- ti,poll-period: how much time to wait (in milliseconds) before reading again the
+  values from the tsc2007.
+
+[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+[1]: Documentation/devicetree/bindings/gpio/gpio.txt
+
+Example:
+       &i2c1 {
+               /* ... */
+               tsc2007@49 {
+                       compatible = "ti,tsc2007";
+                       reg = <0x49>;
+                       interrupt-parent = <&gpio4>;
+                       interrupts = <0x0 0x8>;
+                       gpios = <&gpio4 0 0>;
+                       ti,x-plate-ohms = <180>;
+               };
+
+               /* ... */
+       };
diff --git a/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt b/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt
new file mode 100644 (file)
index 0000000..c864a46
--- /dev/null
@@ -0,0 +1,21 @@
+Texas Instruments TWL family (twl4030) pwrbutton module
+
+This module is part of the TWL4030. For more details about the whole
+chip see Documentation/devicetree/bindings/mfd/twl-familly.txt.
+
+This module provides a simple power button event via an Interrupt.
+
+Required properties:
+- compatible: should be one of the following
+   - "ti,twl4030-pwrbutton": For controllers compatible with twl4030
+- interrupts: should be one of the following
+   - <8>: For controllers compatible with twl4030
+
+Example:
+
+&twl {
+       twl_pwrbutton: pwrbutton {
+               compatible = "ti,twl4030-pwrbutton";
+               interrupts = <8>;
+       };
+};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/marvell,dove-pmu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/marvell,dove-pmu-intc.txt
new file mode 100644 (file)
index 0000000..1feb582
--- /dev/null
@@ -0,0 +1,17 @@
+Marvell Dove Power Management Unit interrupt controller
+
+Required properties:
+- compatible: shall be "marvell,dove-pmu-intc"
+- reg: base address of PMU interrupt registers starting with CAUSE register
+- interrupts: PMU interrupt of the main interrupt controller
+- interrupt-controller: identifies the node as an interrupt controller
+- #interrupt-cells: number of cells to encode an interrupt source, shall be 1
+
+Example:
+       pmu_intc: pmu-interrupt-ctrl@d0050 {
+               compatible = "marvell,dove-pmu-intc";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               reg = <0xd0050 0x8>;
+               interrupts = <33>;
+       };
index 80ff3dfb1f325e89993184324e8ed053fd15e867..d7221b84987cd684169bee2765a050cba3511c75 100644 (file)
@@ -2,6 +2,13 @@ LEDs connected to tca6507
 
 Required properties:
 - compatible : should be : "ti,tca6507".
+- #address-cells: must be 1
+- #size-cells: must be 0
+- reg: typically 0x45.
+
+Optional properties:
+- gpio-controller: allows lines to be used as output-only GPIOs.
+- #gpio-cells: if present, must be 0.
 
 Each led is represented as a sub-node of the ti,tca6507 device.
 
@@ -10,6 +17,7 @@ LED sub-node properties:
 - reg : number of LED line (could be from 0 to 6)
 - linux,default-trigger : (optional)
    see Documentation/devicetree/bindings/leds/common.txt
+- compatible: either "led" (the default) or "gpio".
 
 Examples:
 
@@ -19,6 +27,9 @@ tca6507@45 {
        #size-cells = <0>;
        reg = <0x45>;
 
+       gpio-controller;
+       #gpio-cells = <2>;
+
        led0: red-aux@0 {
                label = "red:aux";
                reg = <0x0>;
@@ -29,5 +40,10 @@ tca6507@45 {
                reg = <0x5>;
                linux,default-trigger = "default-on";
        };
+
+       wifi-reset@6 {
+               reg = <0x6>;
+               compatible = "gpio";
+       };
 };
 
index c67b975c89063f51fa20ae563f601c7c6113fe08..532b1d440abc15d1f1d1e61791b274a6ec8dafe0 100644 (file)
@@ -16,6 +16,8 @@ Required Properties:
          specific extensions.
        - "samsung,exynos5250-dw-mshc": for controllers with Samsung Exynos5250
          specific extensions.
+       - "samsung,exynos5420-dw-mshc": for controllers with Samsung Exynos5420
+         specific extensions.
 
 * samsung,dw-mshc-ciu-div: Specifies the divider value for the card interface
   unit (ciu) clock. This property is applicable only for Exynos5 SoC's and
diff --git a/Documentation/devicetree/bindings/mmc/ti-omap.txt b/Documentation/devicetree/bindings/mmc/ti-omap.txt
new file mode 100644 (file)
index 0000000..8de5799
--- /dev/null
@@ -0,0 +1,54 @@
+* TI MMC host controller for OMAP1 and 2420
+
+The MMC Host Controller on TI OMAP1 and 2420 family provides
+an interface for MMC, SD, and SDIO types of memory cards.
+
+This file documents differences between the core properties described
+by mmc.txt and the properties used by the omap mmc driver.
+
+Note that this driver will not work with omap2430 or later omaps,
+please see the omap hsmmc driver for the current omaps.
+
+Required properties:
+- compatible: Must be "ti,omap2420-mmc", for OMAP2420 controllers
+- ti,hwmods: For 2420, must be "msdi<n>", where n is controller
+  instance starting 1
+
+Examples:
+
+       msdi1: mmc@4809c000 {
+               compatible = "ti,omap2420-mmc";
+               ti,hwmods = "msdi1";
+               reg = <0x4809c000 0x80>;
+               interrupts = <83>;
+               dmas = <&sdma 61 &sdma 62>;
+               dma-names = "tx", "rx";
+       };
+
+* TI MMC host controller for OMAP1 and 2420
+
+The MMC Host Controller on TI OMAP1 and 2420 family provides
+an interface for MMC, SD, and SDIO types of memory cards.
+
+This file documents differences between the core properties described
+by mmc.txt and the properties used by the omap mmc driver.
+
+Note that this driver will not work with omap2430 or later omaps,
+please see the omap hsmmc driver for the current omaps.
+
+Required properties:
+- compatible: Must be "ti,omap2420-mmc", for OMAP2420 controllers
+- ti,hwmods: For 2420, must be "msdi<n>", where n is controller
+  instance starting 1
+
+Examples:
+
+       msdi1: mmc@4809c000 {
+               compatible = "ti,omap2420-mmc";
+               ti,hwmods = "msdi1";
+               reg = <0x4809c000 0x80>;
+               interrupts = <83>;
+               dmas = <&sdma 61 &sdma 62>;
+               dma-names = "tx", "rx";
+       };
+
index 551b2a179d016df4bd9bb8e611f38633d57d6640..458d5963468826647d2469c23f542bde3ffe047c 100644 (file)
@@ -17,6 +17,14 @@ Required properties:
 Optional properties:
   - nand-on-flash-bbt: boolean to enable on flash bbt option if not
                        present false
+  - fsl,use-minimum-ecc: Protect this NAND flash with the minimum ECC
+                       strength required. The required ECC strength is
+                       automatically discoverable for some flash
+                       (e.g., according to the ONFI standard).
+                       However, note that if this strength is not
+                       discoverable or this property is not enabled,
+                       the software may chooses an implementation-defined
+                       ECC scheme.
 
 The device tree may optionally contain sub-nodes describing partitions of the
 address space. See partition.txt for more detail.
index f1421e2bbab7387a87e1885794b9688780d6de73..86e0a5601ff5dfb05d9eeed35eb3e638ea58cc7b 100644 (file)
@@ -2,7 +2,9 @@ PXA3xx NAND DT bindings
 
 Required properties:
 
- - compatible:         Should be "marvell,pxa3xx-nand"
+ - compatible:         Should be set to one of the following:
+                       marvell,pxa3xx-nand
+                       marvell,armada370-nand
  - reg:                The register base for the controller
  - interrupts:         The interrupt to map
  - #address-cells:     Set to <1> if the node includes partitions
@@ -13,6 +15,8 @@ Optional properties:
  - marvell,nand-keep-config:   Set to keep the NAND controller config as set
                                by the bootloader
  - num-cs:                     Number of chipselect lines to usw
+ - nand-on-flash-bbt:          boolean to enable on flash bbt option if
+                               not present false
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/rng/qcom,prng.txt b/Documentation/devicetree/bindings/rng/qcom,prng.txt
new file mode 100644 (file)
index 0000000..8e5853c
--- /dev/null
@@ -0,0 +1,17 @@
+Qualcomm MSM pseudo random number generator.
+
+Required properties:
+
+- compatible  : should be "qcom,prng"
+- reg         : specifies base physical address and size of the registers map
+- clocks      : phandle to clock-controller plus clock-specifier pair
+- clock-names : "core" clocks all registers, FIFO and circuits in PRNG IP block
+
+Example:
+
+       rng@f9bff000 {
+               compatible = "qcom,prng";
+               reg = <0xf9bff000 0x200>;
+               clocks = <&clock GCC_PRNG_AHB_CLK>;
+               clock-names = "core";
+       };
diff --git a/Documentation/devicetree/bindings/sound/bcm2835-i2s.txt b/Documentation/devicetree/bindings/sound/bcm2835-i2s.txt
new file mode 100644 (file)
index 0000000..65783de
--- /dev/null
@@ -0,0 +1,25 @@
+* Broadcom BCM2835 SoC I2S/PCM module
+
+Required properties:
+- compatible: "brcm,bcm2835-i2s"
+- reg: A list of base address and size entries:
+       * The first entry should cover the PCM registers
+       * The second entry should cover the PCM clock registers
+- dmas: List of DMA controller phandle and DMA request line ordered pairs.
+- dma-names: Identifier string for each DMA request line in the dmas property.
+  These strings correspond 1:1 with the ordered pairs in dmas.
+
+  One of the DMA channels will be responsible for transmission (should be
+  named "tx") and one for reception (should be named "rx").
+
+Example:
+
+bcm2835_i2s: i2s@7e203000 {
+       compatible = "brcm,bcm2835-i2s";
+       reg = <0x7e203000 0x20>,
+             <0x7e101098 0x02>;
+
+       dmas = <&dma 2>,
+              <&dma 3>;
+       dma-names = "tx", "rx";
+};
diff --git a/Documentation/devicetree/bindings/sound/cs42l52.txt b/Documentation/devicetree/bindings/sound/cs42l52.txt
new file mode 100644 (file)
index 0000000..bc03c93
--- /dev/null
@@ -0,0 +1,46 @@
+CS42L52 audio CODEC
+
+Required properties:
+
+  - compatible : "cirrus,cs42l52"
+
+  - reg : the I2C address of the device for I2C
+
+Optional properties:
+
+  - cirrus,reset-gpio : GPIO controller's phandle and the number
+  of the GPIO used to reset the codec.
+
+  - cirrus,chgfreq-divisor : Values used to set the Charge Pump Frequency.
+  Allowable values of 0x00 through 0x0F. These are raw values written to the
+  register, not the actual frequency. The frequency is determined by the following.
+  Frequency = (64xFs)/(N+2)
+  N = chgfreq_val
+  Fs = Sample Rate (variable)
+
+  - cirrus,mica-differential-cfg : boolean, If present, then the MICA input is configured
+  as a differential input. If not present then the MICA input is configured as
+  Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input.
+
+  - cirrus,micb-differential-cfg : boolean, If present, then the MICB input is configured
+  as a differential input. If not present then the MICB input is configured as
+  Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input.
+
+  - cirrus,micbias-lvl: Set the output voltage level on the MICBIAS Pin
+  0 = 0.5 x VA
+  1 = 0.6 x VA
+  2 = 0.7 x VA
+  3 = 0.8 x VA
+  4 = 0.83 x VA
+  5 = 0.91 x VA
+
+Example:
+
+codec: codec@4a {
+       compatible = "cirrus,cs42l52";
+       reg = <0x4a>;
+       reset-gpio = <&gpio 10 0>;
+       cirrus,chgfreq-divisor = <0x05>;
+       cirrus.mica-differential-cfg;
+       cirrus,micbias-lvl = <5>;
+};
diff --git a/Documentation/devicetree/bindings/tty/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/tty/serial/renesas,sci-serial.txt
new file mode 100644 (file)
index 0000000..6ad1adf
--- /dev/null
@@ -0,0 +1,53 @@
+* Renesas SH-Mobile Serial Communication Interface
+
+Required properties:
+- compatible : Should be "renesas,sci-<port type>-uart", where <port type> may be
+  SCI, SCIF, IRDA, SCIFA or SCIFB.
+- reg : Address and length of the register set for the device
+- interrupts : Should contain the following IRQs: ERI, RXI, TXI and BRI.
+- cell-index : The device id.
+- renesas,scscr : Should contain a bitfield used by the Serial Control Register.
+  b7 = SCSCR_TIE
+  b6 = SCSCR_RIE
+  b5 = SCSCR_TE
+  b4 = SCSCR_RE
+  b3 = SCSCR_REIE
+  b2 = SCSCR_TOIE
+  b1 = SCSCR_CKE1
+  b0 = SCSCR_CKE0
+- renesas,scbrr-algo-id : Algorithm ID for the Bit Rate Register
+  1 = SCBRR_ALGO_1 ((clk + 16 * bps) / (16 * bps) - 1)
+  2 = SCBRR_ALGO_2 ((clk + 16 * bps) / (32 * bps) - 1)
+  3 = SCBRR_ALGO_3 (((clk * 2) + 16 * bps) / (16 * bps) - 1)
+  4 = SCBRR_ALGO_4 (((clk * 2) + 16 * bps) / (32 * bps) - 1)
+  5 = SCBRR_ALGO_5 (((clk * 1000 / 32) / bps) - 1)
+
+Optional properties:
+- renesas,autoconf : Set if device is capable of auto configuration
+- renesas,regtype : Overwrite the register layout. In most cases you can rely
+  on auto-probing (omit this property or set to 0) but some legacy devices
+  use a non-default register layout. Possible layouts are
+  0 = SCIx_PROBE_REGTYPE (default)
+  1 = SCIx_SCI_REGTYPE
+  2 = SCIx_IRDA_REGTYPE
+  3 = SCIx_SCIFA_REGTYPE
+  4 = SCIx_SCIFB_REGTYPE
+  5 = SCIx_SH2_SCIF_FIFODATA_REGTYPE
+  6 = SCIx_SH3_SCIF_REGTYPE
+  7 = SCIx_SH4_SCIF_REGTYPE
+  8 = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE
+  9 = SCIx_SH4_SCIF_FIFODATA_REGTYPE
+ 10 = SCIx_SH7705_SCIF_REGTYPE
+
+
+Example:
+       sci@0xe6c50000 {
+               compatible = "renesas,sci-SCIFA-uart";
+               interrupt-parent = <&intca>;
+               reg = <0xe6c50000 0x100>;
+               interrupts = <0x0c20>, <0x0c20>, <0x0c20>, <0x0c20>;
+               cell-index = <1>;
+               renesas,scscr = <0x30>;
+               renesas,scbrr-algo-id = <4>;
+               renesas,autoconf;
+       };
index ce95ed1c6d3e26578eaca876aa0f7caf26fa101d..13f329ff62a72f81661cf2aadbbacc6bcd3d68b0 100644 (file)
@@ -9,6 +9,7 @@ aeroflexgaisler Aeroflex Gaisler AB
 ak     Asahi Kasei Corp.
 altr   Altera Corp.
 amcc   Applied Micro Circuits Corporation (APM, formally AMCC)
+amstaos        AMS-Taos Inc.
 apm    Applied Micro Circuits Corporation (APM)
 arm    ARM Ltd.
 atmel  Atmel Corporation
@@ -26,9 +27,11 @@ cortina      Cortina Systems, Inc.
 dallas Maxim Integrated Products (formerly Dallas Semiconductor)
 davicom        DAVICOM Semiconductor, Inc.
 denx   Denx Software Engineering
+dmo    Data Modul AG
 emmicro        EM Microelectronic
 epson  Seiko Epson Corp.
 est    ESTeem Wireless Modems
+eukrea  Eukréa Electromatique
 fsl    Freescale Semiconductor
 GEFanuc        GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 gef    GE Fanuc Intelligent Platforms Embedded Systems, Inc.
@@ -75,6 +78,7 @@ toshiba       Toshiba Corporation
 toumaz Toumaz
 v3     V3 Semiconductor
 via    VIA Technologies, Inc.
+voipac Voipac Technologies s.r.o.
 winbond Winbond Electronics corp.
 wlf    Wolfson Microelectronics
 wm     Wondermedia Technologies, Inc.
index fcdd48f7dcffc0f71540dacb48aa4f501c6dd5de..f90e294d7631f9b538ba3e5e72c2ab1b096a5479 100644 (file)
@@ -9,11 +9,37 @@ Required properties:
 
 Optional properties:
 - timeout-sec: contains the watchdog timeout in seconds.
+- interrupts : Should contain WDT interrupt.
+- atmel,max-heartbeat-sec : Should contain the maximum heartbeat value in
+       seconds. This value should be less or equal to 16. It is used to
+       compute the WDV field.
+- atmel,min-heartbeat-sec : Should contain the minimum heartbeat value in
+       seconds. This value must be smaller than the max-heartbeat-sec value.
+       It is used to compute the WDD field.
+- atmel,watchdog-type : Should be "hardware" or "software". Hardware watchdog
+       use the at91 watchdog reset. Software watchdog use the watchdog
+       interrupt to trigger a software reset.
+- atmel,reset-type : Should be "proc" or "all".
+       "all" : assert peripherals and processor reset signals
+       "proc" : assert the processor reset signal
+       This is valid only when using "hardware" watchdog.
+- atmel,disable : Should be present if you want to disable the watchdog.
+- atmel,idle-halt : Should be present if you want to stop the watchdog when
+       entering idle state.
+- atmel,dbg-halt : Should be present if you want to stop the watchdog when
+       entering debug state.
 
 Example:
-
        watchdog@fffffd40 {
                compatible = "atmel,at91sam9260-wdt";
                reg = <0xfffffd40 0x10>;
-               timeout-sec = <10>;
+               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+               timeout-sec = <15>;
+               atmel,watchdog-type = "hardware";
+               atmel,reset-type = "all";
+               atmel,dbg-halt;
+               atmel,idle-halt;
+               atmel,max-heartbeat-sec = <16>;
+               atmel,min-heartbeat-sec = <0>;
+               status = "okay";
        };
index 5bdc8cb5fc2855047004cf673d735fa23c561fb8..4f7897e99cba8a8fc7b5a33343825cfb94ce2d68 100644 (file)
@@ -242,6 +242,8 @@ IIO
   devm_iio_device_free()
   devm_iio_trigger_alloc()
   devm_iio_trigger_free()
+  devm_iio_device_register()
+  devm_iio_device_unregister()
 
 IO region
   devm_request_region()
diff --git a/Documentation/gpio/board.txt b/Documentation/gpio/board.txt
new file mode 100644 (file)
index 0000000..0d03506
--- /dev/null
@@ -0,0 +1,115 @@
+GPIO Mappings
+=============
+
+This document explains how GPIOs can be assigned to given devices and functions.
+Note that it only applies to the new descriptor-based interface. For a
+description of the deprecated integer-based GPIO interface please refer to
+gpio-legacy.txt (actually, there is no real mapping possible with the old
+interface; you just fetch an integer from somewhere and request the
+corresponding GPIO.
+
+Platforms that make use of GPIOs must select ARCH_REQUIRE_GPIOLIB (if GPIO usage
+is mandatory) or ARCH_WANT_OPTIONAL_GPIOLIB (if GPIO support can be omitted) in
+their Kconfig. Then, how GPIOs are mapped depends on what the platform uses to
+describe its hardware layout. Currently, mappings can be defined through device
+tree, ACPI, and platform data.
+
+Device Tree
+-----------
+GPIOs can easily be mapped to devices and functions in the device tree. The
+exact way to do it depends on the GPIO controller providing the GPIOs, see the
+device tree bindings for your controller.
+
+GPIOs mappings are defined in the consumer device's node, in a property named
+<function>-gpios, where <function> is the function the driver will request
+through gpiod_get(). For example:
+
+       foo_device {
+               compatible = "acme,foo";
+               ...
+               led-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>, /* red */
+                           <&gpio 16 GPIO_ACTIVE_HIGH>, /* green */
+                           <&gpio 17 GPIO_ACTIVE_HIGH>; /* blue */
+
+               power-gpio = <&gpio 1 GPIO_ACTIVE_LOW>;
+       };
+
+This property will make GPIOs 15, 16 and 17 available to the driver under the
+"led" function, and GPIO 1 as the "power" GPIO:
+
+       struct gpio_desc *red, *green, *blue, *power;
+
+       red = gpiod_get_index(dev, "led", 0);
+       green = gpiod_get_index(dev, "led", 1);
+       blue = gpiod_get_index(dev, "led", 2);
+
+       power = gpiod_get(dev, "power");
+
+The led GPIOs will be active-high, while the power GPIO will be active-low (i.e.
+gpiod_is_active_low(power) will be true).
+
+ACPI
+----
+ACPI does not support function names for GPIOs. Therefore, only the "idx"
+argument of gpiod_get_index() is useful to discriminate between GPIOs assigned
+to a device. The "con_id" argument can still be set for debugging purposes (it
+will appear under error messages as well as debug and sysfs nodes).
+
+Platform Data
+-------------
+Finally, GPIOs can be bound to devices and functions using platform data. Board
+files that desire to do so need to include the following header:
+
+       #include <linux/gpio/driver.h>
+
+GPIOs are mapped by the means of tables of lookups, containing instances of the
+gpiod_lookup structure. Two macros are defined to help declaring such mappings:
+
+       GPIO_LOOKUP(chip_label, chip_hwnum, dev_id, con_id, flags)
+       GPIO_LOOKUP_IDX(chip_label, chip_hwnum, dev_id, con_id, idx, flags)
+
+where
+
+  - chip_label is the label of the gpiod_chip instance providing the GPIO
+  - chip_hwnum is the hardware number of the GPIO within the chip
+  - dev_id is the identifier of the device that will make use of this GPIO. If
+       NULL, the GPIO will be available to all devices.
+  - con_id is the name of the GPIO function from the device point of view. It
+       can be NULL.
+  - idx is the index of the GPIO within the function.
+  - flags is defined to specify the following properties:
+       * GPIOF_ACTIVE_LOW      - to configure the GPIO as active-low
+       * GPIOF_OPEN_DRAIN      - GPIO pin is open drain type.
+       * GPIOF_OPEN_SOURCE     - GPIO pin is open source type.
+
+In the future, these flags might be extended to support more properties.
+
+Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0.
+
+A lookup table can then be defined as follows:
+
+       struct gpiod_lookup gpios_table[] = {
+       GPIO_LOOKUP_IDX("gpio.0", 15, "foo.0", "led", 0, GPIO_ACTIVE_HIGH),
+       GPIO_LOOKUP_IDX("gpio.0", 16, "foo.0", "led", 1, GPIO_ACTIVE_HIGH),
+       GPIO_LOOKUP_IDX("gpio.0", 17, "foo.0", "led", 2, GPIO_ACTIVE_HIGH),
+       GPIO_LOOKUP("gpio.0", 1, "foo.0", "power", GPIO_ACTIVE_LOW),
+       };
+
+And the table can be added by the board code as follows:
+
+       gpiod_add_table(gpios_table, ARRAY_SIZE(gpios_table));
+
+The driver controlling "foo.0" will then be able to obtain its GPIOs as follows:
+
+       struct gpio_desc *red, *green, *blue, *power;
+
+       red = gpiod_get_index(dev, "led", 0);
+       green = gpiod_get_index(dev, "led", 1);
+       blue = gpiod_get_index(dev, "led", 2);
+
+       power = gpiod_get(dev, "power");
+       gpiod_direction_output(power, 1);
+
+Since the "power" GPIO is mapped as active-low, its actual signal will be 0
+after this code. Contrary to the legacy integer GPIO interface, the active-low
+property is handled during mapping and is thus transparent to GPIO consumers.
diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt
new file mode 100644 (file)
index 0000000..07c74a3
--- /dev/null
@@ -0,0 +1,197 @@
+GPIO Descriptor Consumer Interface
+==================================
+
+This document describes the consumer interface of the GPIO framework. Note that
+it describes the new descriptor-based interface. For a description of the
+deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
+
+
+Guidelines for GPIOs consumers
+==============================
+
+Drivers that can't work without standard GPIO calls should have Kconfig entries
+that depend on GPIOLIB. The functions that allow a driver to obtain and use
+GPIOs are available by including the following file:
+
+       #include <linux/gpio/consumer.h>
+
+All the functions that work with the descriptor-based GPIO interface are
+prefixed with gpiod_. The gpio_ prefix is used for the legacy interface. No
+other function in the kernel should use these prefixes.
+
+
+Obtaining and Disposing GPIOs
+=============================
+
+With the descriptor-based interface, GPIOs are identified with an opaque,
+non-forgeable handler that must be obtained through a call to one of the
+gpiod_get() functions. Like many other kernel subsystems, gpiod_get() takes the
+device that will use the GPIO and the function the requested GPIO is supposed to
+fulfill:
+
+       struct gpio_desc *gpiod_get(struct device *dev, const char *con_id)
+
+If a function is implemented by using several GPIOs together (e.g. a simple LED
+device that displays digits), an additional index argument can be specified:
+
+       struct gpio_desc *gpiod_get_index(struct device *dev,
+                                         const char *con_id, unsigned int idx)
+
+Both functions return either a valid GPIO descriptor, or an error code checkable
+with IS_ERR(). They will never return a NULL pointer.
+
+Device-managed variants of these functions are also defined:
+
+       struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id)
+
+       struct gpio_desc *devm_gpiod_get_index(struct device *dev,
+                                              const char *con_id,
+                                              unsigned int idx)
+
+A GPIO descriptor can be disposed of using the gpiod_put() function:
+
+       void gpiod_put(struct gpio_desc *desc)
+
+It is strictly forbidden to use a descriptor after calling this function. The
+device-managed variant is, unsurprisingly:
+
+       void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
+
+
+Using GPIOs
+===========
+
+Setting Direction
+-----------------
+The first thing a driver must do with a GPIO is setting its direction. This is
+done by invoking one of the gpiod_direction_*() functions:
+
+       int gpiod_direction_input(struct gpio_desc *desc)
+       int gpiod_direction_output(struct gpio_desc *desc, int value)
+
+The return value is zero for success, else a negative errno. It should be
+checked, since the get/set calls don't return errors and since misconfiguration
+is possible. You should normally issue these calls from a task context. However,
+for spinlock-safe GPIOs it is OK to use them before tasking is enabled, as part
+of early board setup.
+
+For output GPIOs, the value provided becomes the initial output value. This
+helps avoid signal glitching during system startup.
+
+A driver can also query the current direction of a GPIO:
+
+       int gpiod_get_direction(const struct gpio_desc *desc)
+
+This function will return either GPIOF_DIR_IN or GPIOF_DIR_OUT.
+
+Be aware that there is no default direction for GPIOs. Therefore, **using a GPIO
+without setting its direction first is illegal and will result in undefined
+behavior!**
+
+
+Spinlock-Safe GPIO Access
+-------------------------
+Most GPIO controllers can be accessed with memory read/write instructions. Those
+don't need to sleep, and can safely be done from inside hard (non-threaded) IRQ
+handlers and similar contexts.
+
+Use the following calls to access GPIOs from an atomic context:
+
+       int gpiod_get_value(const struct gpio_desc *desc);
+       void gpiod_set_value(struct gpio_desc *desc, int value);
+
+The values are boolean, zero for low, nonzero for high. When reading the value
+of an output pin, the value returned should be what's seen on the pin. That
+won't always match the specified output value, because of issues including
+open-drain signaling and output latencies.
+
+The get/set calls do not return errors because "invalid GPIO" should have been
+reported earlier from gpiod_direction_*(). However, note that not all platforms
+can read the value of output pins; those that can't should always return zero.
+Also, using these calls for GPIOs that can't safely be accessed without sleeping
+(see below) is an error.
+
+
+GPIO Access That May Sleep
+--------------------------
+Some GPIO controllers must be accessed using message based buses like I2C or
+SPI. Commands to read or write those GPIO values require waiting to get to the
+head of a queue to transmit a command and get its response. This requires
+sleeping, which can't be done from inside IRQ handlers.
+
+Platforms that support this type of GPIO distinguish them from other GPIOs by
+returning nonzero from this call:
+
+       int gpiod_cansleep(const struct gpio_desc *desc)
+
+To access such GPIOs, a different set of accessors is defined:
+
+       int gpiod_get_value_cansleep(const struct gpio_desc *desc)
+       void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
+
+Accessing such GPIOs requires a context which may sleep, for example a threaded
+IRQ handler, and those accessors must be used instead of spinlock-safe
+accessors without the cansleep() name suffix.
+
+Other than the fact that these accessors might sleep, and will work on GPIOs
+that can't be accessed from hardIRQ handlers, these calls act the same as the
+spinlock-safe calls.
+
+
+Active-low State and Raw GPIO Values
+------------------------------------
+Device drivers like to manage the logical state of a GPIO, i.e. the value their
+device will actually receive, no matter what lies between it and the GPIO line.
+In some cases, it might make sense to control the actual GPIO line value. The
+following set of calls ignore the active-low property of a GPIO and work on the
+raw line value:
+
+       int gpiod_get_raw_value(const struct gpio_desc *desc)
+       void gpiod_set_raw_value(struct gpio_desc *desc, int value)
+       int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
+       void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value)
+
+The active-low state of a GPIO can also be queried using the following call:
+
+       int gpiod_is_active_low(const struct gpio_desc *desc)
+
+Note that these functions should only be used with great moderation ; a driver
+should not have to care about the physical line level.
+
+GPIOs mapped to IRQs
+--------------------
+GPIO lines can quite often be used as IRQs. You can get the IRQ number
+corresponding to a given GPIO using the following call:
+
+       int gpiod_to_irq(const struct gpio_desc *desc)
+
+It will return an IRQ number, or an negative errno code if the mapping can't be
+done (most likely because that particular GPIO cannot be used as IRQ). It is an
+unchecked error to use a GPIO that wasn't set up as an input using
+gpiod_direction_input(), or to use an IRQ number that didn't originally come
+from gpiod_to_irq(). gpiod_to_irq() is not allowed to sleep.
+
+Non-error values returned from gpiod_to_irq() can be passed to request_irq() or
+free_irq(). They will often be stored into IRQ resources for platform devices,
+by the board-specific initialization code. Note that IRQ trigger options are
+part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are system wakeup
+capabilities.
+
+
+Interacting With the Legacy GPIO Subsystem
+==========================================
+Many kernel subsystems still handle GPIOs using the legacy integer-based
+interface. Although it is strongly encouraged to upgrade them to the safer
+descriptor-based API, the following two functions allow you to convert a GPIO
+descriptor into the GPIO integer namespace and vice-versa:
+
+       int desc_to_gpio(const struct gpio_desc *desc)
+       struct gpio_desc *gpio_to_desc(unsigned gpio)
+
+The GPIO number returned by desc_to_gpio() can be safely used as long as the
+GPIO descriptor has not been freed. All the same, a GPIO number passed to
+gpio_to_desc() must have been properly acquired, and usage of the returned GPIO
+descriptor is only possible after the GPIO number has been released.
+
+Freeing a GPIO obtained by one API with the other API is forbidden and an
+unchecked error.
diff --git a/Documentation/gpio/driver.txt b/Documentation/gpio/driver.txt
new file mode 100644 (file)
index 0000000..9da0bfa
--- /dev/null
@@ -0,0 +1,75 @@
+GPIO Descriptor Driver Interface
+================================
+
+This document serves as a guide for GPIO chip drivers writers. Note that it
+describes the new descriptor-based interface. For a description of the
+deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
+
+Each GPIO controller driver needs to include the following header, which defines
+the structures used to define a GPIO driver:
+
+       #include <linux/gpio/driver.h>
+
+
+Internal Representation of GPIOs
+================================
+
+Inside a GPIO driver, individual GPIOs are identified by their hardware number,
+which is a unique number between 0 and n, n being the number of GPIOs managed by
+the chip. This number is purely internal: the hardware number of a particular
+GPIO descriptor is never made visible outside of the driver.
+
+On top of this internal number, each GPIO also need to have a global number in
+the integer GPIO namespace so that it can be used with the legacy GPIO
+interface. Each chip must thus have a "base" number (which can be automatically
+assigned), and for each GPIO the global number will be (base + hardware number).
+Although the integer representation is considered deprecated, it still has many
+users and thus needs to be maintained.
+
+So for example one platform could use numbers 32-159 for GPIOs, with a
+controller defining 128 GPIOs at a "base" of 32 ; while another platform uses
+numbers 0..63 with one set of GPIO controllers, 64-79 with another type of GPIO
+controller, and on one particular board 80-95 with an FPGA. The numbers need not
+be contiguous; either of those platforms could also use numbers 2000-2063 to
+identify GPIOs in a bank of I2C GPIO expanders.
+
+
+Controller Drivers: gpio_chip
+=============================
+
+In the gpiolib framework each GPIO controller is packaged as a "struct
+gpio_chip" (see linux/gpio/driver.h for its complete definition) with members
+common to each controller of that type:
+
+ - methods to establish GPIO direction
+ - methods used to access GPIO values
+ - method to return the IRQ number associated to a given GPIO
+ - flag saying whether calls to its methods may sleep
+ - optional debugfs dump method (showing extra state like pullup config)
+ - optional base number (will be automatically assigned if omitted)
+ - label for diagnostics and GPIOs mapping using platform data
+
+The code implementing a gpio_chip should support multiple instances of the
+controller, possibly using the driver model. That code will configure each
+gpio_chip and issue gpiochip_add(). Removing a GPIO controller should be rare;
+use gpiochip_remove() when it is unavoidable.
+
+Most often a gpio_chip is part of an instance-specific structure with state not
+exposed by the GPIO interfaces, such as addressing, power management, and more.
+Chips such as codecs will have complex non-GPIO state.
+
+Any debugfs dump method should normally ignore signals which haven't been
+requested as GPIOs. They can use gpiochip_is_requested(), which returns either
+NULL or the label associated with that GPIO when it was requested.
+
+Locking IRQ usage
+-----------------
+Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
+to mark the GPIO as being used as an IRQ:
+
+       int gpiod_lock_as_irq(struct gpio_desc *desc)
+
+This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
+is released:
+
+       void gpiod_unlock_as_irq(struct gpio_desc *desc)
diff --git a/Documentation/gpio/gpio.txt b/Documentation/gpio/gpio.txt
new file mode 100644 (file)
index 0000000..cd9b356
--- /dev/null
@@ -0,0 +1,119 @@
+GPIO Interfaces
+===============
+
+The documents in this directory give detailed instructions on how to access
+GPIOs in drivers, and how to write a driver for a device that provides GPIOs
+itself.
+
+Due to the history of GPIO interfaces in the kernel, there are two different
+ways to obtain and use GPIOs:
+
+  - The descriptor-based interface is the preferred way to manipulate GPIOs,
+and is described by all the files in this directory excepted gpio-legacy.txt.
+  - The legacy integer-based interface which is considered deprecated (but still
+usable for compatibility reasons) is documented in gpio-legacy.txt.
+
+The remainder of this document applies to the new descriptor-based interface.
+gpio-legacy.txt contains the same information applied to the legacy
+integer-based interface.
+
+
+What is a GPIO?
+===============
+
+A "General Purpose Input/Output" (GPIO) is a flexible software-controlled
+digital signal. They are provided from many kinds of chip, and are familiar
+to Linux developers working with embedded and custom hardware. Each GPIO
+represents a bit connected to a particular pin, or "ball" on Ball Grid Array
+(BGA) packages. Board schematics show which external hardware connects to
+which GPIOs. Drivers can be written generically, so that board setup code
+passes such pin configuration data to drivers.
+
+System-on-Chip (SOC) processors heavily rely on GPIOs. In some cases, every
+non-dedicated pin can be configured as a GPIO; and most chips have at least
+several dozen of them. Programmable logic devices (like FPGAs) can easily
+provide GPIOs; multifunction chips like power managers, and audio codecs
+often have a few such pins to help with pin scarcity on SOCs; and there are
+also "GPIO Expander" chips that connect using the I2C or SPI serial buses.
+Most PC southbridges have a few dozen GPIO-capable pins (with only the BIOS
+firmware knowing how they're used).
+
+The exact capabilities of GPIOs vary between systems. Common options:
+
+  - Output values are writable (high=1, low=0). Some chips also have
+    options about how that value is driven, so that for example only one
+    value might be driven, supporting "wire-OR" and similar schemes for the
+    other value (notably, "open drain" signaling).
+
+  - Input values are likewise readable (1, 0). Some chips support readback
+    of pins configured as "output", which is very useful in such "wire-OR"
+    cases (to support bidirectional signaling). GPIO controllers may have
+    input de-glitch/debounce logic, sometimes with software controls.
+
+  - Inputs can often be used as IRQ signals, often edge triggered but
+    sometimes level triggered. Such IRQs may be configurable as system
+    wakeup events, to wake the system from a low power state.
+
+  - Usually a GPIO will be configurable as either input or output, as needed
+    by different product boards; single direction ones exist too.
+
+  - Most GPIOs can be accessed while holding spinlocks, but those accessed
+    through a serial bus normally can't. Some systems support both types.
+
+On a given board each GPIO is used for one specific purpose like monitoring
+MMC/SD card insertion/removal, detecting card write-protect status, driving
+a LED, configuring a transceiver, bit-banging a serial bus, poking a hardware
+watchdog, sensing a switch, and so on.
+
+
+Common GPIO Properties
+======================
+
+These properties are met through all the other documents of the GPIO interface
+and it is useful to understand them, especially if you need to define GPIO
+mappings.
+
+Active-High and Active-Low
+--------------------------
+It is natural to assume that a GPIO is "active" when its output signal is 1
+("high"), and inactive when it is 0 ("low"). However in practice the signal of a
+GPIO may be inverted before is reaches its destination, or a device could decide
+to have different conventions about what "active" means. Such decisions should
+be transparent to device drivers, therefore it is possible to define a GPIO as
+being either active-high ("1" means "active", the default) or active-low ("0"
+means "active") so that drivers only need to worry about the logical signal and
+not about what happens at the line level.
+
+Open Drain and Open Source
+--------------------------
+Sometimes shared signals need to use "open drain" (where only the low signal
+level is actually driven), or "open source" (where only the high signal level is
+driven) signaling. That term applies to CMOS transistors; "open collector" is
+used for TTL. A pullup or pulldown resistor causes the high or low signal level.
+This is sometimes called a "wire-AND"; or more practically, from the negative
+logic (low=true) perspective this is a "wire-OR".
+
+One common example of an open drain signal is a shared active-low IRQ line.
+Also, bidirectional data bus signals sometimes use open drain signals.
+
+Some GPIO controllers directly support open drain and open source outputs; many
+don't. When you need open drain signaling but your hardware doesn't directly
+support it, there's a common idiom you can use to emulate it with any GPIO pin
+that can be used as either an input or an output:
+
+ LOW:  gpiod_direction_output(gpio, 0) ... this drives the signal and overrides
+       the pullup.
+
+ HIGH: gpiod_direction_input(gpio) ... this turns off the output, so the pullup
+       (or some other device) controls the signal.
+
+The same logic can be applied to emulate open source signaling, by driving the
+high signal and configuring the GPIO as input for low. This open drain/open
+source emulation can be handled transparently by the GPIO framework.
+
+If you are "driving" the signal high but gpiod_get_value(gpio) reports a low
+value (after the appropriate rise time passes), you know some other component is
+driving the shared signal low. That's not necessarily an error. As one common
+example, that's how I2C clocks are stretched:  a slave that needs a slower clock
+delays the rising edge of SCK, and the I2C master adjusts its signaling rate
+accordingly.
diff --git a/Documentation/gpio/sysfs.txt b/Documentation/gpio/sysfs.txt
new file mode 100644 (file)
index 0000000..c2c3a97
--- /dev/null
@@ -0,0 +1,155 @@
+GPIO Sysfs Interface for Userspace
+==================================
+
+Platforms which use the "gpiolib" implementors framework may choose to
+configure a sysfs user interface to GPIOs. This is different from the
+debugfs interface, since it provides control over GPIO direction and
+value instead of just showing a gpio state summary. Plus, it could be
+present on production systems without debugging support.
+
+Given appropriate hardware documentation for the system, userspace could
+know for example that GPIO #23 controls the write protect line used to
+protect boot loader segments in flash memory. System upgrade procedures
+may need to temporarily remove that protection, first importing a GPIO,
+then changing its output state, then updating the code before re-enabling
+the write protection. In normal use, GPIO #23 would never be touched,
+and the kernel would have no need to know about it.
+
+Again depending on appropriate hardware documentation, on some systems
+userspace GPIO can be used to determine system configuration data that
+standard kernels won't know about. And for some tasks, simple userspace
+GPIO drivers could be all that the system really needs.
+
+Note that standard kernel drivers exist for common "LEDs and Buttons"
+GPIO tasks:  "leds-gpio" and "gpio_keys", respectively. Use those
+instead of talking directly to the GPIOs; they integrate with kernel
+frameworks better than your userspace code could.
+
+
+Paths in Sysfs
+--------------
+There are three kinds of entry in /sys/class/gpio:
+
+   -   Control interfaces used to get userspace control over GPIOs;
+
+   -   GPIOs themselves; and
+
+   -   GPIO controllers ("gpio_chip" instances).
+
+That's in addition to standard files including the "device" symlink.
+
+The control interfaces are write-only:
+
+    /sys/class/gpio/
+
+       "export" ... Userspace may ask the kernel to export control of
+               a GPIO to userspace by writing its number to this file.
+
+               Example:  "echo 19 > export" will create a "gpio19" node
+               for GPIO #19, if that's not requested by kernel code.
+
+       "unexport" ... Reverses the effect of exporting to userspace.
+
+               Example:  "echo 19 > unexport" will remove a "gpio19"
+               node exported using the "export" file.
+
+GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
+and have the following read/write attributes:
+
+    /sys/class/gpio/gpioN/
+
+       "direction" ... reads as either "in" or "out". This value may
+               normally be written. Writing as "out" defaults to
+               initializing the value as low. To ensure glitch free
+               operation, values "low" and "high" may be written to
+               configure the GPIO as an output with that initial value.
+
+               Note that this attribute *will not exist* if the kernel
+               doesn't support changing the direction of a GPIO, or
+               it was exported by kernel code that didn't explicitly
+               allow userspace to reconfigure this GPIO's direction.
+
+       "value" ... reads as either 0 (low) or 1 (high). If the GPIO
+               is configured as an output, this value may be written;
+               any nonzero value is treated as high.
+
+               If the pin can be configured as interrupt-generating interrupt
+               and if it has been configured to generate interrupts (see the
+               description of "edge"), you can poll(2) on that file and
+               poll(2) will return whenever the interrupt was triggered. If
+               you use poll(2), set the events POLLPRI and POLLERR. If you
+               use select(2), set the file descriptor in exceptfds. After
+               poll(2) returns, either lseek(2) to the beginning of the sysfs
+               file and read the new value or close the file and re-open it
+               to read the value.
+
+       "edge" ... reads as either "none", "rising", "falling", or
+               "both". Write these strings to select the signal edge(s)
+               that will make poll(2) on the "value" file return.
+
+               This file exists only if the pin can be configured as an
+               interrupt generating input pin.
+
+       "active_low" ... reads as either 0 (false) or 1 (true). Write
+               any nonzero value to invert the value attribute both
+               for reading and writing. Existing and subsequent
+               poll(2) support configuration via the edge attribute
+               for "rising" and "falling" edges will follow this
+               setting.
+
+GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
+controller implementing GPIOs starting at #42) and have the following
+read-only attributes:
+
+    /sys/class/gpio/gpiochipN/
+
+       "base" ... same as N, the first GPIO managed by this chip
+
+       "label" ... provided for diagnostics (not always unique)
+
+       "ngpio" ... how many GPIOs this manges (N to N + ngpio - 1)
+
+Board documentation should in most cases cover what GPIOs are used for
+what purposes. However, those numbers are not always stable; GPIOs on
+a daughtercard might be different depending on the base board being used,
+or other cards in the stack. In such cases, you may need to use the
+gpiochip nodes (possibly in conjunction with schematics) to determine
+the correct GPIO number to use for a given signal.
+
+
+Exporting from Kernel code
+--------------------------
+Kernel code can explicitly manage exports of GPIOs which have already been
+requested using gpio_request():
+
+       /* export the GPIO to userspace */
+       int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
+
+       /* reverse gpio_export() */
+       void gpiod_unexport(struct gpio_desc *desc);
+
+       /* create a sysfs link to an exported GPIO node */
+       int gpiod_export_link(struct device *dev, const char *name,
+                     struct gpio_desc *desc);
+
+       /* change the polarity of a GPIO node in sysfs */
+       int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value);
+
+After a kernel driver requests a GPIO, it may only be made available in
+the sysfs interface by gpiod_export(). The driver can control whether the
+signal direction may change. This helps drivers prevent userspace code
+from accidentally clobbering important system state.
+
+This explicit exporting can help with debugging (by making some kinds
+of experiments easier), or can provide an always-there interface that's
+suitable for documenting as part of a board support package.
+
+After the GPIO has been exported, gpiod_export_link() allows creating
+symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
+use this to provide the interface under their own device in sysfs with
+a descriptive name.
+
+Drivers can use gpiod_sysfs_set_active_low() to hide GPIO line polarity
+differences between boards from user space. Polarity change can be done both
+before and after gpiod_export(), and previously enabled poll(2) support for
+either rising or falling edge will be reconfigured to follow this setting.
index c263740f0cba83b5c3f17e95ecae83326da06458..0f5bba9aa02d47f49e8773623e3ae2c54f6c7957 100644 (file)
@@ -2,6 +2,10 @@ Kernel driver it87
 ==================
 
 Supported chips:
+  * IT8603E
+    Prefix: 'it8603'
+    Addresses scanned: from Super I/O config space (8 I/O ports)
+    Datasheet: Not publicly available
   * IT8705F
     Prefix: 'it87'
     Addresses scanned: from Super I/O config space (8 I/O ports)
@@ -90,7 +94,7 @@ motherboard models.
 Description
 -----------
 
-This driver implements support for the IT8705F, IT8712F, IT8716F,
+This driver implements support for the IT8603E, IT8705F, IT8712F, IT8716F,
 IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, IT8771E, IT8772E,
 IT8782F, IT8783E/F, and SiS950 chips.
 
@@ -129,6 +133,10 @@ to userspace applications.
 The IT8728F, IT8771E, and IT8772E are considered compatible with the IT8721F,
 until a datasheet becomes available (hopefully.)
 
+The IT8603E is a custom design, hardware monitoring part is similar to
+IT8728F. It only supports 16-bit fan mode, the full speed mode of the
+fan is not supported (value 0 of pwmX_enable).
+
 Temperatures are measured in degrees Celsius. An alarm is triggered once
 when the Overtemperature Shutdown limit is crossed.
 
@@ -145,13 +153,16 @@ alarm is triggered if the voltage has crossed a programmable minimum or
 maximum limit. Note that minimum in this case always means 'closest to
 zero'; this is important for negative voltage measurements. All voltage
 inputs can measure voltages between 0 and 4.08 volts, with a resolution of
-0.016 volt (except IT8721F/IT8758E and IT8728F: 0.012 volt.) The battery
-voltage in8 does not have limit registers.
-
-On the IT8721F/IT8758E, IT8782F, and IT8783E/F, some voltage inputs are
-internal and scaled inside the chip (in7 (optional for IT8782F and IT8783E/F),
-in8 and optionally in3). The driver handles this transparently so user-space
-doesn't have to care.
+0.016 volt (except IT8603E, IT8721F/IT8758E and IT8728F: 0.012 volt.) The
+battery voltage in8 does not have limit registers.
+
+On the IT8603E, IT8721F/IT8758E, IT8782F, and IT8783E/F, some voltage inputs
+are internal and scaled inside the chip:
+* in3 (optional)
+* in7 (optional for IT8782F and IT8783E/F)
+* in8 (always)
+* in9 (relevant for IT8603E only)
+The driver handles this transparently so user-space doesn't have to care.
 
 The VID lines (IT8712F/IT8716F/IT8718F/IT8720F) encode the core voltage value:
 the voltage level your processor should work with. This is hardcoded by
index 50680a59a2ff9a913e449a1d71ced9fab3004fe4..e5cf610b855f9e330b6a514e74c367c52313b857 100644 (file)
@@ -890,6 +890,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        edd=            [EDD]
                        Format: {"off" | "on" | "skip[mbr]"}
 
+       efi=            [EFI]
+                       Format: { "old_map" }
+                       old_map [X86-64]: switch to the old ioremap-based EFI
+                       runtime services mapping. 32-bit still uses this one by
+                       default.
+
        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
@@ -1992,6 +1998,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        noapic          [SMP,APIC] Tells the kernel to not make use of any
                        IOAPICs that may be present in the system.
 
+       nokaslr         [X86]
+                       Disable kernel base offset ASLR (Address Space
+                       Layout Randomization) if built into the kernel.
+
        noautogroup     Disable scheduler automatic task group creation.
 
        nobats          [PPC] Do not use BATs for mapping kernel lowmem
diff --git a/Documentation/kmsg/s390/zcrypt b/Documentation/kmsg/s390/zcrypt
new file mode 100644 (file)
index 0000000..7fb2087
--- /dev/null
@@ -0,0 +1,20 @@
+/*?
+ * Text: "Cryptographic device %x failed and was set offline\n"
+ * Severity: Error
+ * Parameter:
+ *   @1: device index
+ * Description:
+ * A cryptographic device failed to process a cryptographic request.
+ * The cryptographic device driver could not correct the error and
+ * set the device offline. The application that issued the
+ * request received an indication that the request has failed.
+ * User action:
+ * Use the lszcrypt command to confirm that the cryptographic
+ * hardware is still configured to your LPAR or z/VM guest virtual
+ * machine. If the device is available to your Linux instance the
+ * command output contains a line that begins with 'card<device index>',
+ * where <device index> is the two-digit decimal number in the message text.
+ * After ensuring that the device is available, use the chzcrypt command to
+ * set it online again.
+ * If the error persists, contact your support organization.
+ */
index c8c42e64e953b4cd47d23da125ac5e057d1c158d..020cccdbdd0ce9052d26b6dd4cd2bcef8dab7a4e 100644 (file)
@@ -500,7 +500,7 @@ odd-numbered bank is idle, one can see the new value of the pointer P (&B),
 but the old value of the variable B (2).
 
 
-Another example of where data dependency barriers might by required is where a
+Another example of where data dependency barriers might be required is where a
 number is read from memory and then used to calculate the index for an array
 access:
 
@@ -882,12 +882,12 @@ cache it for later use.
 
 Consider:
 
-       CPU 1                   CPU 2
+       CPU 1                   CPU 2
        ======================= =======================
-                               LOAD B
-                               DIVIDE          } Divide instructions generally
-                               DIVIDE          } take a long time to perform
-                               LOAD A
+                               LOAD B
+                               DIVIDE          } Divide instructions generally
+                               DIVIDE          } take a long time to perform
+                               LOAD A
 
 Which might appear as this:
 
@@ -910,13 +910,13 @@ Which might appear as this:
 Placing a read barrier or a data dependency barrier just before the second
 load:
 
-       CPU 1                   CPU 2
+       CPU 1                   CPU 2
        ======================= =======================
-                               LOAD B
-                               DIVIDE
-                               DIVIDE
+                               LOAD B
+                               DIVIDE
+                               DIVIDE
                                <read barrier>
-                               LOAD A
+                               LOAD A
 
 will force any value speculatively obtained to be reconsidered to an extent
 dependent on the type of barrier used.  If there was no change made to the
@@ -1887,8 +1887,8 @@ functions:
      space should suffice for PCI.
 
      [*] NOTE! attempting to load from the same location as was written to may
-        cause a malfunction - consider the 16550 Rx/Tx serial registers for
-        example.
+        cause a malfunction - consider the 16550 Rx/Tx serial registers for
+        example.
 
      Used with prefetchable I/O memory, an mmiowb() barrier may be required to
      force stores to be ordered.
@@ -1955,19 +1955,19 @@ barriers for the most part act at the interface between the CPU and its cache
                                  :
        +--------+    +--------+  :   +--------+    +-----------+
        |        |    |        |  :   |        |    |           |    +--------+
-       |  CPU   |    | Memory |  :   | CPU    |    |           |    |        |
-       |  Core  |--->| Access |----->| Cache  |<-->|           |    |        |
+       |  CPU   |    | Memory |  :   | CPU    |    |           |    |        |
+       |  Core  |--->| Access |----->| Cache  |<-->|           |    |        |
        |        |    | Queue  |  :   |        |    |           |--->| Memory |
-       |        |    |        |  :   |        |    |           |    |        |
-       +--------+    +--------+  :   +--------+    |           |    |        |
+       |        |    |        |  :   |        |    |           |    |        |
+       +--------+    +--------+  :   +--------+    |           |    |        |
                                  :                 | Cache     |    +--------+
                                  :                 | Coherency |
                                  :                 | Mechanism |    +--------+
        +--------+    +--------+  :   +--------+    |           |    |        |
        |        |    |        |  :   |        |    |           |    |        |
        |  CPU   |    | Memory |  :   | CPU    |    |           |--->| Device |
-       |  Core  |--->| Access |----->| Cache  |<-->|           |    |        |
-       |        |    | Queue  |  :   |        |    |           |    |        |
+       |  Core  |--->| Access |----->| Cache  |<-->|           |    |        |
+       |        |    | Queue  |  :   |        |    |           |    |        |
        |        |    |        |  :   |        |    |           |    +--------+
        +--------+    +--------+  :   +--------+    +-----------+
                                  :
@@ -2090,7 +2090,7 @@ CPU's caches by some other cache event:
        p = &v;         q = p;
                        <D:request p>
        <B:modify p=&v> <D:commit p=&v>
-                       <D:read p>
+                       <D:read p>
                        x = *q;
                        <C:read *q>     Reads from v before v updated in cache
                        <C:unbusy>
@@ -2115,7 +2115,7 @@ queue before processing any further requests:
        p = &v;         q = p;
                        <D:request p>
        <B:modify p=&v> <D:commit p=&v>
-                       <D:read p>
+                       <D:read p>
                        smp_read_barrier_depends()
                        <C:unbusy>
                        <C:commit v=2>
index 0c980ad40b17be5c34a271c87c7983e112620d6b..4d17487d5ad9e5b4f10008c6b817636fcae53494 100644 (file)
@@ -313,7 +313,7 @@ static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
        int i;
        void *dp = get_dp(mic, type);
 
-       for (i = mic_aligned_size(struct mic_bootparam); i < PAGE_SIZE;
+       for (i = sizeof(struct mic_bootparam); i < PAGE_SIZE;
                i += mic_total_desc_size(d)) {
                d = dp + i;
 
@@ -445,8 +445,8 @@ init_vr(struct mic_info *mic, int fd, int type,
                __func__, mic->name, vr0->va, vr0->info, vr_size,
                vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
        mpsslog("magic 0x%x expected 0x%x\n",
-               vr0->info->magic, MIC_MAGIC + type);
-       assert(vr0->info->magic == MIC_MAGIC + type);
+               le32toh(vr0->info->magic), MIC_MAGIC + type);
+       assert(le32toh(vr0->info->magic) == MIC_MAGIC + type);
        if (vr1) {
                vr1->va = (struct mic_vring *)
                        &va[MIC_DEVICE_PAGE_END + vr_size];
@@ -458,8 +458,8 @@ init_vr(struct mic_info *mic, int fd, int type,
                        __func__, mic->name, vr1->va, vr1->info, vr_size,
                        vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
                mpsslog("magic 0x%x expected 0x%x\n",
-                       vr1->info->magic, MIC_MAGIC + type + 1);
-               assert(vr1->info->magic == MIC_MAGIC + type + 1);
+                       le32toh(vr1->info->magic), MIC_MAGIC + type + 1);
+               assert(le32toh(vr1->info->magic) == MIC_MAGIC + type + 1);
        }
 done:
        return va;
@@ -520,7 +520,7 @@ static void *
 virtio_net(void *arg)
 {
        static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
-       static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __aligned(64);
+       static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __attribute__ ((aligned(64)));
        struct iovec vnet_iov[2][2] = {
                { { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
                  { .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
@@ -1412,6 +1412,12 @@ mic_config(void *arg)
        }
 
        do {
+               ret = lseek(fd, 0, SEEK_SET);
+               if (ret < 0) {
+                       mpsslog("%s: Failed to seek to file start '%s': %s\n",
+                               mic->name, pathname, strerror(errno));
+                       goto close_error1;
+               }
                ret = read(fd, value, sizeof(value));
                if (ret < 0) {
                        mpsslog("%s: Failed to read sysfs entry '%s': %s\n",
diff --git a/Documentation/mtd/nand/pxa3xx-nand.txt b/Documentation/mtd/nand/pxa3xx-nand.txt
new file mode 100644 (file)
index 0000000..840fd41
--- /dev/null
@@ -0,0 +1,113 @@
+
+About this document
+===================
+
+Some notes about Marvell's NAND controller available in PXA and Armada 370/XP
+SoC (aka NFCv1 and NFCv2), with an emphasis on the latter.
+
+NFCv2 controller background
+===========================
+
+The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
+larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
+chunked transfers.
+
+For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)
+we'll have this layout in the pages:
+
+  ------------------------------------------------------------------------------
+  | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
+  ------------------------------------------------------------------------------
+
+The driver reads the data and spare portions independently and builds an internal
+buffer with this layout (in the 4 KiB page case):
+
+  ------------------------------------------
+  |     4096B data     |     64B spare     |
+  ------------------------------------------
+
+Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'
+OOB, one per chunk read.
+
+  -------------------------------------------------------------------
+  |     4096B data     |  32B spare | 30B ECC | 32B spare | 30B ECC |
+  -------------------------------------------------------------------
+
+So, in order to achieve reading (for instance), we issue several READ0 commands
+(with some additional controller-specific magic) and read two chunks of 2080B
+(2048 data + 32 spare) each.
+The driver accommodates this data to expose the NAND core a contiguous buffer
+(4096 data + spare) or (4096 + spare + ECC + spare + ECC).
+
+ECC
+===
+
+The controller has built-in hardware ECC capabilities. In addition it is
+configurable between two modes: 1) Hamming, 2) BCH.
+
+Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way
+the controller is configured to transfer the data.
+
+In the BCH mode the ECC code will be calculated for each transfered chunk
+and expected to be located (when reading/programming) right after the spare
+bytes as the figure above shows.
+
+So, repeating the above scheme, a 2048B data chunk will be followed by 32B
+spare, and then the ECC controller will read/write the ECC code (30B in
+this case):
+
+  ------------------------------------
+  | 2048B data | 32B spare | 30B ECC |
+  ------------------------------------
+
+If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.
+If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.
+So in Hamming mode, a 2048B page will have a 24B ECC.
+
+Despite all of the above, the controller requires the driver to only read or
+write in multiples of 8-bytes, because the data buffer is 64-bits.
+
+OOB
+===
+
+Because of the above scheme, and because the "spare" OOB is really located in
+the middle of a page, spare OOB cannot be read or write independently of the
+data area. In other words, in order to read the OOB (aka READOOB), the entire
+page (aka READ0) has to be read.
+
+In the same sense, in order to write to the spare OOB the driver has to write
+an *entire* page.
+
+Factory bad blocks handling
+===========================
+
+Given the ECC BCH requires to layout the device's pages in a split
+data/OOB/data/OOB way, the controller has a view of the flash page that's
+different from the specified (aka the manufacturer's) view. In other words,
+
+Factory view:
+
+  -----------------------------------------------
+  |                    Data           |x  OOB   |
+  -----------------------------------------------
+
+Driver's view:
+
+  -----------------------------------------------
+  |      Data      | OOB |      Data   x  | OOB |
+  -----------------------------------------------
+
+It can be seen from the above, that the factory bad block marker must be
+searched within the 'data' region, and not in the usual OOB region.
+
+In addition, this means under regular usage the driver will write such
+position (since it belongs to the data region) and every used block is
+likely to be marked as bad.
+
+For this reason, marking the block as bad in the OOB is explicitly
+disabled by using the NAND_BBT_NO_OOB_BBM option in the driver. The rationale
+for this is that there's no point in marking a block as bad, because good
+blocks are also 'marked as bad' (in the OOB BBM sense) under normal usage.
+
+Instead, the driver relies on the bad block table alone, and should only perform
+the bad block scan on the very first time (when the device hasn't been used).
index fd1cd8aae4eb584b3b963a884f477f22cd037b2d..16eb314f56cc45ce923d9354960bdf67ea4e6b98 100644 (file)
@@ -146,8 +146,8 @@ On removal:
  1) set the 'list_op_pending' word to the address of the 'lock entry'
     to be removed,
  2) remove the lock entry for this lock from the 'head' list,
2) release the futex lock, and
2) clear the 'lock_op_pending' word.
3) release the futex lock, and
4) clear the 'lock_op_pending' word.
 
 On exit, the kernel will consider the address stored in
 'list_op_pending' and the address of each 'lock word' found by walking
index 881582f75c9ceb14e6eaacc48f3edecef31b3e3a..c584a51add15ad1ca8033207e46bf497abb33570 100644 (file)
@@ -28,4 +28,11 @@ reference.
 Current X86-64 implementations only support 40 bits of address space,
 but we support up to 46 bits. This expands into MBZ space in the page tables.
 
+->trampoline_pgd:
+
+We map EFI runtime services in the aforementioned PGD in the virtual
+range of 64Gb (arbitrarily set, can be raised if needed)
+
+0xffffffef00000000 - 0xffffffff00000000
+
 -Andi Kleen, Jul 2004
index d5829d14774a676e3f2ae93602756f2f2df8c4cb..90a64d52bea2f33464f86e4dc93954b2bc105f50 100644 (file)
@@ -95,8 +95,9 @@ The treatment of these regions depends on the type of Zorro space:
 -------------
 
 linux/include/linux/zorro.h
-linux/include/asm-{m68k,ppc}/zorro.h
-linux/include/linux/zorro_ids.h
+linux/include/uapi/linux/zorro.h
+linux/include/uapi/linux/zorro_ids.h
+linux/arch/m68k/include/asm/zorro.h
 linux/drivers/zorro
 /proc/bus/zorro
 
index 8285ed4676b6388502be84ddde71d1e201827ce8..731e55888f5471c9227e02241175c7210168e607 100644 (file)
@@ -2142,6 +2142,11 @@ L:       linux-usb@vger.kernel.org
 S:     Maintained
 F:     drivers/usb/chipidea/
 
+CHROME HARDWARE PLATFORM SUPPORT
+M:     Olof Johansson <olof@lixom.net>
+S:     Maintained
+F:     drivers/platform/chrome/
+
 CISCO VIC ETHERNET NIC DRIVER
 M:     Christian Benvenuti <benve@cisco.com>
 M:     Sujith Sankar <ssujith@cisco.com>
@@ -4038,12 +4043,26 @@ W:      http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
 S:     Maintained
 F:     fs/hpfs/
 
+HSI SUBSYSTEM
+M:     Sebastian Reichel <sre@debian.org>
+S:     Maintained
+F:     Documentation/ABI/testing/sysfs-bus-hsi
+F:     drivers/hsi/
+F:     include/linux/hsi/
+F:     include/uapi/linux/hsi/
+
 HSO 3G MODEM DRIVER
 M:     Jan Dumon <j.dumon@option.com>
 W:     http://www.pharscape.org
 S:     Maintained
 F:     drivers/net/usb/hso.c
 
+HSR NETWORK PROTOCOL
+M:     Arvid Brodin <arvid.brodin@alten.se>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     net/hsr/
+
 HTCPEN TOUCHSCREEN DRIVER
 M:     Pau Oliva Fora <pof@eslack.org>
 L:     linux-input@vger.kernel.org
@@ -4886,7 +4905,7 @@ F:        include/linux/sunrpc/
 F:     include/uapi/linux/sunrpc/
 
 KERNEL VIRTUAL MACHINE (KVM)
-M:     Gleb Natapov <gleb@redhat.com>
+M:     Gleb Natapov <gleb@kernel.org>
 M:     Paolo Bonzini <pbonzini@redhat.com>
 L:     kvm@vger.kernel.org
 W:     http://www.linux-kvm.org
@@ -5112,6 +5131,11 @@ F:       drivers/lguest/
 F:     include/linux/lguest*.h
 F:     tools/lguest/
 
+LIBLOCKDEP
+M:     Sasha Levin <sasha.levin@oracle.com>
+S:     Maintained
+F:     tools/lib/lockdep/
+
 LINUX FOR IBM pSERIES (RS/6000)
 M:     Paul Mackerras <paulus@au.ibm.com>
 W:     http://www.ibm.com/linux/ltc/projects/ppc
@@ -5256,7 +5280,7 @@ S:        Maintained
 F:     Documentation/lockdep*.txt
 F:     Documentation/lockstat.txt
 F:     include/linux/lockdep.h
-F:     kernel/lockdep*
+F:     kernel/locking/
 
 LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks)
 M:     "Richard Russon (FlatCap)" <ldm@flatcap.org>
@@ -6854,8 +6878,7 @@ S:        Maintained
 F:     drivers/scsi/qla1280.[ch]
 
 QLOGIC QLA2XXX FC-SCSI DRIVER
-M:     Andrew Vasquez <andrew.vasquez@qlogic.com>
-M:     linux-driver@qlogic.com
+M:     qla2xxx-upstream@qlogic.com
 L:     linux-scsi@vger.kernel.org
 S:     Supported
 F:     Documentation/scsi/LICENSE.qla2xxx
@@ -7380,7 +7403,6 @@ S:        Maintained
 F:     kernel/sched/
 F:     include/linux/sched.h
 F:     include/uapi/linux/sched.h
-F:     kernel/wait.c
 F:     include/linux/wait.h
 
 SCORE ARCHITECTURE
index c0c2d58e3998613572208012d90ed9164ec8d3b2..2c88e44a1dd4d9dbf726ab1f071db8accb805884 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 13
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = One Giant Leap for Frogkind
 
 # *DOCUMENTATION*
index 2ee0c9bfd0325537a5d9299649abac4992b722f5..9063ae6553ccb7a0a220b8db667ac770627addbf 100644 (file)
@@ -8,6 +8,7 @@
 
 config ARC
        def_bool y
+       select BUILDTIME_EXTABLE_SORT
        select CLONE_BACKWARDS
        # ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev
        select DEVTMPFS if !INITRAMFS_SOURCE=""
index eefc29f08cdbe4ba0ea3f4b12d8f1234d59c0527..5d06eee43ea9a18ddd8876ac66c7c6d5fed29ec6 100644 (file)
@@ -46,14 +46,14 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
  *
  * @info:              SoC SMP specific info for /proc/cpuinfo etc
  * @cpu_kick:          For Master to kickstart a cpu (optionally at a PC)
- * @ipi_send:          To send IPI to a @cpumask
- * @ips_clear:         To clear IPI received by @cpu at @irq
+ * @ipi_send:          To send IPI to a @cpu
+ * @ips_clear:         To clear IPI received at @irq
  */
 struct plat_smp_ops {
        const char      *info;
        void            (*cpu_kick)(int cpu, unsigned long pc);
-       void            (*ipi_send)(void *callmap);
-       void            (*ipi_clear)(int cpu, int irq);
+       void            (*ipi_send)(int cpu);
+       void            (*ipi_clear)(int irq);
 };
 
 /* TBD: stop exporting it for direct population by platform */
index 6f30484f34b78c5fa5052e68bbcbd3b4280a193f..68125dd766c68feeb9de6715c9d1694ed24e5491 100644 (file)
@@ -8,6 +8,9 @@
 
 /******** no-legacy-syscalls-ABI *******/
 
+#ifndef _UAPI_ASM_ARC_UNISTD_H
+#define _UAPI_ASM_ARC_UNISTD_H
+
 #define __ARCH_WANT_SYS_EXECVE
 #define __ARCH_WANT_SYS_CLONE
 #define __ARCH_WANT_SYS_VFORK
@@ -32,3 +35,5 @@ __SYSCALL(__NR_arc_gettls, sys_arc_gettls)
 /* Generic syscall (fs/filesystems.c - lost in asm-generic/unistd.h */
 #define __NR_sysfs             (__NR_arch_specific_syscall + 3)
 __SYSCALL(__NR_sysfs, sys_sysfs)
+
+#endif
index e46d81f709797a868b7cc68cc81ef71277a0f070..63177e4cb66d0d3a323b3e53081d4caaf2550ac0 100644 (file)
@@ -79,9 +79,9 @@ static int arc_pmu_cache_event(u64 config)
        cache_result    = (config >> 16) & 0xff;
        if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
                return -EINVAL;
-       if (cache_type >= PERF_COUNT_HW_CACHE_OP_MAX)
+       if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
                return -EINVAL;
-       if (cache_type >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+       if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
                return -EINVAL;
 
        ret = arc_pmu_cache_map[cache_type][cache_op][cache_result];
index c2f9ebbc38f61f819a0194fcc08de77ebdb5beb4..93c2fb5737ee27a625866d499337565bdad8c36c 100644 (file)
@@ -197,51 +197,62 @@ int __init setup_profiling_timer(unsigned int multiplier)
 /*              Inter Processor Interrupt Handling                           */
 /*****************************************************************************/
 
-/*
- * structures for inter-processor calls
- * A Collection of single bit ipi messages
- *
- */
-
-/*
- * TODO_rajesh investigate tlb message types.
- * IPI Timer not needed because each ARC has an individual Interrupting Timer
- */
 enum ipi_msg_type {
-       IPI_NOP = 0,
+       IPI_EMPTY = 0,
        IPI_RESCHEDULE = 1,
        IPI_CALL_FUNC,
-       IPI_CPU_STOP
+       IPI_CPU_STOP,
 };
 
-struct ipi_data {
-       unsigned long bits;
-};
+/*
+ * In arches with IRQ for each msg type (above), receiver can use IRQ-id  to
+ * figure out what msg was sent. For those which don't (ARC has dedicated IPI
+ * IRQ), the msg-type needs to be conveyed via per-cpu data
+ */
 
-static DEFINE_PER_CPU(struct ipi_data, ipi_data);
+static DEFINE_PER_CPU(unsigned long, ipi_data);
 
-static void ipi_send_msg(const struct cpumask *callmap, enum ipi_msg_type msg)
+static void ipi_send_msg_one(int cpu, enum ipi_msg_type msg)
 {
+       unsigned long __percpu *ipi_data_ptr = per_cpu_ptr(&ipi_data, cpu);
+       unsigned long old, new;
        unsigned long flags;
-       unsigned int cpu;
+
+       pr_debug("%d Sending msg [%d] to %d\n", smp_processor_id(), msg, cpu);
 
        local_irq_save(flags);
 
-       for_each_cpu(cpu, callmap) {
-               struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
-               set_bit(msg, &ipi->bits);
-       }
+       /*
+        * Atomically write new msg bit (in case others are writing too),
+        * and read back old value
+        */
+       do {
+               new = old = *ipi_data_ptr;
+               new |= 1U << msg;
+       } while (cmpxchg(ipi_data_ptr, old, new) != old);
 
-       /* Call the platform specific cross-CPU call function  */
-       if (plat_smp_ops.ipi_send)
-               plat_smp_ops.ipi_send((void *)callmap);
+       /*
+        * Optimize IPI sending for multiple concurrent senders.
+        * If receiver already has unprocessed msg (old != 0), elide new IPI.
+        * Taken IPI will see this updated msg and process with orig msg
+        */
+       if (plat_smp_ops.ipi_send && !old)
+               plat_smp_ops.ipi_send(cpu);
 
        local_irq_restore(flags);
 }
 
+static void ipi_send_msg(const struct cpumask *callmap, enum ipi_msg_type msg)
+{
+       unsigned int cpu;
+
+       for_each_cpu(cpu, callmap)
+               ipi_send_msg_one(cpu, msg);
+}
+
 void smp_send_reschedule(int cpu)
 {
-       ipi_send_msg(cpumask_of(cpu), IPI_RESCHEDULE);
+       ipi_send_msg_one(cpu, IPI_RESCHEDULE);
 }
 
 void smp_send_stop(void)
@@ -254,7 +265,7 @@ void smp_send_stop(void)
 
 void arch_send_call_function_single_ipi(int cpu)
 {
-       ipi_send_msg(cpumask_of(cpu), IPI_CALL_FUNC);
+       ipi_send_msg_one(cpu, IPI_CALL_FUNC);
 }
 
 void arch_send_call_function_ipi_mask(const struct cpumask *mask)
@@ -265,33 +276,29 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 /*
  * ipi_cpu_stop - handle IPI from smp_send_stop()
  */
-static void ipi_cpu_stop(unsigned int cpu)
+static void ipi_cpu_stop(void)
 {
        machine_halt();
 }
 
-static inline void __do_IPI(unsigned long *ops, struct ipi_data *ipi, int cpu)
+static inline void __do_IPI(unsigned long msg)
 {
-       unsigned long msg = 0;
+       switch (msg) {
+       case IPI_RESCHEDULE:
+               scheduler_ipi();
+               break;
 
-       do {
-               msg = find_next_bit(ops, BITS_PER_LONG, msg+1);
+       case IPI_CALL_FUNC:
+               generic_smp_call_function_interrupt();
+               break;
 
-               switch (msg) {
-               case IPI_RESCHEDULE:
-                       scheduler_ipi();
-                       break;
-
-               case IPI_CALL_FUNC:
-                       generic_smp_call_function_interrupt();
-                       break;
-
-               case IPI_CPU_STOP:
-                       ipi_cpu_stop(cpu);
-                       break;
-               }
-       } while (msg < BITS_PER_LONG);
+       case IPI_CPU_STOP:
+               ipi_cpu_stop();
+               break;
 
+       default:
+               pr_warn("IPI with unexpected msg %ld\n", msg);
+       }
 }
 
 /*
@@ -300,19 +307,25 @@ static inline void __do_IPI(unsigned long *ops, struct ipi_data *ipi, int cpu)
  */
 irqreturn_t do_IPI(int irq, void *dev_id)
 {
-       int cpu = smp_processor_id();
-       struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
-       unsigned long ops;
+       unsigned long pending;
+
+       pr_debug("IPI [%ld] received on cpu %d\n",
+                *this_cpu_ptr(&ipi_data), smp_processor_id());
 
        if (plat_smp_ops.ipi_clear)
-               plat_smp_ops.ipi_clear(cpu, irq);
+               plat_smp_ops.ipi_clear(irq);
 
        /*
-        * XXX: is this loop really needed
-        * And do we need to move ipi_clean inside
+        * "dequeue" the msg corresponding to this IPI (and possibly other
+        * piggybacked msg from elided IPIs: see ipi_send_msg_one() above)
         */
-       while ((ops = xchg(&ipi->bits, 0)) != 0)
-               __do_IPI(&ops, ipi, cpu);
+       pending = xchg(this_cpu_ptr(&ipi_data), 0);
+
+       do {
+               unsigned long msg = __ffs(pending);
+               __do_IPI(msg);
+               pending &= ~(1U << msg);
+       } while (pending);
 
        return IRQ_HANDLED;
 }
index 91b55349a5f8a9d82a9f59de19aaf8ee68b1a706..8a12741f5f7ab79668212259036fe0c2872bb037 100644 (file)
@@ -88,18 +88,14 @@ void iss_model_init_smp(unsigned int cpu)
        smp_ipi_irq_setup(cpu, IDU_INTERRUPT_0 + cpu);
 }
 
-static void iss_model_ipi_send(void *arg)
+static void iss_model_ipi_send(int cpu)
 {
-       struct cpumask *callmap = arg;
-       unsigned int cpu;
-
-       for_each_cpu(cpu, callmap)
-               idu_irq_assert(cpu);
+       idu_irq_assert(cpu);
 }
 
-static void iss_model_ipi_clear(int cpu, int irq)
+static void iss_model_ipi_clear(int irq)
 {
-       idu_irq_clear(IDU_INTERRUPT_0 + cpu);
+       idu_irq_clear(IDU_INTERRUPT_0 + smp_processor_id());
 }
 
 void iss_model_init_early_smp(void)
index c1f1a7eee953de4378b1f74bd4907c969f96dceb..ff4fa7bbfa24d77272004bc62998e0e8aa12f727 100644 (file)
@@ -644,8 +644,9 @@ config ARCH_MSM
          stack and controls some vital subsystems
          (clock and power control, etc).
 
-config ARCH_SHMOBILE
-       bool "Renesas SH-Mobile / R-Mobile"
+config ARCH_SHMOBILE_LEGACY
+       bool "Renesas SH-Mobile / R-Mobile (non-multiplatform)"
+       select ARCH_SHMOBILE
        select ARM_PATCH_PHYS_VIRT
        select CLKDEV_LOOKUP
        select GENERIC_CLOCKEVENTS
@@ -660,7 +661,8 @@ config ARCH_SHMOBILE
        select PM_GENERIC_DOMAINS if PM
        select SPARSE_IRQ
        help
-         Support for Renesas's SH-Mobile and R-Mobile ARM platforms.
+         Support for Renesas's SH-Mobile and R-Mobile ARM platforms using
+         a non-multiplatform kernel.
 
 config ARCH_RPC
        bool "RiscPC"
@@ -728,6 +730,7 @@ config ARCH_S3C64XX
        select CLKSRC_SAMSUNG_PWM
        select COMMON_CLK
        select CPU_V6
+       select CPU_V6K
        select GENERIC_CLOCKEVENTS
        select GPIO_SAMSUNG
        select HAVE_S3C2410_I2C if I2C
@@ -1611,7 +1614,7 @@ config HZ_FIXED
        default 200 if ARCH_EBSA110 || ARCH_S3C24XX || ARCH_S5P64X0 || \
                ARCH_S5PV210 || ARCH_EXYNOS4
        default AT91_TIMER_HZ if ARCH_AT91
-       default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE
+       default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE_LEGACY
        default 0
 
 choice
@@ -1796,8 +1799,8 @@ config ARCH_WANT_GENERAL_HUGETLB
 source "mm/Kconfig"
 
 config FORCE_MAX_ZONEORDER
-       int "Maximum zone order" if ARCH_SHMOBILE
-       range 11 64 if ARCH_SHMOBILE
+       int "Maximum zone order" if ARCH_SHMOBILE_LEGACY
+       range 11 64 if ARCH_SHMOBILE_LEGACY
        default "12" if SOC_AM33XX
        default "9" if SA1111
        default "11"
index 5765abf5ce84576d8de31df83d709160905d7b19..5ae3793b54a796ebaa5adef5dfb3b73c844cb78f 100644 (file)
@@ -2,6 +2,18 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
+config ARM_PTDUMP
+       bool "Export kernel pagetable layout ot userspace via debugfs"
+       depends on DEBUG_KERNEL
+       select DEBUG_FS
+       ---help---
+         Say Y here if you want to show the kernel pagetable layout in a
+         debugfs file. This information is only useful for kernel developers
+         who are working in architecture specific areas of the kernel.
+         It is probably not a good idea to enable this feature in a production
+         kernel.
+         If in doubt, say "N"
+
 config STRICT_DEVMEM
        bool "Filter access to /dev/mem"
        depends on MMU
@@ -255,6 +267,13 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on i.MX35.
 
+       config DEBUG_IMX50_UART
+               bool "i.MX50 Debug UART"
+               depends on SOC_IMX50
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on i.MX50.
+
        config DEBUG_IMX51_UART
                bool "i.MX51 Debug UART"
                depends on SOC_IMX51
@@ -897,6 +916,7 @@ config DEBUG_IMX_UART_PORT
                                                DEBUG_IMX21_IMX27_UART || \
                                                DEBUG_IMX31_UART || \
                                                DEBUG_IMX35_UART || \
+                                               DEBUG_IMX50_UART || \
                                                DEBUG_IMX51_UART || \
                                                DEBUG_IMX53_UART || \
                                                DEBUG_IMX6Q_UART || \
@@ -931,6 +951,7 @@ config DEBUG_LL_INCLUDE
                                 DEBUG_IMX21_IMX27_UART || \
                                 DEBUG_IMX31_UART || \
                                 DEBUG_IMX35_UART || \
+                                DEBUG_IMX50_UART || \
                                 DEBUG_IMX51_UART || \
                                 DEBUG_IMX53_UART ||\
                                 DEBUG_IMX6Q_UART || \
@@ -1150,4 +1171,15 @@ config PID_IN_CONTEXTIDR
          additional instructions during context switch. Say Y here only if you
          are planning to use hardware trace tools with this kernel.
 
+config DEBUG_SET_MODULE_RONX
+       bool "Set loadable kernel module data as NX and text as RO"
+       depends on MODULES
+       ---help---
+         This option helps catch unintended modifications to loadable
+         kernel module's text and read-only data. It also prevents execution
+         of module data. Such protection may interfere with run-time code
+         patching and dynamic kernel tracing - and they might also protect
+         against certain classes of kernel exploits.
+         If in doubt, say "N".
+
 endmenu
index c99b1086d83dfa8c0c407bab392ff5bb12927ab5..1edf8ebd8494967d8466c79ecbb79cfcc266e3b7 100644 (file)
@@ -190,7 +190,6 @@ machine-$(CONFIG_ARCH_S5PC100)              += s5pc100
 machine-$(CONFIG_ARCH_S5PV210)         += s5pv210
 machine-$(CONFIG_ARCH_SA1100)          += sa1100
 machine-$(CONFIG_ARCH_SHMOBILE)        += shmobile
-machine-$(CONFIG_ARCH_SHMOBILE_MULTI)  += shmobile
 machine-$(CONFIG_ARCH_SIRF)            += prima2
 machine-$(CONFIG_ARCH_SOCFPGA)         += socfpga
 machine-$(CONFIG_ARCH_STI)             += sti
diff --git a/arch/arm/arm-soc-for-next-contents.txt b/arch/arm/arm-soc-for-next-contents.txt
new file mode 100644 (file)
index 0000000..29fb173
--- /dev/null
@@ -0,0 +1,8 @@
+Contents of arm-soc branches contained in for-next
+
+
+
+next/soc
+       patches
+               ARM: ep93xx: remove deprecated IRQF_DISABLED
+               ARM: ep93xx: use soc bus
index e7190bb5998e149906a4763e815712953c7421f5..f54d5a25c7ee1c0b7803c94179bc5c30f7d7d66b 100644 (file)
@@ -64,7 +64,7 @@ else
 endif
 endif
 
-ifeq ($(CONFIG_ARCH_SHMOBILE),y)
+ifeq ($(CONFIG_ARCH_SHMOBILE_LEGACY),y)
 OBJS           += head-shmobile.o
 endif
 
index d57c1a65b24f981fb25c62aa58c73c1fedd84ab8..741bf73aed5a575708ac025d4ac28e434aa31b1b 100644 (file)
@@ -90,6 +90,7 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
        kirkwood-mplcec4.dtb \
        kirkwood-mv88f6281gtw-ge.dtb \
        kirkwood-netgear_readynas_duo_v2.dtb \
+       kirkwood-netgear_readynas_nv+_v2.dtb \
        kirkwood-ns2.dtb \
        kirkwood-ns2lite.dtb \
        kirkwood-ns2max.dtb \
@@ -114,6 +115,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
        armada-xp-axpwifiap.dtb \
        armada-xp-db.dtb \
        armada-xp-gp.dtb \
+       armada-xp-netgear-rn2120.dtb \
        armada-xp-matrix.dtb \
        armada-xp-openblocks-ax3-4.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
@@ -127,19 +129,33 @@ dtb-$(CONFIG_ARCH_MXC) += \
        imx27-phytec-phycard-s-som.dtb \
        imx27-phytec-phycard-s-rdk.dtb \
        imx31-bug.dtb \
+       imx50-evk.dtb \
        imx51-apf51.dtb \
        imx51-apf51dev.dtb \
        imx51-babbage.dtb \
+       imx51-eukrea-mbimxsd51-baseboard.dtb \
        imx53-ard.dtb \
        imx53-evk.dtb \
        imx53-m53evk.dtb \
        imx53-mba53.dtb \
        imx53-qsb.dtb \
        imx53-smd.dtb \
+       imx53-voipac-bsb.dtb \
+       imx6dl-gw51xx.dtb \
+       imx6dl-gw52xx.dtb \
+       imx6dl-gw53xx.dtb \
+       imx6dl-gw54xx.dtb \
        imx6dl-sabreauto.dtb \
        imx6dl-sabresd.dtb \
        imx6dl-wandboard.dtb \
        imx6q-arm2.dtb \
+       imx6q-cm-fx6.dtb \
+       imx6q-dmo-edmqmx6.dtb \
+       imx6q-gw51xx.dtb \
+       imx6q-gw52xx.dtb \
+       imx6q-gw53xx.dtb \
+       imx6q-gw5400-a.dtb \
+       imx6q-gw54xx.dtb \
        imx6q-phytec-pbab01.dtb \
        imx6q-sabreauto.dtb \
        imx6q-sabrelite.dtb \
@@ -163,6 +179,7 @@ dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
        imx28-cfa10056.dtb \
        imx28-cfa10057.dtb \
        imx28-cfa10058.dtb \
+       imx28-duckbill.dtb \
        imx28-evk.dtb \
        imx28-m28cu3.dtb \
        imx28-m28evk.dtb \
@@ -216,7 +233,7 @@ dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
 dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb
 dtb-$(CONFIG_ARCH_S3C64XX) += s3c6410-mini6410.dtb \
        s3c6410-smdk6410.dtb
-dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
+dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += emev2-kzm9d.dtb \
        r7s72100-genmai.dtb \
        r8a7740-armadillo800eva.dtb \
        r8a7778-bockw.dtb \
@@ -225,6 +242,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
        r8a7779-marzen.dtb \
        r8a7779-marzen-reference.dtb \
        r8a7791-koelsch.dtb \
+       r8a7791-koelsch-reference.dtb \
        r8a7790-lager.dtb \
        r8a7790-lager-reference.dtb \
        sh73a0-kzm9g.dtb \
index b4f95c2bbf74696577b544fd69bd41ed94dda4a9..72a9b3fc425111ec9924fb47defeffee169672e2 100644 (file)
 / {
        model = "IGEP COM AM335x on AQUILA Expansion";
        compatible = "isee,am335x-base0033", "isee,am335x-igep0033", "ti,am33xx";
+
+       hdmi {
+               compatible = "ti,tilcdc,slave";
+               i2c = <&i2c0>;
+               pinctrl-names = "default", "off";
+               pinctrl-0 = <&nxp_hdmi_pins>;
+               pinctrl-1 = <&nxp_hdmi_off_pins>;
+               status = "okay";
+       };
+
+       leds_base {
+               pinctrl-names = "default";
+               pinctrl-0 = <&leds_base_pins>;
+
+               compatible = "gpio-leds";
+
+               led@0 {
+                       label = "base:red:user";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;   /* gpio1_21 */
+                       default-state = "off";
+               };
+
+               led@1 {
+                       label = "base:green:user";
+                       gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;    /* gpio2_0 */
+                       default-state = "off";
+               };
+       };
+};
+
+&am33xx_pinmux {
+       nxp_hdmi_pins: pinmux_nxp_hdmi_pins {
+               pinctrl-single,pins = <
+                       0x1b0 (PIN_OUTPUT | MUX_MODE3)  /* xdma_event_intr0.clkout1 */
+                       0xa0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data0 */
+                       0xa4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data1 */
+                       0xa8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data2 */
+                       0xac (PIN_OUTPUT | MUX_MODE0)   /* lcd_data3 */
+                       0xb0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data4 */
+                       0xb4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data5 */
+                       0xb8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data6 */
+                       0xbc (PIN_OUTPUT | MUX_MODE0)   /* lcd_data7 */
+                       0xc0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data8 */
+                       0xc4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data9 */
+                       0xc8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data10 */
+                       0xcc (PIN_OUTPUT | MUX_MODE0)   /* lcd_data11 */
+                       0xd0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data12 */
+                       0xd4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data13 */
+                       0xd8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data14 */
+                       0xdc (PIN_OUTPUT | MUX_MODE0)   /* lcd_data15 */
+                       0xe0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_vsync */
+                       0xe4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_hsync */
+                       0xe8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_pclk */
+                       0xec (PIN_OUTPUT | MUX_MODE0)   /* lcd_ac_bias_en */
+               >;
+       };
+       nxp_hdmi_off_pins: pinmux_nxp_hdmi_off_pins {
+               pinctrl-single,pins = <
+                       0x1b0 (PIN_OUTPUT | MUX_MODE3)  /* xdma_event_intr0.clkout1 */
+               >;
+       };
+
+       leds_base_pins: pinmux_leds_base_pins {
+               pinctrl-single,pins = <
+                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a5.gpio1_21 */
+                       0x88 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_csn3.gpio2_0 */
+               >;
+       };
+};
+
+&lcdc {
+       status = "okay";
+};
+
+&i2c0 {
+       eeprom: eeprom@50 {
+               compatible = "at,24c256";
+               reg = <0x50>;
+       };
 };
index 6196244793113cfb8c0aac21dcf2259558174ed6..7063311a58d96785dd297f89b982970a59a185bb 100644 (file)
        pinctrl-0 = <&uart0_pins>;
 };
 
+&usb {
+       status = "okay";
+
+       control@44e10000 {
+               status = "okay";
+       };
+
+       usb-phy@47401300 {
+               status = "okay";
+       };
+
+       usb-phy@47401b00 {
+               status = "okay";
+       };
+
+       usb@47401000 {
+               status = "okay";
+       };
+
+       usb@47401800 {
+               status = "okay";
+               dr_mode = "host";
+       };
+
+       dma-controller@07402000  {
+               status = "okay";
+       };
+};
+
 #include "tps65910.dtsi"
 
 &tps {
index 90ce29dbe119e4680b6f7b9b61d177319d8251c1..08a56bcfc7248704b34ad1789418308819b3bcbf 100644 (file)
                                        spi-max-frequency = <50000000>;
                                };
                        };
+               };
 
-                       pcie-controller {
+               pcie-controller {
+                       status = "okay";
+                       /*
+                        * The two PCIe units are accessible through
+                        * both standard PCIe slots and mini-PCIe
+                        * slots on the board.
+                        */
+                       pcie@1,0 {
+                               /* Port 0, Lane 0 */
+                               status = "okay";
+                       };
+                       pcie@2,0 {
+                               /* Port 1, Lane 0 */
                                status = "okay";
-                               /*
-                                * The two PCIe units are accessible through
-                                * both standard PCIe slots and mini-PCIe
-                                * slots on the board.
-                                */
-                               pcie@1,0 {
-                                       /* Port 0, Lane 0 */
-                                       status = "okay";
-                               };
-                               pcie@2,0 {
-                                       /* Port 1, Lane 0 */
-                                       status = "okay";
-                               };
                        };
                };
        };
index 2471d9da767bfad77a4419c20d17407473e704fb..944e8785b30833ea34ace20884c6844a7d3cfe15 100644 (file)
                                green_pwr_led {
                                        label = "mirabox:green:pwr";
                                        gpios = <&gpio1 31 1>;
-                                       linux,default-trigger = "heartbeat";
+                                       default-state = "keep";
                                };
 
                                blue_stat_led {
                                        label = "mirabox:blue:stat";
                                        gpios = <&gpio2 0 1>;
-                                       linux,default-trigger = "cpu0";
+                                       default-state = "off";
                                };
 
                                green_stat_led {
                                        reg = <0x25>;
                                };
                        };
+
+                       nand@d0000 {
+                               status = "okay";
+                               num-cs = <1>;
+                               marvell,nand-keep-config;
+                               marvell,nand-enable-arbiter;
+                               nand-on-flash-bbt;
+
+                               partition@0 {
+                                       label = "U-Boot";
+                                       reg = <0 0x400000>;
+                               };
+                               partition@400000 {
+                                       label = "Linux";
+                                       reg = <0x400000 0x400000>;
+                               };
+                               partition@800000 {
+                                       label = "Filesystem";
+                                       reg = <0x800000 0x3f800000>;
+                               };
+                       };
                };
        };
 };
index 8ac2ac1f69cc0d6f50101c815fada7c9183ce9d8..1c2d13d3e5979f96e77ffef6324a5e0b4aaf7829 100644 (file)
@@ -11,6 +11,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
 #include "armada-370.dtsi"
 
 / {
@@ -62,6 +64,7 @@
                                        marvell,pins = "mpp57";
                                        marvell,function = "gpio";
                                };
+
                                sata1_led_pin: sata1-led-pin {
                                        marvell,pins = "mpp15";
                                        marvell,function = "gpio";
                                        marvell,function = "gpio";
                                };
 
+                               backup_button_pin: backup-button-pin {
+                                       marvell,pins = "mpp58";
+                                       marvell,function = "gpio";
+                               };
+
+                               power_button_pin: power-button-pin {
+                                       marvell,pins = "mpp62";
+                                       marvell,function = "gpio";
+                               };
+
+                               reset_button_pin: reset-button-pin {
+                                       marvell,pins = "mpp6";
+                                       marvell,function = "gpio";
+                               };
+
                                poweroff: poweroff {
                                        marvell,pins = "mpp8";
                                        marvell,function = "gpio";
                        };
 
                        mdio {
-                               phy0: ethernet-phy@0 {
+                               phy0: ethernet-phy@0 { /* Marvell 88E1318 */
                                        reg = <0>;
                                };
                        };
        };
 
        clocks {
-              #address-cells = <1>;
-              #size-cells = <0>;
-
-              g762_clk: fixedclk {
+              g762_clk: g762-oscillator {
                         compatible = "fixed-clock";
                         #clock-cells = <0>;
                         clock-frequency = <8192>;
               };
        };
 
-       gpio_leds {
+       gpio-leds {
                compatible = "gpio-leds";
-               pinctrl-0 = < &power_led_pin
-                             &sata1_led_pin
-                             &sata2_led_pin
-                             &backup_led_pin >;
+               pinctrl-0 = <&power_led_pin
+                            &sata1_led_pin
+                            &sata2_led_pin
+                            &backup_led_pin>;
                pinctrl-names = "default";
 
-               blue_power_led {
+               blue-power-led {
                        label = "rn102:blue:pwr";
-                       gpios = <&gpio1 25 1>;  /* GPIO 57 Active Low */
-                       linux,default-trigger = "heartbeat";
+                       gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+                       default-state = "keep";
                };
 
-               green_sata1_led {
+               green-sata1-led {
                        label = "rn102:green:sata1";
-                       gpios = <&gpio0 15 1>;  /* GPIO 15 Active Low */
+                       gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
                        default-state = "on";
                };
 
-               green_sata2_led {
+               green-sata2-led {
                        label = "rn102:green:sata2";
-                       gpios = <&gpio0 14 1>;   /* GPIO 14 Active Low */
+                       gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
                        default-state = "on";
                };
 
-               green_backup_led {
+               green-backup-led {
                        label = "rn102:green:backup";
-                       gpios = <&gpio1 24 1>;   /* GPIO 56 Active Low */
+                       gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
                        default-state = "on";
                };
        };
 
-       gpio_keys {
+       gpio-keys {
                compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
+               pinctrl-0 = <&power_button_pin
+                            &reset_button_pin
+                            &backup_button_pin>;
+               pinctrl-names = "default";
 
-               button@1 {
+               power-button {
                        label = "Power Button";
-                       linux,code = <116>;     /* KEY_POWER */
-                       gpios = <&gpio1 30 0>;
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
                };
 
-               button@2 {
+               reset-button {
                        label = "Reset Button";
-                       linux,code = <0x198>;   /* KEY_RESTART */
-                       gpios = <&gpio0 6 1>;
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
                };
 
-               button@3 {
+               backup-button {
                        label = "Backup Button";
-                       linux,code = <133>;     /* KEY_COPY */
-                       gpios = <&gpio1 26 1>;
+                       linux,code = <KEY_COPY>;
+                       gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
                };
        };
 
-       gpio_poweroff {
+       gpio-poweroff {
                compatible = "gpio-poweroff";
                pinctrl-0 = <&poweroff>;
                pinctrl-names = "default";
-               gpios = <&gpio0 8 1>;
+               gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
        };
-
 };
index b0b32f5fbeb473c6a44275db69e2b27928648a58..e48e5fb6a065866c321c44193f4dc09b83dde091 100644 (file)
@@ -11,6 +11,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
 #include "armada-370.dtsi"
 
 / {
                                        marvell,function = "gpio";
                                };
 
-                               backup_key_pin: backup-key-pin {
+                               backup_button_pin: backup-button-pin {
                                        marvell,pins = "mpp52";
                                        marvell,function = "gpio";
                                };
 
-                               power_key_pin: power-key-pin {
+                               power_button_pin: power-button-pin {
                                        marvell,pins = "mpp62";
                                        marvell,function = "gpio";
                                };
                                        marvell,function = "gpio";
                                };
 
-                               reset_key_pin: reset-key-pin {
+                               reset_button_pin: reset-button-pin {
                                        marvell,pins = "mpp65";
                                        marvell,function = "gpio";
                                };
                        };
 
                        mdio {
-                               phy0: ethernet-phy@0 {
+                               phy0: ethernet-phy@0 { /* Marvell 88E1318 */
                                        reg = <0>;
                                };
 
-                               phy1: ethernet-phy@1 {
+                               phy1: ethernet-phy@1 { /* Marvell 88E1318 */
                                        reg = <1>;
                                };
                        };
                                        fan_startv = <1>;
                                        pwm_polarity = <0>;
                                };
+
+                               pca9554: pca9554@23 {
+                                       compatible = "nxp,pca9554";
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       reg = <0x23>;
+                               };
                        };
                };
        };
 
        clocks {
-              #address-cells = <1>;
-              #size-cells = <0>;
-
-              g762_clk: fixedclk {
+              g762_clk: g762-oscillator {
                         compatible = "fixed-clock";
                         #clock-cells = <0>;
                         clock-frequency = <8192>;
               };
        };
 
-       gpio_leds {
+       gpio-leds {
                compatible = "gpio-leds";
                pinctrl-0 = <&backup_led_pin &power_led_pin>;
                pinctrl-names = "default";
 
-               blue_backup_led {
+               blue-backup-led {
                        label = "rn104:blue:backup";
-                       gpios = <&gpio1 31 0>;   /* GPIO 63 Active High */
+                       gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
 
-               blue_power_led {
+               blue-power-led {
                        label = "rn104:blue:pwr";
-                       gpios = <&gpio2 0 1>;    /* GPIO 64 Active Low */
+                       gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
                        linux,default-trigger = "keep";
                };
+
+               blue-sata1-led {
+                       label = "rn104:blue:sata1";
+                       gpios = <&pca9554 0 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               blue-sata2-led {
+                       label = "rn104:blue:sata2";
+                       gpios = <&pca9554 1 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               blue-sata3-led {
+                       label = "rn104:blue:sata3";
+                       gpios = <&pca9554 2 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               blue-sata4-led {
+                       label = "rn104:blue:sata4";
+                       gpios = <&pca9554 3 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
        };
 
-       gpio_keys {
+       gpio-keys {
                compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               pinctrl-0 = <&backup_key_pin
-                            &power_key_pin
-                            &reset_key_pin>;
+               pinctrl-0 = <&backup_button_pin
+                            &power_button_pin
+                            &reset_button_pin>;
                pinctrl-names = "default";
 
-               button@1 {
+               backup-button {
                        label = "Backup Button";
-                       linux,code = <133>;     /* KEY_COPY */
-                       gpios = <&gpio1 20 1>;
+                       linux,code = <KEY_COPY>;
+                       gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
                };
 
-               button@2 {
+               power-button {
                        label = "Power Button";
-                       linux,code = <116>;     /* KEY_POWER */
-                       gpios = <&gpio1 30 0>;
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
                };
 
-               button@3 {
+               reset-button {
                        label = "Reset Button";
-                       linux,code = <0x198>;   /* KEY_RESTART */
-                       gpios = <&gpio2 1 1>;
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
                };
        };
 
-       gpio_poweroff {
+       gpio-poweroff {
                compatible = "gpio-poweroff";
                pinctrl-0 = <&poweroff>;
                pinctrl-names = "default";
-               gpios = <&gpio1 28 1>;
+               gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
        };
 };
index 00d6a798c705b9b04408a8d28af70cd7b7cc6868..45839e53538e9c05e4005603c586abd650a3c744 100644 (file)
 
                        coherency-fabric@20200 {
                                compatible = "marvell,coherency-fabric";
-                               reg = <0x20200 0xb0>, <0x21810 0x1c>;
+                               reg = <0x20200 0xb0>, <0x21010 0x1c>;
                        };
 
                        serial@12000 {
                                status = "disabled";
                        };
 
+                       nand@d0000 {
+                               compatible = "marvell,armada370-nand";
+                               reg = <0xd0000 0x54>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               interrupts = <113>;
+                               clocks = <&coredivclk 0>;
+                               status = "disabled";
+                       };
                };
        };
 
index 2298e4a910e230748dda13cb70cab55713932a10..274e2ad5f51c67114b99786c0c4356971cdec492 100644 (file)
                                        spi-max-frequency = <108000000>;
                                };
                        };
+
+                       nand@d0000 {
+                               status = "okay";
+                               num-cs = <1>;
+                               marvell,nand-keep-config;
+                               marvell,nand-enable-arbiter;
+                               nand-on-flash-bbt;
+                       };
                };
        };
 };
index 3f5e6121c730a21ae2079acff268da2be20518ef..98335fb34b7ad5a11d9f40b6564bddc161431455 100644 (file)
@@ -47,7 +47,7 @@
                /*
                 * MV78230 has 2 PCIe units Gen2.0: One unit can be
                 * configured as x4 or quad x1 lanes. One unit is
-                * x4/x1.
+                * x1 only.
                 */
                pcie-controller {
                        compatible = "marvell,armada-xp-pcie";
 
                        ranges =
                               <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000   /* Port 0.0 registers */
-                               0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000   /* Port 2.0 registers */
                                0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000   /* Port 0.1 registers */
                                0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000   /* Port 0.2 registers */
                                0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000   /* Port 0.3 registers */
+                               0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000   /* Port 1.0 registers */
                                0x82000000 0x1 0       MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
                                0x81000000 0x1 0       MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO  */
                                0x82000000 0x2 0       MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
@@ -74,8 +74,8 @@
                                0x81000000 0x3 0       MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO  */
                                0x82000000 0x4 0       MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
                                0x81000000 0x4 0       MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO  */
-                               0x82000000 0x9 0       MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
-                               0x81000000 0x9 0       MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO  */>;
+                               0x82000000 0x5 0       MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
+                               0x81000000 0x5 0       MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO  */>;
 
                        pcie@1,0 {
                                device_type = "pci";
                                status = "disabled";
                        };
 
-                       pcie@9,0 {
+                       pcie@5,0 {
                                device_type = "pci";
-                               assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
-                               reg = <0x4800 0 0 0 0>;
+                               assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+                               reg = <0x2800 0 0 0 0>;
                                #address-cells = <3>;
                                #size-cells = <2>;
                                #interrupt-cells = <1>;
-                               ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
-                                         0x81000000 0 0 0x81000000 0x9 0 1 0>;
+                               ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
+                                         0x81000000 0 0 0x81000000 0x5 0 1 0>;
                                interrupt-map-mask = <0 0 0 0>;
-                               interrupt-map = <0 0 0 0 &mpic 99>;
-                               marvell,pcie-port = <2>;
+                               interrupt-map = <0 0 0 0 &mpic 62>;
+                               marvell,pcie-port = <1>;
                                marvell,pcie-lane = <0>;
-                               clocks = <&gateclk 26>;
+                               clocks = <&gateclk 9>;
                                status = "disabled";
                        };
                };
index 3e9fd1353f895d6778972e95518850268ef6eb4e..66609684d41b59ef701530fd2076553ffc4e9b6b 100644 (file)
@@ -48,7 +48,7 @@
                /*
                 * MV78260 has 3 PCIe units Gen2.0: Two units can be
                 * configured as x4 or quad x1 lanes. One unit is
-                * x4/x1.
+                * x4 only.
                 */
                pcie-controller {
                        compatible = "marvell,armada-xp-pcie";
@@ -68,7 +68,9 @@
                                0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000   /* Port 0.2 registers */
                                0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000   /* Port 0.3 registers */
                                0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000   /* Port 1.0 registers */
-                               0x82000000 0 0x82000 MBUS_ID(0xf0, 0x01) 0x82000 0 0x00002000   /* Port 3.0 registers */
+                               0x82000000 0 0x84000 MBUS_ID(0xf0, 0x01) 0x84000 0 0x00002000   /* Port 1.1 registers */
+                               0x82000000 0 0x88000 MBUS_ID(0xf0, 0x01) 0x88000 0 0x00002000   /* Port 1.2 registers */
+                               0x82000000 0 0x8c000 MBUS_ID(0xf0, 0x01) 0x8c000 0 0x00002000   /* Port 1.3 registers */
                                0x82000000 0x1 0     MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
                                0x81000000 0x1 0     MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO  */
                                0x82000000 0x2 0     MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
                                0x81000000 0x3 0     MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO  */
                                0x82000000 0x4 0     MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
                                0x81000000 0x4 0     MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO  */
-                               0x82000000 0x9 0     MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
-                               0x81000000 0x9 0     MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO  */
-                               0x82000000 0xa 0     MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */
-                               0x81000000 0xa 0     MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO  */>;
+
+                               0x82000000 0x5 0     MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
+                               0x81000000 0x5 0     MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO  */
+                               0x82000000 0x6 0     MBUS_ID(0x08, 0xd8) 0 1 0 /* Port 1.1 MEM */
+                               0x81000000 0x6 0     MBUS_ID(0x08, 0xd0) 0 1 0 /* Port 1.1 IO  */
+                               0x82000000 0x7 0     MBUS_ID(0x08, 0xb8) 0 1 0 /* Port 1.2 MEM */
+                               0x81000000 0x7 0     MBUS_ID(0x08, 0xb0) 0 1 0 /* Port 1.2 IO  */
+                               0x82000000 0x8 0     MBUS_ID(0x08, 0x78) 0 1 0 /* Port 1.3 MEM */
+                               0x81000000 0x8 0     MBUS_ID(0x08, 0x70) 0 1 0 /* Port 1.3 IO  */
+
+                               0x82000000 0x9 0     MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
+                               0x81000000 0x9 0     MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO  */>;
 
                        pcie@1,0 {
                                device_type = "pci";
                                #address-cells = <3>;
                                #size-cells = <2>;
                                #interrupt-cells = <1>;
-                                ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
-                                          0x81000000 0 0 0x81000000 0x2 0 1 0>;
+                               ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+                                         0x81000000 0 0 0x81000000 0x2 0 1 0>;
                                interrupt-map-mask = <0 0 0 0>;
                                interrupt-map = <0 0 0 0 &mpic 59>;
                                marvell,pcie-port = <0>;
                                status = "disabled";
                        };
 
-                       pcie@9,0 {
+                       pcie@5,0 {
                                device_type = "pci";
-                               assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
-                               reg = <0x4800 0 0 0 0>;
+                               assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+                               reg = <0x2800 0 0 0 0>;
                                #address-cells = <3>;
                                #size-cells = <2>;
                                #interrupt-cells = <1>;
-                               ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
-                                         0x81000000 0 0 0x81000000 0x9 0 1 0>;
+                               ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
+                                         0x81000000 0 0 0x81000000 0x5 0 1 0>;
                                interrupt-map-mask = <0 0 0 0>;
-                               interrupt-map = <0 0 0 0 &mpic 99>;
-                               marvell,pcie-port = <2>;
+                               interrupt-map = <0 0 0 0 &mpic 62>;
+                               marvell,pcie-port = <1>;
                                marvell,pcie-lane = <0>;
-                               clocks = <&gateclk 26>;
+                               clocks = <&gateclk 9>;
                                status = "disabled";
                        };
 
-                       pcie@10,0 {
+                       pcie@6,0 {
                                device_type = "pci";
-                               assigned-addresses = <0x82000800 0 0x82000 0 0x2000>;
-                               reg = <0x5000 0 0 0 0>;
+                               assigned-addresses = <0x82000800 0 0x84000 0 0x2000>;
+                               reg = <0x3000 0 0 0 0>;
                                #address-cells = <3>;
                                #size-cells = <2>;
                                #interrupt-cells = <1>;
-                               ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0
-                                         0x81000000 0 0 0x81000000 0xa 0 1 0>;
+                               ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0
+                                         0x81000000 0 0 0x81000000 0x6 0 1 0>;
                                interrupt-map-mask = <0 0 0 0>;
-                               interrupt-map = <0 0 0 0 &mpic 103>;
-                               marvell,pcie-port = <3>;
+                               interrupt-map = <0 0 0 0 &mpic 63>;
+                               marvell,pcie-port = <1>;
+                               marvell,pcie-lane = <1>;
+                               clocks = <&gateclk 10>;
+                               status = "disabled";
+                       };
+
+                       pcie@7,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x88000 0 0x2000>;
+                               reg = <0x3800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0
+                                         0x81000000 0 0 0x81000000 0x7 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &mpic 64>;
+                               marvell,pcie-port = <1>;
+                               marvell,pcie-lane = <2>;
+                               clocks = <&gateclk 11>;
+                               status = "disabled";
+                       };
+
+                       pcie@8,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>;
+                               reg = <0x4000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0
+                                         0x81000000 0 0 0x81000000 0x8 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &mpic 65>;
+                               marvell,pcie-port = <1>;
+                               marvell,pcie-lane = <3>;
+                               clocks = <&gateclk 12>;
+                               status = "disabled";
+                       };
+
+                       pcie@9,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
+                               reg = <0x4800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
+                                         0x81000000 0 0 0x81000000 0x9 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &mpic 99>;
+                               marvell,pcie-port = <2>;
                                marvell,pcie-lane = <0>;
-                               clocks = <&gateclk 27>;
+                               clocks = <&gateclk 26>;
                                status = "disabled";
                        };
                };
diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
new file mode 100644 (file)
index 0000000..8b2a787
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Device Tree file for NETGEAR ReadyNAS 2120
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-xp-mv78230.dtsi"
+
+/ {
+       model = "NETGEAR ReadyNAS 2120";
+       compatible = "netgear,readynas-2120", "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp";
+
+       chosen {
+               bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0 0x00000000 0 0x80000000>; /* 2GB */
+       };
+
+       soc {
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+                         MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+
+               pcie-controller {
+                       status = "okay";
+
+                       /* Connected to first Marvell 88SE9170 SATA controller */
+                       pcie@1,0 {
+                               /* Port 0, Lane 0 */
+                               status = "okay";
+                       };
+
+                       /* Connected to second Marvell 88SE9170 SATA controller */
+                       pcie@2,0 {
+                               /* Port 0, Lane 1 */
+                               status = "okay";
+                       };
+
+                       /* Connected to Fresco Logic FL1009 USB 3.0 controller */
+                       pcie@5,0 {
+                               /* Port 1, Lane 0 */
+                               status = "okay";
+                       };
+               };
+
+               internal-regs {
+                       pinctrl {
+                               poweroff: poweroff {
+                                       marvell,pins = "mpp42";
+                                       marvell,function = "gpio";
+                               };
+
+                               power_button_pin: power-button-pin {
+                                       marvell,pins = "mpp27";
+                                       marvell,function = "gpio";
+                               };
+
+                               reset_button_pin: reset-button-pin {
+                                       marvell,pins = "mpp41";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata1_led_pin: sata1-led-pin {
+                                       marvell,pins = "mpp31";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata2_led_pin: sata2-led-pin {
+                                       marvell,pins = "mpp40";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata3_led_pin: sata3-led-pin {
+                                       marvell,pins = "mpp44";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata4_led_pin: sata4-led-pin {
+                                       marvell,pins = "mpp47";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata1_power_pin: sata1-power-pin {
+                                       marvell,pins = "mpp24";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata2_power_pin: sata2-power-pin {
+                                       marvell,pins = "mpp25";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata3_power_pin: sata3-power-pin {
+                                       marvell,pins = "mpp26";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata4_power_pin: sata4-power-pin {
+                                       marvell,pins = "mpp28";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata1_pres_pin: sata1-pres-pin {
+                                       marvell,pins = "mpp32";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata2_pres_pin: sata2-pres-pin {
+                                       marvell,pins = "mpp33";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata3_pres_pin: sata3-pres-pin {
+                                       marvell,pins = "mpp34";
+                                       marvell,function = "gpio";
+                               };
+
+                               sata4_pres_pin: sata4-pres-pin {
+                                       marvell,pins = "mpp35";
+                                       marvell,function = "gpio";
+                               };
+
+                               err_led_pin: err-led-pin {
+                                       marvell,pins = "mpp45";
+                                       marvell,function = "gpio";
+                               };
+                       };
+
+                       serial@12000 {
+                               clocks = <&coreclk 0>;
+                               status = "okay";
+                       };
+
+                       mdio {
+                               phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+                                       reg = <0>;
+                               };
+
+                               phy1: ethernet-phy@1 { /* Marvell 88E1318 */
+                                       reg = <1>;
+                               };
+                       };
+
+                       ethernet@70000 {
+                               status = "okay";
+                               phy = <&phy0>;
+                               phy-mode = "rgmii-id";
+                       };
+
+                       ethernet@74000 {
+                               status = "okay";
+                               phy = <&phy1>;
+                               phy-mode = "rgmii-id";
+                       };
+
+                       /* Front USB 2.0 port */
+                       usb@50000 {
+                               status = "okay";
+                       };
+
+                       i2c@11000 {
+                               compatible = "marvell,mv64xxx-i2c";
+                               clock-frequency = <400000>;
+                               status = "okay";
+
+                               /* Controller for rear fan #1 of 3 (Protechnic
+                                * MGT4012XB-O20, 8000RPM) near eSATA port */
+                               g762_fan1: g762@3e {
+                                       compatible = "gmt,g762";
+                                       reg = <0x3e>;
+                                       clocks = <&g762_clk>; /* input clock */
+                                       fan_gear_mode = <0>;
+                                       fan_startv = <1>;
+                                       pwm_polarity = <0>;
+                               };
+
+                               /*  Controller for rear (center) fan #2 of 3 */
+                               g762_fan2: g762@48 {
+                                       compatible = "gmt,g762";
+                                       reg = <0x48>;
+                                       clocks = <&g762_clk>; /* input clock */
+                                       fan_gear_mode = <0>;
+                                       fan_startv = <1>;
+                                       pwm_polarity = <0>;
+                               };
+
+                               /*  Controller for rear fan #3 of 3 */
+                               g762_fan3: g762@49 {
+                                       compatible = "gmt,g762";
+                                       reg = <0x49>;
+                                       clocks = <&g762_clk>; /* input clock */
+                                       fan_gear_mode = <0>;
+                                       fan_startv = <1>;
+                                       pwm_polarity = <0>;
+                               };
+
+                               /* Temperature sensor */
+                               g751: g751@4c {
+                                       compatible = "gmt,g751";
+                                       reg = <0x4c>;
+                               };
+                       };
+               };
+       };
+
+       clocks {
+              g762_clk: g762-oscillator {
+                        compatible = "fixed-clock";
+                        #clock-cells = <0>;
+                        clock-frequency = <32768>;
+              };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&sata1_led_pin &sata2_led_pin &err_led_pin
+                            &sata3_led_pin &sata4_led_pin>;
+               pinctrl-names = "default";
+
+               red-sata1-led {
+                       label = "rn2120:red:sata1";
+                       gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red-sata2-led {
+                       label = "rn2120:red:sata2";
+                       gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red-sata3-led {
+                       label = "rn2120:red:sata3";
+                       gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red-sata4-led {
+                       label = "rn2120:red:sata4";
+                       gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red-err-led {
+                       label = "rn2120:red:err";
+                       gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-0 = <&power_button_pin &reset_button_pin>;
+               pinctrl-names = "default";
+
+               power-button {
+                       label = "Power Button";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
+               };
+
+               reset-button {
+                       label = "Reset Button";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-poweroff {
+               compatible = "gpio-poweroff";
+               pinctrl-0 = <&poweroff>;
+               pinctrl-names = "default";
+               gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+       };
+};
index 5695afcc04bf1a7fa7fa13024acd8bb794464ed5..99bcf76e6953d3e0af3e72fe6372cdecdfbecb1f 100644 (file)
                                green_led {
                                        label = "green_led";
                                        gpios = <&gpio1 21 1>;
-                                       default-state = "off";
-                                       linux,default-trigger = "heartbeat";
+                                       default-state = "keep";
                                };
                        };
 
index 56ee8282a7a8ef201f1833135ddfb3b4d81e38a9..997901f7ed7381c77ff6c669f4f7571474ebd4b2 100644 (file)
                        watchdog@fffffd40 {
                                compatible = "atmel,at91sam9260-wdt";
                                reg = <0xfffffd40 0x10>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               atmel,watchdog-type = "hardware";
+                               atmel,reset-type = "all";
+                               atmel,dbg-halt;
+                               atmel,idle-halt;
                                status = "disabled";
                        };
                };
index d5bd65f7460258daa91bb4a5227071b2b67fc5de..45fb0a46d398213d3b439f08a30f540f89e148a9 100644 (file)
                        watchdog@fffffd40 {
                                compatible = "atmel,at91sam9260-wdt";
                                reg = <0xfffffd40 0x10>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               atmel,watchdog-type = "hardware";
+                               atmel,reset-type = "all";
+                               atmel,dbg-halt;
+                               atmel,idle-halt;
                                status = "disabled";
                        };
 
index c3e514837074c1874412e88cb294fd4ec976a2ba..16534c70012dc83227e2bd343cfb67f5f9a2a223 100644 (file)
                        watchdog@fffffd40 {
                                compatible = "atmel,at91sam9260-wdt";
                                reg = <0xfffffd40 0x10>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               atmel,watchdog-type = "hardware";
+                               atmel,reset-type = "all";
+                               atmel,dbg-halt;
+                               atmel,idle-halt;
                                status = "disabled";
                        };
 
index 6224f9fe2f2b7205f32a3205ff78d0b31036ad09..b30a6e08d0276c398f96a884cdff5aab5cdafa81 100644 (file)
                        watchdog@fffffe40 {
                                compatible = "atmel,at91sam9260-wdt";
                                reg = <0xfffffe40 0x10>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               atmel,watchdog-type = "hardware";
+                               atmel,reset-type = "all";
+                               atmel,dbg-halt;
+                               atmel,idle-halt;
                                status = "disabled";
                        };
                };
index 40267a116c3c44438d7d915e10c9d119a4577540..289bcfc16ede5f3aad7d2fbecaf20594b952e465 100644 (file)
                        watchdog@fffffe40 {
                                compatible = "atmel,at91sam9260-wdt";
                                reg = <0xfffffe40 0x10>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               atmel,watchdog-type = "hardware";
+                               atmel,reset-type = "all";
+                               atmel,dbg-halt;
+                               atmel,idle-halt;
                                status = "disabled";
                        };
 
index 1e12aeff403b018cf174ff1b710af391f970c997..aa537ed13f0a578ade79e74c62a56302f1d65437 100644 (file)
@@ -85,6 +85,8 @@
                        reg = <0x7e205000 0x1000>;
                        interrupts = <2 21>;
                        clocks = <&clk_i2c>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
                        status = "disabled";
                };
 
@@ -93,6 +95,8 @@
                        reg = <0x7e804000 0x1000>;
                        interrupts = <2 21>;
                        clocks = <&clk_i2c>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
                        status = "disabled";
                };
 
index dc259e8b8a73a8630dc9698295e662f0ab66e43d..42cef0a8ce95e31ada8a27a72cfc8edf965244ee 100644 (file)
                i2c2_bus: i2c2-bus {
                        samsung,pin-pud = <0>;
                };
+
+               max77686_irq: max77686-irq {
+                       samsung,pins = "gpx3-2";
+                       samsung,pin-function = <0>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
        };
 
        i2c@12C60000 {
 
                max77686@09 {
                        compatible = "maxim,max77686";
+                       interrupt-parent = <&gpx3>;
+                       interrupts = <2 0>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&max77686_irq>;
+                       wakeup-source;
                        reg = <0x09>;
 
                        voltage-regulators {
                };
        };
 
-       dwmmc0@12200000 {
+       mmc@12200000 {
                num-slots = <1>;
                supports-highspeed;
                broken-cd;
                };
        };
 
-       dwmmc1@12210000 {
+       mmc@12210000 {
                status = "disabled";
        };
 
-       dwmmc2@12220000 {
+       mmc@12220000 {
                num-slots = <1>;
                supports-highspeed;
                fifo-depth = <0x80>;
                };
        };
 
-       dwmmc3@12230000 {
+       mmc@12230000 {
                num-slots = <1>;
                supports-highspeed;
                broken-cd;
index 8349a248eceaf242f8a079e6c565af109ee69708..7a70f4ca502a1665fa21cb31360d2869cbd3617c 100644 (file)
@@ -23,7 +23,7 @@
                power {
                        label = "Power";
                        gpios = <&gpio0 18 1>;
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
        };
 
index 113a8bc7bee73649a33cc3e212336536f47399b3..db24b41a5264072dc74d39d2497b1be72e8a2d93 100644 (file)
                                marvell,#interrupts = <5>;
                        };
 
+                       pmu_intc: pmu-interrupt-ctrl@d0050 {
+                               compatible = "marvell,dove-pmu-intc";
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0xd0050 0x8>;
+                               interrupts = <33>;
+                               marvell,#interrupts = <7>;
+                       };
+
                        core_clk: core-clocks@d0214 {
                                compatible = "marvell,dove-core-clock";
                                reg = <0xd0214 0x4>;
                        rtc: real-time-clock@d8500 {
                                compatible = "marvell,orion-rtc";
                                reg = <0xd8500 0x20>;
+                               interrupt-parent = <&pmu_intc>;
+                               interrupts = <5>;
                        };
 
                        crypto: crypto-engine@30000 {
                                status = "disabled";
 
                                ethphy: ethernet-phy {
-                                       device-type = "ethernet-phy";
+                                       device_type = "ethernet-phy";
                                        /* set phy address in board file */
                                };
                        };
index 861aa7d6fc7dbc480c0b9d6b185d6a291d38fcd2..baaa66cc39bfb4a4e2faabf2edc273778006faa2 100644 (file)
@@ -9,7 +9,9 @@
  */
 /dts-v1/;
 
-/include/ "emev2.dtsi"
+#include "emev2.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 
 / {
        model = "EMEV2 KZM9D Board";
                vddvario-supply = <&reg_1p8v>;
                vdd33a-supply = <&reg_3p3v>;
        };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               button@1 {
+                       debounce_interval = <50>;
+                       wakeup = <1>;
+                       label = "DSW2-1";
+                       linux,code = <KEY_1>;
+                       gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+               };
+               button@2 {
+                       debounce_interval = <50>;
+                       wakeup = <1>;
+                       label = "DSW2-2";
+                       linux,code = <KEY_2>;
+                       gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+               };
+               button@3 {
+                       debounce_interval = <50>;
+                       wakeup = <1>;
+                       label = "DSW2-3";
+                       linux,code = <KEY_3>;
+                       gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+               };
+               button@4 {
+                       debounce_interval = <50>;
+                       wakeup = <1>;
+                       label = "DSW2-4";
+                       linux,code = <KEY_4>;
+                       gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+               };
+       };
 };
index 9063a4434d6a59b26e3bac76e24f1643bc6121e8..256c2f8b9d0a859ce11d6e10f2f30d1ae2ecbc7c 100644 (file)
@@ -8,7 +8,7 @@
  * kind, whether express or implied.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
        compatible = "renesas,emev2";
                             <0 121 4>;
        };
 
+       smu@e0110000 {
+               compatible = "renesas,emev2-smu";
+               reg = <0xe0110000 0x10000>;
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               c32ki: c32ki {
+                       compatible = "fixed-clock";
+                       clock-frequency = <32768>;
+                       #clock-cells = <0>;
+               };
+               pll3_fo: pll3_fo {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&c32ki>;
+                       clock-div = <1>;
+                       clock-mult = <7000>;
+                       #clock-cells = <0>;
+               };
+               usia_u0_sclkdiv: usia_u0_sclkdiv {
+                       compatible = "renesas,emev2-smu-clkdiv";
+                       reg = <0x610 0>;
+                       clocks = <&pll3_fo>;
+                       #clock-cells = <0>;
+               };
+               usib_u1_sclkdiv: usib_u1_sclkdiv {
+                       compatible = "renesas,emev2-smu-clkdiv";
+                       reg = <0x65c 0>;
+                       clocks = <&pll3_fo>;
+                       #clock-cells = <0>;
+               };
+               usib_u2_sclkdiv: usib_u2_sclkdiv {
+                       compatible = "renesas,emev2-smu-clkdiv";
+                       reg = <0x65c 16>;
+                       clocks = <&pll3_fo>;
+                       #clock-cells = <0>;
+               };
+               usib_u3_sclkdiv: usib_u3_sclkdiv {
+                       compatible = "renesas,emev2-smu-clkdiv";
+                       reg = <0x660 0>;
+                       clocks = <&pll3_fo>;
+                       #clock-cells = <0>;
+               };
+               usia_u0_sclk: usia_u0_sclk {
+                       compatible = "renesas,emev2-smu-gclk";
+                       reg = <0x4a0 1>;
+                       clocks = <&usia_u0_sclkdiv>;
+                       #clock-cells = <0>;
+               };
+               usib_u1_sclk: usib_u1_sclk {
+                       compatible = "renesas,emev2-smu-gclk";
+                       reg = <0x4b8 1>;
+                       clocks = <&usib_u1_sclkdiv>;
+                       #clock-cells = <0>;
+               };
+               usib_u2_sclk: usib_u2_sclk {
+                       compatible = "renesas,emev2-smu-gclk";
+                       reg = <0x4bc 1>;
+                       clocks = <&usib_u2_sclkdiv>;
+                       #clock-cells = <0>;
+               };
+               usib_u3_sclk: usib_u3_sclk {
+                       compatible = "renesas,emev2-smu-gclk";
+                       reg = <0x4c0 1>;
+                       clocks = <&usib_u3_sclkdiv>;
+                       #clock-cells = <0>;
+               };
+               sti_sclk: sti_sclk {
+                       compatible = "renesas,emev2-smu-gclk";
+                       reg = <0x528 1>;
+                       clocks = <&c32ki>;
+                       #clock-cells = <0>;
+               };
+       };
+
        sti@e0180000 {
                compatible = "renesas,em-sti";
                reg = <0xe0180000 0x54>;
                interrupts = <0 125 0>;
+               clocks = <&sti_sclk>;
+               clock-names = "sclk";
        };
 
        uart@e1020000 {
                compatible = "renesas,em-uart";
                reg = <0xe1020000 0x38>;
                interrupts = <0 8 0>;
+               clocks = <&usia_u0_sclk>;
+               clock-names = "sclk";
        };
 
        uart@e1030000 {
                compatible = "renesas,em-uart";
                reg = <0xe1030000 0x38>;
                interrupts = <0 9 0>;
+               clocks = <&usib_u1_sclk>;
+               clock-names = "sclk";
        };
 
        uart@e1040000 {
                compatible = "renesas,em-uart";
                reg = <0xe1040000 0x38>;
                interrupts = <0 10 0>;
+               clocks = <&usib_u2_sclk>;
+               clock-names = "sclk";
        };
 
        uart@e1050000 {
                compatible = "renesas,em-uart";
                reg = <0xe1050000 0x38>;
                interrupts = <0 11 0>;
+               clocks = <&usib_u3_sclk>;
+               clock-names = "sclk";
        };
 
        gpio0: gpio@e0050000 {
index 074739d39e2db04490c3575fbb2131519f6cf53d..e52b038a7a1171ac1559b86b5d3a18cdfb144ff8 100644 (file)
                interrupts = <1 9 0xf04>;
        };
 
-       dwmmc_0: dwmmc0@12200000 {
-               compatible = "samsung,exynos5250-dw-mshc";
-               interrupts = <0 75 0>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-       };
-
-       dwmmc_1: dwmmc1@12210000 {
-               compatible = "samsung,exynos5250-dw-mshc";
-               interrupts = <0 76 0>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-       };
-
-       dwmmc_2: dwmmc2@12220000 {
-               compatible = "samsung,exynos5250-dw-mshc";
-               interrupts = <0 77 0>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-       };
-
        serial@12C00000 {
                compatible = "samsung,exynos4210-uart";
                reg = <0x12C00000 0x100>;
index 684527087aa4cc2bdc8da3c3f801a1626f3d9439..b77a37ec81c25b89affa2f90d8ef7007b0d4072a 100644 (file)
                status = "disabled";
        };
 
-       dwmmc_0: dwmmc0@12200000 {
+       mmc_0: mmc@12200000 {
+               status = "okay";
                num-slots = <1>;
                supports-highspeed;
                broken-cd;
-               fifo-depth = <0x80>;
                card-detect-delay = <200>;
                samsung,dw-mshc-ciu-div = <3>;
                samsung,dw-mshc-sdr-timing = <2 3>;
                };
        };
 
-       dwmmc_1: dwmmc1@12210000 {
-               status = "disabled";
-       };
-
-       dwmmc_2: dwmmc2@12220000 {
+       mmc_2: mmc@12220000 {
+               status = "okay";
                num-slots = <1>;
                supports-highspeed;
-               fifo-depth = <0x80>;
                card-detect-delay = <200>;
                samsung,dw-mshc-ciu-div = <3>;
                samsung,dw-mshc-sdr-timing = <2 3>;
                };
        };
 
-       dwmmc_3: dwmmc3@12230000 {
-               status = "disabled";
-       };
-
        i2s0: i2s@03830000 {
                status = "okay";
        };
index f86d56760a45a0f42692f5636376c899f81edbc3..13746dfb20aae1307f4ec9ef7636d89a83cb173a 100644 (file)
                };
        };
 
-       dwmmc0@12200000 {
+       mmc@12200000 {
+               status = "okay";
                num-slots = <1>;
                supports-highspeed;
                broken-cd;
-               fifo-depth = <0x80>;
                card-detect-delay = <200>;
                samsung,dw-mshc-ciu-div = <3>;
                samsung,dw-mshc-sdr-timing = <2 3>;
                };
        };
 
-       dwmmc1@12210000 {
-               status = "disabled";
-       };
-
-       dwmmc2@12220000 {
+       mmc@12220000 {
+               status = "okay";
                num-slots = <1>;
                supports-highspeed;
-               fifo-depth = <0x80>;
                card-detect-delay = <200>;
                samsung,dw-mshc-ciu-div = <3>;
                samsung,dw-mshc-sdr-timing = <2 3>;
                };
        };
 
-       dwmmc3@12230000 {
-               status = "disabled";
-       };
-
        spi_0: spi@12d20000 {
                status = "disabled";
        };
index fd711e245e8d311f392bedfed7bb48dee4d4b7e6..a9395c426db44a7ddaeefd3b56040928a8f06e2f 100644 (file)
         * On Snow we've got SIP WiFi and so can keep drive strengths low to
         * reduce EMI.
         */
-       dwmmc3@12230000 {
+       mmc@12230000 {
                slot@0 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>;
index 9db5047812f3d6c05a36643abbea0e1fb33e8195..b98ffc3a5fe289514a661cd5b5b7099c1c044be5 100644 (file)
                gsc1 = &gsc_1;
                gsc2 = &gsc_2;
                gsc3 = &gsc_3;
-               mshc0 = &dwmmc_0;
-               mshc1 = &dwmmc_1;
-               mshc2 = &dwmmc_2;
-               mshc3 = &dwmmc_3;
+               mshc0 = &mmc_0;
+               mshc1 = &mmc_1;
+               mshc2 = &mmc_2;
+               mshc3 = &mmc_3;
                i2c0 = &i2c_0;
                i2c1 = &i2c_1;
                i2c2 = &i2c_2;
                pinctrl-0 = <&spi2_bus>;
        };
 
-       dwmmc_0: dwmmc0@12200000 {
+       mmc_0: mmc@12200000 {
+               compatible = "samsung,exynos5250-dw-mshc";
+               interrupts = <0 75 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
                reg = <0x12200000 0x1000>;
                clocks = <&clock 280>, <&clock 139>;
                clock-names = "biu", "ciu";
+               fifo-depth = <0x80>;
+               status = "disabled";
        };
 
-       dwmmc_1: dwmmc1@12210000 {
+       mmc_1: mmc@12210000 {
+               compatible = "samsung,exynos5250-dw-mshc";
+               interrupts = <0 76 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
                reg = <0x12210000 0x1000>;
                clocks = <&clock 281>, <&clock 140>;
                clock-names = "biu", "ciu";
+               fifo-depth = <0x80>;
+               status = "disabled";
        };
 
-       dwmmc_2: dwmmc2@12220000 {
+       mmc_2: mmc@12220000 {
+               compatible = "samsung,exynos5250-dw-mshc";
+               interrupts = <0 77 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
                reg = <0x12220000 0x1000>;
                clocks = <&clock 282>, <&clock 141>;
                clock-names = "biu", "ciu";
+               fifo-depth = <0x80>;
+               status = "disabled";
        };
 
-       dwmmc_3: dwmmc3@12230000 {
+       mmc_3: mmc@12230000 {
                compatible = "samsung,exynos5250-dw-mshc";
                reg = <0x12230000 0x1000>;
                interrupts = <0 78 0>;
                #size-cells = <0>;
                clocks = <&clock 283>, <&clock 142>;
                clock-names = "biu", "ciu";
+               fifo-depth = <0x80>;
+               status = "disabled";
        };
 
        i2s0: i2s@03830000 {
index 79524c74c60354344bd9026b67614ce414ffbe31..fb5a1e25c632d3a4cbb3544e5e44ee67a0c1d8aa 100644 (file)
                };
        };
 
+       mmc@12200000 {
+               status = "okay";
+               broken-cd;
+               supports-highspeed;
+               card-detect-delay = <200>;
+               samsung,dw-mshc-ciu-div = <3>;
+               samsung,dw-mshc-sdr-timing = <0 4>;
+               samsung,dw-mshc-ddr-timing = <0 2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+
+               slot@0 {
+                       reg = <0>;
+                       bus-width = <8>;
+               };
+       };
+
+       mmc@12220000 {
+               status = "okay";
+               supports-highspeed;
+               card-detect-delay = <200>;
+               samsung,dw-mshc-ciu-div = <3>;
+               samsung,dw-mshc-sdr-timing = <2 3>;
+               samsung,dw-mshc-ddr-timing = <1 2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+
+               slot@0 {
+                       reg = <0>;
+                       bus-width = <4>;
+               };
+       };
+
        dp-controller@145B0000 {
                pinctrl-names = "default";
                pinctrl-0 = <&dp_hpd>;
index 09aa06cb3d3af77be582328167c25f8735a09fb2..6ffefd163fa0603fc9ae9602770e533a4b7e8857 100644 (file)
@@ -22,6 +22,9 @@
        compatible = "samsung,exynos5420";
 
        aliases {
+               mshc0 = &mmc_0;
+               mshc1 = &mmc_1;
+               mshc2 = &mmc_2;
                pinctrl0 = &pinctrl_0;
                pinctrl1 = &pinctrl_1;
                pinctrl2 = &pinctrl_2;
@@ -31,6 +34,8 @@
                i2c1 = &i2c_1;
                i2c2 = &i2c_2;
                i2c3 = &i2c_3;
+               gsc0 = &gsc_0;
+               gsc1 = &gsc_1;
        };
 
        cpus {
                clock-names = "mfc";
        };
 
+       mmc_0: mmc@12200000 {
+               compatible = "samsung,exynos5420-dw-mshc-smu";
+               interrupts = <0 75 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x12200000 0x2000>;
+               clocks = <&clock 351>, <&clock 132>;
+               clock-names = "biu", "ciu";
+               fifo-depth = <0x40>;
+               status = "disabled";
+       };
+
+       mmc_1: mmc@12210000 {
+               compatible = "samsung,exynos5420-dw-mshc-smu";
+               interrupts = <0 76 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x12210000 0x2000>;
+               clocks = <&clock 352>, <&clock 133>;
+               clock-names = "biu", "ciu";
+               fifo-depth = <0x40>;
+               status = "disabled";
+       };
+
+       mmc_2: mmc@12220000 {
+               compatible = "samsung,exynos5420-dw-mshc";
+               interrupts = <0 77 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x12220000 0x1000>;
+               clocks = <&clock 353>, <&clock 134>;
+               clock-names = "biu", "ciu";
+               fifo-depth = <0x40>;
+               status = "disabled";
+       };
+
        mct@101C0000 {
                compatible = "samsung,exynos4210-mct";
                reg = <0x101C0000 0x800>;
                clocks = <&clock 431>, <&clock 143>;
                clock-names = "mixer", "sclk_hdmi";
        };
+
+       gsc_0: video-scaler@13e00000 {
+               compatible = "samsung,exynos5-gsc";
+               reg = <0x13e00000 0x1000>;
+               interrupts = <0 85 0>;
+               clocks = <&clock 465>;
+               clock-names = "gscl";
+               samsung,power-domain = <&gsc_pd>;
+       };
+
+       gsc_1: video-scaler@13e10000 {
+               compatible = "samsung,exynos5-gsc";
+               reg = <0x13e10000 0x1000>;
+               interrupts = <0 86 0>;
+               clocks = <&clock 466>;
+               clock-names = "gscl";
+               samsung,power-domain = <&gsc_pd>;
+       };
 };
index 1f026adefd451e594628d1855acf949f9cd7d7cf..a33f66c11b73edbf3671f02017e7780704c36b05 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio1 29 0>;
                };
 
-               reg_lcd_3v3: lcd-3v3 {
+               reg_lcd_3v3: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "lcd-3v3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index 526bfdbd87f9f84f08747c6c045c059a657d2cbc..7e6eef2488e807c12c36aaebfd3e64b076f7622f 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index cb64e2b191ea1ae48098c1c79ced4afe6f57b521..455169e99d49b5ad5388e8122012f3f6f6e27f72 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/imx25-pinfunc.h b/arch/arm/boot/dts/imx25-pinfunc.h
new file mode 100644 (file)
index 0000000..9238a95
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ * Based on imx35-pinfunc.h in the same directory Which is:
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX25_PINFUNC_H
+#define __DTS_IMX25_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MX25_PAD_A10__A10                      0x008 0x000 0x000 0x00 0x000
+#define MX25_PAD_A10__GPIO_4_0                 0x008 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_A13__A13                      0x00c 0x22C 0x000 0x00 0x000
+#define MX25_PAD_A13__GPIO_4_1                 0x00c 0x22C 0x000 0x05 0x000
+
+#define MX25_PAD_A14__A14                      0x010 0x230 0x000 0x10 0x000
+#define MX25_PAD_A14__GPIO_2_0                 0x010 0x230 0x000 0x15 0x000
+
+#define MX25_PAD_A15__A15                      0x014 0x234 0x000 0x10 0x000
+#define MX25_PAD_A15__GPIO_2_1                 0x014 0x234 0x000 0x15 0x000
+
+#define MX25_PAD_A16__A16                      0x018 0x000 0x000 0x10 0x000
+#define MX25_PAD_A16__GPIO_2_2                 0x018 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_A17__A17                      0x01c 0x238 0x000 0x10 0x000
+#define MX25_PAD_A17__GPIO_2_3                 0x01c 0x238 0x000 0x15 0x000
+
+#define MX25_PAD_A18__A18                      0x020 0x23c 0x000 0x10 0x000
+#define MX25_PAD_A18__GPIO_2_4                 0x020 0x23c 0x000 0x15 0x000
+#define MX25_PAD_A18__FEC_COL                  0x020 0x23c 0x504 0x17 0x000
+
+#define MX25_PAD_A19__A19                      0x024 0x240 0x000 0x10 0x000
+#define MX25_PAD_A19__FEC_RX_ER                        0x024 0x240 0x518 0x17 0x000
+#define MX25_PAD_A19__GPIO_2_5                 0x024 0x240 0x000 0x15 0x000
+
+#define MX25_PAD_A20__A20                      0x028 0x244 0x000 0x10 0x000
+#define MX25_PAD_A20__GPIO_2_6                 0x028 0x244 0x000 0x15 0x000
+#define MX25_PAD_A20__FEC_RDATA2               0x028 0x244 0x50c 0x17 0x000
+
+#define MX25_PAD_A21__A21                      0x02c 0x248 0x000 0x10 0x000
+#define MX25_PAD_A21__GPIO_2_7                 0x02c 0x248 0x000 0x15 0x000
+#define MX25_PAD_A21__FEC_RDATA3               0x02c 0x248 0x510 0x17 0x000
+
+#define MX25_PAD_A22__A22                      0x030 0x000 0x000 0x10 0x000
+#define MX25_PAD_A22__GPIO_2_8                 0x030 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_A23__A23                      0x034 0x24c 0x000 0x10 0x000
+#define MX25_PAD_A23__GPIO_2_9                 0x034 0x24c 0x000 0x15 0x000
+
+#define MX25_PAD_A24__A24                      0x038 0x250 0x000 0x10 0x000
+#define MX25_PAD_A24__GPIO_2_10                        0x038 0x250 0x000 0x15 0x000
+#define MX25_PAD_A24__FEC_RX_CLK               0x038 0x250 0x514 0x17 0x000
+
+#define MX25_PAD_A25__A25                      0x03c 0x254 0x000 0x10 0x000
+#define MX25_PAD_A25__GPIO_2_11                        0x03c 0x254 0x000 0x15 0x000
+#define MX25_PAD_A25__FEC_CRS                  0x03c 0x254 0x508 0x17 0x000
+
+#define MX25_PAD_EB0__EB0                      0x040 0x258 0x000 0x10 0x000
+#define MX25_PAD_EB0__AUD4_TXD                 0x040 0x258 0x464 0x14 0x000
+#define MX25_PAD_EB0__GPIO_2_12                        0x040 0x258 0x000 0x15 0x000
+
+#define MX25_PAD_EB1__EB1                      0x044 0x25c 0x000 0x10 0x000
+#define MX25_PAD_EB1__AUD4_RXD                 0x044 0x25c 0x460 0x14 0x000
+#define MX25_PAD_EB1__GPIO_2_13                        0x044 0x25c 0x000 0x15 0x000
+
+#define MX25_PAD_OE__OE                                0x048 0x260 0x000 0x10 0x000
+#define MX25_PAD_OE__AUD4_TXC                  0x048 0x260 0x000 0x14 0x000
+#define MX25_PAD_OE__GPIO_2_14                 0x048 0x260 0x000 0x15 0x000
+
+#define MX25_PAD_CS0__CS0                      0x04c 0x000 0x000 0x00 0x000
+#define MX25_PAD_CS0__GPIO_4_2                 0x04c 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_CS1__CS1                      0x050 0x000 0x000 0x00 0x000
+#define MX25_PAD_CS1__NF_CE3                   0x050 0x000 0x000 0x01 0x000
+#define MX25_PAD_CS1__GPIO_4_3                 0x050 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_CS4__CS4                      0x054 0x264 0x000 0x10 0x000
+#define MX25_PAD_CS4__NF_CE1                   0x054 0x264 0x000 0x01 0x000
+#define MX25_PAD_CS4__UART5_CTS                        0x054 0x264 0x000 0x13 0x000
+#define MX25_PAD_CS4__GPIO_3_20                        0x054 0x264 0x000 0x15 0x000
+
+#define MX25_PAD_CS5__CS5                      0x058 0x268 0x000 0x10 0x000
+#define MX25_PAD_CS5__NF_CE2                   0x058 0x268 0x000 0x01 0x000
+#define MX25_PAD_CS5__UART5_RTS                        0x058 0x268 0x574 0x13 0x000
+#define MX25_PAD_CS5__GPIO_3_21                        0x058 0x268 0x000 0x15 0x000
+
+#define MX25_PAD_NF_CE0__NF_CE0                        0x05c 0x26c 0x000 0x10 0x000
+#define MX25_PAD_NF_CE0__GPIO_3_22             0x05c 0x26c 0x000 0x15 0x000
+
+#define MX25_PAD_ECB__ECB                      0x060 0x270 0x000 0x10 0x000
+#define MX25_PAD_ECB__UART5_TXD_MUX            0x060 0x270 0x000 0x13 0x000
+#define MX25_PAD_ECB__GPIO_3_23                        0x060 0x270 0x000 0x15 0x000
+
+#define MX25_PAD_LBA__LBA                      0x064 0x274 0x000 0x10 0x000
+#define MX25_PAD_LBA__UART5_RXD_MUX            0x064 0x274 0x578 0x13 0x000
+#define MX25_PAD_LBA__GPIO_3_24                        0x064 0x274 0x000 0x15 0x000
+
+#define MX25_PAD_BCLK__BCLK                    0x068 0x000 0x000 0x00 0x000
+#define MX25_PAD_BCLK__GPIO_4_4                        0x068 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_RW__RW                                0x06c 0x278 0x000 0x10 0x000
+#define MX25_PAD_RW__AUD4_TXFS                 0x06c 0x278 0x474 0x14 0x000
+#define MX25_PAD_RW__GPIO_3_25                 0x06c 0x278 0x000 0x15 0x000
+
+#define MX25_PAD_NFWE_B__NFWE_B                        0x070 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFWE_B__GPIO_3_26             0x070 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFRE_B__NFRE_B                        0x074 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFRE_B__GPIO_3_27             0x074 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFALE__NFALE                  0x078 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFALE__GPIO_3_28              0x078 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFCLE__NFCLE                  0x07c 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFCLE__GPIO_3_29              0x07c 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFWP_B__NFWP_B                        0x080 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFWP_B__GPIO_3_30             0x080 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFRB__NFRB                    0x084 0x27c 0x000 0x10 0x000
+#define MX25_PAD_NFRB__GPIO_3_31               0x084 0x27c 0x000 0x15 0x000
+
+#define MX25_PAD_D15__D15                      0x088 0x280 0x000 0x00 0x000
+#define MX25_PAD_D15__LD16                     0x088 0x280 0x000 0x01 0x000
+#define MX25_PAD_D15__GPIO_4_5                 0x088 0x280 0x000 0x05 0x000
+
+#define MX25_PAD_D14__D14                      0x08c 0x284 0x000 0x00 0x000
+#define MX25_PAD_D14__LD17                     0x08c 0x284 0x000 0x01 0x000
+#define MX25_PAD_D14__GPIO_4_6                 0x08c 0x284 0x000 0x05 0x000
+
+#define MX25_PAD_D13__D13                      0x090 0x288 0x000 0x00 0x000
+#define MX25_PAD_D13__LD18                     0x090 0x288 0x000 0x01 0x000
+#define MX25_PAD_D13__GPIO_4_7                 0x090 0x288 0x000 0x05 0x000
+
+#define MX25_PAD_D12__D12                      0x094 0x28c 0x000 0x00 0x000
+#define MX25_PAD_D12__GPIO_4_8                 0x094 0x28c 0x000 0x05 0x000
+
+#define MX25_PAD_D11__D11                      0x098 0x290 0x000 0x00 0x000
+#define MX25_PAD_D11__GPIO_4_9                 0x098 0x290 0x000 0x05 0x000
+
+#define MX25_PAD_D10__D10                      0x09c 0x294 0x000 0x00 0x000
+#define MX25_PAD_D10__GPIO_4_10                        0x09c 0x294 0x000 0x05 0x000
+#define MX25_PAD_D10__USBOTG_OC                        0x09c 0x294 0x57c 0x06 0x000
+
+#define MX25_PAD_D9__D9                                0x0a0 0x298 0x000 0x00 0x000
+#define MX25_PAD_D9__GPIO_4_11                 0x0a0 0x298 0x000 0x05 0x000
+#define MX25_PAD_D9__USBH2_PWR                 0x0a0 0x298 0x000 0x06 0x000
+
+#define MX25_PAD_D8__D8                                0x0a4 0x29c 0x000 0x00 0x000
+#define MX25_PAD_D8__GPIO_4_12                 0x0a4 0x29c 0x000 0x05 0x000
+#define MX25_PAD_D8__USBH2_OC                  0x0a4 0x29c 0x580 0x06 0x000
+
+#define MX25_PAD_D7__D7                                0x0a8 0x2a0 0x000 0x00 0x000
+#define MX25_PAD_D7__GPIO_4_13                 0x0a8 0x2a0 0x000 0x05 0x000
+
+#define MX25_PAD_D6__D6                                0x0ac 0x2a4 0x000 0x00 0x000
+#define MX25_PAD_D6__GPIO_4_14                 0x0ac 0x2a4 0x000 0x05 0x000
+
+#define MX25_PAD_D5__D5                                0x0b0 0x2a8 0x000 0x00 0x000
+#define MX25_PAD_D5__GPIO_4_15                 0x0b0 0x2a8 0x000 0x05 0x000
+
+#define MX25_PAD_D4__D4                                0x0b4 0x2ac 0x000 0x00 0x000
+#define MX25_PAD_D4__GPIO_4_16                 0x0b4 0x2ac 0x000 0x05 0x000
+
+#define MX25_PAD_D3__D3                                0x0b8 0x2b0 0x000 0x00 0x000
+#define MX25_PAD_D3__GPIO_4_17                 0x0b8 0x2b0 0x000 0x05 0x000
+
+#define MX25_PAD_D2__D2                                0x0bc 0x2b4 0x000 0x00 0x000
+#define MX25_PAD_D2__GPIO_4_18                 0x0bc 0x2b4 0x000 0x05 0x000
+
+#define MX25_PAD_D1__D1                                0x0c0 0x2b8 0x000 0x00 0x000
+#define MX25_PAD_D1__GPIO_4_19                 0x0c0 0x2b8 0x000 0x05 0x000
+
+#define MX25_PAD_D0__D0                                0x0c4 0x2bc 0x000 0x00 0x000
+#define MX25_PAD_D0__GPIO_4_20                 0x0c4 0x2bc 0x000 0x05 0x000
+
+#define MX25_PAD_LD0__LD0                      0x0c8 0x2c0 0x000 0x10 0x000
+#define MX25_PAD_LD0__CSI_D0                   0x0c8 0x2c0 0x488 0x12 0x000
+#define MX25_PAD_LD0__GPIO_2_15                        0x0c8 0x2c0 0x000 0x15 0x000
+
+#define MX25_PAD_LD1__LD1                      0x0cc 0x2c4 0x000 0x10 0x000
+#define MX25_PAD_LD1__CSI_D1                   0x0cc 0x2c4 0x48c 0x12 0x000
+#define MX25_PAD_LD1__GPIO_2_16                        0x0cc 0x2c4 0x000 0x15 0x000
+
+#define MX25_PAD_LD2__LD2                      0x0d0 0x2c8 0x000 0x10 0x000
+#define MX25_PAD_LD2__GPIO_2_17                        0x0d0 0x2c8 0x000 0x15 0x000
+
+#define MX25_PAD_LD3__LD3                      0x0d4 0x2cc 0x000 0x10 0x000
+#define MX25_PAD_LD3__GPIO_2_18                        0x0d4 0x2cc 0x000 0x15 0x000
+
+#define MX25_PAD_LD4__LD4                      0x0d8 0x2d0 0x000 0x10 0x000
+#define MX25_PAD_LD4__GPIO_2_19                        0x0d8 0x2d0 0x000 0x15 0x000
+
+#define MX25_PAD_LD5__LD5                      0x0dc 0x2d4 0x000 0x10 0x000
+#define MX25_PAD_LD5__GPIO_1_19                        0x0dc 0x2d4 0x000 0x15 0x000
+
+#define MX25_PAD_LD6__LD6                      0x0e0 0x2d8 0x000 0x10 0x000
+#define MX25_PAD_LD6__GPIO_1_20                        0x0e0 0x2d8 0x000 0x15 0x000
+
+#define MX25_PAD_LD7__LD7                      0x0e4 0x2dc 0x000 0x10 0x000
+#define MX25_PAD_LD7__GPIO_1_21                        0x0e4 0x2dc 0x000 0x15 0x000
+
+#define MX25_PAD_LD8__LD8                      0x0e8 0x2e0 0x000 0x10 0x000
+#define MX25_PAD_LD8__FEC_TX_ERR               0x0e8 0x2e0 0x000 0x15 0x000
+
+#define MX25_PAD_LD9__LD9                      0x0ec 0x2e4 0x000 0x10 0x000
+#define MX25_PAD_LD9__FEC_COL                  0x0ec 0x2e4 0x504 0x15 0x001
+
+#define MX25_PAD_LD10__LD10                    0x0f0 0x2e8 0x000 0x10 0x000
+#define MX25_PAD_LD10__FEC_RX_ER               0x0f0 0x2e8 0x518 0x15 0x001
+
+#define MX25_PAD_LD11__LD11                    0x0f4 0x2ec 0x000 0x10 0x000
+#define MX25_PAD_LD11__FEC_RDATA2              0x0f4 0x2ec 0x50c 0x15 0x001
+
+#define MX25_PAD_LD12__LD12                    0x0f8 0x2f0 0x000 0x10 0x000
+#define MX25_PAD_LD12__FEC_RDATA3              0x0f8 0x2f0 0x510 0x15 0x001
+
+#define MX25_PAD_LD13__LD13                    0x0fc 0x2f4 0x000 0x10 0x000
+#define MX25_PAD_LD13__FEC_TDATA2              0x0fc 0x2f4 0x000 0x15 0x000
+
+#define MX25_PAD_LD14__LD14                    0x100 0x2f8 0x000 0x10 0x000
+#define MX25_PAD_LD14__FEC_TDATA3              0x100 0x2f8 0x000 0x15 0x000
+
+#define MX25_PAD_LD15__LD15                    0x104 0x2fc 0x000 0x10 0x000
+#define MX25_PAD_LD15__FEC_RX_CLK              0x104 0x2fc 0x514 0x15 0x001
+
+#define MX25_PAD_HSYNC__HSYNC                  0x108 0x300 0x000 0x10 0x000
+#define MX25_PAD_HSYNC__GPIO_1_22              0x108 0x300 0x000 0x15 0x000
+
+#define MX25_PAD_VSYNC__VSYNC                  0x10c 0x304 0x000 0x10 0x000
+#define MX25_PAD_VSYNC__GPIO_1_23              0x10c 0x304 0x000 0x15 0x000
+
+#define MX25_PAD_LSCLK__LSCLK                  0x110 0x308 0x000 0x10 0x000
+#define MX25_PAD_LSCLK__GPIO_1_24              0x110 0x308 0x000 0x15 0x000
+
+#define MX25_PAD_OE_ACD__OE_ACD                        0x114 0x30c 0x000 0x10 0x000
+#define MX25_PAD_OE_ACD__GPIO_1_25             0x114 0x30c 0x000 0x15 0x000
+
+#define MX25_PAD_CONTRAST__CONTRAST            0x118 0x310 0x000 0x10 0x000
+#define MX25_PAD_CONTRAST__PWM4_PWMO           0x118 0x310 0x000 0x14 0x000
+#define MX25_PAD_CONTRAST__FEC_CRS             0x118 0x310 0x508 0x15 0x001
+
+#define MX25_PAD_PWM__PWM                      0x11c 0x314 0x000 0x10 0x000
+#define MX25_PAD_PWM__GPIO_1_26                        0x11c 0x314 0x000 0x15 0x000
+#define MX25_PAD_PWM__USBH2_OC                 0x11c 0x314 0x580 0x16 0x001
+
+#define MX25_PAD_CSI_D2__CSI_D2                        0x120 0x318 0x000 0x10 0x000
+#define MX25_PAD_CSI_D2__UART5_RXD_MUX         0x120 0x318 0x578 0x11 0x001
+#define MX25_PAD_CSI_D2__GPIO_1_27             0x120 0x318 0x000 0x15 0x000
+#define MX25_PAD_CSI_D2__CSPI3_MOSI            0x120 0x318 0x000 0x17 0x000
+
+#define MX25_PAD_CSI_D3__CSI_D3                        0x124 0x31c 0x000 0x10 0x000
+#define MX25_PAD_CSI_D3__GPIO_1_28             0x124 0x31c 0x000 0x15 0x000
+#define MX25_PAD_CSI_D3__CSPI3_MISO            0x124 0x31c 0x4b4 0x17 0x001
+
+#define MX25_PAD_CSI_D4__CSI_D4                        0x128 0x320 0x000 0x10 0x000
+#define MX25_PAD_CSI_D4__UART5_RTS             0x128 0x320 0x574 0x11 0x001
+#define MX25_PAD_CSI_D4__GPIO_1_29             0x128 0x320 0x000 0x15 0x000
+#define MX25_PAD_CSI_D4__CSPI3_SCLK            0x128 0x320 0x000 0x17 0x000
+
+#define MX25_PAD_CSI_D5__CSI_D5                        0x12c 0x324 0x000 0x10 0x000
+#define MX25_PAD_CSI_D5__GPIO_1_30             0x12c 0x324 0x000 0x15 0x000
+#define MX25_PAD_CSI_D5__CSPI3_RDY             0x12c 0x324 0x000 0x17 0x000
+
+#define MX25_PAD_CSI_D6__CSI_D6                        0x130 0x328 0x000 0x10 0x000
+#define MX25_PAD_CSI_D6__GPIO_1_31             0x130 0x328 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_D7__CSI_D7                        0x134 0x32c 0x000 0x10 0x000
+#define MX25_PAD_CSI_D7__GPIO_1_6              0x134 0x32c 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_D8__CSI_D8                        0x138 0x330 0x000 0x10 0x000
+#define MX25_PAD_CSI_D8__GPIO_1_7              0x138 0x330 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_D9__CSI_D9                        0x13c 0x334 0x000 0x10 0x000
+#define MX25_PAD_CSI_D9__GPIO_4_21             0x13c 0x334 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_MCLK__CSI_MCLK            0x140 0x338 0x000 0x10 0x000
+#define MX25_PAD_CSI_MCLK__GPIO_1_8            0x140 0x338 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_VSYNC__CSI_VSYNC          0x144 0x33c 0x000 0x10 0x000
+#define MX25_PAD_CSI_VSYNC__GPIO_1_9           0x144 0x33c 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_HSYNC__CSI_HSYNC          0x148 0x340 0x000 0x10 0x000
+#define MX25_PAD_CSI_HSYNC__GPIO_1_10          0x148 0x340 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK                0x14c 0x344 0x000 0x10 0x000
+#define MX25_PAD_CSI_PIXCLK__GPIO_1_11         0x14c 0x344 0x000 0x15 0x000
+
+#define MX25_PAD_I2C1_CLK__I2C1_CLK            0x150 0x348 0x000 0x10 0x000
+#define MX25_PAD_I2C1_CLK__GPIO_1_12           0x150 0x348 0x000 0x15 0x000
+
+#define MX25_PAD_I2C1_DAT__I2C1_DAT            0x154 0x34c 0x000 0x10 0x000
+#define MX25_PAD_I2C1_DAT__GPIO_1_13           0x154 0x34c 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI                0x158 0x350 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_MOSI__GPIO_1_14         0x158 0x350 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_MISO__CSPI1_MISO                0x15c 0x354 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_MISO__GPIO_1_15         0x15c 0x354 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_SS0__CSPI1_SS0          0x160 0x358 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_SS0__GPIO_1_16          0x160 0x358 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_SS1__CSPI1_SS1          0x164 0x35c 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_SS1__GPIO_1_17          0x164 0x35c 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK                0x168 0x360 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_SCLK__GPIO_1_18         0x168 0x360 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_RDY__CSPI1_RDY          0x16c 0x364 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_RDY__GPIO_2_22          0x16c 0x364 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_RXD__UART1_RXD          0x170 0x368 0x000 0x10 0x000
+#define MX25_PAD_UART1_RXD__GPIO_4_22          0x170 0x368 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_TXD__UART1_TXD          0x174 0x36c 0x000 0x10 0x000
+#define MX25_PAD_UART1_TXD__GPIO_4_23          0x174 0x36c 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_RTS__UART1_RTS          0x178 0x370 0x000 0x10 0x000
+#define MX25_PAD_UART1_RTS__CSI_D0             0x178 0x370 0x488 0x11 0x001
+#define MX25_PAD_UART1_RTS__GPIO_4_24          0x178 0x370 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_CTS__UART1_CTS          0x17c 0x374 0x000 0x10 0x000
+#define MX25_PAD_UART1_CTS__CSI_D1             0x17c 0x374 0x48c 0x11 0x001
+#define MX25_PAD_UART1_CTS__GPIO_4_25          0x17c 0x374 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_RXD__UART2_RXD          0x180 0x378 0x000 0x10 0x000
+#define MX25_PAD_UART2_RXD__GPIO_4_26          0x180 0x378 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_TXD__UART2_TXD          0x184 0x37c 0x000 0x10 0x000
+#define MX25_PAD_UART2_TXD__GPIO_4_27          0x184 0x37c 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_RTS__UART2_RTS          0x188 0x380 0x000 0x10 0x000
+#define MX25_PAD_UART2_RTS__FEC_COL            0x188 0x380 0x504 0x12 0x002
+#define MX25_PAD_UART2_RTS__GPIO_4_28          0x188 0x380 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_CTS__FEC_RX_ER          0x18c 0x384 0x518 0x12 0x002
+#define MX25_PAD_UART2_CTS__UART2_CTS          0x18c 0x384 0x000 0x10 0x000
+#define MX25_PAD_UART2_CTS__GPIO_4_29          0x18c 0x384 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_CMD__SD1_CMD              0x190 0x388 0x000 0x10 0x000
+#define MX25_PAD_SD1_CMD__FEC_RDATA2           0x190 0x388 0x50c 0x12 0x002
+#define MX25_PAD_SD1_CMD__GPIO_2_23            0x190 0x388 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_CLK__SD1_CLK              0x194 0x38c 0x000 0x10 0x000
+#define MX25_PAD_SD1_CLK__FEC_RDATA3           0x194 0x38c 0x510 0x12 0x002
+#define MX25_PAD_SD1_CLK__GPIO_2_24            0x194 0x38c 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA0__SD1_DATA0          0x198 0x390 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA0__GPIO_2_25          0x198 0x390 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA1__SD1_DATA1          0x19c 0x394 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA1__AUD7_RXD           0x19c 0x394 0x478 0x13 0x000
+#define MX25_PAD_SD1_DATA1__GPIO_2_26          0x19c 0x394 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA2__SD1_DATA2          0x1a0 0x398 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA2__FEC_RX_CLK         0x1a0 0x398 0x514 0x15 0x002
+#define MX25_PAD_SD1_DATA2__GPIO_2_27          0x1a0 0x398 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA3__SD1_DATA3          0x1a4 0x39c 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA3__FEC_CRS            0x1a4 0x39c 0x508 0x10 0x002
+#define MX25_PAD_SD1_DATA3__GPIO_2_28          0x1a4 0x39c 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW0__KPP_ROW0            0x1a8 0x3a0 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW0__GPIO_2_29           0x1a8 0x3a0 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW1__KPP_ROW1            0x1ac 0x3a4 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW1__GPIO_2_30           0x1ac 0x3a4 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW2__KPP_ROW2            0x1b0 0x3a8 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW2__CSI_D0              0x1b0 0x3a8 0x488 0x13 0x002
+#define MX25_PAD_KPP_ROW2__GPIO_2_31           0x1b0 0x3a8 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW3__KPP_ROW3            0x1b4 0x3ac 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW3__CSI_LD1             0x1b4 0x3ac 0x48c 0x13 0x002
+#define MX25_PAD_KPP_ROW3__GPIO_3_0            0x1b4 0x3ac 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL0__KPP_COL0            0x1b8 0x3b0 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL0__UART4_RXD_MUX       0x1b8 0x3b0 0x570 0x11 0x001
+#define MX25_PAD_KPP_COL0__AUD5_TXD            0x1b8 0x3b0 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL0__GPIO_3_1            0x1b8 0x3b0 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL1__KPP_COL1            0x1bc 0x3b4 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL1__UART4_TXD_MUX       0x1bc 0x3b4 0x000 0x11 0x000
+#define MX25_PAD_KPP_COL1__AUD5_RXD            0x1bc 0x3b4 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL1__GPIO_3_2            0x1bc 0x3b4 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL2__KPP_COL2            0x1c0 0x3b8 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL2__UART4_RTS           0x1c0 0x3b8 0x000 0x11 0x000
+#define MX25_PAD_KPP_COL2__AUD5_TXC            0x1c0 0x3b8 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL2__GPIO_3_3            0x1c0 0x3b8 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL3__KPP_COL3            0x1c4 0x3bc 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL3__UART4_CTS           0x1c4 0x3bc 0x000 0x11 0x000
+#define MX25_PAD_KPP_COL3__AUD5_TXFS           0x1c4 0x3bc 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL3__GPIO_3_4            0x1c4 0x3bc 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_MDC__FEC_MDC              0x1c8 0x3c0 0x000 0x10 0x000
+#define MX25_PAD_FEC_MDC__AUD4_TXD             0x1c8 0x3c0 0x464 0x12 0x001
+#define MX25_PAD_FEC_MDC__GPIO_3_5             0x1c8 0x3c0 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_MDIO__FEC_MDIO            0x1cc 0x3c4 0x000 0x10 0x000
+#define MX25_PAD_FEC_MDIO__AUD4_RXD            0x1cc 0x3c4 0x460 0x12 0x001
+#define MX25_PAD_FEC_MDIO__GPIO_3_6            0x1cc 0x3c4 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TDATA0__FEC_TDATA0                0x1d0 0x3c8 0x000 0x10 0x000
+#define MX25_PAD_FEC_TDATA0__GPIO_3_7          0x1d0 0x3c8 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TDATA1__FEC_TDATA1                0x1d4 0x3cc 0x000 0x10 0x000
+#define MX25_PAD_FEC_TDATA1__AUD4_TXFS         0x1d4 0x3cc 0x474 0x12 0x001
+#define MX25_PAD_FEC_TDATA1__GPIO_3_8          0x1d4 0x3cc 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TX_EN__FEC_TX_EN          0x1d8 0x3d0 0x000 0x10 0x000
+#define MX25_PAD_FEC_TX_EN__GPIO_3_9           0x1d8 0x3d0 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_RDATA0__FEC_RDATA0                0x1dc 0x3d4 0x000 0x10 0x000
+#define MX25_PAD_FEC_RDATA0__GPIO_3_10         0x1dc 0x3d4 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_RDATA1__FEC_RDATA1                0x1e0 0x3d8 0x000 0x10 0x000
+#define MX25_PAD_FEC_RDATA1__GPIO_3_11         0x1e0 0x3d8 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_RX_DV__FEC_RX_DV          0x1e4 0x3dc 0x000 0x10 0x000
+#define MX25_PAD_FEC_RX_DV__CAN2_RX            0x1e4 0x3dc 0x484 0x14 0x000
+#define MX25_PAD_FEC_RX_DV__GPIO_3_12          0x1e4 0x3dc 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK                0x1e8 0x3e0 0x000 0x10 0x000
+#define MX25_PAD_FEC_TX_CLK__GPIO_3_13         0x1e8 0x3e0 0x000 0x15 0x000
+
+#define MX25_PAD_RTCK__RTCK                    0x1ec 0x3e4 0x000 0x10 0x000
+#define MX25_PAD_RTCK__OWIRE                   0x1ec 0x3e4 0x000 0x11 0x000
+#define MX25_PAD_RTCK__GPIO_3_14               0x1ec 0x3e4 0x000 0x15 0x000
+
+#define MX25_PAD_DE_B__DE_B                    0x1f0 0x3ec 0x000 0x10 0x000
+#define MX25_PAD_DE_B__GPIO_2_20               0x1f0 0x3ec 0x000 0x15 0x000
+
+#define MX25_PAD_TDO__TDO                      0x000 0x3e8 0x000 0x00 0x000
+
+#define MX25_PAD_GPIO_A__GPIO_A                        0x1f4 0x3f0 0x000 0x10 0x000
+#define MX25_PAD_GPIO_A__CAN1_TX               0x1f4 0x3f0 0x000 0x16 0x000
+#define MX25_PAD_GPIO_A__USBOTG_PWR            0x1f4 0x3f0 0x000 0x12 0x000
+
+#define MX25_PAD_GPIO_B__GPIO_B                        0x1f8 0x3f4 0x000 0x10 0x000
+#define MX25_PAD_GPIO_B__CAN1_RX               0x1f8 0x3f4 0x480 0x16 0x001
+#define MX25_PAD_GPIO_B__USBOTG_OC             0x1f8 0x3f4 0x57c 0x12 0x001
+
+#define MX25_PAD_GPIO_C__GPIO_C                        0x1fc 0x3f8 0x000 0x10 0x000
+#define MX25_PAD_GPIO_C__CAN2_TX               0x1fc 0x3f8 0x000 0x16 0x000
+
+#define MX25_PAD_GPIO_D__GPIO_D                        0x200 0x3fc 0x000 0x10 0x000
+#define MX25_PAD_GPIO_E__LD16                  0x204 0x400 0x000 0x02 0x000
+#define MX25_PAD_GPIO_D__CAN2_RX               0x200 0x3fc 0x484 0x16 0x001
+
+#define MX25_PAD_GPIO_E__GPIO_E                        0x204 0x400 0x000 0x10 0x000
+#define MX25_PAD_GPIO_F__LD17                  0x208 0x404 0x000 0x02 0x000
+#define MX25_PAD_GPIO_E__AUD7_TXD              0x204 0x400 0x000 0x14 0x000
+
+#define MX25_PAD_GPIO_F__GPIO_F                        0x208 0x404 0x000 0x10 0x000
+#define MX25_PAD_GPIO_F__AUD7_TXC              0x208 0x404 0x000 0x14 0x000
+
+#define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK                0x20c 0x000 0x000 0x10 0x000
+#define MX25_PAD_EXT_ARMCLK__GPIO_3_15         0x20c 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK      0x210 0x000 0x000 0x10 0x000
+#define MX25_PAD_UPLL_BYPCLK__GPIO_3_16                0x210 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_VSTBY_REQ__VSTBY_REQ          0x214 0x408 0x000 0x10 0x000
+#define MX25_PAD_VSTBY_REQ__AUD7_TXFS          0x214 0x408 0x000 0x14 0x000
+#define MX25_PAD_VSTBY_REQ__GPIO_3_17          0x214 0x408 0x000 0x15 0x000
+#define MX25_PAD_VSTBY_ACK__VSTBY_ACK          0x218 0x40c 0x000 0x10 0x000
+#define MX25_PAD_VSTBY_ACK__GPIO_3_18          0x218 0x40c 0x000 0x15 0x000
+
+#define MX25_PAD_POWER_FAIL__POWER_FAIL                0x21c 0x410 0x000 0x10 0x000
+#define MX25_PAD_POWER_FAIL__AUD7_RXD          0x21c 0x410 0x478 0x14 0x001
+#define MX25_PAD_POWER_FAIL__GPIO_3_19         0x21c 0x410 0x000 0x15 0x000
+
+#define MX25_PAD_CLKO__CLKO                    0x220 0x414 0x000 0x10 0x000
+#define MX25_PAD_CLKO__GPIO_2_21               0x220 0x414 0x000 0x15 0x000
+
+#define MX25_PAD_BOOT_MODE0__BOOT_MODE0                0x224 0x000 0x000 0x00 0x000
+#define MX25_PAD_BOOT_MODE0__GPIO_4_30         0x224 0x000 0x000 0x05 0x000
+#define MX25_PAD_BOOT_MODE1__BOOT_MODE1                0x228 0x000 0x000 0x00 0x000
+#define MX25_PAD_BOOT_MODE1__GPIO_4_31         0x228 0x000 0x000 0x05 0x000
+
+#endif /* __DTS_IMX25_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx25-pingrp.h b/arch/arm/boot/dts/imx25-pingrp.h
new file mode 100644 (file)
index 0000000..16c7a19
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DTS_IMX25_PINGRP_H
+#define __DTS_IMX25_PINGRP_H
+
+#define MX25_AUDMUX_PINGRP1 \
+       MX25_PAD_KPP_COL3__AUD5_TXFS                    0xe0 \
+       MX25_PAD_KPP_COL2__AUD5_TXC                     0xe0 \
+       MX25_PAD_KPP_COL1__AUD5_RXD                     0xe0 \
+       MX25_PAD_KPP_COL0__AUD5_TXD                     0xe0
+
+#define MX25_ESDHC1_PINGRP1 \
+       MX25_PAD_SD1_CMD__SD1_CMD                       0x400000c0 \
+       MX25_PAD_SD1_CLK__SD1_CLK                       0x400000c0 \
+       MX25_PAD_SD1_DATA0__SD1_DATA0                   0x400000c0 \
+       MX25_PAD_SD1_DATA1__SD1_DATA1                   0x400000c0 \
+       MX25_PAD_SD1_DATA2__SD1_DATA2                   0x400000c0 \
+       MX25_PAD_SD1_DATA3__SD1_DATA3                   0x400000c0
+
+#define MX25_FEC_PINGRP1 \
+       MX25_PAD_FEC_MDC__FEC_MDC                       0x80000000 \
+       MX25_PAD_FEC_MDIO__FEC_MDIO                     0x400001e0 \
+       MX25_PAD_FEC_TDATA0__FEC_TDATA0                 0x80000000 \
+       MX25_PAD_FEC_TDATA1__FEC_TDATA1                 0x80000000 \
+       MX25_PAD_FEC_TX_EN__FEC_TX_EN                   0x80000000 \
+       MX25_PAD_FEC_RDATA0__FEC_RDATA0                 0x80000000 \
+       MX25_PAD_FEC_RDATA1__FEC_RDATA1                 0x80000000 \
+       MX25_PAD_FEC_RX_DV__FEC_RX_DV                   0x80000000 \
+       MX25_PAD_FEC_TX_CLK__FEC_TX_CLK                 0x1c0
+
+#define MX25_I2C1_PINGRP1 \
+       MX25_PAD_I2C1_CLK__I2C1_CLK                     0x80000000 \
+       MX25_PAD_I2C1_DAT__I2C1_DAT                     0x80000000
+
+#define MX25_LCDC_PINGRP1 \
+       MX25_PAD_LD0__LD0                               0x1 \
+       MX25_PAD_LD1__LD1                               0x1 \
+       MX25_PAD_LD2__LD2                               0x1 \
+       MX25_PAD_LD3__LD3                               0x1 \
+       MX25_PAD_LD4__LD4                               0x1 \
+       MX25_PAD_LD5__LD5                               0x1 \
+       MX25_PAD_LD6__LD6                               0x1 \
+       MX25_PAD_LD7__LD7                               0x1 \
+       MX25_PAD_LD8__LD8                               0x1 \
+       MX25_PAD_LD9__LD9                               0x1 \
+       MX25_PAD_LD10__LD10                             0x1 \
+       MX25_PAD_LD11__LD11                             0x1 \
+       MX25_PAD_LD12__LD12                             0x1 \
+       MX25_PAD_LD13__LD13                             0x1 \
+       MX25_PAD_LD14__LD14                             0x1 \
+       MX25_PAD_LD15__LD15                             0x1 \
+       MX25_PAD_GPIO_E__LD16                           0x1 \
+       MX25_PAD_GPIO_F__LD17                           0x1 \
+       MX25_PAD_HSYNC__HSYNC                           0x80000000 \
+       MX25_PAD_VSYNC__VSYNC                           0x80000000 \
+       MX25_PAD_LSCLK__LSCLK                           0x80000000 \
+       MX25_PAD_OE_ACD__OE_ACD                         0x80000000 \
+       MX25_PAD_CONTRAST__CONTRAST                     0x80000000
+
+#define MX25_UART1_PINGRP1 \
+       MX25_PAD_UART1_RTS__UART1_RTS                   0xe0 \
+       MX25_PAD_UART1_CTS__UART1_CTS                   0xe0 \
+       MX25_PAD_UART1_TXD__UART1_TXD                   0x80000000 \
+       MX25_PAD_UART1_RXD__UART1_RXD                   0xc0
+
+#define MX25_UART2_PINGRP1 \
+       MX25_PAD_UART2_RXD__UART2_RXD                   0x80000000 \
+       MX25_PAD_UART2_TXD__UART2_TXD                   0x80000000 \
+       MX25_PAD_UART2_RTS__UART2_RTS                   0x80000000 \
+       MX25_PAD_UART2_CTS__UART2_CTS                   0x80000000
+
+#endif /* __DTS_IMX25_PINGRP_H */
index 737ed5da8f715fec5180c60a6bdd33e9c6fefc9a..1a86eabeeecb9c3f2b2e9ba277b2a0193fc1b388 100644 (file)
@@ -10,6 +10,8 @@
  */
 
 #include "skeleton.dtsi"
+#include "imx25-pinfunc.h"
+#include "imx25-pingrp.h"
 
 / {
        aliases {
                                status = "disabled";
                        };
 
-                       iomuxc@43fac000{
+                       iomuxc: iomuxc@43fac000 {
                                compatible = "fsl,imx25-iomuxc";
                                reg = <0x43fac000 0x4000>;
                        };
 
-                       audmux@43fb0000 {
+                       audmux: audmux@43fb0000 {
                                compatible = "fsl,imx25-audmux", "fsl,imx31-audmux";
                                reg = <0x43fb0000 0x4000>;
                                status = "disabled";
                                compatible = "fsl,imx25-ssi", "fsl,imx21-ssi";
                                reg = <0x50014000 0x4000>;
                                interrupts = <11>;
+                               clocks = <&clks 118>;
+                               clock-names = "ipg";
+                               dmas = <&sdma 24 1 0>,
+                                      <&sdma 25 1 0>;
+                               dma-names = "rx", "tx";
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx25-ssi", "fsl,imx21-ssi";
                                reg = <0x50034000 0x4000>;
                                interrupts = <12>;
+                               clocks = <&clks 117>;
+                               clock-names = "ipg";
+                               dmas = <&sdma 28 1 0>,
+                                      <&sdma 29 1 0>;
+                               dma-names = "rx", "tx";
                                status = "disabled";
                        };
 
                                #interrupt-cells = <2>;
                        };
 
-                       sdma@53fd4000 {
+                       sdma: sdma@53fd4000 {
                                compatible = "fsl,imx25-sdma", "fsl,imx35-sdma";
                                reg = <0x53fd4000 0x4000>;
                                clocks = <&clks 112>, <&clks 68>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
                                interrupts = <34>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx25.bin";
                        };
 
                        wdog@53fdc000 {
index ba4c6df08ece2ec6e4cd0ce05437b61ffe407b2d..8bc75c70ec10128caa38ed6b1cdbdf4a9ae90964 100644 (file)
        };
 };
 
+&iomuxc {
+       imx27-apf27 {
+               pinctrl_fec1: fec1grp {
+                       fsl,pins = <MX27_FEC1_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX27_UART1_PINGRP1>;
+               };
+       };
+};
+
 &uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
        status = "okay";
 };
 
index 47c8c26012e4d24661124f15ff8396f428136797..0010b3e6da8ace13c62cd1ba91c1406155ac0c4f 100644 (file)
                bits-per-pixel = <16>;  /* non-standard but required */
                fsl,pcr = <0xfae80083>; /* non-standard but required */
                display-timings {
-                       timing0: 640x480 {
+                       timing0: 800x480 {
                                clock-frequency = <33000033>;
                                hactive = <800>;
-                               vactive = <640>;
+                               vactive = <480>;
                                hback-porch = <96>;
                                hfront-porch = <96>;
                                vback-porch = <20>;
@@ -60,6 +60,8 @@
 &cspi1 {
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio4 28 1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_cspi1>;
        status = "okay";
 };
 
        fsl,spi-num-chipselects = <3>;
        cs-gpios = <&gpio4 21 1>, <&gpio4 27 1>,
                        <&gpio2 17 1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_cspi2>;
        status = "okay";
 };
 
 &fb {
        display = <&display>;
        fsl,dmacr = <0x00020010>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_imxfb1>;
        status = "okay";
 };
 
 &i2c1 {
        clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        rtc@68 {
 };
 
 &i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&iomuxc {
+       imx27-apf27dev {
+               pinctrl_cspi1: cspi1grp {
+                       fsl,pins = <MX27_CSPI1_PINGRP1>;
+               };
+
+               pinctrl_cspi2: cspi2grp {
+                       fsl,pins = <MX27_CSPI2_PINGRP1>;
+               };
+
+               pinctrl_imxfb1: imxfbgrp {
+                       fsl,pins = <MX27_FB_PINGRP1>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX27_I2C1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX27_I2C2_PINGRP1>;
+               };
+
+               pinctrl_sdhc2: sdhc2grp {
+                       fsl,pins = <MX27_SDHC2_PINGRP1>;
+               };
+       };
+};
+
+&sdhci2 {
+       bus-width = <4>;
+       cd-gpios = <&gpio3 14 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sdhc2>;
        status = "okay";
 };
index 5a31c776513f5705e94a5f1a5f306740e898c201..0a90df159f3888129fec05913cfd3e08c71d24f2 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3v3: 3v3 {
+               reg_3v3: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3V3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
@@ -54,6 +57,8 @@
 };
 
 &i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        rtc@51 {
        };
 };
 
+&iomuxc {
+       imx27-phycard-s-rdk {
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX27_I2C2_PINGRP1>;
+               };
+
+               pinctrl_owire1: owire1grp {
+                       fsl,pins = <MX27_OWIRE1_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX27_UART1_PINGRP1
+                               MX27_UART1_RTSCTS_PINGRP1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX27_UART2_PINGRP1
+                               MX27_UART2_RTSCTS_PINGRP1
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX27_UART3_PINGRP1
+                               MX27_UART3_RTSCTS_PINGRP1
+                       >;
+               };
+       };
+};
+
 &owire {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_owire1>;
        status = "okay";
 };
 
 
 &uart1 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &uart2 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &uart3 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
        status = "okay";
 };
index c8d57d1d074362e14c91113cc8cbf42079724ffe..62e7fcb45c7c706b1da521d655599f4fc133b779 100644 (file)
        status = "okay";
 };
 
+&iomuxc {
+       imx27-phycard-s-som {
+               pinctrl_fec1: fec1grp {
+                       fsl,pins = <MX27_FEC1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX27_I2C2_PINGRP1>;
+               };
+       };
+};
+
 &fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
        status = "okay";
 };
 
 &i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        at24@52 {
index 0fc6551786c6817216045c8ddfc86a6c5790d58e..e79246950186abcb6f8ed444574d8a595ffba1ec 100644 (file)
        cs-gpios = <&gpio4 28 0>, <&gpio4 27 0>;
 };
 
+&iomuxc {
+       imx27_phycore_rdk {
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX27_UART1_PINGRP1
+                               MX27_UART1_RTSCTS_PINGRP1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX27_UART2_PINGRP1
+                               MX27_UART2_RTSCTS_PINGRP1
+                       >;
+               };
+       };
+};
+
 &sdhci2 {
        bus-width = <4>;
        cd-gpios = <&gpio3 29 0>;
 
 &uart1 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
 };
 
 &uart2 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
index 4ec402c389457f6e5416dc573459127fd4128de7..56960c794388e43be2c19a6765456c83b1998fd2 100644 (file)
 
 &fec {
        phy-reset-gpios = <&gpio3 30 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
        status = "okay";
 };
 
 &i2c2 {
        clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        at24@52 {
        };
 };
 
+&iomuxc {
+       imx27_phycard_s_som {
+               pinctrl_fec1: fec1grp {
+                       fsl,pins = <MX27_FEC1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX27_I2C2_PINGRP1>;
+               };
+       };
+};
+
 &nfc {
        nand-bus-width = <8>;
        nand-ecc-mode = "hw";
        status = "okay";
 };
 
-&uart1 {
-       status = "okay";
-};
-
 &weim {
        status = "okay";
 
diff --git a/arch/arm/boot/dts/imx27-pinfunc.h b/arch/arm/boot/dts/imx27-pinfunc.h
new file mode 100644 (file)
index 0000000..4d3e8e5
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ * Copyright 2013 Markus Pargmann <mpa@pengutronix.de>, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DTS_IMX27_PINFUNC_H
+#define __DTS_IMX27_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <pin mux_id>
+ * mux_id consists of
+ * function + (direction << 2) + (gpio_oconf << 4) + (gpio_iconfa << 8) + (gpio_iconfb << 10)
+ *
+ * function:      0 - Primary function
+ *                1 - Alternate function
+ *                2 - GPIO
+ * direction:     0 - Input
+ *                1 - Output
+ * gpio_oconf:    0 - A_IN
+ *                1 - B_IN
+ *                2 - C_IN
+ *                3 - Data Register
+ * gpio_iconfa/b: 0 - GPIO_IN
+ *                1 - Interrupt Status Register
+ *                2 - 0
+ *                3 - 1
+ *
+ * 'pin' is an integer between 0 and 0xbf. imx27 has 6 ports with 32 configurable
+ * configurable pins each. 'pin' is PORT * 32 + PORT_PIN, PORT_PIN is the pin
+ * number on the specific port (between 0 and 31).
+ */
+
+#define MX27_PAD_USBH2_CLK__USBH2_CLK                      0x00 0x000
+#define MX27_PAD_USBH2_CLK__GPIO1_0                        0x00 0x036
+#define MX27_PAD_USBH2_DIR__USBH2_DIR                      0x01 0x000
+#define MX27_PAD_USBH2_DIR__GPIO1_1                        0x01 0x036
+#define MX27_PAD_USBH2_DATA7__USBH2_DATA7                  0x02 0x004
+#define MX27_PAD_USBH2_DATA7__GPIO1_2                      0x02 0x036
+#define MX27_PAD_USBH2_NXT__USBH2_NXT                      0x03 0x000
+#define MX27_PAD_USBH2_NXT__GPIO1_3                        0x03 0x036
+#define MX27_PAD_USBH2_STP__USBH2_STP                      0x04 0x004
+#define MX27_PAD_USBH2_STP__GPIO1_4                        0x04 0x036
+#define MX27_PAD_LSCLK__LSCLK                              0x05 0x004
+#define MX27_PAD_LSCLK__GPIO1_5                            0x05 0x036
+#define MX27_PAD_LD0__LD0                                  0x06 0x004
+#define MX27_PAD_LD0__GPIO1_6                              0x06 0x036
+#define MX27_PAD_LD1__LD1                                  0x07 0x004
+#define MX27_PAD_LD1__GPIO1_7                              0x07 0x036
+#define MX27_PAD_LD2__LD2                                  0x08 0x004
+#define MX27_PAD_LD2__GPIO1_8                              0x08 0x036
+#define MX27_PAD_LD3__LD3                                  0x09 0x004
+#define MX27_PAD_LD3__GPIO1_9                              0x09 0x036
+#define MX27_PAD_LD4__LD4                                  0x0a 0x004
+#define MX27_PAD_LD4__GPIO1_10                             0x0a 0x036
+#define MX27_PAD_LD5__LD5                                  0x0b 0x004
+#define MX27_PAD_LD5__GPIO1_11                             0x0b 0x036
+#define MX27_PAD_LD6__LD6                                  0x0c 0x004
+#define MX27_PAD_LD6__GPIO1_12                             0x0c 0x036
+#define MX27_PAD_LD7__LD7                                  0x0d 0x004
+#define MX27_PAD_LD7__GPIO1_13                             0x0d 0x036
+#define MX27_PAD_LD8__LD8                                  0x0e 0x004
+#define MX27_PAD_LD8__GPIO1_14                             0x0e 0x036
+#define MX27_PAD_LD9__LD9                                  0x0f 0x004
+#define MX27_PAD_LD9__GPIO1_15                             0x0f 0x036
+#define MX27_PAD_LD10__LD10                                0x10 0x004
+#define MX27_PAD_LD10__GPIO1_16                            0x10 0x036
+#define MX27_PAD_LD11__LD11                                0x11 0x004
+#define MX27_PAD_LD11__GPIO1_17                            0x11 0x036
+#define MX27_PAD_LD12__LD12                                0x12 0x004
+#define MX27_PAD_LD12__GPIO1_18                            0x12 0x036
+#define MX27_PAD_LD13__LD13                                0x13 0x004
+#define MX27_PAD_LD13__GPIO1_19                            0x13 0x036
+#define MX27_PAD_LD14__LD14                                0x14 0x004
+#define MX27_PAD_LD14__GPIO1_20                            0x14 0x036
+#define MX27_PAD_LD15__LD15                                0x15 0x004
+#define MX27_PAD_LD15__GPIO1_21                            0x15 0x036
+#define MX27_PAD_LD16__LD16                                0x16 0x004
+#define MX27_PAD_LD16__GPIO1_22                            0x16 0x036
+#define MX27_PAD_LD17__LD17                                0x17 0x004
+#define MX27_PAD_LD17__GPIO1_23                            0x17 0x036
+#define MX27_PAD_REV__REV                                  0x18 0x004
+#define MX27_PAD_REV__GPIO1_24                             0x18 0x036
+#define MX27_PAD_CLS__CLS                                  0x19 0x004
+#define MX27_PAD_CLS__GPIO1_25                             0x19 0x036
+#define MX27_PAD_PS__PS                                    0x1a 0x004
+#define MX27_PAD_PS__GPIO1_26                              0x1a 0x036
+#define MX27_PAD_SPL_SPR__SPL_SPR                          0x1b 0x004
+#define MX27_PAD_SPL_SPR__GPIO1_27                         0x1b 0x036
+#define MX27_PAD_HSYNC__HSYNC                              0x1c 0x004
+#define MX27_PAD_HSYNC__GPIO1_28                           0x1c 0x036
+#define MX27_PAD_VSYNC__VSYNC                              0x1d 0x004
+#define MX27_PAD_VSYNC__GPIO1_29                           0x1d 0x036
+#define MX27_PAD_CONTRAST__CONTRAST                        0x1e 0x004
+#define MX27_PAD_CONTRAST__GPIO1_30                        0x1e 0x036
+#define MX27_PAD_OE_ACD__OE_ACD                            0x1f 0x004
+#define MX27_PAD_OE_ACD__GPIO1_31                          0x1f 0x036
+#define MX27_PAD_UNUSED0__UNUSED0                          0x20 0x004
+#define MX27_PAD_UNUSED0__GPIO2_0                          0x20 0x036
+#define MX27_PAD_UNUSED1__UNUSED1                          0x21 0x004
+#define MX27_PAD_UNUSED1__GPIO2_1                          0x21 0x036
+#define MX27_PAD_UNUSED2__UNUSED2                          0x22 0x004
+#define MX27_PAD_UNUSED2__GPIO2_2                          0x22 0x036
+#define MX27_PAD_UNUSED3__UNUSED3                          0x23 0x004
+#define MX27_PAD_UNUSED3__GPIO2_3                          0x23 0x036
+#define MX27_PAD_SD2_D0__SD2_D0                            0x24 0x004
+#define MX27_PAD_SD2_D0__MSHC_DATA0                        0x24 0x005
+#define MX27_PAD_SD2_D0__GPIO2_4                           0x24 0x036
+#define MX27_PAD_SD2_D1__SD2_D1                            0x25 0x004
+#define MX27_PAD_SD2_D1__MSHC_DATA1                        0x25 0x005
+#define MX27_PAD_SD2_D1__GPIO2_5                           0x25 0x036
+#define MX27_PAD_SD2_D2__SD2_D2                            0x26 0x004
+#define MX27_PAD_SD2_D2__MSHC_DATA2                        0x26 0x005
+#define MX27_PAD_SD2_D2__GPIO2_6                           0x26 0x036
+#define MX27_PAD_SD2_D3__SD2_D3                            0x27 0x004
+#define MX27_PAD_SD2_D3__MSHC_DATA3                        0x27 0x005
+#define MX27_PAD_SD2_D3__GPIO2_7                           0x27 0x036
+#define MX27_PAD_SD2_CMD__SD2_CMD                          0x28 0x004
+#define MX27_PAD_SD2_CMD__MSHC_BS                          0x28 0x005
+#define MX27_PAD_SD2_CMD__GPIO2_8                          0x28 0x036
+#define MX27_PAD_SD2_CLK__SD2_CLK                          0x29 0x004
+#define MX27_PAD_SD2_CLK__MSHC_SCLK                        0x29 0x005
+#define MX27_PAD_SD2_CLK__GPIO2_9                          0x29 0x036
+#define MX27_PAD_CSI_D0__CSI_D0                            0x2a 0x000
+#define MX27_PAD_CSI_D0__UART6_TXD                         0x2a 0x005
+#define MX27_PAD_CSI_D0__GPIO2_10                          0x2a 0x036
+#define MX27_PAD_CSI_D1__CSI_D1                            0x2b 0x000
+#define MX27_PAD_CSI_D1__UART6_RXD                         0x2b 0x001
+#define MX27_PAD_CSI_D1__GPIO2_11                          0x2b 0x036
+#define MX27_PAD_CSI_D2__CSI_D2                            0x2c 0x000
+#define MX27_PAD_CSI_D2__UART6_CTS                         0x2c 0x005
+#define MX27_PAD_CSI_D2__GPIO2_12                          0x2c 0x036
+#define MX27_PAD_CSI_D3__CSI_D3                            0x2d 0x000
+#define MX27_PAD_CSI_D3__UART6_RTS                         0x2d 0x001
+#define MX27_PAD_CSI_D3__GPIO2_13                          0x2d 0x036
+#define MX27_PAD_CSI_D4__CSI_D4                            0x2e 0x000
+#define MX27_PAD_CSI_D4__GPIO2_14                          0x2e 0x036
+#define MX27_PAD_CSI_MCLK__CSI_MCLK                        0x2f 0x004
+#define MX27_PAD_CSI_MCLK__GPIO2_15                        0x2f 0x036
+#define MX27_PAD_CSI_PIXCLK__CSI_PIXCLK                    0x30 0x000
+#define MX27_PAD_CSI_PIXCLK__GPIO2_16                      0x30 0x036
+#define MX27_PAD_CSI_D5__CSI_D5                            0x31 0x000
+#define MX27_PAD_CSI_D5__GPIO2_17                          0x31 0x036
+#define MX27_PAD_CSI_D6__CSI_D6                            0x32 0x000
+#define MX27_PAD_CSI_D6__UART5_TXD                         0x32 0x005
+#define MX27_PAD_CSI_D6__GPIO2_18                          0x32 0x036
+#define MX27_PAD_CSI_D7__CSI_D7                            0x33 0x000
+#define MX27_PAD_CSI_D7__UART5_RXD                         0x33 0x001
+#define MX27_PAD_CSI_D7__GPIO2_19                          0x33 0x036
+#define MX27_PAD_CSI_VSYNC__CSI_VSYNC                      0x34 0x000
+#define MX27_PAD_CSI_VSYNC__UART5_CTS                      0x34 0x005
+#define MX27_PAD_CSI_VSYNC__GPIO2_20                       0x34 0x036
+#define MX27_PAD_CSI_HSYNC__CSI_HSYNC                      0x35 0x000
+#define MX27_PAD_CSI_HSYNC__UART5_RTS                      0x35 0x001
+#define MX27_PAD_CSI_HSYNC__GPIO2_21                       0x35 0x036
+#define MX27_PAD_USBH1_SUSP__USBH1_SUSP                    0x36 0x004
+#define MX27_PAD_USBH1_SUSP__GPIO2_22                      0x36 0x036
+#define MX27_PAD_USB_PWR__USB_PWR                          0x37 0x004
+#define MX27_PAD_USB_PWR__GPIO2_23                         0x37 0x036
+#define MX27_PAD_USB_OC_B__USB_OC_B                        0x38 0x000
+#define MX27_PAD_USB_OC_B__GPIO2_24                        0x38 0x036
+#define MX27_PAD_USBH1_RCV__USBH1_RCV                      0x39 0x004
+#define MX27_PAD_USBH1_RCV__GPIO2_25                       0x39 0x036
+#define MX27_PAD_USBH1_FS__USBH1_FS                        0x3a 0x004
+#define MX27_PAD_USBH1_FS__UART4_RTS                       0x3a 0x001
+#define MX27_PAD_USBH1_FS__GPIO2_26                        0x3a 0x036
+#define MX27_PAD_USBH1_OE_B__USBH1_OE_B                    0x3b 0x004
+#define MX27_PAD_USBH1_OE_B__GPIO2_27                      0x3b 0x036
+#define MX27_PAD_USBH1_TXDM__USBH1_TXDM                    0x3c 0x004
+#define MX27_PAD_USBH1_TXDM__UART4_TXD                     0x3c 0x005
+#define MX27_PAD_USBH1_TXDM__GPIO2_28                      0x3c 0x036
+#define MX27_PAD_USBH1_TXDP__USBH1_TXDP                    0x3d 0x004
+#define MX27_PAD_USBH1_TXDP__UART4_CTS                     0x3d 0x005
+#define MX27_PAD_USBH1_TXDP__GPIO2_29                      0x3d 0x036
+#define MX27_PAD_USBH1_RXDM__USBH1_RXDM                    0x3e 0x004
+#define MX27_PAD_USBH1_RXDM__GPIO2_30                      0x3e 0x036
+#define MX27_PAD_USBH1_RXDP__USBH1_RXDP                    0x3f 0x004
+#define MX27_PAD_USBH1_RXDP__UART4_RXD                     0x3f 0x001
+#define MX27_PAD_USBH1_RXDP__GPIO2_31                      0x3f 0x036
+#define MX27_PAD_UNUSED4__UNUSED4                          0x40 0x004
+#define MX27_PAD_UNUSED4__GPIO3_0                          0x40 0x036
+#define MX27_PAD_UNUSED5__UNUSED5                          0x41 0x004
+#define MX27_PAD_UNUSED5__GPIO3_1                          0x41 0x036
+#define MX27_PAD_UNUSED6__UNUSED6                          0x42 0x004
+#define MX27_PAD_UNUSED6__GPIO3_2                          0x42 0x036
+#define MX27_PAD_UNUSED7__UNUSED7                          0x43 0x004
+#define MX27_PAD_UNUSED7__GPIO3_3                          0x43 0x036
+#define MX27_PAD_UNUSED8__UNUSED8                          0x44 0x004
+#define MX27_PAD_UNUSED8__GPIO3_4                          0x44 0x036
+#define MX27_PAD_I2C2_SDA__I2C2_SDA                        0x45 0x004
+#define MX27_PAD_I2C2_SDA__GPIO3_5                         0x45 0x036
+#define MX27_PAD_I2C2_SCL__I2C2_SCL                        0x46 0x004
+#define MX27_PAD_I2C2_SCL__GPIO3_6                         0x46 0x036
+#define MX27_PAD_USBOTG_DATA5__USBOTG_DATA5                0x47 0x004
+#define MX27_PAD_USBOTG_DATA5__GPIO3_7                     0x47 0x036
+#define MX27_PAD_USBOTG_DATA6__USBOTG_DATA6                0x48 0x004
+#define MX27_PAD_USBOTG_DATA6__GPIO3_8                     0x48 0x036
+#define MX27_PAD_USBOTG_DATA0__USBOTG_DATA0                0x49 0x004
+#define MX27_PAD_USBOTG_DATA0__GPIO3_9                     0x49 0x036
+#define MX27_PAD_USBOTG_DATA2__USBOTG_DATA2                0x4a 0x004
+#define MX27_PAD_USBOTG_DATA2__GPIO3_10                    0x4a 0x036
+#define MX27_PAD_USBOTG_DATA1__USBOTG_DATA1                0x4b 0x004
+#define MX27_PAD_USBOTG_DATA1__GPIO3_11                    0x4b 0x036
+#define MX27_PAD_USBOTG_DATA4__USBOTG_DATA4                0x4c 0x004
+#define MX27_PAD_USBOTG_DATA4__GPIO3_12                    0x4c 0x036
+#define MX27_PAD_USBOTG_DATA3__USBOTG_DATA3                0x4d 0x004
+#define MX27_PAD_USBOTG_DATA3__GPIO3_13                    0x4d 0x036
+#define MX27_PAD_TOUT__TOUT                                0x4e 0x004
+#define MX27_PAD_TOUT__GPIO3_14                            0x4e 0x036
+#define MX27_PAD_TIN__TIN                                  0x4f 0x000
+#define MX27_PAD_TIN__GPIO3_15                             0x4f 0x036
+#define MX27_PAD_SSI4_FS__SSI4_FS                          0x50 0x004
+#define MX27_PAD_SSI4_FS__GPIO3_16                         0x50 0x036
+#define MX27_PAD_SSI4_RXDAT__SSI4_RXDAT                    0x51 0x004
+#define MX27_PAD_SSI4_RXDAT__GPIO3_17                      0x51 0x036
+#define MX27_PAD_SSI4_TXDAT__SSI4_TXDAT                    0x52 0x004
+#define MX27_PAD_SSI4_TXDAT__GPIO3_18                      0x52 0x036
+#define MX27_PAD_SSI4_CLK__SSI4_CLK                        0x53 0x004
+#define MX27_PAD_SSI4_CLK__GPIO3_19                        0x53 0x036
+#define MX27_PAD_SSI1_FS__SSI1_FS                          0x54 0x004
+#define MX27_PAD_SSI1_FS__GPIO3_20                         0x54 0x036
+#define MX27_PAD_SSI1_RXDAT__SSI1_RXDAT                    0x55 0x004
+#define MX27_PAD_SSI1_RXDAT__GPIO3_21                      0x55 0x036
+#define MX27_PAD_SSI1_TXDAT__SSI1_TXDAT                    0x56 0x004
+#define MX27_PAD_SSI1_TXDAT__GPIO3_22                      0x56 0x036
+#define MX27_PAD_SSI1_CLK__SSI1_CLK                        0x57 0x004
+#define MX27_PAD_SSI1_CLK__GPIO3_23                        0x57 0x036
+#define MX27_PAD_SSI2_FS__SSI2_FS                          0x58 0x004
+#define MX27_PAD_SSI2_FS__GPT5_TOUT                        0x58 0x005
+#define MX27_PAD_SSI2_FS__GPIO3_24                         0x58 0x036
+#define MX27_PAD_SSI2_RXDAT__SSI2_RXDAT                    0x59 0x004
+#define MX27_PAD_SSI2_RXDAT__GPTS_TIN                      0x59 0x001
+#define MX27_PAD_SSI2_RXDAT__GPIO3_25                      0x59 0x036
+#define MX27_PAD_SSI2_TXDAT__SSI2_TXDAT                    0x5a 0x004
+#define MX27_PAD_SSI2_TXDAT__GPT4_TOUT                     0x5a 0x005
+#define MX27_PAD_SSI2_TXDAT__GPIO3_26                      0x5a 0x036
+#define MX27_PAD_SSI2_CLK__SSI2_CLK                        0x5b 0x004
+#define MX27_PAD_SSI2_CLK__GPT4_TIN                        0x5b 0x001
+#define MX27_PAD_SSI2_CLK__GPIO3_27                        0x5b 0x036
+#define MX27_PAD_SSI3_FS__SSI3_FS                          0x5c 0x004
+#define MX27_PAD_SSI3_FS__SLCDC2_D0                        0x5c 0x001
+#define MX27_PAD_SSI3_FS__GPIO3_28                         0x5c 0x036
+#define MX27_PAD_SSI3_RXDAT__SSI3_RXDAT                    0x5d 0x004
+#define MX27_PAD_SSI3_RXDAT__SLCDC2_RS                     0x5d 0x001
+#define MX27_PAD_SSI3_RXDAT__GPIO3_29                      0x5d 0x036
+#define MX27_PAD_SSI3_TXDAT__SSI3_TXDAT                    0x5e 0x004
+#define MX27_PAD_SSI3_TXDAT__SLCDC2_CS                     0x5e 0x001
+#define MX27_PAD_SSI3_TXDAT__GPIO3_30                      0x5e 0x036
+#define MX27_PAD_SSI3_CLK__SSI3_CLK                        0x5f 0x004
+#define MX27_PAD_SSI3_CLK__SLCDC2_CLK                      0x5f 0x001
+#define MX27_PAD_SSI3_CLK__GPIO3_31                        0x5f 0x036
+#define MX27_PAD_SD3_CMD__SD3_CMD                          0x60 0x004
+#define MX27_PAD_SD3_CMD__FEC_TXD0                         0x60 0x006
+#define MX27_PAD_SD3_CMD__GPIO4_0                          0x60 0x036
+#define MX27_PAD_SD3_CLK__SD3_CLK                          0x61 0x004
+#define MX27_PAD_SD3_CLK__ETMTRACEPKT15                    0x61 0x005
+#define MX27_PAD_SD3_CLK__FEC_TXD1                         0x61 0x006
+#define MX27_PAD_SD3_CLK__GPIO4_1                          0x61 0x036
+#define MX27_PAD_ATA_DATA0__ATA_DATA0                      0x62 0x004
+#define MX27_PAD_ATA_DATA0__SD3_D0                         0x62 0x005
+#define MX27_PAD_ATA_DATA0__FEC_TXD2                       0x62 0x006
+#define MX27_PAD_ATA_DATA0__GPIO4_2                        0x62 0x036
+#define MX27_PAD_ATA_DATA1__ATA_DATA1                      0x63 0x004
+#define MX27_PAD_ATA_DATA1__SD3_D1                         0x63 0x005
+#define MX27_PAD_ATA_DATA1__FEC_TXD3                       0x63 0x006
+#define MX27_PAD_ATA_DATA1__GPIO4_3                        0x63 0x036
+#define MX27_PAD_ATA_DATA2__ATA_DATA2                      0x64 0x004
+#define MX27_PAD_ATA_DATA2__SD3_D2                         0x64 0x005
+#define MX27_PAD_ATA_DATA2__FEC_RX_ER                      0x64 0x002
+#define MX27_PAD_ATA_DATA2__GPIO4_4                        0x64 0x036
+#define MX27_PAD_ATA_DATA3__ATA_DATA3                      0x65 0x004
+#define MX27_PAD_ATA_DATA3__SD3_D3                         0x65 0x005
+#define MX27_PAD_ATA_DATA3__FEC_RXD1                       0x65 0x002
+#define MX27_PAD_ATA_DATA3__GPIO4_5                        0x65 0x036
+#define MX27_PAD_ATA_DATA4__ATA_DATA4                      0x66 0x004
+#define MX27_PAD_ATA_DATA4__ETMTRACEPKT14                  0x66 0x005
+#define MX27_PAD_ATA_DATA4__FEC_RXD2                       0x66 0x002
+#define MX27_PAD_ATA_DATA4__GPIO4_6                        0x66 0x036
+#define MX27_PAD_ATA_DATA5__ATA_DATA5                      0x67 0x004
+#define MX27_PAD_ATA_DATA5__ETMTRACEPKT13                  0x67 0x005
+#define MX27_PAD_ATA_DATA5__FEC_RXD3                       0x67 0x002
+#define MX27_PAD_ATA_DATA5__GPIO4_7                        0x67 0x036
+#define MX27_PAD_ATA_DATA6__ATA_DATA6                      0x68 0x004
+#define MX27_PAD_ATA_DATA6__FEC_MDIO                       0x68 0x005
+#define MX27_PAD_ATA_DATA6__GPIO4_8                        0x68 0x036
+#define MX27_PAD_ATA_DATA7__ATA_DATA7                      0x69 0x004
+#define MX27_PAD_ATA_DATA7__ETMTRACEPKT12                  0x69 0x005
+#define MX27_PAD_ATA_DATA7__FEC_MDC                        0x69 0x006
+#define MX27_PAD_ATA_DATA7__GPIO4_9                        0x69 0x036
+#define MX27_PAD_ATA_DATA8__ATA_DATA8                      0x6a 0x004
+#define MX27_PAD_ATA_DATA8__ETMTRACEPKT11                  0x6a 0x005
+#define MX27_PAD_ATA_DATA8__FEC_CRS                        0x6a 0x002
+#define MX27_PAD_ATA_DATA8__GPIO4_10                       0x6a 0x036
+#define MX27_PAD_ATA_DATA9__ATA_DATA9                      0x6b 0x004
+#define MX27_PAD_ATA_DATA9__ETMTRACEPKT10                  0x6b 0x005
+#define MX27_PAD_ATA_DATA9__FEC_TX_CLK                     0x6b 0x002
+#define MX27_PAD_ATA_DATA9__GPIO4_11                       0x6b 0x036
+#define MX27_PAD_ATA_DATA10__ATA_DATA10                    0x6c 0x004
+#define MX27_PAD_ATA_DATA10__ETMTRACEPKT9                  0x6c 0x005
+#define MX27_PAD_ATA_DATA10__FEC_RXD0                      0x6c 0x002
+#define MX27_PAD_ATA_DATA10__GPIO4_12                      0x6c 0x036
+#define MX27_PAD_ATA_DATA11__ATA_DATA11                    0x6d 0x004
+#define MX27_PAD_ATA_DATA11__ETMTRACEPKT8                  0x6d 0x005
+#define MX27_PAD_ATA_DATA11__FEC_RX_DV                     0x6d 0x002
+#define MX27_PAD_ATA_DATA11__GPIO4_13                      0x6d 0x036
+#define MX27_PAD_ATA_DATA12__ATA_DATA12                    0x6e 0x004
+#define MX27_PAD_ATA_DATA12__ETMTRACEPKT7                  0x6e 0x005
+#define MX27_PAD_ATA_DATA12__FEC_RX_CLK                    0x6e 0x002
+#define MX27_PAD_ATA_DATA12__GPIO4_14                      0x6e 0x036
+#define MX27_PAD_ATA_DATA13__ATA_DATA13                    0x6f 0x004
+#define MX27_PAD_ATA_DATA13__ETMTRACEPKT6                  0x6f 0x005
+#define MX27_PAD_ATA_DATA13__FEC_COL                       0x6f 0x002
+#define MX27_PAD_ATA_DATA13__GPIO4_15                      0x6f 0x036
+#define MX27_PAD_ATA_DATA14__ATA_DATA14                    0x70 0x004
+#define MX27_PAD_ATA_DATA14__ETMTRACEPKT5                  0x70 0x005
+#define MX27_PAD_ATA_DATA14__FEC_TX_ER                     0x70 0x006
+#define MX27_PAD_ATA_DATA14__GPIO4_16                      0x70 0x036
+#define MX27_PAD_I2C_DATA__I2C_DATA                        0x71 0x004
+#define MX27_PAD_I2C_DATA__GPIO4_17                        0x71 0x036
+#define MX27_PAD_I2C_CLK__I2C_CLK                          0x72 0x004
+#define MX27_PAD_I2C_CLK__GPIO4_18                         0x72 0x036
+#define MX27_PAD_CSPI2_SS2__CSPI2_SS2                      0x73 0x004
+#define MX27_PAD_CSPI2_SS2__USBH2_DATA4                    0x73 0x005
+#define MX27_PAD_CSPI2_SS2__GPIO4_19                       0x73 0x036
+#define MX27_PAD_CSPI2_SS1__CSPI2_SS1                      0x74 0x004
+#define MX27_PAD_CSPI2_SS1__USBH2_DATA3                    0x74 0x005
+#define MX27_PAD_CSPI2_SS1__GPIO4_20                       0x74 0x036
+#define MX27_PAD_CSPI2_SS0__CSPI2_SS0                      0x75 0x004
+#define MX27_PAD_CSPI2_SS0__USBH2_DATA6                    0x75 0x005
+#define MX27_PAD_CSPI2_SS0__GPIO4_21                       0x75 0x036
+#define MX27_PAD_CSPI2_SCLK__CSPI2_SCLK                    0x76 0x004
+#define MX27_PAD_CSPI2_SCLK__USBH2_DATA0                   0x76 0x005
+#define MX27_PAD_CSPI2_SCLK__GPIO4_22                      0x76 0x036
+#define MX27_PAD_CSPI2_MISO__CSPI2_MISO                    0x77 0x004
+#define MX27_PAD_CSPI2_MISO__USBH2_DATA2                   0x77 0x005
+#define MX27_PAD_CSPI2_MISO__GPIO4_23                      0x77 0x036
+#define MX27_PAD_CSPI2_MOSI__CSPI2_MOSI                    0x78 0x004
+#define MX27_PAD_CSPI2_MOSI__USBH2_DATA1                   0x78 0x005
+#define MX27_PAD_CSPI2_MOSI__GPIO4_24                      0x78 0x036
+#define MX27_PAD_CSPI1_RDY__CSPI1_RDY                      0x79 0x000
+#define MX27_PAD_CSPI1_RDY__GPIO4_25                       0x79 0x036
+#define MX27_PAD_CSPI1_SS2__CSPI1_SS2                      0x7a 0x004
+#define MX27_PAD_CSPI1_SS2__USBH2_DATA5                    0x7a 0x005
+#define MX27_PAD_CSPI1_SS2__GPIO4_26                       0x7a 0x036
+#define MX27_PAD_CSPI1_SS1__CSPI1_SS1                      0x7b 0x004
+#define MX27_PAD_CSPI1_SS1__GPIO4_27                       0x7b 0x036
+#define MX27_PAD_CSPI1_SS0__CSPI1_SS0                      0x7c 0x004
+#define MX27_PAD_CSPI1_SS0__GPIO4_28                       0x7c 0x036
+#define MX27_PAD_CSPI1_SCLK__CSPI1_SCLK                    0x7d 0x004
+#define MX27_PAD_CSPI1_SCLK__GPIO4_29                      0x7d 0x036
+#define MX27_PAD_CSPI1_MISO__CSPI1_MISO                    0x7e 0x004
+#define MX27_PAD_CSPI1_MISO__GPIO4_30                      0x7e 0x036
+#define MX27_PAD_CSPI1_MOSI__CSPI1_MOSI                    0x7f 0x004
+#define MX27_PAD_CSPI1_MOSI__GPIO4_31                      0x7f 0x036
+#define MX27_PAD_USBOTG_NXT__USBOTG_NXT                    0x80 0x000
+#define MX27_PAD_USBOTG_NXT__KP_COL6A                      0x80 0x005
+#define MX27_PAD_USBOTG_NXT__GPIO5_0                       0x80 0x036
+#define MX27_PAD_USBOTG_STP__USBOTG_STP                    0x81 0x004
+#define MX27_PAD_USBOTG_STP__KP_ROW6A                      0x81 0x005
+#define MX27_PAD_USBOTG_STP__GPIO5_1                       0x81 0x036
+#define MX27_PAD_USBOTG_DIR__USBOTG_DIR                    0x82 0x000
+#define MX27_PAD_USBOTG_DIR__KP_ROW7A                      0x82 0x005
+#define MX27_PAD_USBOTG_DIR__GPIO5_2                       0x82 0x036
+#define MX27_PAD_UART2_CTS__UART2_CTS                      0x83 0x004
+#define MX27_PAD_UART2_CTS__KP_COL7                        0x83 0x005
+#define MX27_PAD_UART2_CTS__GPIO5_3                        0x83 0x036
+#define MX27_PAD_UART2_RTS__UART2_RTS                      0x84 0x000
+#define MX27_PAD_UART2_RTS__KP_ROW7                        0x84 0x005
+#define MX27_PAD_UART2_RTS__GPIO5_4                        0x84 0x036
+#define MX27_PAD_PWMO__PWMO                                0x85 0x004
+#define MX27_PAD_PWMO__GPIO5_5                             0x85 0x036
+#define MX27_PAD_UART2_TXD__UART2_TXD                      0x86 0x004
+#define MX27_PAD_UART2_TXD__KP_COL6                        0x86 0x005
+#define MX27_PAD_UART2_TXD__GPIO5_6                        0x86 0x036
+#define MX27_PAD_UART2_RXD__UART2_RXD                      0x87 0x000
+#define MX27_PAD_UART2_RXD__KP_ROW6                        0x87 0x005
+#define MX27_PAD_UART2_RXD__GPIO5_7                        0x87 0x036
+#define MX27_PAD_UART3_TXD__UART3_TXD                      0x88 0x004
+#define MX27_PAD_UART3_TXD__GPIO5_8                        0x88 0x036
+#define MX27_PAD_UART3_RXD__UART3_RXD                      0x89 0x000
+#define MX27_PAD_UART3_RXD__GPIO5_9                        0x89 0x036
+#define MX27_PAD_UART3_CTS__UART3_CTS                      0x8a 0x004
+#define MX27_PAD_UART3_CTS__GPIO5_10                       0x8a 0x036
+#define MX27_PAD_UART3_RTS__UART3_RTS                      0x8b 0x000
+#define MX27_PAD_UART3_RTS__GPIO5_11                       0x8b 0x036
+#define MX27_PAD_UART1_TXD__UART1_TXD                      0x8c 0x004
+#define MX27_PAD_UART1_TXD__GPIO5_12                       0x8c 0x036
+#define MX27_PAD_UART1_RXD__UART1_RXD                      0x8d 0x000
+#define MX27_PAD_UART1_RXD__GPIO5_13                       0x8d 0x036
+#define MX27_PAD_UART1_CTS__UART1_CTS                      0x8e 0x004
+#define MX27_PAD_UART1_CTS__GPIO5_14                       0x8e 0x036
+#define MX27_PAD_UART1_RTS__UART1_RTS                      0x8f 0x000
+#define MX27_PAD_UART1_RTS__GPIO5_15                       0x8f 0x036
+#define MX27_PAD_RTCK__RTCK                                0x90 0x004
+#define MX27_PAD_RTCK__OWIRE                               0x90 0x005
+#define MX27_PAD_RTCK__GPIO5_16                            0x90 0x036
+#define MX27_PAD_RESET_OUT_B__RESET_OUT_B                  0x91 0x004
+#define MX27_PAD_RESET_OUT_B__GPIO5_17                     0x91 0x036
+#define MX27_PAD_SD1_D0__SD1_D0                            0x92 0x004
+#define MX27_PAD_SD1_D0__CSPI3_MISO                        0x92 0x001
+#define MX27_PAD_SD1_D0__GPIO5_18                          0x92 0x036
+#define MX27_PAD_SD1_D1__SD1_D1                            0x93 0x004
+#define MX27_PAD_SD1_D1__GPIO5_19                          0x93 0x036
+#define MX27_PAD_SD1_D2__SD1_D2                            0x94 0x004
+#define MX27_PAD_SD1_D2__GPIO5_20                          0x94 0x036
+#define MX27_PAD_SD1_D3__SD1_D3                            0x95 0x004
+#define MX27_PAD_SD1_D3__CSPI3_SS                          0x95 0x005
+#define MX27_PAD_SD1_D3__GPIO5_21                          0x95 0x036
+#define MX27_PAD_SD1_CMD__SD1_CMD                          0x96 0x004
+#define MX27_PAD_SD1_CMD__CSPI3_MOSI                       0x96 0x005
+#define MX27_PAD_SD1_CMD__GPIO5_22                         0x96 0x036
+#define MX27_PAD_SD1_CLK__SD1_CLK                          0x97 0x004
+#define MX27_PAD_SD1_CLK__CSPI3_SCLK                       0x97 0x005
+#define MX27_PAD_SD1_CLK__GPIO5_23                         0x97 0x036
+#define MX27_PAD_USBOTG_CLK__USBOTG_CLK                    0x98 0x000
+#define MX27_PAD_USBOTG_CLK__GPIO5_24                      0x98 0x036
+#define MX27_PAD_USBOTG_DATA7__USBOTG_DATA7                0x99 0x004
+#define MX27_PAD_USBOTG_DATA7__GPIO5_25                    0x99 0x036
+#define MX27_PAD_UNUSED9__UNUSED9                          0x9a 0x004
+#define MX27_PAD_UNUSED9__GPIO5_26                         0x9a 0x036
+#define MX27_PAD_UNUSED10__UNUSED10                        0x9b 0x004
+#define MX27_PAD_UNUSED10__GPIO5_27                        0x9b 0x036
+#define MX27_PAD_UNUSED11__UNUSED11                        0x9c 0x004
+#define MX27_PAD_UNUSED11__GPIO5_28                        0x9c 0x036
+#define MX27_PAD_UNUSED12__UNUSED12                        0x9d 0x004
+#define MX27_PAD_UNUSED12__GPIO5_29                        0x9d 0x036
+#define MX27_PAD_UNUSED13__UNUSED13                        0x9e 0x004
+#define MX27_PAD_UNUSED13__GPIO5_30                        0x9e 0x036
+#define MX27_PAD_UNUSED14__UNUSED14                        0x9f 0x004
+#define MX27_PAD_UNUSED14__GPIO5_31                        0x9f 0x036
+#define MX27_PAD_NFRB__NFRB                                0xa0 0x000
+#define MX27_PAD_NFRB__ETMTRACEPKT3                        0xa0 0x005
+#define MX27_PAD_NFRB__GPIO6_0                             0xa0 0x036
+#define MX27_PAD_NFCLE__NFCLE                              0xa1 0x004
+#define MX27_PAD_NFCLE__ETMTRACEPKT0                       0xa1 0x005
+#define MX27_PAD_NFCLE__GPIO6_1                            0xa1 0x036
+#define MX27_PAD_NFWP_B__NFWP_B                            0xa2 0x004
+#define MX27_PAD_NFWP_B__ETMTRACEPKT1                      0xa2 0x005
+#define MX27_PAD_NFWP_B__GPIO6_2                           0xa2 0x036
+#define MX27_PAD_NFCE_B__NFCE_B                            0xa3 0x004
+#define MX27_PAD_NFCE_B__ETMTRACEPKT2                      0xa3 0x005
+#define MX27_PAD_NFCE_B__GPIO6_3                           0xa3 0x036
+#define MX27_PAD_NFALE__NFALE                              0xa4 0x004
+#define MX27_PAD_NFALE__ETMPIPESTAT0                       0xa4 0x005
+#define MX27_PAD_NFALE__GPIO6_4                            0xa4 0x036
+#define MX27_PAD_NFRE_B__NFRE_B                            0xa5 0x004
+#define MX27_PAD_NFRE_B__ETMPIPESTAT1                      0xa5 0x005
+#define MX27_PAD_NFRE_B__GPIO6_5                           0xa5 0x036
+#define MX27_PAD_NFWE_B__NFWE_B                            0xa6 0x004
+#define MX27_PAD_NFWE_B__ETMPIPESTAT2                      0xa6 0x005
+#define MX27_PAD_NFWE_B__GPIO6_6                           0xa6 0x036
+#define MX27_PAD_PC_POE__PC_POE                            0xa7 0x004
+#define MX27_PAD_PC_POE__ATA_BUFFER_EN                     0xa7 0x005
+#define MX27_PAD_PC_POE__GPIO6_7                           0xa7 0x036
+#define MX27_PAD_PC_RW_B__PC_RW_B                          0xa8 0x004
+#define MX27_PAD_PC_RW_B__ATA_IORDY                        0xa8 0x001
+#define MX27_PAD_PC_RW_B__GPIO6_8                          0xa8 0x036
+#define MX27_PAD_IOIS16__IOIS16                            0xa9 0x000
+#define MX27_PAD_IOIS16__ATA_INTRQ                         0xa9 0x001
+#define MX27_PAD_IOIS16__GPIO6_9                           0xa9 0x036
+#define MX27_PAD_PC_RST__PC_RST                            0xaa 0x004
+#define MX27_PAD_PC_RST__ATA_RESET_B                       0xaa 0x005
+#define MX27_PAD_PC_RST__GPIO6_10                          0xaa 0x036
+#define MX27_PAD_PC_BVD2__PC_BVD2                          0xab 0x000
+#define MX27_PAD_PC_BVD2__ATA_DMACK                        0xab 0x005
+#define MX27_PAD_PC_BVD2__GPIO6_11                         0xab 0x036
+#define MX27_PAD_PC_BVD1__PC_BVD1                          0xac 0x000
+#define MX27_PAD_PC_BVD1__ATA_DMARQ                        0xac 0x001
+#define MX27_PAD_PC_BVD1__GPIO6_12                         0xac 0x036
+#define MX27_PAD_PC_VS2__PC_VS2                            0xad 0x000
+#define MX27_PAD_PC_VS2__ATA_DA0                           0xad 0x005
+#define MX27_PAD_PC_VS2__GPIO6_13                          0xad 0x036
+#define MX27_PAD_PC_VS1__PC_VS1                            0xae 0x000
+#define MX27_PAD_PC_VS1__ATA_DA1                           0xae 0x005
+#define MX27_PAD_PC_VS1__GPIO6_14                          0xae 0x036
+#define MX27_PAD_CLKO__CLKO                                0xaf 0x004
+#define MX27_PAD_CLKO__GPIO6_15                            0xaf 0x036
+#define MX27_PAD_PC_PWRON__PC_PWRON                        0xb0 0x000
+#define MX27_PAD_PC_PWRON__ATA_DA2                         0xb0 0x005
+#define MX27_PAD_PC_PWRON__GPIO6_16                        0xb0 0x036
+#define MX27_PAD_PC_READY__PC_READY                        0xb1 0x000
+#define MX27_PAD_PC_READY__ATA_CS0                         0xb1 0x005
+#define MX27_PAD_PC_READY__GPIO6_17                        0xb1 0x036
+#define MX27_PAD_PC_WAIT_B__PC_WAIT_B                      0xb2 0x000
+#define MX27_PAD_PC_WAIT_B__ATA_CS1                        0xb2 0x005
+#define MX27_PAD_PC_WAIT_B__GPIO6_18                       0xb2 0x036
+#define MX27_PAD_PC_CD2_B__PC_CD2_B                        0xb3 0x000
+#define MX27_PAD_PC_CD2_B__ATA_DIOW                        0xb3 0x005
+#define MX27_PAD_PC_CD2_B__GPIO6_19                        0xb3 0x036
+#define MX27_PAD_PC_CD1_B__PC_CD1_B                        0xb4 0x000
+#define MX27_PAD_PC_CD1_B__ATA_DIOR                        0xb4 0x005
+#define MX27_PAD_PC_CD1_B__GPIO6_20                        0xb4 0x036
+#define MX27_PAD_CS4_B__CS4_B                              0xb5 0x004
+#define MX27_PAD_CS4_B__ETMTRACESYNC                       0xb5 0x005
+#define MX27_PAD_CS4_B__GPIO6_21                           0xb5 0x036
+#define MX27_PAD_CS5_B__CS5_B                              0xb6 0x004
+#define MX27_PAD_CS5_B__ETMTRACECLK                        0xb6 0x005
+#define MX27_PAD_CS5_B__GPIO6_22                           0xb6 0x036
+#define MX27_PAD_ATA_DATA15__ATA_DATA15                    0xb7 0x004
+#define MX27_PAD_ATA_DATA15__ETMTRACEPKT4                  0xb7 0x005
+#define MX27_PAD_ATA_DATA15__FEC_TX_EN                     0xb7 0x006
+#define MX27_PAD_ATA_DATA15__GPIO6_23                      0xb7 0x036
+#define MX27_PAD_UNUSED15__UNUSED15                        0xb8 0x004
+#define MX27_PAD_UNUSED15__GPIO6_24                        0xb8 0x036
+#define MX27_PAD_UNUSED16__UNUSED16                        0xb9 0x004
+#define MX27_PAD_UNUSED16__GPIO6_25                        0xb9 0x036
+#define MX27_PAD_UNUSED17__UNUSED17                        0xba 0x004
+#define MX27_PAD_UNUSED17__GPIO6_26                        0xba 0x036
+#define MX27_PAD_UNUSED18__UNUSED18                        0xbb 0x004
+#define MX27_PAD_UNUSED18__GPIO6_27                        0xbb 0x036
+#define MX27_PAD_UNUSED19__UNUSED19                        0xbc 0x004
+#define MX27_PAD_UNUSED19__GPIO6_28                        0xbc 0x036
+#define MX27_PAD_UNUSED20__UNUSED20                        0xbd 0x004
+#define MX27_PAD_UNUSED20__GPIO6_29                        0xbd 0x036
+#define MX27_PAD_UNUSED21__UNUSED21                        0xbe 0x004
+#define MX27_PAD_UNUSED21__GPIO6_30                        0xbe 0x036
+#define MX27_PAD_UNUSED22__UNUSED22                        0xbf 0x004
+#define MX27_PAD_UNUSED22__GPIO6_31                        0xbf 0x036
+
+#endif /* __DTS_IMX27_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx27-pingrp.h b/arch/arm/boot/dts/imx27-pingrp.h
new file mode 100644 (file)
index 0000000..f3fbf5a
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2013 Markus Pargmann <mpa@pengutronix.de>, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __DTS_IMX27_PINGRP_H
+#define __DTS_IMX27_PINGRP_H
+
+#include "imx27-pinfunc.h"
+
+#define MX27_CSPI1_PINGRP1 \
+       MX27_PAD_CSPI1_MISO__CSPI1_MISO 0x0 \
+       MX27_PAD_CSPI1_MOSI__CSPI1_MOSI 0x0 \
+       MX27_PAD_CSPI1_SCLK__CSPI1_SCLK 0x0
+
+#define MX27_CSPI2_PINGRP1 \
+       MX27_PAD_CSPI2_MISO__CSPI2_MISO 0x0 \
+       MX27_PAD_CSPI2_MOSI__CSPI2_MOSI 0x0 \
+       MX27_PAD_CSPI2_SCLK__CSPI2_SCLK 0x0
+
+#define MX27_CSPI3_PINGRP1 \
+       MX27_PAD_SD1_CLK__CSPI3_SCLK 0x0 \
+       MX27_PAD_SD1_D0__CSPI3_MISO 0x0 \
+       MX27_PAD_SD1_CMD__CSPI3_MOSI 0x0
+
+#define MX27_FB_PINGRP1 \
+       MX27_PAD_CLS__CLS 0x0 \
+       MX27_PAD_CONTRAST__CONTRAST 0x0 \
+       MX27_PAD_LD0__LD0 0x0 \
+       MX27_PAD_LD1__LD1 0x0 \
+       MX27_PAD_LD2__LD2 0x0 \
+       MX27_PAD_LD3__LD3 0x0 \
+       MX27_PAD_LD4__LD4 0x0 \
+       MX27_PAD_LD5__LD5 0x0 \
+       MX27_PAD_LD6__LD6 0x0 \
+       MX27_PAD_LD7__LD7 0x0 \
+       MX27_PAD_LD8__LD8 0x0 \
+       MX27_PAD_LD9__LD9 0x0 \
+       MX27_PAD_LD10__LD10 0x0 \
+       MX27_PAD_LD11__LD11 0x0 \
+       MX27_PAD_LD12__LD12 0x0 \
+       MX27_PAD_LD13__LD13 0x0 \
+       MX27_PAD_LD14__LD14 0x0 \
+       MX27_PAD_LD15__LD15 0x0 \
+       MX27_PAD_LD16__LD16 0x0 \
+       MX27_PAD_LD17__LD17 0x0 \
+       MX27_PAD_LSCLK__LSCLK 0x0 \
+       MX27_PAD_OE_ACD__OE_ACD 0x0 \
+       MX27_PAD_PS__PS 0x0 \
+       MX27_PAD_REV__REV 0x0 \
+       MX27_PAD_SPL_SPR__SPL_SPR 0x0 \
+       MX27_PAD_HSYNC__HSYNC 0x0 \
+       MX27_PAD_VSYNC__VSYNC 0x0
+
+#define MX27_FEC1_PINGRP1 \
+       MX27_PAD_SD3_CMD__FEC_TXD0 0x0 \
+       MX27_PAD_SD3_CLK__FEC_TXD1 0x0 \
+       MX27_PAD_ATA_DATA0__FEC_TXD2 0x0 \
+       MX27_PAD_ATA_DATA1__FEC_TXD3 0x0 \
+       MX27_PAD_ATA_DATA2__FEC_RX_ER 0x0 \
+       MX27_PAD_ATA_DATA3__FEC_RXD1 0x0 \
+       MX27_PAD_ATA_DATA4__FEC_RXD2 0x0 \
+       MX27_PAD_ATA_DATA5__FEC_RXD3 0x0 \
+       MX27_PAD_ATA_DATA6__FEC_MDIO 0x0 \
+       MX27_PAD_ATA_DATA7__FEC_MDC 0x0 \
+       MX27_PAD_ATA_DATA8__FEC_CRS 0x0 \
+       MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x0 \
+       MX27_PAD_ATA_DATA10__FEC_RXD0 0x0 \
+       MX27_PAD_ATA_DATA11__FEC_RX_DV 0x0 \
+       MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x0 \
+       MX27_PAD_ATA_DATA13__FEC_COL 0x0 \
+       MX27_PAD_ATA_DATA14__FEC_TX_ER 0x0 \
+       MX27_PAD_ATA_DATA15__FEC_TX_EN 0x0
+
+#define MX27_I2C1_PINGRP1 \
+       MX27_PAD_I2C_DATA__I2C_DATA 0x0 \
+       MX27_PAD_I2C_CLK__I2C_CLK 0x0
+
+#define MX27_I2C2_PINGRP1 \
+       MX27_PAD_I2C2_SDA__I2C2_SDA 0x0 \
+       MX27_PAD_I2C2_SCL__I2C2_SCL 0x0
+
+#define MX27_OWIRE1_PINGRP1 \
+       MX27_PAD_RTCK__OWIRE 0x0
+
+#define MX27_SDHC1_PINGRP1 \
+       MX27_PAD_SD1_CLK__SD1_CLK \
+       MX27_PAD_SD1_CMD__SD1_CMD \
+       MX27_PAD_SD1_D0__SD1_D0 \
+       MX27_PAD_SD1_D1__SD1_D1 \
+       MX27_PAD_SD1_D2__SD1_D2 \
+       MX27_PAD_SD1_D3__SD1_D3
+
+#define MX27_SDHC2_PINGRP1 \
+       MX27_PAD_SD2_CLK__SD2_CLK \
+       MX27_PAD_SD2_CMD__SD2_CMD \
+       MX27_PAD_SD2_D0__SD2_D0 \
+       MX27_PAD_SD2_D1__SD2_D1 \
+       MX27_PAD_SD2_D2__SD2_D2 \
+       MX27_PAD_SD2_D3__SD2_D3
+
+#define MX27_SDHC3_PINGRP1 \
+       MX27_PAD_SD3_CLK__SD3_CLK \
+       MX27_PAD_SD3_CMD__SD3_CMD \
+       MX27_PAD_SD3_D0__SD3_D0 \
+       MX27_PAD_SD3_D1__SD3_D1 \
+       MX27_PAD_SD3_D2__SD3_D2 \
+       MX27_PAD_SD3_D3__SD3_D3
+
+#define MX27_UART1_PINGRP1 \
+       MX27_PAD_UART1_TXD__UART1_TXD 0x0 \
+       MX27_PAD_UART1_RXD__UART1_RXD 0x0
+
+#define MX27_UART1_RTSCTS_PINGRP1 \
+       MX27_PAD_UART1_CTS__UART1_CTS 0x0 \
+       MX27_PAD_UART1_RTS__UART1_RTS 0x0
+
+#define MX27_UART2_PINGRP1 \
+       MX27_PAD_UART2_TXD__UART2_TXD 0x0 \
+       MX27_PAD_UART2_RXD__UART2_RXD 0x0
+
+#define MX27_UART2_RTSCTS_PINGRP1 \
+       MX27_PAD_UART2_CTS__UART2_CTS 0x0 \
+       MX27_PAD_UART2_RTS__UART2_RTS 0x0
+
+#define MX27_UART3_PINGRP1 \
+       MX27_PAD_UART3_TXD__UART3_TXD 0x0 \
+       MX27_PAD_UART3_RXD__UART3_RXD 0x0
+
+#define MX27_UART3_RTSCTS_PINGRP1 \
+       MX27_PAD_UART3_CTS__UART3_CTS 0x0 \
+       MX27_PAD_UART3_RTS__UART3_RTS 0x0
+
+#endif /* __DTS_IMX27_PINGRP_H */
index 826231eb44466f9187a564b3a587c7b18d686b28..5cfe2884eb67e29cf752851857a06047a7aa17a8 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "skeleton.dtsi"
+#include "imx27-pingrp.h"
 
 / {
        aliases {
                                status = "disabled";
                        };
 
-                       gpio1: gpio@10015000 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015000 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio2: gpio@10015100 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015100 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio3: gpio@10015200 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015200 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio4: gpio@10015300 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015300 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio5: gpio@10015400 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015400 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio6: gpio@10015500 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015500 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
+                       iomuxc: iomuxc@10015000 {
+                               compatible = "fsl,imx27-iomuxc";
+                               reg = <0x10015000 0x600>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges;
+
+                               gpio1: gpio@10015000 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015000 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio2: gpio@10015100 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015100 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio3: gpio@10015200 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015200 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio4: gpio@10015300 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015300 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio5: gpio@10015400 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015400 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio6: gpio@10015500 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015500 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
                        };
 
                        audmux: audmux@10016000 {
index e2efd8d89c4fb82bca3602274380c7a81a515518..741aecbf0b321ba1b7fd06c3a837fd1e263e6ae4 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index 6f254ca816cbd42b3ff80d61c3bfdb86c6f8438d..e1ce9179db63b612839a85d35b5122fd3fd4dd59 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index cabb6171a19d925c214442daa47473a6a2be31a5..ae7c3390e65a5ddc6210c4d256b406719e624d14 100644 (file)
                usb0: usb@80080000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb0_otg_cfa10036>;
+                       dr_mode = "peripheral";
+                       phy_type = "utmi";
                        status = "okay";
                };
        };
index f93e9a700e52b39287ff6761cf9c2ffdc21ea617..6729872ffe9abd2855debdd52fbdeab2f14a1ef7 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb_pins_cfa10037>;
                        regulator-name = "usb1_vbus";
index 7087b4bf6a8f88e5748a70747af337de3524a5c0..093fd7b69a48a02ed8d710c8a9d0d3f31b0bd05f 100644 (file)
                                i2c-parent = <&i2c1>;
 
                                i2c@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
                                        reg = <0>;
+
+                                       adc0: nau7802@2a {
+                                               compatible = "nuvoton,nau7802";
+                                               reg = <0x2a>;
+                                               nuvoton,vldo = <3000>;
+                                       };
                                };
 
                                i2c@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
                                        reg = <1>;
+
+                                       adc1: nau7802@2a {
+                                               compatible = "nuvoton,nau7802";
+                                               reg = <0x2a>;
+                                               nuvoton,vldo = <3000>;
+                                       };
                                };
 
                                i2c@2 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
                                        reg = <2>;
+
+                                       adc2: nau7802@2a {
+                                               compatible = "nuvoton,nau7802";
+                                               reg = <0x2a>;
+                                               nuvoton,vldo = <3000>;
+                                       };
                                };
 
                                i2c@3 {
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb_pins_cfa10049>;
                        regulator-name = "usb1_vbus";
index 3c1312885ae0dafc1642e30d27a58cc3cf49d12b..1ebd44edaf8d611aa6e9519d4cadfa61bafa8a55 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb_pins_cfa10057>;
                        regulator-name = "usb1_vbus";
index 2469d34df0ae1499de3236f13e180969dd78eed7..a4f0acb93437e36e0a3abf340e4291c5bdad7aff 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@0 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb_pins_cfa10058>;
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
diff --git a/arch/arm/boot/dts/imx28-duckbill.dts b/arch/arm/boot/dts/imx28-duckbill.dts
new file mode 100644 (file)
index 0000000..5f326c1
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2013 Michael Heimpold <mhei@heimpold.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx28.dtsi"
+
+/ {
+       model = "I2SE Duckbill";
+       compatible = "i2se,duckbill", "fsl,imx28";
+
+       memory {
+               reg = <0x40000000 0x08000000>;
+       };
+
+       apb@80000000 {
+               apbh@80000000 {
+                       ssp0: ssp@80010000 {
+                               compatible = "fsl,imx28-mmc";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&mmc0_8bit_pins_a
+                                       &mmc0_cd_cfg &mmc0_sck_cfg>;
+                               bus-width = <8>;
+                               vmmc-supply = <&reg_3p3v>;
+                               status = "okay";
+                       };
+
+                       pinctrl@80018000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&hog_pins_a>;
+
+                               hog_pins_a: hog@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_ENET0_RX_CLK__GPIO_4_13 /* PHY Reset */
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               led_pins_a: led_gpio@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART1_RX__GPIO_3_4
+                                               MX28_PAD_AUART1_TX__GPIO_3_5
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+                       };
+               };
+
+               apbx@80040000 {
+                       duart: serial@80074000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&duart_pins_a>;
+                               status = "okay";
+                       };
+
+                       usbphy0: usbphy@8007c000 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       ahb@80080000 {
+               usb0: usb@80080000 {
+                       status = "okay";
+               };
+
+               mac0: ethernet@800f0000 {
+                       phy-mode = "rmii";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mac0_pins_a>;
+                       phy-supply = <&reg_3p3v>;
+                       phy-reset-gpios = <&gpio4 13 0>;
+                       phy-reset-duration = <100>;
+                       status = "okay";
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins_a>;
+
+               status {
+                       label = "duckbill:green:status";
+                       gpios = <&gpio3 5 0>;
+               };
+
+               failure {
+                       label = "duckbill:red:status";
+                       gpios = <&gpio3 4 0>;
+               };
+       };
+};
index 4267c2b05d600ac8bfb9cf2612a3b72977d7dc0e..e4cc44c98585f415744e30a41fd4d066797043a3 100644 (file)
                        i2c0: i2c@80058000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&i2c0_pins_a>;
+                               clock-frequency = <400000>;
                                status = "okay";
 
                                sgtl5000: codec@0a {
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio3 28 0>;
                };
 
-               reg_fec_3v3: fec-3v3 {
+               reg_fec_3v3: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "fec-3v3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio2 15 0>;
                };
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@3 {
                        compatible = "regulator-fixed";
+                       reg = <3>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        enable-active-high;
                };
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@4 {
                        compatible = "regulator-fixed";
+                       reg = <4>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        enable-active-high;
                };
 
-               reg_lcd_3v3: lcd-3v3 {
+               reg_lcd_3v3: regulator@5 {
                        compatible = "regulator-fixed";
+                       reg = <5>;
                        regulator-name = "lcd-3v3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        enable-active-high;
                };
 
-               reg_can_3v3: can-3v3 {
+               reg_can_3v3: regulator@6 {
                        compatible = "regulator-fixed";
+                       reg = <6>;
                        regulator-name = "can-3v3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index d3958da60bd72e95052ff08af73a46b83b461c58..d6e71ed3147b90932ee93b840048d3b64810357f 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio3 29 0>;
                };
 
-               reg_vddio_sd1: vddio-sd1 {
+               reg_vddio_sd1: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "vddio-sd1";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio2 19 0>;
                };
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@3 {
                        compatible = "regulator-fixed";
+                       reg = <3>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index 8e2477fbe1d70963d583973ed4c46a6554c99104..e6d0fa69973ed87613cde114a50ad7a580892c3c 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio3 28 0>;
                };
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        gpio = <&gpio3 12 0>;
                };
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@3 {
                        compatible = "regulator-fixed";
+                       reg = <3>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index 4870f07bf56a86423c6a910a5c86ce6fce1624a4..2612a01e8da9dab8a611e928fe8dc8c921c3a799 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index be5a0550d58c3312d37f36e04c937d5739c7f181..3c54e8d152e6dccabeaf61b79506c8ae5e6534fc 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -53,8 +56,9 @@
                        enable-active-high;
                };
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        enable-active-high;
                };
 
-               reg_2p5v: 2p5v {
+               reg_2p5v: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "2P5V";
                        regulator-min-microvolt = <2500000>;
                        regulator-max-microvolt = <2500000>;
                        regulator-always-on;
                };
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@3 {
                        compatible = "regulator-fixed";
+                       reg = <3>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
 
-               reg_can_xcvr: can-xcvr {
+               reg_can_xcvr: regulator@4 {
                        compatible = "regulator-fixed";
+                       reg = <4>;
                        regulator-name = "CAN XCVR";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
@@ -89,8 +96,9 @@
                        pinctrl-0 = <&tx28_flexcan_xcvr_pins>;
                };
 
-               reg_lcd: lcd-power {
+               reg_lcd: regulator@5 {
                        compatible = "regulator-fixed";
+                       reg = <5>;
                        regulator-name = "LCD POWER";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        enable-active-high;
                };
 
-               reg_lcd_reset: lcd-reset {
+               reg_lcd_reset: regulator@6 {
                        compatible = "regulator-fixed";
+                       reg = <6>;
                        regulator-name = "LCD RESET";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index cda19c8b0a470ecb6900255c8a9eb17b85bdf9dc..51ff33512f62777f679bda207d40e6ece1b26432 100644 (file)
                                        fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
+                               auart2_pins_a: auart2-pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART2_RX__AUART2_RX
+                                               MX28_PAD_AUART2_TX__AUART2_TX
+                                               MX28_PAD_AUART2_CTS__AUART2_CTS
+                                               MX28_PAD_AUART2_RTS__AUART2_RTS
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
                                auart3_pins_a: auart3@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
diff --git a/arch/arm/boot/dts/imx50-evk.dts b/arch/arm/boot/dts/imx50-evk.dts
new file mode 100644 (file)
index 0000000..a859264
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx50.dtsi"
+
+/ {
+       model = "Freescale i.MX50 Evaluation Kit";
+       compatible = "fsl,imx50-evk", "fsl,imx50";
+
+       memory {
+               reg = <0x70000000 0x80000000>;
+       };
+};
+
+&cspi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_cspi>;
+       fsl,spi-num-chipselects = <2>;
+       cs-gpios = <&gpio4 11 0>, <&gpio4 13 0>;
+       status = "okay";
+
+       flash: m25p32@1 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "m25p32", "m25p80";
+               spi-max-frequency = <25000000>;
+               reg = <1>;
+
+               partition@0 {
+                       label = "bootloader";
+                       reg = <0x0 0x100000>;
+                       read-only;
+               };
+
+               partition@100000 {
+                       label = "kernel";
+                       reg = <0x100000 0x300000>;
+               };
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       phy-mode = "rmii";
+       phy-reset-gpios = <&gpio4 12 0>;
+       status = "okay";
+};
+
+&iomuxc {
+       imx50-evk {
+               pinctrl_cspi: cspigrp {
+                       fsl,pins = <MX50_CSPI_PINGRP1>;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX50_FEC_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX50_UART1_PINGRP1>;
+               };
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&usbh2 {
+       status = "okay";
+};
+
+&usbh3 {
+       status = "okay";
+};
+
+&usbotg {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx50-pinfunc.h b/arch/arm/boot/dts/imx50-pinfunc.h
new file mode 100644 (file)
index 0000000..97e6e7f
--- /dev/null
@@ -0,0 +1,923 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DTS_IMX50_PINFUNC_H
+#define __DTS_IMX50_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX50_PAD_KEY_COL0__KPP_COL_0                           0x020 0x2cc 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL0__GPIO4_0                             0x020 0x2cc 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL0__EIM_NANDF_CLE                       0x020 0x2cc 0x000 0x2 0x0
+#define MX50_PAD_KEY_COL0__CTI_TRIGIN7                         0x020 0x2cc 0x000 0x6 0x0
+#define MX50_PAD_KEY_COL0__USBPHY1_TXREADY                     0x020 0x2cc 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW0__KPP_ROW_0                           0x024 0x2d0 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW0__GPIO4_1                             0x024 0x2d0 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW0__EIM_NANDF_ALE                       0x024 0x2d0 0x000 0x2 0x0
+#define MX50_PAD_KEY_ROW0__CTI_TRIGIN_ACK7                     0x024 0x2d0 0x000 0x6 0x0
+#define MX50_PAD_KEY_ROW0__USBPHY1_RXVALID                     0x024 0x2d0 0x000 0x7 0x0
+#define MX50_PAD_KEY_COL1__KPP_COL_1                           0x028 0x2d4 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL1__GPIO4_2                             0x028 0x2d4 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL1__EIM_NANDF_CEN_0                     0x028 0x2d4 0x000 0x2 0x0
+#define MX50_PAD_KEY_COL1__CTI_TRIGOUT_ACK6                    0x028 0x2d4 0x000 0x6 0x0
+#define MX50_PAD_KEY_COL1__USBPHY1_RXACTIVE                    0x028 0x2d4 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW1__KPP_ROW_1                           0x02c 0x2d8 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW1__GPIO4_3                             0x02c 0x2d8 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW1__EIM_NANDF_CEN_1                     0x02c 0x2d8 0x000 0x2 0x0
+#define MX50_PAD_KEY_ROW1__CTI_TRIGOUT_ACK7                    0x02c 0x2d8 0x000 0x6 0x0
+#define MX50_PAD_KEY_ROW1__USBPHY1_RXERROR                     0x02c 0x2d8 0x000 0x7 0x0
+#define MX50_PAD_KEY_COL2__KPP_COL_1                           0x030 0x2dc 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL2__GPIO4_4                             0x030 0x2dc 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL2__EIM_NANDF_CEN_2                     0x030 0x2dc 0x000 0x2 0x0
+#define MX50_PAD_KEY_COL2__CTI_TRIGOUT6                                0x030 0x2dc 0x000 0x6 0x0
+#define MX50_PAD_KEY_COL2__USBPHY1_SIECLOCK                    0x030 0x2dc 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW2__KPP_ROW_2                           0x034 0x2e0 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW2__GPIO4_5                             0x034 0x2e0 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW2__EIM_NANDF_CEN_3                     0x034 0x2e0 0x000 0x2 0x0
+#define MX50_PAD_KEY_ROW2__CTI_TRIGOUT7                                0x034 0x2e0 0x000 0x6 0x0
+#define MX50_PAD_KEY_ROW2__USBPHY1_LINESTATE_0                 0x034 0x2e0 0x000 0x7 0x0
+#define MX50_PAD_KEY_COL3__KPP_COL_2                           0x038 0x2e4 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL3__GPIO4_6                             0x038 0x2e4 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL3__EIM_NANDF_READY0                    0x038 0x2e4 0x7b4 0x2 0x0
+#define MX50_PAD_KEY_COL3__SDMA_EXT_EVENT_0                    0x038 0x2e4 0x7b8 0x6 0x0
+#define MX50_PAD_KEY_COL3__USBPHY1_LINESTATE_1                 0x038 0x2e4 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW3__KPP_ROW_3                           0x03c 0x2e8 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW3__GPIO4_7                             0x03c 0x2e8 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW3__EIM_NANDF_DQS                       0x03c 0x2e8 0x7b0 0x2 0x0
+#define MX50_PAD_KEY_ROW3__SDMA_EXT_EVENT_1                    0x03c 0x2e8 0x7bc 0x6 0x0
+#define MX50_PAD_KEY_ROW3__USBPHY1_VBUSVALID                   0x03c 0x2e8 0x000 0x7 0x0
+#define MX50_PAD_I2C1_SCL__I2C1_SCL                            0x040 0x2ec 0x000 0x0 0x0
+#define MX50_PAD_I2C1_SCL__GPIO6_18                            0x040 0x2ec 0x000 0x1 0x0
+#define MX50_PAD_I2C1_SCL__UART2_TXD_MUX                       0x040 0x2ec 0x7cc 0x2 0x0
+#define MX50_PAD_I2C1_SDA__I2C1_SDA                            0x044 0x2f0 0x000 0x0 0x0
+#define MX50_PAD_I2C1_SDA__GPIO6_19                            0x044 0x2f0 0x000 0x1 0x0
+#define MX50_PAD_I2C1_SDA__UART2_RXD_MUX                       0x044 0x2f0 0x7cc 0x2 0x1
+#define MX50_PAD_I2C2_SCL__I2C2_SCL                            0x048 0x2f4 0x000 0x0 0x0
+#define MX50_PAD_I2C2_SCL__GPIO6_20                            0x048 0x2f4 0x000 0x1 0x0
+#define MX50_PAD_I2C2_SCL__UART2_CTS                           0x048 0x2f4 0x000 0x2 0x0
+#define MX50_PAD_I2C2_SDA__I2C2_SDA                            0x04c 0x2f8 0x000 0x0 0x0
+#define MX50_PAD_I2C2_SDA__GPIO6_21                            0x04c 0x2f8 0x000 0x1 0x0
+#define MX50_PAD_I2C2_SDA__UART2_RTS                           0x04c 0x2f8 0x7c8 0x2 0x1
+#define MX50_PAD_I2C3_SCL__I2C3_SCL                            0x050 0x2fc 0x000 0x0 0x0
+#define MX50_PAD_I2C3_SCL__GPIO6_22                            0x050 0x2fc 0x000 0x1 0x0
+#define MX50_PAD_I2C3_SCL__FEC_MDC                             0x050 0x2fc 0x000 0x2 0x0
+#define MX50_PAD_I2C3_SCL__GPC_PMIC_RDY                                0x050 0x2fc 0x000 0x3 0x0
+#define MX50_PAD_I2C3_SCL__GPT_CAPIN1                          0x050 0x2fc 0x000 0x5 0x0
+#define MX50_PAD_I2C3_SCL__OBSERVE_MUX_OBSRV_INT_OUT0          0x050 0x2fc 0x000 0x6 0x0
+#define MX50_PAD_I2C3_SCL__USBOH1_USBOTG_OC                    0x050 0x2fc 0x7e8 0x7 0x0
+#define MX50_PAD_I2C3_SDA__I2C3_SDA                            0x054 0x300 0x000 0x0 0x0
+#define MX50_PAD_I2C3_SDA__GPIO6_23                            0x054 0x300 0x000 0x1 0x0
+#define MX50_PAD_I2C3_SDA__FEC_MDIO                            0x054 0x300 0x774 0x2 0x0
+#define MX50_PAD_I2C3_SDA__TZIC_PWRFAIL_INT                    0x054 0x300 0x000 0x3 0x0
+#define MX50_PAD_I2C3_SDA__SRTC_ALARM_DEB                      0x054 0x300 0x000 0x4 0x0
+#define MX50_PAD_I2C3_SDA__GPT_CAPIN2                          0x054 0x300 0x000 0x5 0x0
+#define MX50_PAD_I2C3_SDA__OBSERVE_MUX_OBSRV_INT_OUT1          0x054 0x300 0x000 0x6 0x0
+#define MX50_PAD_I2C3_SDA__USBOH1_USBOTG_PWR                   0x054 0x300 0x000 0x7 0x0
+#define MX50_PAD_PWM1__PWM1_PWMO                               0x058 0x304 0x000 0x0 0x0
+#define MX50_PAD_PWM1__GPIO6_24                                        0x058 0x304 0x000 0x1 0x0
+#define MX50_PAD_PWM1__USBOH1_USBOTG_OC                                0x058 0x304 0x7e8 0x2 0x1
+#define MX50_PAD_PWM1__GPT_CMPOUT1                             0x058 0x304 0x000 0x5 0x0
+#define MX50_PAD_PWM1__OBSERVE_MUX_OBSRV_INT_OUT2              0x058 0x304 0x000 0x6 0x0
+#define MX50_PAD_PWM1__SJC_FAIL                                        0x058 0x304 0x000 0x7 0x0
+#define MX50_PAD_PWM2__PWM2_PWMO                               0x05c 0x308 0x000 0x0 0x0
+#define MX50_PAD_PWM2__GPIO6_25                                        0x05c 0x308 0x000 0x1 0x0
+#define MX50_PAD_PWM2__USBOH1_USBOTG_PWR                       0x05c 0x308 0x000 0x2 0x0
+#define MX50_PAD_PWM2__GPT_CMPOUT2                             0x05c 0x308 0x000 0x5 0x0
+#define MX50_PAD_PWM2__OBSERVE_MUX_OBSRV_INT_OUT3              0x05c 0x308 0x000 0x6 0x0
+#define MX50_PAD_PWM2__SRC_ANY_PU_RST                          0x05c 0x308 0x000 0x7 0x0
+#define MX50_PAD_OWIRE__OWIRE_LINE                             0x060 0x30c 0x000 0x0 0x0
+#define MX50_PAD_OWIRE__GPIO6_26                               0x060 0x30c 0x000 0x1 0x0
+#define MX50_PAD_OWIRE__USBOH1_USBH1_OC                                0x060 0x30c 0x000 0x2 0x0
+#define MX50_PAD_OWIRE__CCM_SSI_EXT1_CLK                       0x060 0x30c 0x000 0x3 0x0
+#define MX50_PAD_OWIRE__EPDC_PWRIRQ                            0x060 0x30c 0x000 0x4 0x0
+#define MX50_PAD_OWIRE__GPT_CMPOUT3                            0x060 0x30c 0x000 0x5 0x0
+#define MX50_PAD_OWIRE__OBSERVE_MUX_OBSRV_INT_OUT4             0x060 0x30c 0x000 0x6 0x0
+#define MX50_PAD_OWIRE__SJC_JTAG_ACT                           0x060 0x30c 0x000 0x7 0x0
+#define MX50_PAD_EPITO__EPIT1_EPITO                            0x064 0x310 0x000 0x0 0x0
+#define MX50_PAD_EPITO__GPIO6_27                               0x064 0x310 0x000 0x1 0x0
+#define MX50_PAD_EPITO__USBOH1_USBH1_PWR                       0x064 0x310 0x000 0x2 0x0
+#define MX50_PAD_EPITO__CCM_SSI_EXT2_CLK                       0x064 0x310 0x000 0x3 0x0
+#define MX50_PAD_EPITO__DPLLIP1_TOG_EN                         0x064 0x310 0x000 0x4 0x0
+#define MX50_PAD_EPITO__GPT_CLK_IN                             0x064 0x310 0x000 0x5 0x0
+#define MX50_PAD_EPITO__PMU_IRQ_B                              0x064 0x310 0x000 0x6 0x0
+#define MX50_PAD_EPITO__SJC_DE_B                               0x064 0x310 0x000 0x7 0x0
+#define MX50_PAD_WDOG__WDOG1_WDOG_B                            0x068 0x314 0x000 0x0 0x0
+#define MX50_PAD_WDOG__GPIO6_28                                        0x068 0x314 0x000 0x1 0x0
+#define MX50_PAD_WDOG__WDOG1_WDOG_RST_B_DEB                    0x068 0x314 0x000 0x2 0x0
+#define MX50_PAD_WDOG__CCM_XTAL32K                             0x068 0x314 0x000 0x6 0x0
+#define MX50_PAD_WDOG__SJC_DONE                                        0x068 0x314 0x000 0x7 0x0
+#define MX50_PAD_SSI_TXFS__AUDMUX_AUD3_TXFS                    0x06c 0x318 0x000 0x0 0x0
+#define MX50_PAD_SSI_TXFS__GPIO6_0                             0x06c 0x318 0x000 0x1 0x0
+#define MX50_PAD_SSI_TXFS__SRC_BT_FUSE_RSV_1                   0x06c 0x318 0x000 0x6 0x0
+#define MX50_PAD_SSI_TXFS__USBPHY1_DATAOUT_8                   0x06c 0x318 0x000 0x7 0x0
+#define MX50_PAD_SSI_TXC__AUDMUX_AUD3_TXC                      0x070 0x31c 0x000 0x0 0x0
+#define MX50_PAD_SSI_TXC__GPIO6_1                              0x070 0x31c 0x000 0x1 0x0
+#define MX50_PAD_SSI_TXC__SRC_BT_FUSE_RSV_0                    0x070 0x31c 0x000 0x6 0x0
+#define MX50_PAD_SSI_TXC__USBPHY1_DATAOUT_9                    0x070 0x31c 0x000 0x7 0x0
+#define MX50_PAD_SSI_TXD__AUDMUX_AUD3_TXD                      0x074 0x320 0x000 0x0 0x0
+#define MX50_PAD_SSI_TXD__GPIO6_2                              0x074 0x320 0x000 0x1 0x0
+#define MX50_PAD_SSI_TXD__CSPI_RDY                             0x074 0x320 0x6e8 0x4 0x0
+#define MX50_PAD_SSI_TXD__USBPHY1_DATAOUT_10                   0x074 0x320 0x000 0x7 0x0
+#define MX50_PAD_SSI_RXD__AUDMUX_AUD3_RXD                      0x078 0x324 0x000 0x0 0x0
+#define MX50_PAD_SSI_RXD__GPIO6_3                              0x078 0x324 0x000 0x1 0x0
+#define MX50_PAD_SSI_RXD__CSPI_SS3                             0x078 0x324 0x6f4 0x4 0x0
+#define MX50_PAD_SSI_RXD__USBPHY1_DATAOUT_11                   0x078 0x324 0x000 0x7 0x0
+#define MX50_PAD_SSI_RXFS__AUDMUX_AUD3_RXFS                    0x07c 0x328 0x000 0x0 0x0
+#define MX50_PAD_SSI_RXFS__GPIO6_4                             0x07c 0x328 0x000 0x1 0x0
+#define MX50_PAD_SSI_RXFS__UART5_TXD_MUX                       0x07c 0x328 0x7e4 0x2 0x0
+#define MX50_PAD_SSI_RXFS__EIM_WEIM_D_6                                0x07c 0x328 0x804 0x3 0x0
+#define MX50_PAD_SSI_RXFS__CSPI_SS2                            0x07c 0x328 0x6f0 0x4 0x0
+#define MX50_PAD_SSI_RXFS__FEC_COL                             0x07c 0x328 0x770 0x5 0x0
+#define MX50_PAD_SSI_RXFS__FEC_MDC                             0x07c 0x328 0x000 0x6 0x0
+#define MX50_PAD_SSI_RXFS__USBPHY1_DATAOUT_12                  0x07c 0x328 0x000 0x7 0x0
+#define MX50_PAD_SSI_RXC__AUDMUX_AUD3_RXC                      0x080 0x32c 0x000 0x0 0x0
+#define MX50_PAD_SSI_RXC__GPIO6_5                              0x080 0x32c 0x000 0x1 0x0
+#define MX50_PAD_SSI_RXC__UART5_RXD_MUX                                0x080 0x32c 0x7e4 0x2 0x1
+#define MX50_PAD_SSI_RXC__EIM_WEIM_D_7                         0x080 0x32c 0x808 0x3 0x0
+#define MX50_PAD_SSI_RXC__CSPI_SS1                             0x080 0x32c 0x6ec 0x4 0x0
+#define MX50_PAD_SSI_RXC__FEC_RX_CLK                           0x080 0x32c 0x780 0x5 0x0
+#define MX50_PAD_SSI_RXC__FEC_MDIO                             0x080 0x32c 0x774 0x6 0x1
+#define MX50_PAD_SSI_RXC__USBPHY1_DATAOUT_13                   0x080 0x32c 0x000 0x7 0x0
+#define MX50_PAD_UART1_TXD__UART1_TXD_MUX                      0x084 0x330 0x7c4 0x0 0x0
+#define MX50_PAD_UART1_TXD__GPIO6_6                            0x084 0x330 0x000 0x1 0x0
+#define MX50_PAD_UART1_TXD__USBPHY1_DATAOUT_14                 0x084 0x330 0x000 0x7 0x0
+#define MX50_PAD_UART1_RXD__UART1_RXD_MUX                      0x088 0x334 0x7c4 0x0 0x1
+#define MX50_PAD_UART1_RXD__GPIO6_7                            0x088 0x334 0x000 0x1 0x0
+#define MX50_PAD_UART1_RXD__USBPHY1_DATAOUT_15                 0x088 0x334 0x000 0x7 0x0
+#define MX50_PAD_UART1_CTS__UART1_CTS                          0x08c 0x338 0x000 0x0 0x0
+#define MX50_PAD_UART1_CTS__GPIO6_8                            0x08c 0x338 0x000 0x1 0x0
+#define MX50_PAD_UART1_CTS__UART5_TXD_MUX                      0x08c 0x338 0x7e4 0x2 0x2
+#define MX50_PAD_UART1_CTS__ESDHC4_DAT4                                0x08c 0x338 0x760 0x4 0x0
+#define MX50_PAD_UART1_CTS__ESDHC4_CMD                         0x08c 0x338 0x74c 0x5 0x0
+#define MX50_PAD_UART1_CTS__USBPHY2_DATAOUT_8                  0x08c 0x338 0x000 0x7 0x0
+#define MX50_PAD_UART1_RTS__UART1_RTS                          0x090 0x33c 0x7c0 0x0 0x3
+#define MX50_PAD_UART1_RTS__GPIO6_9                            0x090 0x33c 0x000 0x1 0x0
+#define MX50_PAD_UART1_RTS__UART5_RXD_MUX                      0x090 0x33c 0x7e4 0x2 0x3
+#define MX50_PAD_UART1_RTS__ESDHC4_DAT5                                0x090 0x33c 0x764 0x4 0x0
+#define MX50_PAD_UART1_RTS__ESDHC4_CLK                         0x090 0x33c 0x748 0x5 0x0
+#define MX50_PAD_UART1_RTS__USBPHY2_DATAOUT_9                  0x090 0x33c 0x000 0x7 0x0
+#define MX50_PAD_UART2_TXD__UART2_TXD_MUX                      0x094 0x340 0x7cc 0x0 0x2
+#define MX50_PAD_UART2_TXD__GPIO6_10                           0x094 0x340 0x000 0x1 0x0
+#define MX50_PAD_UART2_TXD__ESDHC4_DAT6                                0x094 0x340 0x768 0x4 0x0
+#define MX50_PAD_UART2_TXD__ESDHC4_DAT4                                0x094 0x340 0x760 0x5 0x1
+#define MX50_PAD_UART2_TXD__USBPHY2_DATAOUT_10                 0x094 0x340 0x000 0x7 0x0
+#define MX50_PAD_UART2_RXD__UART2_RXD_MUX                      0x098 0x344 0x7cc 0x0 0x3
+#define MX50_PAD_UART2_RXD__GPIO6_11                           0x098 0x344 0x000 0x1 0x0
+#define MX50_PAD_UART2_RXD__ESDHC4_DAT7                                0x098 0x344 0x76c 0x4 0x0
+#define MX50_PAD_UART2_RXD__ESDHC4_DAT5                                0x098 0x344 0x764 0x5 0x1
+#define MX50_PAD_UART2_RXD__USBPHY2_DATAOUT_11                 0x098 0x344 0x000 0x7 0x0
+#define MX50_PAD_UART2_CTS__UART2_CTS                          0x09c 0x348 0x000 0x0 0x0
+#define MX50_PAD_UART2_CTS__GPIO6_12                           0x09c 0x348 0x000 0x1 0x0
+#define MX50_PAD_UART2_CTS__ESDHC4_CMD                         0x09c 0x348 0x74c 0x4 0x1
+#define MX50_PAD_UART2_CTS__ESDHC4_DAT6                                0x09c 0x348 0x768 0x5 0x1
+#define MX50_PAD_UART2_CTS__USBPHY2_DATAOUT_12                 0x09c 0x348 0x000 0x7 0x0
+#define MX50_PAD_UART2_RTS__UART2_RTS                          0x0a0 0x34c 0x7c8 0x0 0x2
+#define MX50_PAD_UART2_RTS__GPIO6_13                           0x0a0 0x34c 0x000 0x1 0x0
+#define MX50_PAD_UART2_RTS__ESDHC4_CLK                         0x0a0 0x34c 0x748 0x4 0x1
+#define MX50_PAD_UART2_RTS__ESDHC4_DAT7                                0x0a0 0x34c 0x76c 0x5 0x1
+#define MX50_PAD_UART2_RTS__USBPHY2_DATAOUT_13                 0x0a0 0x34c 0x000 0x7 0x0
+#define MX50_PAD_UART3_TXD__UART3_TXD_MUX                      0x0a4 0x350 0x7d4 0x0 0x0
+#define MX50_PAD_UART3_TXD__GPIO6_14                           0x0a4 0x350 0x000 0x1 0x0
+#define MX50_PAD_UART3_TXD__ESDHC1_DAT4                                0x0a4 0x350 0x000 0x3 0x0
+#define MX50_PAD_UART3_TXD__ESDHC4_DAT0                                0x0a4 0x350 0x000 0x4 0x0
+#define MX50_PAD_UART3_TXD__ESDHC2_WP                          0x0a4 0x350 0x744 0x5 0x0
+#define MX50_PAD_UART3_TXD__EIM_WEIM_D_12                      0x0a4 0x350 0x81c 0x6 0x0
+#define MX50_PAD_UART3_TXD__USBPHY2_DATAOUT_14                 0x0a4 0x350 0x000 0x7 0x0
+#define MX50_PAD_UART3_RXD__UART3_RXD_MUX                      0x0a8 0x354 0x7d4 0x0 0x1
+#define MX50_PAD_UART3_RXD__GPIO6_15                           0x0a8 0x354 0x000 0x1 0x0
+#define MX50_PAD_UART3_RXD__ESDHC1_DAT5                                0x0a8 0x354 0x000 0x3 0x0
+#define MX50_PAD_UART3_RXD__ESDHC4_DAT1                                0x0a8 0x354 0x754 0x4 0x0
+#define MX50_PAD_UART3_RXD__ESDHC2_CD                          0x0a8 0x354 0x740 0x5 0x0
+#define MX50_PAD_UART3_RXD__EIM_WEIM_D_13                      0x0a8 0x354 0x820 0x6 0x0
+#define MX50_PAD_UART3_RXD__USBPHY2_DATAOUT_15                 0x0a8 0x354 0x000 0x7 0x0
+#define MX50_PAD_UART4_TXD__UART4_TXD_MUX                      0x0ac 0x358 0x7dc 0x0 0x0
+#define MX50_PAD_UART4_TXD__GPIO6_16                           0x0ac 0x358 0x000 0x1 0x0
+#define MX50_PAD_UART4_TXD__UART3_CTS                          0x0ac 0x358 0x7d0 0x2 0x0
+#define MX50_PAD_UART4_TXD__ESDHC1_DAT6                                0x0ac 0x358 0x000 0x3 0x0
+#define MX50_PAD_UART4_TXD__ESDHC4_DAT2                                0x0ac 0x358 0x758 0x4 0x0
+#define MX50_PAD_UART4_TXD__ESDHC2_LCTL                                0x0ac 0x358 0x000 0x5 0x0
+#define MX50_PAD_UART4_TXD__EIM_WEIM_D_14                      0x0ac 0x358 0x824 0x6 0x0
+#define MX50_PAD_UART4_RXD__UART4_RXD_MUX                      0x0b0 0x35c 0x7dc 0x0 0x1
+#define MX50_PAD_UART4_RXD__GPIO6_17                           0x0b0 0x35c 0x000 0x1 0x0
+#define MX50_PAD_UART4_RXD__UART3_RTS                          0x0b0 0x35c 0x7d0 0x2 0x1
+#define MX50_PAD_UART4_RXD__ESDHC1_DAT7                                0x0b0 0x35c 0x000 0x3 0x0
+#define MX50_PAD_UART4_RXD__ESDHC4_DAT3                                0x0b0 0x35c 0x75c 0x4 0x0
+#define MX50_PAD_UART4_RXD__ESDHC1_LCTL                                0x0b0 0x35c 0x000 0x5 0x0
+#define MX50_PAD_UART4_RXD__EIM_WEIM_D_15                      0x0b0 0x35c 0x828 0x6 0x0
+#define MX50_PAD_CSPI_SCLK__CSPI_SCLK                          0x0b4 0x360 0x000 0x0 0x0
+#define MX50_PAD_CSPI_SCLK__GPIO4_8                            0x0b4 0x360 0x000 0x1 0x0
+#define MX50_PAD_CSPI_MOSI__CSPI_MOSI                          0x0b8 0x364 0x000 0x0 0x0
+#define MX50_PAD_CSPI_MOSI__GPIO4_9                            0x0b8 0x364 0x000 0x1 0x0
+#define MX50_PAD_CSPI_MISO__CSPI_MISO                          0x0bc 0x368 0x000 0x0 0x0
+#define MX50_PAD_CSPI_MISO__GPIO4_10                           0x0bc 0x368 0x000 0x1 0x0
+#define MX50_PAD_CSPI_SS0__CSPI_SS0                            0x0c0 0x36c 0x000 0x0 0x0
+#define MX50_PAD_CSPI_SS0__GPIO4_11                            0x0c0 0x36c 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_SCLK__ECSPI1_SCLK                      0x0c4 0x370 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_SCLK__GPIO4_12                         0x0c4 0x370 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_SCLK__CSPI_RDY                         0x0c4 0x370 0x6e8 0x2 0x1
+#define MX50_PAD_ECSPI1_SCLK__ECSPI2_RDY                       0x0c4 0x370 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_SCLK__UART3_RTS                                0x0c4 0x370 0x7d0 0x4 0x2
+#define MX50_PAD_ECSPI1_SCLK__EPDC_SDCE_6                      0x0c4 0x370 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_SCLK__EIM_WEIM_D_8                     0x0c4 0x370 0x80c 0x7 0x0
+#define MX50_PAD_ECSPI1_MOSI__ECSPI1_MOSI                      0x0c8 0x374 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_MOSI__GPIO4_13                         0x0c8 0x374 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_MOSI__CSPI_SS1                         0x0c8 0x374 0x6ec 0x2 0x1
+#define MX50_PAD_ECSPI1_MOSI__ECSPI2_SS1                       0x0c8 0x374 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_MOSI__UART3_CTS                                0x0c8 0x374 0x000 0x4 0x0
+#define MX50_PAD_ECSPI1_MOSI__EPDC_SDCE_7                      0x0c8 0x374 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_MOSI__EIM_WEIM_D_9                     0x0c8 0x374 0x810 0x7 0x0
+#define MX50_PAD_ECSPI1_MISO__ECSPI1_MISO                      0x0cc 0x378 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_MISO__GPIO4_14                         0x0cc 0x378 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_MISO__CSPI_SS2                         0x0cc 0x378 0x6f0 0x2 0x1
+#define MX50_PAD_ECSPI1_MISO__ECSPI2_SS2                       0x0cc 0x378 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_MISO__UART4_RTS                                0x0cc 0x378 0x7d8 0x4 0x0
+#define MX50_PAD_ECSPI1_MISO__EPDC_SDCE_8                      0x0cc 0x378 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_MISO__EIM_WEIM_D_10                    0x0cc 0x378 0x814 0x7 0x0
+#define MX50_PAD_ECSPI1_SS0__ECSPI1_SS0                                0x0d0 0x37c 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_SS0__GPIO4_15                          0x0d0 0x37c 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_SS0__CSPI_SS3                          0x0d0 0x37c 0x6f4 0x2 0x1
+#define MX50_PAD_ECSPI1_SS0__ECSPI2_SS3                                0x0d0 0x37c 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_SS0__UART4_CTS                         0x0d0 0x37c 0x000 0x4 0x0
+#define MX50_PAD_ECSPI1_SS0__EPDC_SDCE_9                       0x0d0 0x37c 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_SS0__EIM_WEIM_D_11                     0x0d0 0x37c 0x818 0x7 0x0
+#define MX50_PAD_ECSPI2_SCLK__ECSPI2_SCLK                      0x0d4 0x380 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_SCLK__GPIO4_16                         0x0d4 0x380 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_WR_RWN                    0x0d4 0x380 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_SCLK__ECSPI1_RDY                       0x0d4 0x380 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_SCLK__UART5_RTS                                0x0d4 0x380 0x7e0 0x4 0x0
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_DOTCLK                    0x0d4 0x380 0x000 0x5 0x0
+#define MX50_PAD_ECSPI2_SCLK__EIM_NANDF_CEN_4                  0x0d4 0x380 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_SCLK__EIM_WEIM_D_8                     0x0d4 0x380 0x80c 0x7 0x1
+#define MX50_PAD_ECSPI2_MOSI__ECSPI2_MOSI                      0x0d8 0x384 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_MOSI__GPIO4_17                         0x0d8 0x384 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_RE_E                      0x0d8 0x384 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_MOSI__ECSPI1_SS1                       0x0d8 0x384 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_MOSI__UART5_CTS                                0x0d8 0x384 0x7e0 0x4 0x1
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_ENABLE                    0x0d8 0x384 0x000 0x5 0x0
+#define MX50_PAD_ECSPI2_MOSI__EIM_NANDF_CEN_5                  0x0d8 0x384 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_MOSI__EIM_WEIM_D_9                     0x0d8 0x384 0x810 0x7 0x1
+#define MX50_PAD_ECSPI2_MISO__ECSPI2_MISO                      0x0dc 0x388 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_MISO__GPIO4_18                         0x0dc 0x388 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_RS                                0x0dc 0x388 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_MISO__ECSPI1_SS2                       0x0dc 0x388 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_MISO__UART5_TXD_MUX                    0x0dc 0x388 0x7e4 0x4 0x4
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_VSYNC                     0x0dc 0x388 0x73c 0x5 0x0
+#define MX50_PAD_ECSPI2_MISO__EIM_NANDF_CEN_6                  0x0dc 0x388 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_MISO__EIM_WEIM_D_10                    0x0dc 0x388 0x814 0x7 0x1
+#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS0                                0x0e0 0x38c 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_SS0__GPIO4_19                          0x0e0 0x38c 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_CS                         0x0e0 0x38c 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS3                                0x0e0 0x38c 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_SS0__UART5_RXD_MUX                     0x0e0 0x38c 0x7e4 0x4 0x5
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_HSYNC                      0x0e0 0x38c 0x6f8 0x5 0x0
+#define MX50_PAD_ECSPI2_SS0__EIM_NANDF_CEN_7                   0x0e0 0x38c 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_SS0__EIM_WEIM_D_11                     0x0e0 0x38c 0x818 0x7 0x1
+#define MX50_PAD_SD1_CLK__ESDHC1_CLK                           0x0e4 0x390 0x000 0x0 0x0
+#define MX50_PAD_SD1_CLK__GPIO5_0                              0x0e4 0x390 0x000 0x1 0x0
+#define MX50_PAD_SD1_CLK__CCM_CLKO                             0x0e4 0x390 0x000 0x7 0x0
+#define MX50_PAD_SD1_CMD__ESDHC1_CMD                           0x0e8 0x394 0x000 0x0 0x0
+#define MX50_PAD_SD1_CMD__GPIO5_1                              0x0e8 0x394 0x000 0x1 0x0
+#define MX50_PAD_SD1_CMD__CCM_CLKO2                            0x0e8 0x394 0x000 0x7 0x0
+#define MX50_PAD_SD1_D0__ESDHC1_DAT0                           0x0ec 0x398 0x000 0x0 0x0
+#define MX50_PAD_SD1_D0__GPIO5_2                               0x0ec 0x398 0x000 0x1 0x0
+#define MX50_PAD_SD1_D0__CCM_PLL1_BYP                          0x0ec 0x398 0x6dc 0x7 0x0
+#define MX50_PAD_SD1_D1__ESDHC1_DAT1                           0x0f0 0x39c 0x000 0x0 0x0
+#define MX50_PAD_SD1_D1__GPIO5_3                               0x0f0 0x39c 0x000 0x1 0x0
+#define MX50_PAD_SD1_D1__CCM_PLL2_BYP                          0x0f0 0x39c 0x000 0x7 0x0
+#define MX50_PAD_SD1_D2__ESDHC1_DAT2                           0x0f4 0x3a0 0x000 0x0 0x0
+#define MX50_PAD_SD1_D2__GPIO5_4                               0x0f4 0x3a0 0x000 0x1 0x0
+#define MX50_PAD_SD1_D2__CCM_PLL3_BYP                          0x0f4 0x3a0 0x6e4 0x7 0x0
+#define MX50_PAD_SD1_D3__ESDHC1_DAT3                           0x0f8 0x3a4 0x000 0x0 0x0
+#define MX50_PAD_SD1_D3__GPIO5_5                               0x0f8 0x3a4 0x000 0x1 0x0
+#define MX50_PAD_SD2_CLK__ESDHC2_CLK                           0x0fc 0x3a8 0x000 0x0 0x0
+#define MX50_PAD_SD2_CLK__GPIO5_6                              0x0fc 0x3a8 0x000 0x1 0x0
+#define MX50_PAD_SD2_CLK__MSHC_SCLK                            0x0fc 0x3a8 0x000 0x2 0x0
+#define MX50_PAD_SD2_CMD__ESDHC2_CMD                           0x100 0x3ac 0x000 0x0 0x0
+#define MX50_PAD_SD2_CMD__GPIO5_7                              0x100 0x3ac 0x000 0x1 0x0
+#define MX50_PAD_SD2_CMD__MSHC_BS                              0x100 0x3ac 0x000 0x2 0x0
+#define MX50_PAD_SD2_D0__ESDHC2_DAT0                           0x104 0x3b0 0x000 0x0 0x0
+#define MX50_PAD_SD2_D0__GPIO5_8                               0x104 0x3b0 0x000 0x1 0x0
+#define MX50_PAD_SD2_D0__MSHC_DATA_0                           0x104 0x3b0 0x000 0x2 0x0
+#define MX50_PAD_SD2_D0__KPP_COL_4                             0x104 0x3b0 0x790 0x3 0x0
+#define MX50_PAD_SD2_D1__ESDHC2_DAT1                           0x108 0x3b4 0x000 0x0 0x0
+#define MX50_PAD_SD2_D1__GPIO5_9                               0x108 0x3b4 0x000 0x1 0x0
+#define MX50_PAD_SD2_D1__MSHC_DATA_1                           0x108 0x3b4 0x000 0x2 0x0
+#define MX50_PAD_SD2_D1__KPP_ROW_4                             0x108 0x3b4 0x7a0 0x3 0x0
+#define MX50_PAD_SD2_D2__ESDHC2_DAT2                           0x10c 0x3b8 0x000 0x0 0x0
+#define MX50_PAD_SD2_D2__GPIO5_10                              0x10c 0x3b8 0x000 0x1 0x0
+#define MX50_PAD_SD2_D2__MSHC_DATA_2                           0x10c 0x3b8 0x000 0x2 0x0
+#define MX50_PAD_SD2_D2__KPP_COL_5                             0x10c 0x3b8 0x794 0x3 0x0
+#define MX50_PAD_SD2_D3__ESDHC2_DAT3                           0x110 0x3bc 0x000 0x0 0x0
+#define MX50_PAD_SD2_D3__GPIO5_11                              0x110 0x3bc 0x000 0x1 0x0
+#define MX50_PAD_SD2_D3__MSHC_DATA_3                           0x110 0x3bc 0x000 0x2 0x0
+#define MX50_PAD_SD2_D3__KPP_ROW_5                             0x110 0x3bc 0x7a4 0x3 0x0
+#define MX50_PAD_SD2_D4__ESDHC2_DAT4                           0x114 0x3c0 0x000 0x0 0x0
+#define MX50_PAD_SD2_D4__GPIO5_12                              0x114 0x3c0 0x000 0x1 0x0
+#define MX50_PAD_SD2_D4__AUDMUX_AUD4_RXFS                      0x114 0x3c0 0x6d0 0x2 0x0
+#define MX50_PAD_SD2_D4__KPP_COL_6                             0x114 0x3c0 0x798 0x3 0x0
+#define MX50_PAD_SD2_D4__EIM_WEIM_D_0                          0x114 0x3c0 0x7ec 0x4 0x0
+#define MX50_PAD_SD2_D4__CCM_CCM_OUT_0                         0x114 0x3c0 0x000 0x7 0x0
+#define MX50_PAD_SD2_D5__ESDHC2_DAT5                           0x118 0x3c4 0x000 0x0 0x0
+#define MX50_PAD_SD2_D5__GPIO5_13                              0x118 0x3c4 0x000 0x1 0x0
+#define MX50_PAD_SD2_D5__AUDMUX_AUD4_RXC                       0x118 0x3c4 0x6cc 0x2 0x0
+#define MX50_PAD_SD2_D5__KPP_ROW_6                             0x118 0x3c4 0x7a8 0x3 0x0
+#define MX50_PAD_SD2_D5__EIM_WEIM_D_1                          0x118 0x3c4 0x7f0 0x4 0x0
+#define MX50_PAD_SD2_D5__CCM_CCM_OUT_1                         0x118 0x3c4 0x000 0x7 0x0
+#define MX50_PAD_SD2_D6__ESDHC2_DAT6                           0x11c 0x3c8 0x000 0x0 0x0
+#define MX50_PAD_SD2_D6__GPIO5_14                              0x11c 0x3c8 0x000 0x1 0x0
+#define MX50_PAD_SD2_D6__AUDMUX_AUD4_RXD                       0x11c 0x3c8 0x6c4 0x2 0x0
+#define MX50_PAD_SD2_D6__KPP_COL_7                             0x11c 0x3c8 0x79c 0x3 0x0
+#define MX50_PAD_SD2_D6__EIM_WEIM_D_2                          0x11c 0x3c8 0x7f4 0x4 0x0
+#define MX50_PAD_SD2_D6__CCM_CCM_OUT_2                         0x11c 0x3c8 0x000 0x7 0x0
+#define MX50_PAD_SD2_D7__ESDHC2_DAT7                           0x120 0x3cc 0x000 0x0 0x0
+#define MX50_PAD_SD2_D7__GPIO5_15                              0x120 0x3cc 0x000 0x1 0x0
+#define MX50_PAD_SD2_D7__AUDMUX_AUD4_TXFS                      0x120 0x3cc 0x6d8 0x2 0x0
+#define MX50_PAD_SD2_D7__KPP_ROW_7                             0x120 0x3cc 0x7ac 0x3 0x0
+#define MX50_PAD_SD2_D7__EIM_WEIM_D_3                          0x120 0x3cc 0x7f8 0x4 0x0
+#define MX50_PAD_SD2_D7__CCM_STOP                              0x120 0x3cc 0x000 0x7 0x0
+#define MX50_PAD_SD2_WP__ESDHC2_WP                             0x124 0x3d0 0x744 0x0 0x1
+#define MX50_PAD_SD2_WP__GPIO5_16                              0x124 0x3d0 0x000 0x1 0x0
+#define MX50_PAD_SD2_WP__AUDMUX_AUD4_TXD                       0x124 0x3d0 0x6c8 0x2 0x0
+#define MX50_PAD_SD2_WP__EIM_WEIM_D_4                          0x124 0x3d0 0x7fc 0x4 0x0
+#define MX50_PAD_SD2_WP__CCM_WAIT                              0x124 0x3d0 0x000 0x7 0x0
+#define MX50_PAD_SD2_CD__ESDHC2_CD                             0x128 0x3d4 0x740 0x0 0x1
+#define MX50_PAD_SD2_CD__GPIO5_17                              0x128 0x3d4 0x000 0x1 0x0
+#define MX50_PAD_SD2_CD__AUDMUX_AUD4_TXC                       0x128 0x3d4 0x6d4 0x2 0x0
+#define MX50_PAD_SD2_CD__EIM_WEIM_D_5                          0x128 0x3d4 0x800 0x4 0x0
+#define MX50_PAD_SD2_CD__CCM_REF_EN_B                          0x128 0x3d4 0x000 0x7 0x0
+#define MX50_PAD_DISP_D0__ELCDIF_DAT_0                         0x12c 0x40c 0x6fc 0x0 0x0
+#define MX50_PAD_DISP_D0__GPIO2_0                              0x12c 0x40c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D0__FEC_TX_CLK                           0x12c 0x40c 0x78c 0x2 0x0
+#define MX50_PAD_DISP_D0__EIM_WEIM_A_16                                0x12c 0x40c 0x000 0x3 0x0
+#define MX50_PAD_DISP_D0__SDMA_DEBUG_PC_0                      0x12c 0x40c 0x000 0x6 0x0
+#define MX50_PAD_DISP_D0__USBPHY1_VSTATUS_0                    0x12c 0x40c 0x000 0x7 0x0
+#define MX50_PAD_DISP_D1__ELCDIF_DAT_1                         0x130 0x410 0x700 0x0 0x0
+#define MX50_PAD_DISP_D1__GPIO2_1                              0x130 0x410 0x000 0x1 0x0
+#define MX50_PAD_DISP_D1__FEC_RX_ERR                           0x130 0x410 0x788 0x2 0x0
+#define MX50_PAD_DISP_D1__EIM_WEIM_A_17                                0x130 0x410 0x000 0x3 0x0
+#define MX50_PAD_DISP_D1__SDMA_DEBUG_PC_1                      0x130 0x410 0x000 0x6 0x0
+#define MX50_PAD_DISP_D1__USBPHY1_VSTATUS_1                    0x130 0x410 0x000 0x7 0x0
+#define MX50_PAD_DISP_D2__ELCDIF_DAT_2                         0x134 0x414 0x704 0x0 0x0
+#define MX50_PAD_DISP_D2__GPIO2_2                              0x134 0x414 0x000 0x1 0x0
+#define MX50_PAD_DISP_D2__FEC_RX_DV                            0x134 0x414 0x784 0x2 0x0
+#define MX50_PAD_DISP_D2__EIM_WEIM_A_18                                0x134 0x414 0x000 0x3 0x0
+#define MX50_PAD_DISP_D2__SDMA_DEBUG_PC_2                      0x134 0x414 0x000 0x6 0x0
+#define MX50_PAD_DISP_D2__USBPHY1_VSTATUS_2                    0x134 0x414 0x000 0x7 0x0
+#define MX50_PAD_DISP_D3__ELCDIF_DAT_3                         0x138 0x418 0x708 0x0 0x0
+#define MX50_PAD_DISP_D3__GPIO2_3                              0x138 0x418 0x000 0x1 0x0
+#define MX50_PAD_DISP_D3__FEC_RDATA_1                          0x138 0x418 0x77c 0x2 0x0
+#define MX50_PAD_DISP_D3__EIM_WEIM_A_19                                0x138 0x418 0x000 0x3 0x0
+#define MX50_PAD_DISP_D3__FEC_COL                              0x138 0x418 0x770 0x4 0x1
+#define MX50_PAD_DISP_D3__SDMA_DEBUG_PC_3                      0x138 0x418 0x000 0x6 0x0
+#define MX50_PAD_DISP_D3__USBPHY1_VSTATUS_3                    0x138 0x418 0x000 0x7 0x0
+#define MX50_PAD_DISP_D4__ELCDIF_DAT_4                         0x13c 0x41c 0x70c 0x0 0x0
+#define MX50_PAD_DISP_D4__GPIO2_4                              0x13c 0x41c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D4__FEC_RDATA_0                          0x13c 0x41c 0x778 0x2 0x0
+#define MX50_PAD_DISP_D4__EIM_WEIM_A_20                                0x13c 0x41c 0x000 0x3 0x0
+#define MX50_PAD_DISP_D4__SDMA_DEBUG_PC_4                      0x13c 0x41c 0x000 0x6 0x0
+#define MX50_PAD_DISP_D4__USBPHY1_VSTATUS_4                    0x13c 0x41c 0x000 0x7 0x0
+#define MX50_PAD_DISP_D5__ELCDIF_DAT_5                         0x140 0x420 0x710 0x0 0x0
+#define MX50_PAD_DISP_D5__GPIO2_5                              0x140 0x420 0x000 0x1 0x0
+#define MX50_PAD_DISP_D5__FEC_TX_EN                            0x140 0x420 0x000 0x2 0x0
+#define MX50_PAD_DISP_D5__EIM_WEIM_A_21                                0x140 0x420 0x000 0x3 0x0
+#define MX50_PAD_DISP_D5__SDMA_DEBUG_PC_5                      0x140 0x420 0x000 0x6 0x0
+#define MX50_PAD_DISP_D5__USBPHY1_VSTATUS_5                    0x140 0x420 0x000 0x7 0x0
+#define MX50_PAD_DISP_D6__ELCDIF_DAT_6                         0x144 0x424 0x714 0x0 0x0
+#define MX50_PAD_DISP_D6__GPIO2_6                              0x144 0x424 0x000 0x1 0x0
+#define MX50_PAD_DISP_D6__FEC_TDATA_1                          0x144 0x424 0x000 0x2 0x0
+#define MX50_PAD_DISP_D6__EIM_WEIM_A_22                                0x144 0x424 0x000 0x3 0x0
+#define MX50_PAD_DISP_D6__FEC_RX_CLK                           0x144 0x424 0x780 0x4 0x1
+#define MX50_PAD_DISP_D6__SDMA_DEBUG_PC_6                      0x144 0x424 0x000 0x6 0x0
+#define MX50_PAD_DISP_D6__USBPHY1_VSTATUS_6                    0x144 0x424 0x000 0x7 0x0
+#define MX50_PAD_DISP_D7__ELCDIF_DAT_7                         0x148 0x428 0x718 0x0 0x0
+#define MX50_PAD_DISP_D7__GPIO2_7                              0x148 0x428 0x000 0x1 0x0
+#define MX50_PAD_DISP_D7__FEC_TDATA_0                          0x148 0x428 0x000 0x2 0x0
+#define MX50_PAD_DISP_D7__EIM_WEIM_A_23                                0x148 0x428 0x000 0x3 0x0
+#define MX50_PAD_DISP_D7__SDMA_DEBUG_PC_7                      0x148 0x428 0x000 0x6 0x0
+#define MX50_PAD_DISP_D7__USBPHY1_VSTATUS_7                    0x148 0x428 0x000 0x7 0x0
+#define MX50_PAD_DISP_WR__ELCDIF_WR_RWN                                0x14c 0x42c 0x000 0x0 0x0
+#define MX50_PAD_DISP_WR__GPIO2_16                             0x14c 0x42c 0x000 0x1 0x0
+#define MX50_PAD_DISP_WR__ELCDIF_DOTCLK                                0x14c 0x42c 0x000 0x2 0x0
+#define MX50_PAD_DISP_WR__EIM_WEIM_A_24                                0x14c 0x42c 0x000 0x3 0x0
+#define MX50_PAD_DISP_WR__SDMA_DEBUG_PC_8                      0x14c 0x42c 0x000 0x6 0x0
+#define MX50_PAD_DISP_WR__USBPHY1_AVALID                       0x14c 0x42c 0x000 0x7 0x0
+#define MX50_PAD_DISP_RD__ELCDIF_RD_E                          0x150 0x430 0x000 0x0 0x0
+#define MX50_PAD_DISP_RD__GPIO2_19                             0x150 0x430 0x000 0x1 0x0
+#define MX50_PAD_DISP_RD__ELCDIF_ENABLE                                0x150 0x430 0x000 0x2 0x0
+#define MX50_PAD_DISP_RD__EIM_WEIM_A_25                                0x150 0x430 0x000 0x3 0x0
+#define MX50_PAD_DISP_RD__SDMA_DEBUG_PC_9                      0x150 0x430 0x000 0x6 0x0
+#define MX50_PAD_DISP_RD__USBPHY1_BVALID                       0x150 0x430 0x000 0x7 0x0
+#define MX50_PAD_DISP_RS__ELCDIF_RS                            0x154 0x434 0x000 0x0 0x0
+#define MX50_PAD_DISP_RS__GPIO2_17                             0x154 0x434 0x000 0x1 0x0
+#define MX50_PAD_DISP_RS__ELCDIF_VSYNC                         0x154 0x434 0x73c 0x2 0x1
+#define MX50_PAD_DISP_RS__EIM_WEIM_A_26                                0x154 0x434 0x000 0x3 0x0
+#define MX50_PAD_DISP_RS__SDMA_DEBUG_PC_10                     0x154 0x434 0x000 0x6 0x0
+#define MX50_PAD_DISP_RS__USBPHY1_ENDSESSION                   0x154 0x434 0x000 0x7 0x0
+#define MX50_PAD_DISP_CS__ELCDIF_CS                            0x158 0x438 0x000 0x0 0x0
+#define MX50_PAD_DISP_CS__GPIO2_21                             0x158 0x438 0x000 0x1 0x0
+#define MX50_PAD_DISP_CS__ELCDIF_HSYNC                         0x158 0x438 0x6f8 0x2 0x1
+#define MX50_PAD_DISP_CS__EIM_WEIM_A_27                                0x158 0x438 0x000 0x3 0x0
+#define MX50_PAD_DISP_CS__EIM_WEIM_CS_3                                0x158 0x438 0x000 0x4 0x0
+#define MX50_PAD_DISP_CS__SDMA_DEBUG_PC_11                     0x158 0x438 0x000 0x6 0x0
+#define MX50_PAD_DISP_CS__USBPHY1_IDDIG                                0x158 0x438 0x000 0x7 0x0
+#define MX50_PAD_DISP_BUSY__ELCDIF_BUSY                                0x15c 0x43c 0x6f8 0x0 0x2
+#define MX50_PAD_DISP_BUSY__GPIO2_18                           0x15c 0x43c 0x000 0x1 0x0
+#define MX50_PAD_DISP_BUSY__EIM_WEIM_CS_3                      0x15c 0x43c 0x000 0x4 0x0
+#define MX50_PAD_DISP_BUSY__SDMA_DEBUG_PC_12                   0x15c 0x43c 0x000 0x6 0x0
+#define MX50_PAD_DISP_BUSY__USBPHY2_HOSTDISCONNECT             0x15c 0x43c 0x000 0x7 0x0
+#define MX50_PAD_DISP_RESET__ELCDIF_RESET                      0x160 0x440 0x000 0x0 0x0
+#define MX50_PAD_DISP_RESET__GPIO2_20                          0x160 0x440 0x000 0x1 0x0
+#define MX50_PAD_DISP_RESET__EIM_WEIM_CS_3                     0x160 0x440 0x000 0x4 0x0
+#define MX50_PAD_DISP_RESET__SDMA_DEBUG_PC_13                  0x160 0x440 0x000 0x6 0x0
+#define MX50_PAD_DISP_RESET__USBPHY2_BISTOK                    0x160 0x440 0x000 0x7 0x0
+#define MX50_PAD_SD3_CMD__ESDHC3_CMD                           0x164 0x444 0x000 0x0 0x0
+#define MX50_PAD_SD3_CMD__GPIO5_18                             0x164 0x444 0x000 0x1 0x0
+#define MX50_PAD_SD3_CMD__EIM_NANDF_WRN                                0x164 0x444 0x000 0x2 0x0
+#define MX50_PAD_SD3_CMD__SSP_CMD                              0x164 0x444 0x000 0x3 0x0
+#define MX50_PAD_SD3_CLK__ESDHC3_CLK                           0x168 0x448 0x000 0x0 0x0
+#define MX50_PAD_SD3_CLK__GPIO5_19                             0x168 0x448 0x000 0x1 0x0
+#define MX50_PAD_SD3_CLK__EIM_NANDF_RDN                                0x168 0x448 0x000 0x2 0x0
+#define MX50_PAD_SD3_CLK__SSP_CLK                              0x168 0x448 0x000 0x3 0x0
+#define MX50_PAD_SD3_D0__ESDHC3_DAT0                           0x16c 0x44c 0x000 0x0 0x0
+#define MX50_PAD_SD3_D0__GPIO5_20                              0x16c 0x44c 0x000 0x1 0x0
+#define MX50_PAD_SD3_D0__EIM_NANDF_D_4                         0x16c 0x44c 0x000 0x2 0x0
+#define MX50_PAD_SD3_D0__SSP_D0                                        0x16c 0x44c 0x000 0x3 0x0
+#define MX50_PAD_SD3_D0__CCM_PLL1_BYP                          0x16c 0x44c 0x6dc 0x7 0x1
+#define MX50_PAD_SD3_D1__ESDHC3_DAT1                           0x170 0x450 0x000 0x0 0x0
+#define MX50_PAD_SD3_D1__GPIO5_21                              0x170 0x450 0x000 0x1 0x0
+#define MX50_PAD_SD3_D1__EIM_NANDF_D_5                         0x170 0x450 0x000 0x2 0x0
+#define MX50_PAD_SD3_D1__SSP_D1                                        0x170 0x450 0x000 0x3 0x0
+#define MX50_PAD_SD3_D1__CCM_PLL2_BYP                          0x170 0x450 0x000 0x7 0x0
+#define MX50_PAD_SD3_D2__ESDHC3_DAT2                           0x174 0x454 0x000 0x0 0x0
+#define MX50_PAD_SD3_D2__GPIO5_22                              0x174 0x454 0x000 0x1 0x0
+#define MX50_PAD_SD3_D2__EIM_NANDF_D_6                         0x174 0x454 0x000 0x2 0x0
+#define MX50_PAD_SD3_D2__SSP_D2                                        0x174 0x454 0x000 0x3 0x0
+#define MX50_PAD_SD3_D2__CCM_PLL3_BYP                          0x174 0x454 0x6e4 0x7 0x1
+#define MX50_PAD_SD3_D3__ESDHC3_DAT3                           0x178 0x458 0x000 0x0 0x0
+#define MX50_PAD_SD3_D3__GPIO5_23                              0x178 0x458 0x000 0x1 0x0
+#define MX50_PAD_SD3_D3__EIM_NANDF_D_7                         0x178 0x458 0x000 0x2 0x0
+#define MX50_PAD_SD3_D3__SSP_D3                                        0x178 0x458 0x000 0x3 0x0
+#define MX50_PAD_SD3_D4__ESDHC3_DAT4                           0x17c 0x45c 0x000 0x0 0x0
+#define MX50_PAD_SD3_D4__GPIO5_24                              0x17c 0x45c 0x000 0x1 0x0
+#define MX50_PAD_SD3_D4__EIM_NANDF_D_0                         0x17c 0x45c 0x000 0x2 0x0
+#define MX50_PAD_SD3_D4__SSP_D4                                        0x17c 0x45c 0x000 0x3 0x0
+#define MX50_PAD_SD3_D5__ESDHC3_DAT5                           0x180 0x460 0x000 0x0 0x0
+#define MX50_PAD_SD3_D5__GPIO5_25                              0x180 0x460 0x000 0x1 0x0
+#define MX50_PAD_SD3_D5__EIM_NANDF_D_1                         0x180 0x460 0x000 0x2 0x0
+#define MX50_PAD_SD3_D5__SSP_D5                                        0x180 0x460 0x000 0x3 0x0
+#define MX50_PAD_SD3_D6__ESDHC3_DAT6                           0x184 0x464 0x000 0x0 0x0
+#define MX50_PAD_SD3_D6__GPIO5_26                              0x184 0x464 0x000 0x1 0x0
+#define MX50_PAD_SD3_D6__EIM_NANDF_D_2                         0x184 0x464 0x000 0x2 0x0
+#define MX50_PAD_SD3_D6__SSP_D6                                        0x184 0x464 0x000 0x3 0x0
+#define MX50_PAD_SD3_D7__ESDHC3_DAT7                           0x188 0x468 0x000 0x0 0x0
+#define MX50_PAD_SD3_D7__GPIO5_27                              0x188 0x468 0x000 0x1 0x0
+#define MX50_PAD_SD3_D7__EIM_NANDF_D_3                         0x188 0x468 0x000 0x2 0x0
+#define MX50_PAD_SD3_D7__SSP_D7                                        0x188 0x468 0x000 0x3 0x0
+#define MX50_PAD_SD3_WP__ESDHC3_WP                             0x18c 0x46C 0x000 0x0 0x0
+#define MX50_PAD_SD3_WP__GPIO5_28                              0x18c 0x46C 0x000 0x1 0x0
+#define MX50_PAD_SD3_WP__EIM_NANDF_RESETN                      0x18c 0x46C 0x000 0x2 0x0
+#define MX50_PAD_SD3_WP__SSP_CD                                        0x18c 0x46C 0x000 0x3 0x0
+#define MX50_PAD_SD3_WP__ESDHC4_LCTL                           0x18c 0x46C 0x000 0x4 0x0
+#define MX50_PAD_SD3_WP__EIM_WEIM_CS_3                         0x18c 0x46C 0x000 0x5 0x0
+#define MX50_PAD_DISP_D8__ELCDIF_DAT_8                         0x190 0x470 0x71c 0x0 0x0
+#define MX50_PAD_DISP_D8__GPIO2_8                              0x190 0x470 0x000 0x1 0x0
+#define MX50_PAD_DISP_D8__EIM_NANDF_CLE                                0x190 0x470 0x000 0x2 0x0
+#define MX50_PAD_DISP_D8__ESDHC1_LCTL                          0x190 0x470 0x000 0x3 0x0
+#define MX50_PAD_DISP_D8__ESDHC4_CMD                           0x190 0x470 0x74c 0x4 0x2
+#define MX50_PAD_DISP_D8__KPP_COL_4                            0x190 0x470 0x790 0x5 0x1
+#define MX50_PAD_DISP_D8__FEC_TX_CLK                           0x190 0x470 0x78c 0x6 0x1
+#define MX50_PAD_DISP_D8__USBPHY1_DATAOUT_0                    0x190 0x470 0x000 0x7 0x0
+#define MX50_PAD_DISP_D9__ELCDIF_DAT_9                         0x194 0x474 0x720 0x0 0x0
+#define MX50_PAD_DISP_D9__GPIO2_9                              0x194 0x474 0x000 0x1 0x0
+#define MX50_PAD_DISP_D9__EIM_NANDF_ALE                                0x194 0x474 0x000 0x2 0x0
+#define MX50_PAD_DISP_D9__ESDHC2_LCTL                          0x194 0x474 0x000 0x3 0x0
+#define MX50_PAD_DISP_D9__ESDHC4_CLK                           0x194 0x474 0x748 0x4 0x2
+#define MX50_PAD_DISP_D9__KPP_ROW_4                            0x194 0x474 0x7a0 0x5 0x1
+#define MX50_PAD_DISP_D9__FEC_RX_ER                            0x194 0x474 0x788 0x6 0x1
+#define MX50_PAD_DISP_D9__USBPHY1_DATAOUT_1                    0x194 0x474 0x000 0x7 0x0
+#define MX50_PAD_DISP_D10__ELCDIF_DAT_10                       0x198 0x478 0x724 0x0 0x0
+#define MX50_PAD_DISP_D10__GPIO2_10                            0x198 0x478 0x000 0x1 0x0
+#define MX50_PAD_DISP_D10__EIM_NANDF_CEN_0                     0x198 0x478 0x000 0x2 0x0
+#define MX50_PAD_DISP_D10__ESDHC3_LCTL                         0x198 0x478 0x000 0x3 0x0
+#define MX50_PAD_DISP_D10__ESDHC4_DAT0                         0x198 0x478 0x000 0x4 0x0
+#define MX50_PAD_DISP_D10__KPP_COL_5                           0x198 0x478 0x794 0x5 0x1
+#define MX50_PAD_DISP_D10__FEC_RX_DV                           0x198 0x478 0x784 0x6 0x1
+#define MX50_PAD_DISP_D10__USBPHY1_DATAOUT_2                   0x198 0x478 0x000 0x7 0x0
+#define MX50_PAD_DISP_D11__ELCDIF_DAT_11                       0x19c 0x47c 0x728 0x0 0x0
+#define MX50_PAD_DISP_D11__GPIO2_11                            0x19c 0x47c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D11__EIM_NANDF_CEN_1                     0x19c 0x47c 0x000 0x2 0x0
+#define MX50_PAD_DISP_D11__ESDHC4_DAT1                         0x19c 0x47c 0x754 0x4 0x1
+#define MX50_PAD_DISP_D11__KPP_ROW_5                           0x19c 0x47c 0x7a4 0x5 0x1
+#define MX50_PAD_DISP_D11__FEC_RDATA_1                         0x19c 0x47c 0x77c 0x6 0x1
+#define MX50_PAD_DISP_D11__USBPHY1_DATAOUT_3                   0x19c 0x47c 0x000 0x7 0x0
+#define MX50_PAD_DISP_D12__ELCDIF_DAT_12                       0x1a0 0x480 0x72c 0x0 0x0
+#define MX50_PAD_DISP_D12__GPIO2_12                            0x1a0 0x480 0x000 0x1 0x0
+#define MX50_PAD_DISP_D12__EIM_NANDF_CEN_2                     0x1a0 0x480 0x000 0x2 0x0
+#define MX50_PAD_DISP_D12__ESDHC1_CD                           0x1a0 0x480 0x000 0x3 0x0
+#define MX50_PAD_DISP_D12__ESDHC4_DAT2                         0x1a0 0x480 0x758 0x4 0x1
+#define MX50_PAD_DISP_D12__KPP_COL_6                           0x1a0 0x480 0x798 0x5 0x1
+#define MX50_PAD_DISP_D12__FEC_RDATA_0                         0x1a0 0x480 0x778 0x6 0x1
+#define MX50_PAD_DISP_D12__USBPHY1_DATAOUT_4                   0x1a0 0x480 0x000 0x7 0x0
+#define MX50_PAD_DISP_D13__ELCDIF_DAT_13                       0x1a4 0x484 0x730 0x0 0x0
+#define MX50_PAD_DISP_D13__GPIO2_13                            0x1a4 0x484 0x000 0x1 0x0
+#define MX50_PAD_DISP_D13__EIM_NANDF_CEN_3                     0x1a4 0x484 0x000 0x2 0x0
+#define MX50_PAD_DISP_D13__ESDHC3_CD                           0x1a4 0x484 0x000 0x3 0x0
+#define MX50_PAD_DISP_D13__ESDHC4_DAT3                         0x1a4 0x484 0x75c 0x4 0x1
+#define MX50_PAD_DISP_D13__KPP_ROW_6                           0x1a4 0x484 0x7a8 0x5 0x1
+#define MX50_PAD_DISP_D13__FEC_TX_EN                           0x1a4 0x484 0x000 0x6 0x0
+#define MX50_PAD_DISP_D13__USBPHY1_DATAOUT_5                   0x1a4 0x484 0x000 0x7 0x0
+#define MX50_PAD_DISP_D14__ELCDIF_DAT_14                       0x1a8 0x488 0x734 0x0 0x0
+#define MX50_PAD_DISP_D14__GPIO2_14                            0x1a8 0x488 0x000 0x1 0x0
+#define MX50_PAD_DISP_D14__EIM_NANDF_READY0                    0x1a8 0x488 0x7b4 0x2 0x1
+#define MX50_PAD_DISP_D14__ESDHC1_WP                           0x1a8 0x488 0x000 0x3 0x0
+#define MX50_PAD_DISP_D14__ESDHC4_WP                           0x1a8 0x488 0x000 0x4 0x0
+#define MX50_PAD_DISP_D14__KPP_COL_7                           0x1a8 0x488 0x79c 0x5 0x1
+#define MX50_PAD_DISP_D14__FEC_TDATA_1                         0x1a8 0x488 0x000 0x6 0x0
+#define MX50_PAD_DISP_D14__USBPHY1_DATAOUT_6                   0x1a8 0x488 0x000 0x7 0x0
+#define MX50_PAD_DISP_D15__ELCDIF_DAT_15                       0x1ac 0x48c 0x738 0x0 0x0
+#define MX50_PAD_DISP_D15__GPIO2_15                            0x1ac 0x48c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D15__EIM_NANDF_DQS                       0x1ac 0x48c 0x7b0 0x2 0x1
+#define MX50_PAD_DISP_D15__ESDHC3_RST                          0x1ac 0x48c 0x000 0x3 0x0
+#define MX50_PAD_DISP_D15__ESDHC4_CD                           0x1ac 0x48c 0x000 0x4 0x0
+#define MX50_PAD_DISP_D15__KPP_ROW_7                           0x1ac 0x48c 0x7ac 0x5 0x1
+#define MX50_PAD_DISP_D15__FEC_TDATA_0                         0x1ac 0x48c 0x000 0x6 0x0
+#define MX50_PAD_DISP_D15__USBPHY1_DATAOUT_7                   0x1ac 0x48c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D0__EPDC_SDDO_0                          0x1b0 0x54c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D0__GPIO3_0                              0x1b0 0x54c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D0__EIM_WEIM_D_0                         0x1b0 0x54c 0x7ec 0x2 0x1
+#define MX50_PAD_EPDC_D0__ELCDIF_RS                            0x1b0 0x54c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D0__ELCDIF_DOTCLK                                0x1b0 0x54c 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D0__SDMA_DEBUG_EVT_CHN_LINES_0           0x1b0 0x54c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D0__USBPHY2_DATAOUT_0                    0x1b0 0x54c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D1__EPDC_SDDO_1                          0x1b4 0x550 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D1__GPIO3_1                              0x1b4 0x550 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D1__EIM_WEIM_D_1                         0x1b4 0x550 0x7f0 0x2 0x1
+#define MX50_PAD_EPDC_D1__ELCDIF_CS                            0x1b4 0x550 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D1__ELCDIF_ENABLE                                0x1b4 0x550 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D1__SDMA_DEBUG_EVT_CHN_LINES_1           0x1b4 0x550 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D1__USBPHY2_DATAOUT_1                    0x1b4 0x550 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D2__EPDC_SDDO_2                          0x1b8 0x554 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D2__GPIO3_2                              0x1b8 0x554 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D2__EIM_WEIM_D_2                         0x1b8 0x554 0x7f4 0x2 0x1
+#define MX50_PAD_EPDC_D2__ELCDIF_WR_RWN                                0x1b8 0x554 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D2__ELCDIF_VSYNC                         0x1b8 0x554 0x73c 0x4 0x2
+#define MX50_PAD_EPDC_D2__SDMA_DEBUG_EVT_CHN_LINES_2           0x1b8 0x554 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D2__USBPHY2_DATAOUT_2                    0x1b8 0x554 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D3__EPDC_SDDO_3                          0x1bc 0x558 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D3__GPIO3_3                              0x1bc 0x558 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D3__EIM_WEIM_D_3                         0x1bc 0x558 0x7f8 0x2 0x1
+#define MX50_PAD_EPDC_D3__ELCDIF_RD_E                          0x1bc 0x558 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D3__ELCDIF_HSYNC                         0x1bc 0x558 0x6f8 0x4 0x3
+#define MX50_PAD_EPDC_D3__SDMA_DEBUG_EVT_CHN_LINES_3           0x1bc 0x558 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D3__USBPHY2_DATAOUT_3                    0x1bc 0x558 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D4__EPDC_SDDO_4                          0x1c0 0x55c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D4__GPIO3_4                              0x1c0 0x55c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D4__EIM_WEIM_D_4                         0x1c0 0x55c 0x7fc 0x2 0x1
+#define MX50_PAD_EPDC_D4__SDMA_DEBUG_EVT_CHN_LINES_4           0x1c0 0x55c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D4__USBPHY2_DATAOUT_4                    0x1c0 0x55c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D5__EPDC_SDDO_5                          0x1c4 0x560 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D5__GPIO3_5                              0x1c4 0x560 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D5__EIM_WEIM_D_5                         0x1c4 0x560 0x800 0x2 0x1
+#define MX50_PAD_EPDC_D5__SDMA_DEBUG_EVT_CHN_LINES_5           0x1c4 0x560 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D5__USBPHY2_DATAOUT_5                    0x1c4 0x560 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D6__EPDC_SDDO_6                          0x1c8 0x564 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D6__GPIO3_6                              0x1c8 0x564 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D6__EIM_WEIM_D_6                         0x1c8 0x564 0x804 0x2 0x1
+#define MX50_PAD_EPDC_D6__SDMA_DEBUG_EVT_CHN_LINES_6           0x1c8 0x564 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D6__USBPHY2_DATAOUT_6                    0x1c8 0x564 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D7__EPDC_SDDO_7                          0x1cc 0x568 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D7__GPIO3_7                              0x1cc 0x568 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D7__EIM_WEIM_D_7                         0x1cc 0x568 0x808 0x2 0x1
+#define MX50_PAD_EPDC_D7__SDMA_DEBUG_EVT_CHN_LINES_7           0x1cc 0x568 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D7__USBPHY2_DATAOUT_7                    0x1cc 0x568 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D8__EPDC_SDDO_8                          0x1d0 0x56c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D8__GPIO3_8                              0x1d0 0x56c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D8__EIM_WEIM_D_8                         0x1d0 0x56c 0x80c 0x2 0x2
+#define MX50_PAD_EPDC_D8__ELCDIF_DAT_24                                0x1d0 0x56c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D8__SDMA_DEBUG_MATCHED_DMBUS             0x1d0 0x56c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D8__USBPHY2_VSTATUS_0                    0x1d0 0x56c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D9__EPDC_SDDO_9                          0x1d4 0x570 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D9__GPIO3_9                              0x1d4 0x570 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D9__EIM_WEIM_D_9                         0x1d4 0x570 0x810 0x2 0x2
+#define MX50_PAD_EPDC_D9__ELCDIF_DAT_25                                0x1d4 0x570 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D9__SDMA_DEBUG_EVENT_CHANNEL_SEL         0x1d4 0x570 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D9__USBPHY2_VSTATUS_1                    0x1d4 0x570 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D10__EPDC_SDDO_10                                0x1d8 0x574 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D10__GPIO3_10                            0x1d8 0x574 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D10__EIM_WEIM_D_10                       0x1d8 0x574 0x814 0x2 0x2
+#define MX50_PAD_EPDC_D10__ELCDIF_DAT_26                       0x1d8 0x574 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D10__SDMA_DEBUG_EVENT_CHANNEL_0          0x1d8 0x574 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D10__USBPHY2_VSTATUS_2                   0x1d8 0x574 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D11__EPDC_SDDO_11                                0x1dc 0x578 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D11__GPIO3_11                            0x1dc 0x578 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D11__EIM_WEIM_D_11                       0x1dc 0x578 0x818 0x2 0x2
+#define MX50_PAD_EPDC_D11__ELCDIF_DAT_27                       0x1dc 0x578 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D11__SDMA_DEBUG_EVENT_CHANNEL_1          0x1dc 0x578 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D11__USBPHY2_VSTATUS_3                   0x1dc 0x578 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D12__EPDC_SDDO_12                                0x1e0 0x57c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D12__GPIO3_12                            0x1e0 0x57c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D12__EIM_WEIM_D_12                       0x1e0 0x57c 0x81c 0x2 0x1
+#define MX50_PAD_EPDC_D12__ELCDIF_DAT_28                       0x1e0 0x57c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D12__SDMA_DEBUG_EVENT_CHANNEL_2          0x1e0 0x57c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D12__USBPHY2_VSTATUS_4                   0x1e0 0x57c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D13__EPDC_SDDO_13                                0x1e4 0x580 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D13__GPIO3_13                            0x1e4 0x580 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D13__EIM_WEIM_D_13                       0x1e4 0x580 0x820 0x2 0x1
+#define MX50_PAD_EPDC_D13__ELCDIF_DAT_29                       0x1e4 0x580 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D13__SDMA_DEBUG_EVENT_CHANNEL_3          0x1e4 0x580 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D13__USBPHY2_VSTATUS_5                   0x1e4 0x580 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D14__EPDC_SDDO_14                                0x1e8 0x584 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D14__GPIO3_14                            0x1e8 0x584 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D14__EIM_WEIM_D_14                       0x1e8 0x584 0x824 0x2 0x1
+#define MX50_PAD_EPDC_D14__ELCDIF_DAT_30                       0x1e8 0x584 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D14__AUDMUX_AUD6_TXD                     0x1e8 0x584 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D14__SDMA_DEBUG_EVENT_CHANNEL_4          0x1e8 0x584 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D14__USBPHY2_VSTATUS_6                   0x1e8 0x584 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D15__EPDC_SDDO_15                                0x1ec 0x588 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D15__GPIO3_15                            0x1ec 0x588 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D15__EIM_WEIM_D_15                       0x1ec 0x588 0x828 0x2 0x1
+#define MX50_PAD_EPDC_D15__ELCDIF_DAT_31                       0x1ec 0x588 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D15__AUDMUX_AUD6_TXC                     0x1ec 0x588 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D15__SDMA_DEBUG_EVENT_CHANNEL_5          0x1ec 0x588 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D15__USBPHY2_VSTATUS_7                   0x1ec 0x588 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDCLK__EPDC_GDCLK                                0x1f0 0x58c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDCLK__GPIO3_16                          0x1f0 0x58c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDCLK__EIM_WEIM_D_16                     0x1f0 0x58c 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDCLK__ELCDIF_DAT_16                     0x1f0 0x58c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDCLK__AUDMUX_AUD6_TXFS                  0x1f0 0x58c 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDCLK__SDMA_DEBUG_CORE_STATE_0           0x1f0 0x58c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDCLK__USBPHY2_BISTOK                    0x1f0 0x58c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDSP__EPCD_GDSP                          0x1f4 0x590 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDSP__GPIO3_17                           0x1f4 0x590 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDSP__EIM_WEIM_D_17                      0x1f4 0x590 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDSP__ELCDIF_DAT_17                      0x1f4 0x590 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDSP__AUDMUX_AUD6_RXD                    0x1f4 0x590 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDSP__SDMA_DEBUG_CORE_STATE_1            0x1f4 0x590 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDSP__USBPHY2_BVALID                     0x1f4 0x590 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDOE__EPCD_GDOE                          0x1f8 0x594 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDOE__GPIO3_18                           0x1f8 0x594 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDOE__EIM_WEIM_D_18                      0x1f8 0x594 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDOE__ELCDIF_DAT_18                      0x1f8 0x594 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDOE__AUDMUX_AUD6_RXC                    0x1f8 0x594 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDOE__SDMA_DEBUG_CORE_STATE_2            0x1f8 0x594 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDOE__USBPHY2_ENDSESSION                 0x1f8 0x594 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDRL__EPCD_GDRL                          0x1fc 0x598 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDRL__GPIO3_19                           0x1fc 0x598 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDRL__EIM_WEIM_D_19                      0x1f8 0x598 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDRL__ELCDIF_DAT_19                      0x1fc 0x598 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDRL__AUDMUX_AUD6_RXFS                   0x1fc 0x598 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDRL__SDMA_DEBUG_CORE_STATE_3            0x1fc 0x598 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDRL__USBPHY2_IDDIG                      0x1fc 0x598 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDCLK__EPCD_SDCLK                                0x200 0x59c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCLK__GPIO3_20                          0x200 0x59c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCLK__EIM_WEIM_D_20                     0x200 0x59c 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDCLK__ELCDIF_DAT_20                     0x200 0x59c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDCLK__AUDMUX_AUD5_TXD                   0x200 0x59c 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDCLK__SDMA_DEBUG_BUS_DEVICE_0           0x200 0x59c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDCLK__USBPHY2_HOSTDISCONNECT            0x200 0x59c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDOEZ__EPCD_SDOEZ                                0x204 0x5a0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDOEZ__GPIO3_21                          0x204 0x5a0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDOEZ__EIM_WEIM_D_21                     0x204 0x5a0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDOEZ__ELCDIF_DAT_21                     0x204 0x5a0 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDOEZ__AUDMUX_AUD5_TXC                   0x204 0x5a0 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDOEZ__SDMA_DEBUG_BUS_DEVICE_1           0x204 0x5a0 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDOEZ__USBPHY2_TXREADY                   0x204 0x5a0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDOED__EPCD_SDOED                                0x208 0x5a4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDOED__GPIO3_22                          0x208 0x5a4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDOED__EIM_WEIM_D_22                     0x208 0x5a4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDOED__ELCDIF_DAT_22                     0x208 0x5a4 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDOED__AUDMUX_AUD5_TXFS                  0x208 0x5a4 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDOED__SDMA_DEBUG_BUS_DEVICE_2           0x208 0x5a4 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDOED__USBPHY2_RXVALID                   0x208 0x5a4 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDOE__EPCD_SDOE                          0x20c 0x5a8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDOE__GPIO3_23                           0x20c 0x5a8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDOE__EIM_WEIM_D_23                      0x20c 0x5a8 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDOE__ELCDIF_DAT_23                      0x20c 0x5a8 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDOE__AUDMUX_AUD5_RXD                    0x20c 0x5a8 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDOE__SDMA_DEBUG_BUS_DEVICE_3            0x20c 0x5a8 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDOE__USBPHY2_RXACTIVE                   0x20c 0x5a8 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDLE__EPCD_SDLE                          0x210 0x5ac 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDLE__GPIO3_24                           0x210 0x5ac 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDLE__EIM_WEIM_D_24                      0x210 0x5ac 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDLE__ELCDIF_DAT_8                       0x210 0x5ac 0x71c 0x3 0x1
+#define MX50_PAD_EPDC_SDLE__AUDMUX_AUD5_RXC                    0x210 0x5ac 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDLE__SDMA_DEBUG_BUS_DEVICE_4            0x210 0x5ac 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDLE__USBPHY2_RXERROR                    0x210 0x5ac 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDCLKN__EPCD_SDCLKN                      0x214 0x5b0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCLKN__GPIO3_25                         0x214 0x5b0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCLKN__EIM_WEIM_D_25                    0x214 0x5b0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDCLKN__ELCDIF_DAT_9                     0x214 0x5b0 0x720 0x3 0x1
+#define MX50_PAD_EPDC_SDCLKN__AUDMUX_AUD5_RXFS                 0x214 0x5b0 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDCLKN__SDMA_DEBUG_BUS_ERROR             0x214 0x5b0 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDCLKN__USBPHY2_SIECLOCK                 0x214 0x5b0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDSHR__EPCD_SDSHR                                0x218 0x5b4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDSHR__GPIO3_26                          0x218 0x5b4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDSHR__EIM_WEIM_D_26                     0x218 0x5b4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDSHR__ELCDIF_DAT_10                     0x218 0x5b4 0x724 0x3 0x1
+#define MX50_PAD_EPDC_SDSHR__AUDMUX_AUD4_TXD                   0x218 0x5b4 0x6c8 0x4 0x1
+#define MX50_PAD_EPDC_SDSHR__SDMA_DEBUG_BUS_RWB                        0x218 0x5b4 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDSHR__USBPHY2_LINESTATE_0               0x218 0x5b4 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCOM__EPCD_PWRCOM                      0x21c 0x5b8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCOM__GPIO3_27                         0x21c 0x5b8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCOM__EIM_WEIM_D_27                    0x21c 0x5b8 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCOM__ELCDIF_DAT_11                    0x21c 0x5b8 0x728 0x3 0x1
+#define MX50_PAD_EPDC_PWRCOM__AUDMUX_AUD4_TXC                  0x21c 0x5b8 0x6d4 0x4 0x1
+#define MX50_PAD_EPDC_PWRCOM__SDMA_DEBUG_CORE_RUN              0x21c 0x5b8 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRCOM__USBPHY2_LINESTATE_1              0x21c 0x5b8 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRSTAT__EPCD_PWRSTAT                    0x220 0x5bc 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRSTAT__GPIO3_28                                0x220 0x5bc 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRSTAT__EIM_WEIM_D_28                   0x220 0x5bc 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRSTAT__ELCDIF_DAT_12                   0x220 0x5bc 0x72c 0x3 0x1
+#define MX50_PAD_EPDC_PWRSTAT__AUDMUX_AUD4_TXFS                        0x220 0x5bc 0x6d8 0x4 0x1
+#define MX50_PAD_EPDC_PWRSTAT__SDMA_DEBUG_MODE                 0x220 0x5bc 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRSTAT__USBPHY2_VBUSVALID               0x220 0x5bc 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__EPCD_PWRCTRL0                  0x224 0x5c0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__GPIO3_29                       0x224 0x5c0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__EIM_WEIM_D_29                  0x224 0x5c0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__ELCDIF_DAT_13                  0x224 0x5c0 0x730 0x3 0x1
+#define MX50_PAD_EPDC_PWRCTRL0__AUDMUX_AUD4_RXD                        0x224 0x5c0 0x6c4 0x4 0x1
+#define MX50_PAD_EPDC_PWRCTRL0__SDMA_DEBUG_RTBUFFER_WRITE      0x224 0x5c0 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__USBPHY2_AVALID                 0x224 0x5c0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__EPCD_PWRCTRL1                  0x228 0x5c4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__GPIO3_30                       0x228 0x5c4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__EIM_WEIM_D_30                  0x228 0x5c4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__ELCDIF_DAT_14                  0x228 0x5c4 0x734 0x3 0x1
+#define MX50_PAD_EPDC_PWRCTRL1__AUDMUX_AUD4_RXC                        0x228 0x5c4 0x6cc 0x4 0x1
+#define MX50_PAD_EPDC_PWRCTRL1__SDMA_DEBUG_YIELD               0x228 0x5c4 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__USBPHY1_ONBIST                 0x228 0x5c4 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__EPCD_PWRCTRL2                  0x22c 0x5c8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__GPIO3_31                       0x22c 0x5c8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__EIM_WEIM_D_31                  0x22c 0x5c8 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__ELCDIF_DAT_15                  0x22c 0x5c8 0x738 0x3 0x1
+#define MX50_PAD_EPDC_PWRCTRL2__AUDMUX_AUD4_RXFS               0x22c 0x5c8 0x6d0 0x4 0x1
+#define MX50_PAD_EPDC_PWRCTRL2__SDMA_EXT_EVENT_0               0x22c 0x5c8 0x7b8 0x6 0x1
+#define MX50_PAD_EPDC_PWRCTRL2__USBPHY2_ONBIST                 0x22c 0x5c8 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__EPCD_PWRCTRL3                  0x230 0x5cc 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__GPIO4_20                       0x230 0x5cc 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__EIM_WEIM_EB_2                  0x230 0x5cc 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__SDMA_EXT_EVENT_1               0x230 0x5cc 0x7bc 0x6 0x1
+#define MX50_PAD_EPDC_PWRCTRL3__USBPHY1_BISTOK                 0x230 0x5cc 0x000 0x7 0x0
+#define MX50_PAD_EPDC_VCOM0__EPCD_VCOM_0                       0x234 0x5d0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_VCOM0__GPIO4_21                          0x234 0x5d0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_VCOM0__EIM_WEIM_EB_3                     0x234 0x5d0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_VCOM0__USBPHY2_BISTOK                    0x234 0x5d0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_VCOM1__EPCD_VCOM_1                       0x238 0x5d4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_VCOM1__GPIO4_22                          0x238 0x5d4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_VCOM1__EIM_WEIM_CS_3                     0x238 0x5d4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_BDR0__EPCD_BDR_0                         0x23c 0x5d8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_BDR0__GPIO4_23                           0x23c 0x5d8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_BDR0__ELCDIF_DAT_7                       0x23c 0x5d8 0x718 0x3 0x1
+#define MX50_PAD_EPDC_BDR1__EPCD_BDR_1                         0x240 0x5dc 0x000 0x0 0x0
+#define MX50_PAD_EPDC_BDR1__GPIO4_24                           0x240 0x5dc 0x000 0x1 0x0
+#define MX50_PAD_EPDC_BDR1__ELCDIF_DAT_6                       0x240 0x5dc 0x714 0x3 0x1
+#define MX50_PAD_EPDC_SDCE0__EPCD_SDCE_0                       0x244 0x5e0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE0__GPIO4_25                          0x244 0x5e0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE0__ELCDIF_DAT_5                      0x244 0x5e0 0x710 0x3 0x1
+#define MX50_PAD_EPDC_SDCE1__EPCD_SDCE_1                       0x248 0x5e4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE1__GPIO4_26                          0x248 0x5e4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE1__ELCDIF_DAT_4                      0x248 0x5e4 0x70c 0x3 0x0
+#define MX50_PAD_EPDC_SDCE2__EPCD_SDCE_2                       0x24c 0x5e8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE2__GPIO4_27                          0x24c 0x5e8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE2__ELCDIF_DAT_3                      0x24c 0x5e8 0x708 0x3 0x1
+#define MX50_PAD_EPDC_SDCE3__EPCD_SDCE_3                       0x250 0x5ec 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE3__GPIO4_28                          0x250 0x5ec 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE3__ELCDIF_DAT_2                      0x250 0x5ec 0x704 0x3 0x1
+#define MX50_PAD_EPDC_SDCE4__EPCD_SDCE_4                       0x254 0x5f0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE4__GPIO4_29                          0x254 0x5f0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE4__ELCDIF_DAT_1                      0x254 0x5f0 0x700 0x3 0x1
+#define MX50_PAD_EPDC_SDCE5__EPCD_SDCE_5                       0x258 0x5f4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE5__GPIO4_30                          0x258 0x5f4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE5__ELCDIF_DAT_0                      0x258 0x5f4 0x6fc 0x3 0x1
+#define MX50_PAD_EIM_DA0__EIM_WEIM_A_0                         0x25c 0x5f8 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA0__GPIO1_0                              0x25c 0x5f8 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA0__KPP_COL_4                            0x25c 0x5f8 0x790 0x3 0x2
+#define MX50_PAD_EIM_DA0__TPIU_TRACE_0                         0x25c 0x5f8 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA0__SRC_BT_CFG1_0                                0x25c 0x5f8 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA1__EIM_WEIM_A_1                         0x260 0x5fc 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA1__GPIO1_1                              0x260 0x5fc 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA1__KPP_ROW_4                            0x260 0x5fc 0x7a0 0x3 0x2
+#define MX50_PAD_EIM_DA1__TPIU_TRACE_1                         0x260 0x5fc 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA1__SRC_BT_CFG1_1                                0x260 0x5fc 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA2__EIM_WEIM_A_2                         0x264 0x600 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA2__GPIO1_2                              0x264 0x600 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA2__KPP_COL_5                            0x264 0x600 0x794 0x3 0x2
+#define MX50_PAD_EIM_DA2__TPIU_TRACE_2                         0x264 0x600 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA2__SRC_BT_CFG1_2                                0x264 0x600 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA3__EIM_WEIM_A_3                         0x268 0x604 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA3__GPIO1_3                              0x268 0x604 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA3__KPP_ROW_5                            0x268 0x604 0x7a4 0x3 0x2
+#define MX50_PAD_EIM_DA3__TPIU_TRACE_3                         0x268 0x604 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA3__SRC_BT_CFG1_3                                0x268 0x604 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA4__EIM_WEIM_A_4                         0x26c 0x608 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA4__GPIO1_4                              0x26c 0x608 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA4__KPP_COL_6                            0x26c 0x608 0x798 0x3 0x2
+#define MX50_PAD_EIM_DA4__TPIU_TRACE_4                         0x26c 0x608 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA4__SRC_BT_CFG1_4                                0x26c 0x608 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA5__EIM_WEIM_A_5                         0x270 0x60c 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA5__GPIO1_5                              0x270 0x60c 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA5__KPP_ROW_6                            0x270 0x60c 0x7a8 0x3 0x2
+#define MX50_PAD_EIM_DA5__TPIU_TRACE_5                         0x270 0x60c 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA5__SRC_BT_CFG1_5                                0x270 0x60c 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA6__EIM_WEIM_A_6                         0x274 0x610 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA6__GPIO1_6                              0x274 0x610 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA6__KPP_COL_7                            0x274 0x610 0x79c 0x3 0x2
+#define MX50_PAD_EIM_DA6__TPIU_TRACE_6                         0x274 0x610 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA6__SRC_BT_CFG1_6                                0x274 0x610 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA7__EIM_WEIM_A_7                         0x278 0x614 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA7__GPIO1_7                              0x278 0x614 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA7__KPP_ROW_7                            0x278 0x614 0x7ac 0x3 0x2
+#define MX50_PAD_EIM_DA7__TPIU_TRACE_7                         0x278 0x614 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA7__SRC_BT_CFG1_7                                0x278 0x614 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA8__EIM_WEIM_A_8                         0x27c 0x618 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA8__GPIO1_8                              0x27c 0x618 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA8__EIM_NANDF_CLE                                0x27c 0x618 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA8__TPIU_TRACE_8                         0x27c 0x618 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA8__SRC_BT_CFG2_0                                0x27c 0x618 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA9__EIM_WEIM_A_9                         0x280 0x61c 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA9__GPIO1_9                              0x280 0x61c 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA9__EIM_NANDF_ALE                                0x280 0x61c 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA9__TPIU_TRACE_9                         0x280 0x61c 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA9__SRC_BT_CFG2_1                                0x280 0x61c 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA10__EIM_WEIM_A_10                       0x284 0x620 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA10__GPIO1_10                            0x284 0x620 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA10__EIM_NANDF_CEN_0                     0x284 0x620 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA10__TPIU_TRACE_10                       0x284 0x620 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA10__SRC_BT_CFG2_2                       0x284 0x620 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA11__EIM_WEIM_A_11                       0x288 0x624 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA11__GPIO1_11                            0x288 0x624 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA11__EIM_NANDF_CEN_1                     0x288 0x624 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA11__TPIU_TRACE_11                       0x288 0x624 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA11__SRC_BT_CFG2_3                       0x288 0x624 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA12__EIM_WEIM_A_12                       0x28c 0x628 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA12__GPIO1_12                            0x28c 0x628 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA12__EIM_NANDF_CEN_2                     0x28c 0x628 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA12__EPDC_SDCE_6                         0x28c 0x628 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA12__TPIU_TRACE_12                       0x28c 0x628 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA12__SRC_BT_CFG2_4                       0x28c 0x628 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA13__EIM_WEIM_A_13                       0x290 0x62c 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA13__GPIO1_13                            0x290 0x62c 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA13__EIM_NANDF_CEN_3                     0x290 0x62c 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA13__EPDC_SDCE_7                         0x290 0x62c 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA13__TPIU_TRACE_13                       0x290 0x62c 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA13__SRC_BT_CFG2_5                       0x290 0x62c 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA14__EIM_WEIM_A_14                       0x294 0x630 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA14__GPIO1_14                            0x294 0x630 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA14__EIM_NANDF_READY0                    0x294 0x630 0x7b4 0x2 0x2
+#define MX50_PAD_EIM_DA14__EPDC_SDCE_8                         0x294 0x630 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA14__TPIU_TRACE_14                       0x294 0x630 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA14__SRC_BT_CFG2_6                       0x294 0x630 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA15__EIM_WEIM_A_15                       0x298 0x634 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA15__GPIO1_15                            0x298 0x634 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA15__EIM_NANDF_DQS                       0x298 0x634 0x7b0 0x2 0x2
+#define MX50_PAD_EIM_DA15__EPDC_SDCE_9                         0x298 0x634 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA15__TPIU_TRACE_15                       0x298 0x634 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA15__SRC_BT_CFG2_7                       0x298 0x634 0x000 0x7 0x0
+#define MX50_PAD_EIM_CS2__EIM_WEIM_CS_2                                0x29c 0x638 0x000 0x0 0x0
+#define MX50_PAD_EIM_CS2__GPIO1_16                             0x29c 0x638 0x000 0x1 0x0
+#define MX50_PAD_EIM_CS2__EIM_WEIM_A_27                                0x29c 0x638 0x000 0x2 0x0
+#define MX50_PAD_EIM_CS2__TPIU_TRCLK                           0x29c 0x638 0x000 0x6 0x0
+#define MX50_PAD_EIM_CS2__SRC_BT_CFG3_0                                0x29c 0x638 0x000 0x7 0x0
+#define MX50_PAD_EIM_CS1__EIM_WEIM_CS_1                                0x2a0 0x63c 0x000 0x0 0x0
+#define MX50_PAD_EIM_CS1__GPIO1_17                             0x2a0 0x63c 0x000 0x1 0x0
+#define MX50_PAD_EIM_CS1__TPIU_TRCTL                           0x2a0 0x63c 0x000 0x6 0x0
+#define MX50_PAD_EIM_CS1__SRC_BT_CFG3_1                                0x2a0 0x63c 0x000 0x7 0x0
+#define MX50_PAD_EIM_CS0__EIM_WEIM_CS_0                                0x2a4 0x640 0x000 0x0 0x0
+#define MX50_PAD_EIM_CS0__GPIO1_18                             0x2a4 0x640 0x000 0x1 0x0
+#define MX50_PAD_EIM_CS0__SRC_BT_CFG3_2                                0x2a4 0x640 0x000 0x7 0x0
+#define MX50_PAD_EIM_EB0__EIM_WEIM_EB_0                                0x2a8 0x644 0x000 0x0 0x0
+#define MX50_PAD_EIM_EB0__GPIO1_19                             0x2a8 0x644 0x000 0x1 0x0
+#define MX50_PAD_EIM_EB0__SRC_BT_CFG3_3                                0x2a8 0x644 0x000 0x7 0x0
+#define MX50_PAD_EIM_EB1__EIM_WEIM_EB_1                                0x2ac 0x648 0x000 0x0 0x0
+#define MX50_PAD_EIM_EB1__GPIO1_20                             0x2ac 0x648 0x000 0x1 0x0
+#define MX50_PAD_EIM_EB1__SRC_BT_CFG3_4                                0x2ac 0x648 0x000 0x7 0x0
+#define MX50_PAD_EIM_WAIT__EIM_WEIM_WAIT                       0x2b0 0x64c 0x000 0x0 0x0
+#define MX50_PAD_EIM_WAIT__GPIO1_21                            0x2b0 0x64c 0x000 0x1 0x0
+#define MX50_PAD_EIM_WAIT__EIM_WEIM_DTACK_B                    0x2b0 0x64c 0x000 0x2 0x0
+#define MX50_PAD_EIM_WAIT__SRC_BT_CFG3_5                       0x2b0 0x64c 0x000 0x7 0x0
+#define MX50_PAD_EIM_BCLK__EIM_WEIM_BCLK                       0x2b4 0x650 0x000 0x0 0x0
+#define MX50_PAD_EIM_BCLK__GPIO1_22                            0x2b4 0x650 0x000 0x1 0x0
+#define MX50_PAD_EIM_BCLK__SRC_BT_CFG3_6                       0x2b4 0x650 0x000 0x7 0x0
+#define MX50_PAD_EIM_RDY__EIM_WEIM_RDY                         0x2b8 0x654 0x000 0x0 0x0
+#define MX50_PAD_EIM_RDY__GPIO1_23                             0x2b8 0x654 0x000 0x1 0x0
+#define MX50_PAD_EIM_RDY__SRC_BT_CFG3_7                                0x2b8 0x654 0x000 0x7 0x0
+#define MX50_PAD_EIM_OE__EIM_WEIM_OE                           0x2bc 0x658 0x000 0x0 0x0
+#define MX50_PAD_EIM_OE__GPIO1_24                              0x2bc 0x658 0x000 0x1 0x0
+#define MX50_PAD_EIM_OE__INT_BOOT                              0x2bc 0x658 0x000 0x7 0x0
+#define MX50_PAD_EIM_RW__EIM_WEIM_RW                           0x2c0 0x65c 0x000 0x0 0x0
+#define MX50_PAD_EIM_RW__GPIO1_25                              0x2c0 0x65c 0x000 0x1 0x0
+#define MX50_PAD_EIM_RW__SYSTEM_RST                            0x2c0 0x65c 0x000 0x7 0x0
+#define MX50_PAD_EIM_LBA__EIM_WEIM_LBA                         0x2c4 0x660 0x000 0x0 0x0
+#define MX50_PAD_EIM_LBA__GPIO1_26                             0x2c4 0x660 0x000 0x1 0x0
+#define MX50_PAD_EIM_LBA__TESTER_ACK                           0x2c4 0x660 0x000 0x7 0x0
+#define MX50_PAD_EIM_CRE__EIM_WEIM_CRE                         0x2c8 0x664 0x000 0x0 0x0
+#define MX50_PAD_EIM_CRE__GPIO1_27                             0x2c8 0x664 0x000 0x1 0x0
+
+#endif /* __DTS_IMX50_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx50-pingrp.h b/arch/arm/boot/dts/imx50-pingrp.h
new file mode 100644 (file)
index 0000000..d46b7e0
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX50_PINGRP_H
+#define __DTS_IMX50_PINGRP_H
+
+#define MX50_CSPI_PINGRP1 \
+       MX50_PAD_CSPI_SCLK__CSPI_SCLK                   0x00 \
+       MX50_PAD_CSPI_MISO__CSPI_MISO                   0x00 \
+       MX50_PAD_CSPI_MOSI__CSPI_MOSI                   0x00 \
+       MX50_PAD_CSPI_SS0__GPIO4_11                     0xc4 \
+       MX50_PAD_ECSPI1_MOSI__CSPI_SS1                  0xf4
+
+#define MX50_ECSPI1_PINGRP1 \
+       MX50_PAD_ECSPI1_SCLK__ECSPI1_SCLK               0x00 \
+       MX50_PAD_ECSPI1_SS0__ECSPI1_SS0                 0x00 \
+       MX50_PAD_ECSPI1_MISO__ECSPI1_MISO               0x00 \
+       MX50_PAD_ECSPI1_MOSI__ECSPI1_MOSI               0x00
+
+#define MX50_ESDHC1_PINGRP1 \
+       MX50_PAD_SD1_D0__ESDHC1_DAT0                    0x1d4 \
+       MX50_PAD_SD1_D1__ESDHC1_DAT1                    0x1d4 \
+       MX50_PAD_SD1_D2__ESDHC1_DAT2                    0x1d4 \
+       MX50_PAD_SD1_D3__ESDHC1_DAT3                    0x1d4 \
+       MX50_PAD_SD1_CMD__ESDHC1_CMD                    0x1e4 \
+       MX50_PAD_SD1_CLK__ESDHC1_CLK                    0xd4
+
+#define MX50_ESDHC1_PINGRP2 \
+       MX50_PAD_SD1_D0__ESDHC1_DAT0                    0x1d4 \
+       MX50_PAD_SD1_D1__ESDHC1_DAT1                    0x1d4 \
+       MX50_PAD_SD1_D2__ESDHC1_DAT2                    0x1d4 \
+       MX50_PAD_SD1_D3__ESDHC1_DAT3                    0x1d4 \
+       MX50_PAD_UART3_TXD__ESDHC1_DAT4                 0x1d4 \
+       MX50_PAD_UART3_RXD__ESDHC1_DAT5                 0x1d4 \
+       MX50_PAD_UART4_TXD__ESDHC1_DAT6                 0x1d4 \
+       MX50_PAD_UART4_RXD__ESDHC1_DAT7                 0x1d4 \
+       MX50_PAD_SD1_CMD__ESDHC1_CMD                    0x14 \
+       MX50_PAD_SD1_CLK__ESDHC1_CLK                    0xd4
+
+#define MX50_ESDHC2_PINGRP1 \
+       MX50_PAD_SD2_CMD__ESDHC2_CMD                    0x1e4 \
+       MX50_PAD_SD2_CLK__ESDHC2_CLK                    0xd4 \
+       MX50_PAD_SD2_D0__ESDHC2_DAT0                    0x1d4 \
+       MX50_PAD_SD2_D1__ESDHC2_DAT1                    0x1d4 \
+       MX50_PAD_SD2_D2__ESDHC2_DAT2                    0x1d4 \
+       MX50_PAD_SD2_D3__ESDHC2_DAT3                    0x1d4 \
+       MX50_PAD_SD2_D4__ESDHC2_DAT4                    0x1d4 \
+       MX50_PAD_SD2_D5__ESDHC2_DAT5                    0x1d4 \
+       MX50_PAD_SD2_D6__ESDHC2_DAT6                    0x1d4 \
+       MX50_PAD_SD2_D7__ESDHC2_DAT7                    0x1d4
+
+#define MX50_ESDHC3_PINGRP1 \
+       MX50_PAD_SD3_D0__ESDHC3_DAT0                    0x1d4 \
+       MX50_PAD_SD3_D1__ESDHC3_DAT1                    0x1d4 \
+       MX50_PAD_SD3_D2__ESDHC3_DAT2                    0x1d4 \
+       MX50_PAD_SD3_D3__ESDHC3_DAT3                    0x1d4 \
+       MX50_PAD_SD3_D4__ESDHC3_DAT4                    0x1d4 \
+       MX50_PAD_SD3_D5__ESDHC3_DAT5                    0x1d4 \
+       MX50_PAD_SD3_D6__ESDHC3_DAT6                    0x1d4 \
+       MX50_PAD_SD3_D7__ESDHC3_DAT7                    0x1d4 \
+       MX50_PAD_SD3_CMD__ESDHC3_CMD                    0x1e4 \
+       MX50_PAD_SD3_CLK__ESDHC3_CLK                    0xd4
+
+#define MX50_FEC_PINGRP1 \
+       MX50_PAD_SSI_RXFS__FEC_MDC                      0x80 \
+       MX50_PAD_SSI_RXC__FEC_MDIO                      0x80 \
+       MX50_PAD_DISP_D0__FEC_TX_CLK                    0x80 \
+       MX50_PAD_DISP_D1__FEC_RX_ERR                    0x80 \
+       MX50_PAD_DISP_D2__FEC_RX_DV                     0x80 \
+       MX50_PAD_DISP_D3__FEC_RDATA_1                   0x80 \
+       MX50_PAD_DISP_D4__FEC_RDATA_0                   0x80 \
+       MX50_PAD_DISP_D5__FEC_TX_EN                     0x80 \
+       MX50_PAD_DISP_D6__FEC_TDATA_1                   0x80 \
+       MX50_PAD_DISP_D7__FEC_TDATA_0                   0x80
+
+#define MX50_FEC_PINGRP2 \
+       MX50_PAD_I2C3_SCL__FEC_MDC                      0x80 \
+       MX50_PAD_I2C3_SDA__FEC_MDIO                     0x80 \
+       MX50_PAD_DISP_D0__FEC_TX_CLK                    0x80 \
+       MX50_PAD_DISP_D10__FEC_RX_DV                    0x80 \
+       MX50_PAD_DISP_D11__FEC_RDATA_1                  0x80 \
+       MX50_PAD_DISP_D12__FEC_RDATA_0                  0x80 \
+       MX50_PAD_DISP_D13__FEC_TX_EN                    0x80 \
+       MX50_PAD_DISP_D14__FEC_TDATA_1                  0x80 \
+       MX50_PAD_DISP_D15__FEC_TDATA_0                  0x80
+
+#define MX50_I2C1_PINGRP1 \
+       MX50_PAD_I2C1_SDA__I2C1_SDA                     0x12c \
+       MX50_PAD_I2C1_SCL__I2C1_SCL                     0x12c
+
+#define MX50_I2C2_PINGRP1 \
+       MX50_PAD_I2C2_SDA__I2C2_SDA                     0x12c \
+       MX50_PAD_I2C2_SCL__I2C2_SCL                     0x12c
+
+#define MX50_I2C3_PINGRP1 \
+       MX50_PAD_I2C3_SDA__I2C3_SDA                     0x12c \
+       MX50_PAD_I2C3_SCL__I2C3_SCL                     0x12c
+
+#define MX50_OWIRE_PINGRP1 \
+       MX50_PAD_OWIRE__OWIRE_LINE                      0x84
+
+#define MX50_UART1_PINGRP1 \
+       MX50_PAD_UART1_TXD__UART1_TXD_MUX               0x1e4 \
+       MX50_PAD_UART1_RXD__UART1_RXD_MUX               0x1e4 \
+       MX50_PAD_UART1_RTS__UART1_RTS                   0x1e4 \
+       MX50_PAD_UART1_CTS__UART1_CTS                   0x1e4
+
+#define MX50_UART2_PINGRP1 \
+       MX50_PAD_UART2_TXD__UART2_TXD_MUX               0x1e4 \
+       MX50_PAD_UART2_RXD__UART2_RXD_MUX               0x1e4 \
+       MX50_PAD_UART2_RTS__UART2_RTS                   0x1e4 \
+       MX50_PAD_UART2_CTS__UART2_CTS                   0x1e4
+
+#define MX50_UART2_PINGRP2 \
+       MX50_PAD_I2C1_SCL__UART2_TXD_MUX                0x1e4 \
+       MX50_PAD_I2C1_SDA__UART2_RXD_MUX                0x1e4 \
+       MX50_PAD_I2C2_SDA__UART2_RTS                    0x1e4 \
+       MX50_PAD_I2C2_SCL__UART2_CTS                    0x1e4
+
+#define MX50_UART3_PINGRP1 \
+       MX50_PAD_UART3_TXD__UART3_TXD_MUX               0x1e4 \
+       MX50_PAD_UART3_RXD__UART3_RXD_MUX               0x1e4 \
+       MX50_PAD_ECSPI1_SCLK__UART3_RTS                 0x1e4 \
+       MX50_PAD_ECSPI1_MOSI__UART3_CTS                 0x1e4
+
+#define MX50_UART4_PINGRP1 \
+       MX50_PAD_UART4_TXD__UART4_TXD_MUX               0x1e4 \
+       MX50_PAD_UART4_RXD__UART4_RXD_MUX               0x1e4 \
+       MX50_PAD_ECSPI1_MISO__UART4_RTS                 0x1e4 \
+       MX50_PAD_ECSPI1_SS0__UART4_CTS                  0x1e4
+
+#define MX50_UART5_PINGRP1 \
+       MX50_PAD_ECSPI2_MISO__UART5_TXD_MUX             0x1e4 \
+       MX50_PAD_ECSPI2_SS0__UART5_RXD_MUX              0x1e4 \
+       MX50_PAD_ECSPI2_SCLK__UART5_RTS                 0x1e4 \
+       MX50_PAD_ECSPI2_MOSI__UART5_CTS                 0x1e4
+
+#endif /* __DTS_IMX50_PINGRP_H */
diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi
new file mode 100644 (file)
index 0000000..fd3a50a
--- /dev/null
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "skeleton.dtsi"
+#include "imx50-pinfunc.h"
+#include "imx50-pingrp.h"
+#include <dt-bindings/clock/imx5-clock.h>
+
+/ {
+       aliases {
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
+               gpio4 = &gpio5;
+               gpio5 = &gpio6;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               serial4 = &uart5;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a8";
+                       reg = <0x0>;
+               };
+       };
+
+       tzic: tz-interrupt-controller@0fffc000 {
+               compatible = "fsl,imx50-tzic", "fsl,imx53-tzic", "fsl,tzic";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               reg = <0x0fffc000 0x4000>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ckil {
+                       compatible = "fsl,imx-ckil", "fixed-clock";
+                       clock-frequency = <32768>;
+               };
+
+               ckih1 {
+                       compatible = "fsl,imx-ckih1", "fixed-clock";
+                       clock-frequency = <22579200>;
+               };
+
+               ckih2 {
+                       compatible = "fsl,imx-ckih2", "fixed-clock";
+                       clock-frequency = <0>;
+               };
+
+               osc {
+                       compatible = "fsl,imx-osc", "fixed-clock";
+                       clock-frequency = <24000000>;
+               };
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&tzic>;
+               ranges;
+
+               aips@50000000 { /* AIPS1 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x50000000 0x10000000>;
+                       ranges;
+
+                       spba@50000000 {
+                               compatible = "fsl,spba-bus", "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x50000000 0x40000>;
+                               ranges;
+
+                               esdhc1: esdhc@50004000 {
+                                       compatible = "fsl,imx50-esdhc";
+                                       reg = <0x50004000 0x4000>;
+                                       interrupts = <1>;
+                                       clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC1_PER_GATE>;
+                                       clock-names = "ipg", "ahb", "per";
+                                       bus-width = <4>;
+                                       status = "disabled";
+                               };
+
+                               esdhc2: esdhc@50008000 {
+                                       compatible = "fsl,imx50-esdhc";
+                                       reg = <0x50008000 0x4000>;
+                                       interrupts = <2>;
+                                       clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC2_PER_GATE>;
+                                       clock-names = "ipg", "ahb", "per";
+                                       bus-width = <4>;
+                                       status = "disabled";
+                               };
+
+                               uart3: serial@5000c000 {
+                                       compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                                       reg = <0x5000c000 0x4000>;
+                                       interrupts = <33>;
+                                       clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
+                                                <&clks IMX5_CLK_UART3_PER_GATE>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ecspi1: ecspi@50010000 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,imx50-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x50010000 0x4000>;
+                                       interrupts = <36>;
+                                       clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
+                                                <&clks IMX5_CLK_ECSPI1_PER_GATE>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ssi2: ssi@50014000 {
+                                       compatible = "fsl,imx50-ssi", "fsl,imx21-ssi";
+                                       reg = <0x50014000 0x4000>;
+                                       interrupts = <30>;
+                                       clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>;
+                                       fsl,fifo-depth = <15>;
+                                       fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
+                                       status = "disabled";
+                               };
+
+                               esdhc3: esdhc@50020000 {
+                                       compatible = "fsl,imx50-esdhc";
+                                       reg = <0x50020000 0x4000>;
+                                       interrupts = <3>;
+                                       clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC3_PER_GATE>;
+                                       clock-names = "ipg", "ahb", "per";
+                                       bus-width = <4>;
+                                       status = "disabled";
+                               };
+
+                               esdhc4: esdhc@50024000 {
+                                       compatible = "fsl,imx50-esdhc";
+                                       reg = <0x50024000 0x4000>;
+                                       interrupts = <4>;
+                                       clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC4_PER_GATE>;
+                                       clock-names = "ipg", "ahb", "per";
+                                       bus-width = <4>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       usbotg: usb@53f80000 {
+                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+                               reg = <0x53f80000 0x0200>;
+                               interrupts = <18>;
+                               clocks = <&clks IMX5_CLK_USB_PHY1_GATE>;
+                               status = "disabled";
+                       };
+
+                       usbh1: usb@53f80200 {
+                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+                               reg = <0x53f80200 0x0200>;
+                               interrupts = <14>;
+                               clocks = <&clks IMX5_CLK_USB_PHY2_GATE>;
+                               status = "disabled";
+                       };
+
+                       usbh2: usb@53f80400 {
+                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+                               reg = <0x53f80400 0x0200>;
+                               interrupts = <16>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+                               status = "disabled";
+                       };
+
+                       usbh3: usb@53f80600 {
+                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+                               reg = <0x53f80600 0x0200>;
+                               interrupts = <17>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+                               status = "disabled";
+                       };
+
+                       gpio1: gpio@53f84000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53f84000 0x4000>;
+                               interrupts = <50 51>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio2: gpio@53f88000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53f88000 0x4000>;
+                               interrupts = <52 53>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio3: gpio@53f8c000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53f8c000 0x4000>;
+                               interrupts = <54 55>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio4: gpio@53f90000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53f90000 0x4000>;
+                               interrupts = <56 57>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       wdog1: wdog@53f98000 {
+                               compatible = "fsl,imx50-wdt", "fsl,imx21-wdt";
+                               reg = <0x53f98000 0x4000>;
+                               interrupts = <58>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
+                       };
+
+                       gpt: timer@53fa0000 {
+                               compatible = "fsl,imx50-gpt", "fsl,imx31-gpt";
+                               reg = <0x53fa0000 0x4000>;
+                               interrupts = <39>;
+                               clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
+                                        <&clks IMX5_CLK_GPT_HF_GATE>;
+                               clock-names = "ipg", "per";
+                       };
+
+                       iomuxc: iomuxc@53fa8000 {
+                               compatible = "fsl,imx50-iomuxc", "fsl,imx53-iomuxc";
+                               reg = <0x53fa8000 0x4000>;
+                       };
+
+                       gpr: iomuxc-gpr@53fa8000 {
+                               compatible = "fsl,imx50-iomuxc-gpr", "syscon";
+                               reg = <0x53fa8000 0xc>;
+                       };
+
+                       pwm1: pwm@53fb4000 {
+                               #pwm-cells = <2>;
+                               compatible = "fsl,imx50-pwm", "fsl,imx27-pwm";
+                               reg = <0x53fb4000 0x4000>;
+                               clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM1_HF_GATE>;
+                               clock-names = "ipg", "per";
+                               interrupts = <61>;
+                       };
+
+                       pwm2: pwm@53fb8000 {
+                               #pwm-cells = <2>;
+                               compatible = "fsl,imx50-pwm", "fsl,imx27-pwm";
+                               reg = <0x53fb8000 0x4000>;
+                               clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM2_HF_GATE>;
+                               clock-names = "ipg", "per";
+                               interrupts = <94>;
+                       };
+
+                       uart1: serial@53fbc000 {
+                               compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                               reg = <0x53fbc000 0x4000>;
+                               interrupts = <31>;
+                               clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART1_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       uart2: serial@53fc0000 {
+                               compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                               reg = <0x53fc0000 0x4000>;
+                               interrupts = <32>;
+                               clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART2_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       src: src@53fd0000 {
+                               compatible = "fsl,imx50-src", "fsl,imx51-src";
+                               reg = <0x53fd0000 0x4000>;
+                               #reset-cells = <1>;
+                       };
+
+                       clks: ccm@53fd4000{
+                               compatible = "fsl,imx50-ccm";
+                               reg = <0x53fd4000 0x4000>;
+                               interrupts = <0 71 0x04 0 72 0x04>;
+                               #clock-cells = <1>;
+                       };
+
+                       gpio5: gpio@53fdc000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53fdc000 0x4000>;
+                               interrupts = <103 104>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio6: gpio@53fe0000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53fe0000 0x4000>;
+                               interrupts = <105 106>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       i2c3: i2c@53fec000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-i2c", "fsl,imx21-i2c";
+                               reg = <0x53fec000 0x4000>;
+                               interrupts = <64>;
+                               clocks = <&clks IMX5_CLK_I2C3_GATE>;
+                               status = "disabled";
+                       };
+
+                       uart4: serial@53ff0000 {
+                               compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                               reg = <0x53ff0000 0x4000>;
+                               interrupts = <13>;
+                               clocks = <&clks IMX5_CLK_UART4_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART4_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+               };
+
+               aips@60000000 { /* AIPS2 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x60000000 0x10000000>;
+                       ranges;
+
+                       uart5: serial@63f90000 {
+                               compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                               reg = <0x63f90000 0x4000>;
+                               interrupts = <86>;
+                               clocks = <&clks IMX5_CLK_UART5_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART5_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       owire: owire@63fa4000 {
+                               compatible = "fsl,imx50-owire", "fsl,imx21-owire";
+                               reg = <0x63fa4000 0x4000>;
+                               clocks = <&clks IMX5_CLK_OWIRE_GATE>;
+                               status = "disabled";
+                       };
+
+                       ecspi2: ecspi@63fac000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-ecspi", "fsl,imx51-ecspi";
+                               reg = <0x63fac000 0x4000>;
+                               interrupts = <37>;
+                               clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
+                                        <&clks IMX5_CLK_ECSPI2_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       sdma: sdma@63fb0000 {
+                               compatible = "fsl,imx50-sdma", "fsl,imx35-sdma";
+                               reg = <0x63fb0000 0x4000>;
+                               interrupts = <6>;
+                               clocks = <&clks IMX5_CLK_SDMA_GATE>,
+                                        <&clks IMX5_CLK_SDMA_GATE>;
+                               clock-names = "ipg", "ahb";
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx50.bin";
+                       };
+
+                       cspi: cspi@63fc0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-cspi", "fsl,imx35-cspi";
+                               reg = <0x63fc0000 0x4000>;
+                               interrupts = <38>;
+                               clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
+                                        <&clks IMX5_CLK_CSPI_IPG_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@63fc4000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-i2c", "fsl,imx21-i2c";
+                               reg = <0x63fc4000 0x4000>;
+                               interrupts = <63>;
+                               clocks = <&clks IMX5_CLK_I2C2_GATE>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@63fc8000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-i2c", "fsl,imx21-i2c";
+                               reg = <0x63fc8000 0x4000>;
+                               interrupts = <62>;
+                               clocks = <&clks IMX5_CLK_I2C1_GATE>;
+                               status = "disabled";
+                       };
+
+                       ssi1: ssi@63fcc000 {
+                               compatible = "fsl,imx50-ssi", "fsl,imx21-ssi";
+                               reg = <0x63fcc000 0x4000>;
+                               interrupts = <29>;
+                               clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>;
+                               fsl,fifo-depth = <15>;
+                               fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
+                               status = "disabled";
+                       };
+
+                       audmux: audmux@63fd0000 {
+                               compatible = "fsl,imx50-audmux", "fsl,imx31-audmux";
+                               reg = <0x63fd0000 0x4000>;
+                               status = "disabled";
+                       };
+
+                       fec: ethernet@63fec000 {
+                               compatible = "fsl,imx53-fec", "fsl,imx25-fec";
+                               reg = <0x63fec000 0x4000>;
+                               interrupts = <87>;
+                               clocks = <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>;
+                               clock-names = "ipg", "ahb", "ptp";
+                               status = "disabled";
+                       };
+               };
+       };
+};
index b3606993f2e8db4e4327305f52fddec70249e9f3..80840daf83c6b714043a8e20f992b68355887993 100644 (file)
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_2>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "mii";
-       phy-reset-gpios = <&gpio3 0 0>;
+       phy-reset-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
        phy-reset-duration = <1>;
        status = "okay";
 };
 
+&iomuxc {
+       imx51-apf51 {
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX51_FEC_PINGRP2>;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <MX51_UART3_PINGRP2>;
+               };
+       };
+};
+
 &nfc {
        nand-bus-width = <8>;
        nand-ecc-mode = "hw";
@@ -50,6 +62,6 @@
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_2>;
+       pinctrl-0 = <&pinctrl_uart3>;
        status = "okay";
 };
index 5a7f552786a112dadff76c0d664fc6fb682f7ccf..f36a3aa115f87410a61803c7f86ad5e1d0336623 100644 (file)
@@ -21,7 +21,7 @@
                crtcs = <&ipu 0>;
                interface-pix-fmt = "bgr666";
                pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ipu_disp1_1>;
+               pinctrl-0 = <&pinctrl_ipu_disp1>;
 
                display-timings {
                        lw700 {
@@ -48,7 +48,7 @@
 
                user-key {
                        label = "user";
-                       gpios = <&gpio1 3 0>;
+                       gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
                        linux,code = <256>; /* BTN_0 */
                };
        };
@@ -58,7 +58,7 @@
 
                user {
                        label = "Heartbeat";
-                       gpios = <&gpio1 2 0>;
+                       gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
                        linux,default-trigger = "heartbeat";
                };
        };
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        fsl,spi-num-chipselects = <2>;
-       cs-gpios = <&gpio4 24 0>, <&gpio4 25 0>;
+       cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>,
+                  <&gpio4 25 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
 
 &ecspi2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi2_1>;
+       pinctrl-0 = <&pinctrl_ecspi2>;
        fsl,spi-num-chipselects = <2>;
-       cs-gpios = <&gpio3 28 1>, <&gpio3 27 1>;
+       cs-gpios = <&gpio3 28 GPIO_ACTIVE_LOW>,
+                  <&gpio3 27 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
-       cd-gpios = <&gpio2 29 0>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       cd-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
        bus-width = <4>;
        status = "okay";
 };
 
 &esdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc2_1>;
+       pinctrl-0 = <&pinctrl_esdhc2>;
        bus-width = <4>;
        non-removable;
        status = "okay";
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_2>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx51-apf51dev {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX51_PAD_EIM_EB2__GPIO2_22   0x0C5
                                MX51_PAD_GPIO1_3__GPIO1_3    0x0C5
                        >;
                };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX51_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_ecspi2: ecspi2grp {
+                       fsl,pins = <MX51_ECSPI2_PINGRP1>;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <MX51_ESDHC1_PINGRP1>;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <MX51_ESDHC2_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX51_I2C2_PINGRP2>;
+               };
+
+               pinctrl_ipu_disp1: ipudisp1grp {
+                       fsl,pins = <MX51_IPU_DISP1_PINGRP1>;
+               };
        };
 };
index be1407cf5abd1b1479e55fbfeac48be44dc90d4c..483178a4401795d235e2ed893a4977fc9a1dcb9a 100644 (file)
@@ -26,7 +26,7 @@
                crtcs = <&ipu 0>;
                interface-pix-fmt = "rgb24";
                pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ipu_disp1_1>;
+               pinctrl-0 = <&pinctrl_ipu_disp1>;
                display-timings {
                        native-mode = <&timing0>;
                        timing0: dvi {
@@ -48,7 +48,7 @@
                crtcs = <&ipu 1>;
                interface-pix-fmt = "rgb565";
                pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ipu_disp2_1>;
+               pinctrl-0 = <&pinctrl_ipu_disp2>;
                status = "disabled";
                display-timings {
                        native-mode = <&timing1>;
@@ -75,7 +75,7 @@
 
                power {
                        label = "Power Button";
-                       gpios = <&gpio2 21 0>;
+                       gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
                        linux,code = <116>; /* KEY_POWER */
                        gpio-key,wakeup;
                };
                        reg=<0>;
                        #clock-cells = <0>;
                        clock-frequency = <26000000>;
-                       gpios = <&gpio4 26 1>;
+                       gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
                };
        };
 };
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        fsl,cd-controller;
        fsl,wp-controller;
        status = "okay";
 
 &esdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc2_1>;
-       cd-gpios = <&gpio1 6 0>;
-       wp-gpios = <&gpio1 5 0>;
+       pinctrl-0 = <&pinctrl_esdhc2>;
+       cd-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+       wp-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_1 &pinctrl_uart3_rtscts_1>;
+       pinctrl-0 = <&pinctrl_uart3 &pinctrl_uart3_rtscts>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        fsl,spi-num-chipselects = <2>;
-       cs-gpios = <&gpio4 24 0>, <&gpio4 25 0>;
+       cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>,
+                  <&gpio4 25 GPIO_ACTIVE_LOW>;
        status = "okay";
 
        pmic: mc13892@0 {
                spi-cs-high;
                reg = <0>;
                interrupt-parent = <&gpio1>;
-               interrupts = <8 0x4>;
+               interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
 
                regulators {
                        sw1_reg: sw1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx51-babbage {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX51_PAD_GPIO1_0__SD1_CD     0x20d5
                                MX51_PAD_CSPI1_RDY__GPIO4_26 0x80000000
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX51_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX51_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <MX51_ESDHC1_PINGRP1>;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <MX51_ESDHC2_PINGRP1>;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX51_FEC_PINGRP1
+                               MX51_PAD_EIM_A20__GPIO2_14 0x85 /* Reset */
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX51_I2C2_PINGRP1>;
+               };
+
+               pinctrl_ipu_disp1: ipudisp1grp {
+                       fsl,pins = <MX51_IPU_DISP1_PINGRP1>;
+               };
+
+               pinctrl_ipu_disp2: ipudisp2grp {
+                       fsl,pins = <MX51_IPU_DISP2_PINGRP1>;
+               };
+
+               pinctrl_kpp: kppgrp {
+                       fsl,pins = <MX51_KPP_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX51_UART1_PINGRP1>;
+               };
+
+               pinctrl_uart1_rtscts: uart1rtsctsgrp {
+                       fsl,pins = <MX51_UART1_RTSCTS_PINGRP1>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX51_UART2_PINGRP1>;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <MX51_UART3_PINGRP1>;
+               };
+
+               pinctrl_uart3_rtscts: uart3rtsctsgrp {
+                       fsl,pins = <MX51_UART3_RTSCTS_PINGRP1>;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1 &pinctrl_uart1_rtscts_1>;
+       pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_rtscts>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        sgtl5000: codec@0a {
 
 &audmux {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
+       pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
 };
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "mii";
+       phy-reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+       phy-reset-duration = <1>;
        status = "okay";
 };
 
 &kpp {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_kpp_1>;
+       pinctrl-0 = <&pinctrl_kpp>;
        linux,keymap = <0x00000067      /* KEY_UP */
                        0x0001006c      /* KEY_DOWN */
                        0x00020072      /* KEY_VOLUMEDOWN */
diff --git a/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi b/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
new file mode 100644 (file)
index 0000000..b22841a
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "imx51.dtsi"
+
+/ {
+       model = "Eukrea CPUIMX51";
+       compatible = "eukrea,cpuimx51", "fsl,imx51";
+
+       memory {
+               reg = <0x90000000 0x10000000>; /* 256M */
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       status = "okay";
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pcf8563@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&iomuxc {
+       imx51-eukrea {
+               pinctrl_tsc2007_1: tsc2007grp-1 {
+                       fsl,pins = <
+                               MX51_PAD_GPIO_NAND__GPIO_NAND 0x1f5
+                               MX51_PAD_NANDF_D8__GPIO4_0 0x1f5
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX51_FEC_PINGRP2>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX51_I2C1_PINGRP1>;
+               };
+       };
+};
+
+&nfc {
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       nand-on-flash-bbt;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts b/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts
new file mode 100644 (file)
index 0000000..cf2e0d8
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/dts-v1/;
+#include "imx51-eukrea-cpuimx51.dtsi"
+
+/ {
+       model = "Eukrea CPUIMX51";
+       compatible = "eukrea,mbimxsd51","eukrea,cpuimx51", "fsl,imx51";
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpiokeys_1>;
+
+               button-1 {
+                       label = "BP1";
+                       gpios = <&gpio3 31 GPIO_ACTIVE_LOW>;
+                       linux,code = <256>;
+                       gpio-key,wakeup;
+                       linux,input-type = <1>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpioled>;
+
+               led1 {
+                       label = "led1";
+                       gpios = <&gpio3 30 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1 &pinctrl_esdhc1_cd>;
+       fsl,cd-controller;
+       status = "okay";
+};
+
+&i2c1 {
+       tlv320aic23: codec@1a {
+               compatible = "ti,tlv320aic23";
+               reg = <0x1a>;
+       };
+};
+
+&iomuxc {
+       imx51-eukrea {
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX51_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <MX51_ESDHC1_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX51_UART1_PINGRP1>;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <MX51_UART3_PINGRP2>;
+               };
+
+               pinctrl_uart3_rtscts: uart3rtsctsgrp {
+                       fsl,pins = <MX51_UART3_RTSCTS_PINGRP2>;
+               };
+
+               pinctrl_backlight_1: backlightgrp-1 {
+                       fsl,pins = <
+                               MX51_PAD_DI1_D1_CS__GPIO3_4 0x1f5
+                       >;
+               };
+
+               pinctrl_esdhc1_cd: esdhc1_cd {
+                       fsl,pins = <
+                               MX51_PAD_GPIO1_0__SD1_CD 0x20d5
+                       >;
+               };
+
+               pinctrl_gpiokeys_1: gpiokeysgrp-1 {
+                       fsl,pins = <
+                               MX51_PAD_NANDF_D9__GPIO3_31 0x1f5
+                       >;
+               };
+
+               pinctrl_gpioled: gpioledgrp-1 {
+                       fsl,pins = <
+                               MX51_PAD_NANDF_D10__GPIO3_30 0x80000000
+                       >;
+               };
+
+               pinctrl_reg_lcd_3v3: reg_lcd_3v3 {
+                       fsl,pins = <
+                               MX51_PAD_CSI1_D9__GPIO3_13 0x1f5
+                       >;
+               };
+       };
+};
+
+&ssi2 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3 &pinctrl_uart3_rtscts>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx51-pingrp.h b/arch/arm/boot/dts/imx51-pingrp.h
new file mode 100644 (file)
index 0000000..550d0d1
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX51_PINGRP_H
+#define __DTS_IMX51_PINGRP_H
+
+#define MX51_AUDMUX_PINGRP1 \
+       MX51_PAD_AUD3_BB_TXD__AUD3_TXD                  0x80000000 \
+       MX51_PAD_AUD3_BB_RXD__AUD3_RXD                  0x80000000 \
+       MX51_PAD_AUD3_BB_CK__AUD3_TXC                   0x80000000 \
+       MX51_PAD_AUD3_BB_FS__AUD3_TXFS                  0x80000000
+
+#define MX51_FEC_PINGRP1 \
+       MX51_PAD_EIM_EB2__FEC_MDIO                      0x80000000 \
+       MX51_PAD_EIM_EB3__FEC_RDATA1                    0x80000000 \
+       MX51_PAD_EIM_CS2__FEC_RDATA2                    0x80000000 \
+       MX51_PAD_EIM_CS3__FEC_RDATA3                    0x80000000 \
+       MX51_PAD_EIM_CS4__FEC_RX_ER                     0x80000000 \
+       MX51_PAD_EIM_CS5__FEC_CRS                       0x80000000 \
+       MX51_PAD_NANDF_RB2__FEC_COL                     0x80000000 \
+       MX51_PAD_NANDF_RB3__FEC_RX_CLK                  0x80000000 \
+       MX51_PAD_NANDF_D9__FEC_RDATA0                   0x80000000 \
+       MX51_PAD_NANDF_D8__FEC_TDATA0                   0x80000000 \
+       MX51_PAD_NANDF_CS2__FEC_TX_ER                   0x80000000 \
+       MX51_PAD_NANDF_CS3__FEC_MDC                     0x80000000 \
+       MX51_PAD_NANDF_CS4__FEC_TDATA1                  0x80000000 \
+       MX51_PAD_NANDF_CS5__FEC_TDATA2                  0x80000000 \
+       MX51_PAD_NANDF_CS6__FEC_TDATA3                  0x80000000 \
+       MX51_PAD_NANDF_CS7__FEC_TX_EN                   0x80000000 \
+       MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK              0x80000000
+
+#define MX51_FEC_PINGRP2 \
+       MX51_PAD_DI_GP3__FEC_TX_ER                      0x80000000 \
+       MX51_PAD_DI2_PIN4__FEC_CRS                      0x80000000 \
+       MX51_PAD_DI2_PIN2__FEC_MDC                      0x80000000 \
+       MX51_PAD_DI2_PIN3__FEC_MDIO                     0x80000000 \
+       MX51_PAD_DI2_DISP_CLK__FEC_RDATA1               0x80000000 \
+       MX51_PAD_DI_GP4__FEC_RDATA2                     0x80000000 \
+       MX51_PAD_DISP2_DAT0__FEC_RDATA3                 0x80000000 \
+       MX51_PAD_DISP2_DAT1__FEC_RX_ER                  0x80000000 \
+       MX51_PAD_DISP2_DAT6__FEC_TDATA1                 0x80000000 \
+       MX51_PAD_DISP2_DAT7__FEC_TDATA2                 0x80000000 \
+       MX51_PAD_DISP2_DAT8__FEC_TDATA3                 0x80000000 \
+       MX51_PAD_DISP2_DAT9__FEC_TX_EN                  0x80000000 \
+       MX51_PAD_DISP2_DAT10__FEC_COL                   0x80000000 \
+       MX51_PAD_DISP2_DAT11__FEC_RX_CLK                0x80000000 \
+       MX51_PAD_DISP2_DAT12__FEC_RX_DV                 0x80000000 \
+       MX51_PAD_DISP2_DAT13__FEC_TX_CLK                0x80000000 \
+       MX51_PAD_DISP2_DAT14__FEC_RDATA0                0x80000000 \
+       MX51_PAD_DISP2_DAT15__FEC_TDATA0                0x80000000
+
+#define MX51_ECSPI1_PINGRP1 \
+       MX51_PAD_CSPI1_MISO__ECSPI1_MISO                0x185 \
+       MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI                0x185 \
+       MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK                0x185
+
+#define MX51_ECSPI2_PINGRP1 \
+       MX51_PAD_NANDF_RB3__ECSPI2_MISO                 0x185 \
+       MX51_PAD_NANDF_D15__ECSPI2_MOSI                 0x185 \
+       MX51_PAD_NANDF_RB2__ECSPI2_SCLK                 0x185
+
+#define MX51_ESDHC1_PINGRP1 \
+       MX51_PAD_SD1_CMD__SD1_CMD                       0x400020d5 \
+       MX51_PAD_SD1_CLK__SD1_CLK                       0x20d5 \
+       MX51_PAD_SD1_DATA0__SD1_DATA0                   0x20d5 \
+       MX51_PAD_SD1_DATA1__SD1_DATA1                   0x20d5 \
+       MX51_PAD_SD1_DATA2__SD1_DATA2                   0x20d5 \
+       MX51_PAD_SD1_DATA3__SD1_DATA3                   0x20d5
+
+#define MX51_ESDHC2_PINGRP1 \
+       MX51_PAD_SD2_CMD__SD2_CMD                       0x400020d5 \
+       MX51_PAD_SD2_CLK__SD2_CLK                       0x20d5 \
+       MX51_PAD_SD2_DATA0__SD2_DATA0                   0x20d5 \
+       MX51_PAD_SD2_DATA1__SD2_DATA1                   0x20d5 \
+       MX51_PAD_SD2_DATA2__SD2_DATA2                   0x20d5 \
+       MX51_PAD_SD2_DATA3__SD2_DATA3                   0x20d5
+
+#define MX51_I2C1_PINGRP1 \
+       MX51_PAD_SD2_CMD__I2C1_SCL                      0x400001ed \
+       MX51_PAD_SD2_CLK__I2C1_SDA                      0x400001ed
+
+#define MX51_I2C2_PINGRP1 \
+       MX51_PAD_KEY_COL4__I2C2_SCL                     0x400001ed \
+       MX51_PAD_KEY_COL5__I2C2_SDA                     0x400001ed
+
+#define MX51_I2C2_PINGRP2 \
+       MX51_PAD_EIM_D27__I2C2_SCL                      0x400001ed \
+       MX51_PAD_EIM_D24__I2C2_SDA                      0x400001ed
+
+#define MX51_I2C2_PINGRP3 \
+       MX51_PAD_GPIO1_2__I2C2_SCL                      0x400001ed \
+       MX51_PAD_GPIO1_3__I2C2_SDA                      0x400001ed
+
+#define MX51_IPU_DISP1_PINGRP1 \
+       MX51_PAD_DISP1_DAT0__DISP1_DAT0                 0x5 \
+       MX51_PAD_DISP1_DAT1__DISP1_DAT1                 0x5 \
+       MX51_PAD_DISP1_DAT2__DISP1_DAT2                 0x5 \
+       MX51_PAD_DISP1_DAT3__DISP1_DAT3                 0x5 \
+       MX51_PAD_DISP1_DAT4__DISP1_DAT4                 0x5 \
+       MX51_PAD_DISP1_DAT5__DISP1_DAT5                 0x5 \
+       MX51_PAD_DISP1_DAT6__DISP1_DAT6                 0x5 \
+       MX51_PAD_DISP1_DAT7__DISP1_DAT7                 0x5 \
+       MX51_PAD_DISP1_DAT8__DISP1_DAT8                 0x5 \
+       MX51_PAD_DISP1_DAT9__DISP1_DAT9                 0x5 \
+       MX51_PAD_DISP1_DAT10__DISP1_DAT10               0x5 \
+       MX51_PAD_DISP1_DAT11__DISP1_DAT11               0x5 \
+       MX51_PAD_DISP1_DAT12__DISP1_DAT12               0x5 \
+       MX51_PAD_DISP1_DAT13__DISP1_DAT13               0x5 \
+       MX51_PAD_DISP1_DAT14__DISP1_DAT14               0x5 \
+       MX51_PAD_DISP1_DAT15__DISP1_DAT15               0x5 \
+       MX51_PAD_DISP1_DAT16__DISP1_DAT16               0x5 \
+       MX51_PAD_DISP1_DAT17__DISP1_DAT17               0x5 \
+       MX51_PAD_DISP1_DAT18__DISP1_DAT18               0x5 \
+       MX51_PAD_DISP1_DAT19__DISP1_DAT19               0x5 \
+       MX51_PAD_DISP1_DAT20__DISP1_DAT20               0x5 \
+       MX51_PAD_DISP1_DAT21__DISP1_DAT21               0x5 \
+       MX51_PAD_DISP1_DAT22__DISP1_DAT22               0x5 \
+       MX51_PAD_DISP1_DAT23__DISP1_DAT23               0x5 \
+       MX51_PAD_DI1_PIN2__DI1_PIN2                     0x5 \
+       MX51_PAD_DI1_PIN3__DI1_PIN3                     0x5
+
+#define MX51_IPU_DISP2_PINGRP1 \
+       MX51_PAD_DISP2_DAT0__DISP2_DAT0                 0x5 \
+       MX51_PAD_DISP2_DAT1__DISP2_DAT1                 0x5 \
+       MX51_PAD_DISP2_DAT2__DISP2_DAT2                 0x5 \
+       MX51_PAD_DISP2_DAT3__DISP2_DAT3                 0x5 \
+       MX51_PAD_DISP2_DAT4__DISP2_DAT4                 0x5 \
+       MX51_PAD_DISP2_DAT5__DISP2_DAT5                 0x5 \
+       MX51_PAD_DISP2_DAT6__DISP2_DAT6                 0x5 \
+       MX51_PAD_DISP2_DAT7__DISP2_DAT7                 0x5 \
+       MX51_PAD_DISP2_DAT8__DISP2_DAT8                 0x5 \
+       MX51_PAD_DISP2_DAT9__DISP2_DAT9                 0x5 \
+       MX51_PAD_DISP2_DAT10__DISP2_DAT10               0x5 \
+       MX51_PAD_DISP2_DAT11__DISP2_DAT11               0x5 \
+       MX51_PAD_DISP2_DAT12__DISP2_DAT12               0x5 \
+       MX51_PAD_DISP2_DAT13__DISP2_DAT13               0x5 \
+       MX51_PAD_DISP2_DAT14__DISP2_DAT14               0x5 \
+       MX51_PAD_DISP2_DAT15__DISP2_DAT15               0x5 \
+       MX51_PAD_DI2_PIN2__DI2_PIN2                     0x5 \
+       MX51_PAD_DI2_PIN3__DI2_PIN3                     0x5 \
+       MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK             0x5 \
+       MX51_PAD_DI_GP4__DI2_PIN15                      0x5
+
+#define MX51_KPP_PINGRP1 \
+       MX51_PAD_KEY_ROW0__KEY_ROW0                     0xe0 \
+       MX51_PAD_KEY_ROW1__KEY_ROW1                     0xe0 \
+       MX51_PAD_KEY_ROW2__KEY_ROW2                     0xe0 \
+       MX51_PAD_KEY_ROW3__KEY_ROW3                     0xe0 \
+       MX51_PAD_KEY_COL0__KEY_COL0                     0xe8 \
+       MX51_PAD_KEY_COL1__KEY_COL1                     0xe8 \
+       MX51_PAD_KEY_COL2__KEY_COL2                     0xe8 \
+       MX51_PAD_KEY_COL3__KEY_COL3                     0xe8
+
+#define MX51_PATA_PINGRP1 \
+       MX51_PAD_NANDF_WE_B__PATA_DIOW                  0x2004 \
+       MX51_PAD_NANDF_RE_B__PATA_DIOR                  0x2004 \
+       MX51_PAD_NANDF_ALE__PATA_BUFFER_EN              0x2004 \
+       MX51_PAD_NANDF_CLE__PATA_RESET_B                0x2004 \
+       MX51_PAD_NANDF_WP_B__PATA_DMACK                 0x2004 \
+       MX51_PAD_NANDF_RB0__PATA_DMARQ                  0x2004 \
+       MX51_PAD_NANDF_RB1__PATA_IORDY                  0x2004 \
+       MX51_PAD_GPIO_NAND__PATA_INTRQ                  0x2004 \
+       MX51_PAD_NANDF_CS2__PATA_CS_0                   0x2004 \
+       MX51_PAD_NANDF_CS3__PATA_CS_1                   0x2004 \
+       MX51_PAD_NANDF_CS4__PATA_DA_0                   0x2004 \
+       MX51_PAD_NANDF_CS5__PATA_DA_1                   0x2004 \
+       MX51_PAD_NANDF_CS6__PATA_DA_2                   0x2004 \
+       MX51_PAD_NANDF_D15__PATA_DATA15                 0x2004 \
+       MX51_PAD_NANDF_D14__PATA_DATA14                 0x2004 \
+       MX51_PAD_NANDF_D13__PATA_DATA13                 0x2004 \
+       MX51_PAD_NANDF_D12__PATA_DATA12                 0x2004 \
+       MX51_PAD_NANDF_D11__PATA_DATA11                 0x2004 \
+       MX51_PAD_NANDF_D10__PATA_DATA10                 0x2004 \
+       MX51_PAD_NANDF_D9__PATA_DATA9                   0x2004 \
+       MX51_PAD_NANDF_D8__PATA_DATA8                   0x2004 \
+       MX51_PAD_NANDF_D7__PATA_DATA7                   0x2004 \
+       MX51_PAD_NANDF_D6__PATA_DATA6                   0x2004 \
+       MX51_PAD_NANDF_D5__PATA_DATA5                   0x2004 \
+       MX51_PAD_NANDF_D4__PATA_DATA4                   0x2004 \
+       MX51_PAD_NANDF_D3__PATA_DATA3                   0x2004 \
+       MX51_PAD_NANDF_D2__PATA_DATA2                   0x2004 \
+       MX51_PAD_NANDF_D1__PATA_DATA1                   0x2004 \
+       MX51_PAD_NANDF_D0__PATA_DATA0                   0x2004
+
+#define MX51_UART1_PINGRP1 \
+       MX51_PAD_UART1_RXD__UART1_RXD                   0x1c5 \
+       MX51_PAD_UART1_TXD__UART1_TXD                   0x1c5
+
+#define MX51_UART1_RTSCTS_PINGRP1 \
+       MX51_PAD_UART1_RTS__UART1_RTS                   0x1c5 \
+       MX51_PAD_UART1_CTS__UART1_CTS                   0x1c5
+
+#define MX51_UART2_PINGRP1 \
+       MX51_PAD_UART2_RXD__UART2_RXD                   0x1c5 \
+       MX51_PAD_UART2_TXD__UART2_TXD                   0x1c5
+
+#define MX51_UART3_PINGRP1 \
+       MX51_PAD_EIM_D25__UART3_RXD                     0x1c5 \
+       MX51_PAD_EIM_D26__UART3_TXD                     0x1c5
+
+#define MX51_UART3_RTSCTS_PINGRP1 \
+       MX51_PAD_EIM_D27__UART3_RTS                     0x1c5 \
+       MX51_PAD_EIM_D24__UART3_CTS                     0x1c5
+
+#define MX51_UART3_PINGRP2 \
+       MX51_PAD_UART3_RXD__UART3_RXD                   0x1c5 \
+       MX51_PAD_UART3_TXD__UART3_TXD                   0x1c5
+
+#define MX51_UART3_RTSCTS_PINGRP2 \
+       MX51_PAD_KEY_COL4__UART3_RTS                    0x1c5 \
+       MX51_PAD_KEY_COL5__UART3_CTS                    0x1c5
+
+#define MX51_USBH1_PINGRP1 \
+       MX51_PAD_USBH1_DATA0__USBH1_DATA0               0x1e5 \
+       MX51_PAD_USBH1_DATA1__USBH1_DATA1               0x1e5 \
+       MX51_PAD_USBH1_DATA2__USBH1_DATA2               0x1e5 \
+       MX51_PAD_USBH1_DATA3__USBH1_DATA3               0x1e5 \
+       MX51_PAD_USBH1_DATA4__USBH1_DATA4               0x1e5 \
+       MX51_PAD_USBH1_DATA5__USBH1_DATA5               0x1e5 \
+       MX51_PAD_USBH1_DATA6__USBH1_DATA6               0x1e5 \
+       MX51_PAD_USBH1_DATA7__USBH1_DATA7               0x1e5 \
+       MX51_PAD_USBH1_CLK__USBH1_CLK                   0x1e5 \
+       MX51_PAD_USBH1_DIR__USBH1_DIR                   0x1e5 \
+       MX51_PAD_USBH1_NXT__USBH1_NXT                   0x1e5 \
+       MX51_PAD_USBH1_STP__USBH1_STP                   0x1e5
+
+#define MX51_USBH2_PINGRP1 \
+       MX51_PAD_EIM_D16__USBH2_DATA0                   0x1e5 \
+       MX51_PAD_EIM_D17__USBH2_DATA1                   0x1e5 \
+       MX51_PAD_EIM_D18__USBH2_DATA2                   0x1e5 \
+       MX51_PAD_EIM_D19__USBH2_DATA3                   0x1e5 \
+       MX51_PAD_EIM_D20__USBH2_DATA4                   0x1e5 \
+       MX51_PAD_EIM_D21__USBH2_DATA5                   0x1e5 \
+       MX51_PAD_EIM_D22__USBH2_DATA6                   0x1e5 \
+       MX51_PAD_EIM_D23__USBH2_DATA7                   0x1e5 \
+       MX51_PAD_EIM_A24__USBH2_CLK                     0x1e5 \
+       MX51_PAD_EIM_A25__USBH2_DIR                     0x1e5 \
+       MX51_PAD_EIM_A27__USBH2_NXT                     0x1e5 \
+       MX51_PAD_EIM_A26__USBH2_STP                     0x1e5
+
+#endif /* __DTS_IMX51_PINGRP_H */
index 4bcdd3ad15e524d95cb553b47fc6f61e5eef9a3a..cad5a5671fbc489f87e339ea533d28c48dc2b908 100644 (file)
 
 #include "skeleton.dtsi"
 #include "imx51-pinfunc.h"
+#include "imx51-pingrp.h"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/imx5-clock.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        aliases {
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
-               cpu@0 {
+               cpu: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a8";
                        reg = <0>;
-                       clock-latency = <61036>; /* two CLK32 periods */
-                       clocks = <&clks 24>;
+                       clock-latency = <62500>;
+                       clocks = <&clks IMX5_CLK_CPU_PODF>;
                        clock-names = "cpu";
                        operating-points = <
-                               /* kHz  uV (No regulator support) */
-                               160000  0
-                               800000  0
+                               166000  1000000
+                               600000  1050000
+                               800000  1100000
                        >;
+                       voltage-tolerance = <5>;
+               };
+       };
+
+       usbphy {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "simple-bus";
+
+               usbphy0: usbphy@0 {
+                       compatible = "usb-nop-xceiv";
+                       reg = <0>;
+                       clocks = <&clks IMX5_CLK_USB_PHY_GATE>;
+                       clock-names = "main_clk";
                };
        };
 
                        compatible = "fsl,imx51-ipu";
                        reg = <0x40000000 0x20000000>;
                        interrupts = <11 10>;
-                       clocks = <&clks 59>, <&clks 110>, <&clks 61>;
+                       clocks = <&clks IMX5_CLK_IPU_GATE>,
+                                <&clks IMX5_CLK_IPU_DI0_GATE>,
+                                <&clks IMX5_CLK_IPU_DI1_GATE>;
                        clock-names = "bus", "di0", "di1";
                        resets = <&src 2>;
                };
                                        compatible = "fsl,imx51-esdhc";
                                        reg = <0x70004000 0x4000>;
                                        interrupts = <1>;
-                                       clocks = <&clks 44>, <&clks 0>, <&clks 71>;
+                                       clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC1_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        status = "disabled";
                                };
                                        compatible = "fsl,imx51-esdhc";
                                        reg = <0x70008000 0x4000>;
                                        interrupts = <2>;
-                                       clocks = <&clks 45>, <&clks 0>, <&clks 72>;
+                                       clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC2_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx51-uart", "fsl,imx21-uart";
                                        reg = <0x7000c000 0x4000>;
                                        interrupts = <33>;
-                                       clocks = <&clks 32>, <&clks 33>;
+                                       clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
+                                                <&clks IMX5_CLK_UART3_PER_GATE>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                };
                                        compatible = "fsl,imx51-ecspi";
                                        reg = <0x70010000 0x4000>;
                                        interrupts = <36>;
-                                       clocks = <&clks 51>, <&clks 52>;
+                                       clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
+                                                <&clks IMX5_CLK_ECSPI1_PER_GATE>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                };
                                        compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
                                        reg = <0x70014000 0x4000>;
                                        interrupts = <30>;
-                                       clocks = <&clks 49>;
-                                       dmas = <&sdma 24 1 0>,
-                                              <&sdma 25 1 0>;
+                                       clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>;
+                                       dmas = <&sdma 24 22 0>,
+                                              <&sdma 25 22 0>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <15>;
                                        fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
                                        compatible = "fsl,imx51-esdhc";
                                        reg = <0x70020000 0x4000>;
                                        interrupts = <3>;
-                                       clocks = <&clks 46>, <&clks 0>, <&clks 73>;
+                                       clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC3_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx51-esdhc";
                                        reg = <0x70024000 0x4000>;
                                        interrupts = <4>;
-                                       clocks = <&clks 47>, <&clks 0>, <&clks 74>;
+                                       clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC4_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                };
                        };
 
-                       usbphy0: usbphy@0 {
-                               compatible = "usb-nop-xceiv";
-                               clocks = <&clks 75>;
-                               clock-names = "main_clk";
-                               status = "okay";
-                       };
-
                        usbotg: usb@73f80000 {
                                compatible = "fsl,imx51-usb", "fsl,imx27-usb";
                                reg = <0x73f80000 0x0200>;
                                interrupts = <18>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 0>;
                                fsl,usbphy = <&usbphy0>;
                                status = "disabled";
                                compatible = "fsl,imx51-usb", "fsl,imx27-usb";
                                reg = <0x73f80200 0x0200>;
                                interrupts = <14>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 1>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-usb", "fsl,imx27-usb";
                                reg = <0x73f80400 0x0200>;
                                interrupts = <16>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 2>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-usb", "fsl,imx27-usb";
                                reg = <0x73f80600 0x0200>;
                                interrupts = <17>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 3>;
                                status = "disabled";
                        };
                                #index-cells = <1>;
                                compatible = "fsl,imx51-usbmisc";
                                reg = <0x73f80800 0x200>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                        };
 
                        gpio1: gpio@73f84000 {
                                compatible = "fsl,imx51-kpp", "fsl,imx21-kpp";
                                reg = <0x73f94000 0x4000>;
                                interrupts = <60>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
                                reg = <0x73f98000 0x4000>;
                                interrupts = <58>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                        };
 
                        wdog2: wdog@73f9c000 {
                                compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
                                reg = <0x73f9c000 0x4000>;
                                interrupts = <59>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-gpt", "fsl,imx31-gpt";
                                reg = <0x73fa0000 0x4000>;
                                interrupts = <39>;
-                               clocks = <&clks 36>, <&clks 41>;
+                               clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
+                                        <&clks IMX5_CLK_GPT_HF_GATE>;
                                clock-names = "ipg", "per";
                        };
 
                                #pwm-cells = <2>;
                                compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
                                reg = <0x73fb4000 0x4000>;
-                               clocks = <&clks 37>, <&clks 38>;
+                               clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM1_HF_GATE>;
                                clock-names = "ipg", "per";
                                interrupts = <61>;
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
                                reg = <0x73fb8000 0x4000>;
-                               clocks = <&clks 39>, <&clks 40>;
+                               clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM2_HF_GATE>;
                                clock-names = "ipg", "per";
                                interrupts = <94>;
                        };
                                compatible = "fsl,imx51-uart", "fsl,imx21-uart";
                                reg = <0x73fbc000 0x4000>;
                                interrupts = <31>;
-                               clocks = <&clks 28>, <&clks 29>;
+                               clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART1_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-uart", "fsl,imx21-uart";
                                reg = <0x73fc0000 0x4000>;
                                interrupts = <32>;
-                               clocks = <&clks 30>, <&clks 31>;
+                               clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART2_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-iim", "fsl,imx27-iim";
                                reg = <0x83f98000 0x4000>;
                                interrupts = <69>;
-                               clocks = <&clks 107>;
+                               clocks = <&clks IMX5_CLK_IIM_GATE>;
                        };
 
                        owire: owire@83fa4000 {
                                compatible = "fsl,imx51-owire", "fsl,imx21-owire";
                                reg = <0x83fa4000 0x4000>;
                                interrupts = <88>;
-                               clocks = <&clks 159>;
+                               clocks = <&clks IMX5_CLK_OWIRE_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-ecspi";
                                reg = <0x83fac000 0x4000>;
                                interrupts = <37>;
-                               clocks = <&clks 53>, <&clks 54>;
+                               clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
+                                        <&clks IMX5_CLK_ECSPI2_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
                                reg = <0x83fb0000 0x4000>;
                                interrupts = <6>;
-                               clocks = <&clks 56>, <&clks 56>;
+                               clocks = <&clks IMX5_CLK_SDMA_GATE>,
+                                        <&clks IMX5_CLK_SDMA_GATE>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx51.bin";
                                compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
                                reg = <0x83fc0000 0x4000>;
                                interrupts = <38>;
-                               clocks = <&clks 55>, <&clks 55>;
+                               clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
+                                        <&clks IMX5_CLK_CSPI_IPG_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
                                reg = <0x83fc4000 0x4000>;
                                interrupts = <63>;
-                               clocks = <&clks 35>;
+                               clocks = <&clks IMX5_CLK_I2C2_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
                                reg = <0x83fc8000 0x4000>;
                                interrupts = <62>;
-                               clocks = <&clks 34>;
+                               clocks = <&clks IMX5_CLK_I2C1_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
                                reg = <0x83fcc000 0x4000>;
                                interrupts = <29>;
-                               clocks = <&clks 48>;
+                               clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>;
                                dmas = <&sdma 28 0 0>,
                                       <&sdma 29 0 0>;
                                dma-names = "rx", "tx";
                        audmux: audmux@83fd0000 {
                                compatible = "fsl,imx51-audmux", "fsl,imx31-audmux";
                                reg = <0x83fd0000 0x4000>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
+                               clock-names = "audmux";
                                status = "disabled";
                        };
 
                                #size-cells = <1>;
                                compatible = "fsl,imx51-weim";
                                reg = <0x83fda000 0x1000>;
-                               clocks = <&clks 57>;
+                               clocks = <&clks IMX5_CLK_EMI_SLOW_GATE>;
                                ranges = <
                                        0 0 0xb0000000 0x08000000
                                        1 0 0xb8000000 0x08000000
                                compatible = "fsl,imx51-nand";
                                reg = <0x83fdb000 0x1000 0xcfff0000 0x10000>;
                                interrupts = <8>;
-                               clocks = <&clks 60>;
+                               clocks = <&clks IMX5_CLK_NFC_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-pata", "fsl,imx27-pata";
                                reg = <0x83fe0000 0x4000>;
                                interrupts = <70>;
-                               clocks = <&clks 172>;
+                               clocks = <&clks IMX5_CLK_PATA_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
                                reg = <0x83fe8000 0x4000>;
                                interrupts = <96>;
-                               clocks = <&clks 50>;
+                               clocks = <&clks IMX5_CLK_SSI3_IPG_GATE>;
                                dmas = <&sdma 46 0 0>,
                                       <&sdma 47 0 0>;
                                dma-names = "rx", "tx";
                                compatible = "fsl,imx51-fec", "fsl,imx27-fec";
                                reg = <0x83fec000 0x4000>;
                                interrupts = <87>;
-                               clocks = <&clks 42>, <&clks 42>, <&clks 42>;
+                               clocks = <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>;
                                clock-names = "ipg", "ahb", "ptp";
                                status = "disabled";
                        };
                };
        };
 };
-
-&iomuxc {
-       audmux {
-               pinctrl_audmux_1: audmuxgrp-1 {
-                       fsl,pins = <
-                               MX51_PAD_AUD3_BB_TXD__AUD3_TXD 0x80000000
-                               MX51_PAD_AUD3_BB_RXD__AUD3_RXD 0x80000000
-                               MX51_PAD_AUD3_BB_CK__AUD3_TXC  0x80000000
-                               MX51_PAD_AUD3_BB_FS__AUD3_TXFS 0x80000000
-                       >;
-               };
-       };
-
-       fec {
-               pinctrl_fec_1: fecgrp-1 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_EB2__FEC_MDIO         0x80000000
-                               MX51_PAD_EIM_EB3__FEC_RDATA1       0x80000000
-                               MX51_PAD_EIM_CS2__FEC_RDATA2       0x80000000
-                               MX51_PAD_EIM_CS3__FEC_RDATA3       0x80000000
-                               MX51_PAD_EIM_CS4__FEC_RX_ER        0x80000000
-                               MX51_PAD_EIM_CS5__FEC_CRS          0x80000000
-                               MX51_PAD_NANDF_RB2__FEC_COL        0x80000000
-                               MX51_PAD_NANDF_RB3__FEC_RX_CLK     0x80000000
-                               MX51_PAD_NANDF_D9__FEC_RDATA0      0x80000000
-                               MX51_PAD_NANDF_D8__FEC_TDATA0      0x80000000
-                               MX51_PAD_NANDF_CS2__FEC_TX_ER      0x80000000
-                               MX51_PAD_NANDF_CS3__FEC_MDC        0x80000000
-                               MX51_PAD_NANDF_CS4__FEC_TDATA1     0x80000000
-                               MX51_PAD_NANDF_CS5__FEC_TDATA2     0x80000000
-                               MX51_PAD_NANDF_CS6__FEC_TDATA3     0x80000000
-                               MX51_PAD_NANDF_CS7__FEC_TX_EN      0x80000000
-                               MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK 0x80000000
-                       >;
-               };
-
-               pinctrl_fec_2: fecgrp-2 {
-                       fsl,pins = <
-                               MX51_PAD_DI_GP3__FEC_TX_ER        0x80000000
-                               MX51_PAD_DI2_PIN4__FEC_CRS        0x80000000
-                               MX51_PAD_DI2_PIN2__FEC_MDC        0x80000000
-                               MX51_PAD_DI2_PIN3__FEC_MDIO       0x80000000
-                               MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 0x80000000
-                               MX51_PAD_DI_GP4__FEC_RDATA2       0x80000000
-                               MX51_PAD_DISP2_DAT0__FEC_RDATA3   0x80000000
-                               MX51_PAD_DISP2_DAT1__FEC_RX_ER    0x80000000
-                               MX51_PAD_DISP2_DAT6__FEC_TDATA1   0x80000000
-                               MX51_PAD_DISP2_DAT7__FEC_TDATA2   0x80000000
-                               MX51_PAD_DISP2_DAT8__FEC_TDATA3   0x80000000
-                               MX51_PAD_DISP2_DAT9__FEC_TX_EN    0x80000000
-                               MX51_PAD_DISP2_DAT10__FEC_COL     0x80000000
-                               MX51_PAD_DISP2_DAT11__FEC_RX_CLK  0x80000000
-                               MX51_PAD_DISP2_DAT12__FEC_RX_DV   0x80000000
-                               MX51_PAD_DISP2_DAT13__FEC_TX_CLK  0x80000000
-                               MX51_PAD_DISP2_DAT14__FEC_RDATA0  0x80000000
-                               MX51_PAD_DISP2_DAT15__FEC_TDATA0  0x80000000
-                       >;
-               };
-       };
-
-       ecspi1 {
-               pinctrl_ecspi1_1: ecspi1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_CSPI1_MISO__ECSPI1_MISO 0x185
-                               MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 0x185
-                               MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 0x185
-                       >;
-               };
-       };
-
-       ecspi2 {
-               pinctrl_ecspi2_1: ecspi2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_NANDF_RB3__ECSPI2_MISO 0x185
-                               MX51_PAD_NANDF_D15__ECSPI2_MOSI 0x185
-                               MX51_PAD_NANDF_RB2__ECSPI2_SCLK 0x185
-                       >;
-               };
-       };
-
-       esdhc1 {
-               pinctrl_esdhc1_1: esdhc1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_SD1_CMD__SD1_CMD     0x400020d5
-                               MX51_PAD_SD1_CLK__SD1_CLK     0x20d5
-                               MX51_PAD_SD1_DATA0__SD1_DATA0 0x20d5
-                               MX51_PAD_SD1_DATA1__SD1_DATA1 0x20d5
-                               MX51_PAD_SD1_DATA2__SD1_DATA2 0x20d5
-                               MX51_PAD_SD1_DATA3__SD1_DATA3 0x20d5
-                       >;
-               };
-       };
-
-       esdhc2 {
-               pinctrl_esdhc2_1: esdhc2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_SD2_CMD__SD2_CMD     0x400020d5
-                               MX51_PAD_SD2_CLK__SD2_CLK     0x20d5
-                               MX51_PAD_SD2_DATA0__SD2_DATA0 0x20d5
-                               MX51_PAD_SD2_DATA1__SD2_DATA1 0x20d5
-                               MX51_PAD_SD2_DATA2__SD2_DATA2 0x20d5
-                               MX51_PAD_SD2_DATA3__SD2_DATA3 0x20d5
-                       >;
-               };
-       };
-
-       i2c2 {
-               pinctrl_i2c2_1: i2c2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_KEY_COL4__I2C2_SCL 0x400001ed
-                               MX51_PAD_KEY_COL5__I2C2_SDA 0x400001ed
-                       >;
-               };
-
-               pinctrl_i2c2_2: i2c2grp-2 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_D27__I2C2_SCL 0x400001ed
-                               MX51_PAD_EIM_D24__I2C2_SDA 0x400001ed
-                       >;
-               };
-
-               pinctrl_i2c2_3: i2c2grp-3 {
-                       fsl,pins = <
-                               MX51_PAD_GPIO1_2__I2C2_SCL 0x400001ed
-                               MX51_PAD_GPIO1_3__I2C2_SDA 0x400001ed
-                       >;
-               };
-       };
-
-       ipu_disp1 {
-               pinctrl_ipu_disp1_1: ipudisp1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_DISP1_DAT0__DISP1_DAT0   0x5
-                               MX51_PAD_DISP1_DAT1__DISP1_DAT1   0x5
-                               MX51_PAD_DISP1_DAT2__DISP1_DAT2   0x5
-                               MX51_PAD_DISP1_DAT3__DISP1_DAT3   0x5
-                               MX51_PAD_DISP1_DAT4__DISP1_DAT4   0x5
-                               MX51_PAD_DISP1_DAT5__DISP1_DAT5   0x5
-                               MX51_PAD_DISP1_DAT6__DISP1_DAT6   0x5
-                               MX51_PAD_DISP1_DAT7__DISP1_DAT7   0x5
-                               MX51_PAD_DISP1_DAT8__DISP1_DAT8   0x5
-                               MX51_PAD_DISP1_DAT9__DISP1_DAT9   0x5
-                               MX51_PAD_DISP1_DAT10__DISP1_DAT10 0x5
-                               MX51_PAD_DISP1_DAT11__DISP1_DAT11 0x5
-                               MX51_PAD_DISP1_DAT12__DISP1_DAT12 0x5
-                               MX51_PAD_DISP1_DAT13__DISP1_DAT13 0x5
-                               MX51_PAD_DISP1_DAT14__DISP1_DAT14 0x5
-                               MX51_PAD_DISP1_DAT15__DISP1_DAT15 0x5
-                               MX51_PAD_DISP1_DAT16__DISP1_DAT16 0x5
-                               MX51_PAD_DISP1_DAT17__DISP1_DAT17 0x5
-                               MX51_PAD_DISP1_DAT18__DISP1_DAT18 0x5
-                               MX51_PAD_DISP1_DAT19__DISP1_DAT19 0x5
-                               MX51_PAD_DISP1_DAT20__DISP1_DAT20 0x5
-                               MX51_PAD_DISP1_DAT21__DISP1_DAT21 0x5
-                               MX51_PAD_DISP1_DAT22__DISP1_DAT22 0x5
-                               MX51_PAD_DISP1_DAT23__DISP1_DAT23 0x5
-                               MX51_PAD_DI1_PIN2__DI1_PIN2       0x5 /* hsync */
-                               MX51_PAD_DI1_PIN3__DI1_PIN3       0x5 /* vsync */
-                       >;
-               };
-       };
-
-       ipu_disp2 {
-               pinctrl_ipu_disp2_1: ipudisp2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_DISP2_DAT0__DISP2_DAT0     0x5
-                               MX51_PAD_DISP2_DAT1__DISP2_DAT1     0x5
-                               MX51_PAD_DISP2_DAT2__DISP2_DAT2     0x5
-                               MX51_PAD_DISP2_DAT3__DISP2_DAT3     0x5
-                               MX51_PAD_DISP2_DAT4__DISP2_DAT4     0x5
-                               MX51_PAD_DISP2_DAT5__DISP2_DAT5     0x5
-                               MX51_PAD_DISP2_DAT6__DISP2_DAT6     0x5
-                               MX51_PAD_DISP2_DAT7__DISP2_DAT7     0x5
-                               MX51_PAD_DISP2_DAT8__DISP2_DAT8     0x5
-                               MX51_PAD_DISP2_DAT9__DISP2_DAT9     0x5
-                               MX51_PAD_DISP2_DAT10__DISP2_DAT10   0x5
-                               MX51_PAD_DISP2_DAT11__DISP2_DAT11   0x5
-                               MX51_PAD_DISP2_DAT12__DISP2_DAT12   0x5
-                               MX51_PAD_DISP2_DAT13__DISP2_DAT13   0x5
-                               MX51_PAD_DISP2_DAT14__DISP2_DAT14   0x5
-                               MX51_PAD_DISP2_DAT15__DISP2_DAT15   0x5
-                               MX51_PAD_DI2_PIN2__DI2_PIN2         0x5 /* hsync */
-                               MX51_PAD_DI2_PIN3__DI2_PIN3         0x5 /* vsync */
-                               MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK 0x5 /* CLK */
-                               MX51_PAD_DI_GP4__DI2_PIN15          0x5 /* DE */
-                       >;
-               };
-       };
-
-       kpp {
-               pinctrl_kpp_1: kppgrp-1 {
-                       fsl,pins = <
-                               MX51_PAD_KEY_ROW0__KEY_ROW0 0xe0
-                               MX51_PAD_KEY_ROW1__KEY_ROW1 0xe0
-                               MX51_PAD_KEY_ROW2__KEY_ROW2 0xe0
-                               MX51_PAD_KEY_ROW3__KEY_ROW3 0xe0
-                               MX51_PAD_KEY_COL0__KEY_COL0 0xe8
-                               MX51_PAD_KEY_COL1__KEY_COL1 0xe8
-                               MX51_PAD_KEY_COL2__KEY_COL2 0xe8
-                               MX51_PAD_KEY_COL3__KEY_COL3 0xe8
-                       >;
-               };
-       };
-
-       pata {
-               pinctrl_pata_1: patagrp-1 {
-                       fsl,pins = <
-                               MX51_PAD_NANDF_WE_B__PATA_DIOW     0x2004
-                               MX51_PAD_NANDF_RE_B__PATA_DIOR     0x2004
-                               MX51_PAD_NANDF_ALE__PATA_BUFFER_EN 0x2004
-                               MX51_PAD_NANDF_CLE__PATA_RESET_B   0x2004
-                               MX51_PAD_NANDF_WP_B__PATA_DMACK    0x2004
-                               MX51_PAD_NANDF_RB0__PATA_DMARQ     0x2004
-                               MX51_PAD_NANDF_RB1__PATA_IORDY     0x2004
-                               MX51_PAD_GPIO_NAND__PATA_INTRQ     0x2004
-                               MX51_PAD_NANDF_CS2__PATA_CS_0      0x2004
-                               MX51_PAD_NANDF_CS3__PATA_CS_1      0x2004
-                               MX51_PAD_NANDF_CS4__PATA_DA_0      0x2004
-                               MX51_PAD_NANDF_CS5__PATA_DA_1      0x2004
-                               MX51_PAD_NANDF_CS6__PATA_DA_2      0x2004
-                               MX51_PAD_NANDF_D15__PATA_DATA15    0x2004
-                               MX51_PAD_NANDF_D14__PATA_DATA14    0x2004
-                               MX51_PAD_NANDF_D13__PATA_DATA13    0x2004
-                               MX51_PAD_NANDF_D12__PATA_DATA12    0x2004
-                               MX51_PAD_NANDF_D11__PATA_DATA11    0x2004
-                               MX51_PAD_NANDF_D10__PATA_DATA10    0x2004
-                               MX51_PAD_NANDF_D9__PATA_DATA9      0x2004
-                               MX51_PAD_NANDF_D8__PATA_DATA8      0x2004
-                               MX51_PAD_NANDF_D7__PATA_DATA7      0x2004
-                               MX51_PAD_NANDF_D6__PATA_DATA6     0x2004
-                               MX51_PAD_NANDF_D5__PATA_DATA5     0x2004
-                               MX51_PAD_NANDF_D4__PATA_DATA4     0x2004
-                               MX51_PAD_NANDF_D3__PATA_DATA3     0x2004
-                               MX51_PAD_NANDF_D2__PATA_DATA2     0x2004
-                               MX51_PAD_NANDF_D1__PATA_DATA1     0x2004
-                               MX51_PAD_NANDF_D0__PATA_DATA0     0x2004
-                       >;
-               };
-       };
-
-       uart1 {
-               pinctrl_uart1_1: uart1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_UART1_RXD__UART1_RXD 0x1c5
-                               MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
-                       >;
-               };
-
-               pinctrl_uart1_rtscts_1: uart1rtscts-1 {
-                       fsl,pins = <
-                               MX51_PAD_UART1_RTS__UART1_RTS 0x1c5
-                               MX51_PAD_UART1_CTS__UART1_CTS 0x1c5
-                       >;
-               };
-       };
-
-       uart2 {
-               pinctrl_uart2_1: uart2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_UART2_RXD__UART2_RXD 0x1c5
-                               MX51_PAD_UART2_TXD__UART2_TXD 0x1c5
-                       >;
-               };
-       };
-
-       uart3 {
-               pinctrl_uart3_1: uart3grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_D25__UART3_RXD 0x1c5
-                               MX51_PAD_EIM_D26__UART3_TXD 0x1c5
-                       >;
-               };
-
-               pinctrl_uart3_rtscts_1: uart3rtscts-1 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_D27__UART3_RTS 0x1c5
-                               MX51_PAD_EIM_D24__UART3_CTS 0x1c5
-                       >;
-               };
-
-               pinctrl_uart3_2: uart3grp-2 {
-                       fsl,pins = <
-                               MX51_PAD_UART3_RXD__UART3_RXD 0x1c5
-                               MX51_PAD_UART3_TXD__UART3_TXD 0x1c5
-                       >;
-               };
-       };
-
-       usbh1 {
-               pinctrl_usbh1_1: usbh1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_USBH1_DATA0__USBH1_DATA0 0x1e5
-                               MX51_PAD_USBH1_DATA1__USBH1_DATA1 0x1e5
-                               MX51_PAD_USBH1_DATA2__USBH1_DATA2 0x1e5
-                               MX51_PAD_USBH1_DATA3__USBH1_DATA3 0x1e5
-                               MX51_PAD_USBH1_DATA4__USBH1_DATA4 0x1e5
-                               MX51_PAD_USBH1_DATA5__USBH1_DATA5 0x1e5
-                               MX51_PAD_USBH1_DATA6__USBH1_DATA6 0x1e5
-                               MX51_PAD_USBH1_DATA7__USBH1_DATA7 0x1e5
-                               MX51_PAD_USBH1_CLK__USBH1_CLK     0x1e5
-                               MX51_PAD_USBH1_DIR__USBH1_DIR     0x1e5
-                               MX51_PAD_USBH1_NXT__USBH1_NXT     0x1e5
-                               MX51_PAD_USBH1_STP__USBH1_STP     0x1e5
-                       >;
-               };
-       };
-
-       usbh2 {
-               pinctrl_usbh2_1: usbh2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_D16__USBH2_DATA0 0x1e5
-                               MX51_PAD_EIM_D17__USBH2_DATA1 0x1e5
-                               MX51_PAD_EIM_D18__USBH2_DATA2 0x1e5
-                               MX51_PAD_EIM_D19__USBH2_DATA3 0x1e5
-                               MX51_PAD_EIM_D20__USBH2_DATA4 0x1e5
-                               MX51_PAD_EIM_D21__USBH2_DATA5 0x1e5
-                               MX51_PAD_EIM_D22__USBH2_DATA6 0x1e5
-                               MX51_PAD_EIM_D23__USBH2_DATA7 0x1e5
-                               MX51_PAD_EIM_A24__USBH2_CLK   0x1e5
-                               MX51_PAD_EIM_A25__USBH2_DIR   0x1e5
-                               MX51_PAD_EIM_A27__USBH2_NXT   0x1e5
-                               MX51_PAD_EIM_A26__USBH2_STP   0x1e5
-                       >;
-               };
-       };
-};
index 174f86938c89c6917b0eccfa13b799cb9c8917ec..2bd97c3783a9f2ec36d96232ce02eaa7895a80ee 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_2>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        cd-gpios = <&gpio1 1 0>;
        wp-gpios = <&gpio1 9 0>;
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx53-ard {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX53_PAD_GPIO_1__GPIO1_1             0x80000000
                                MX53_PAD_EIM_CS1__EMI_WEIM_CS_1      0x80000000
                        >;
                };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <MX53_ESDHC1_PINGRP2>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX53_UART1_PINGRP2>;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_2>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
index 801fda728ed68528049d08a5f860e5d428121db1..214ac2e1802a779373607aabd04ac765fce4d610 100644 (file)
@@ -34,7 +34,7 @@
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        cd-gpios = <&gpio3 13 0>;
        wp-gpios = <&gpio3 14 0>;
        status = "okay";
@@ -42,7 +42,7 @@
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        fsl,spi-num-chipselects = <2>;
        cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>;
        status = "okay";
@@ -69,7 +69,7 @@
 
 &esdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc3_1>;
+       pinctrl-0 = <&pinctrl_esdhc3>;
        cd-gpios = <&gpio3 11 0>;
        wp-gpios = <&gpio3 12 0>;
        status = "okay";
@@ -79,7 +79,7 @@
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx53-evk {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX53_PAD_EIM_EB2__GPIO2_30  0x80000000
                                MX53_PAD_PATA_DA_1__GPIO7_7 0x80000000
                        >;
                };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX53_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <MX53_ESDHC1_PINGRP1>;
+               };
+
+               pinctrl_esdhc3: esdhc3grp {
+                       fsl,pins = <MX53_ESDHC3_PINGRP1>;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX53_FEC_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX53_I2C2_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX53_UART1_PINGRP1>;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        pmic: mc13892@08 {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        phy-reset-gpios = <&gpio7 6 0>;
        status = "okay";
index 7d304d02ed384e744c4789e3329ccdd80e103ac6..c623774ba3864fd3558c2f67bc2657784c33d144 100644 (file)
@@ -26,7 +26,7 @@
                        crtcs = <&ipu 1>;
                        interface-pix-fmt = "bgr666";
                        pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_ipu_disp2_1>;
+                       pinctrl-0 = <&pinctrl_ipu_disp1>;
 
                        display-timings {
                                800x480p60 {
@@ -51,6 +51,7 @@
                pwms = <&pwm1 0 3000>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
+               power-supply = <&reg_backlight>;
        };
 
        leds {
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p2v: 3p2v {
+               reg_3p2v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P2V";
                        regulator-min-microvolt = <3200000>;
                        regulator-max-microvolt = <3200000>;
                        regulator-always-on;
                };
+
+
+               reg_backlight: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "lcd-supply";
+                       regulator-min-microvolt = <3200000>;
+                       regulator-max-microvolt = <3200000>;
+                       regulator-always-on;
+               };
+
+               reg_usbh1_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio1 2 0>;
+                       enable-active-low;
+               };
        };
 
        sound {
 
 &audmux {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_2>;
+       pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
 };
 
 &can1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can1_3>;
+       pinctrl-0 = <&pinctrl_can1>;
        status = "okay";
 };
 
 &can2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can2_1>;
+       pinctrl-0 = <&pinctrl_can2>;
        status = "okay";
 };
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        cd-gpios = <&gpio1 1 0>;
        wp-gpios = <&gpio1 9 0>;
        status = "okay";
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        status = "okay";
 };
 
 &i2c1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_2>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        sgtl5000: codec@0a {
                reg = <0x0a>;
                VDDA-supply = <&reg_3p2v>;
                VDDIO-supply = <&reg_3p2v>;
-               clocks = <&clks 150>;
+               clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
        };
 };
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_2>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        clock-frequency = <400000>;
        status = "okay";
 
 
 &i2c3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c3_1>;
+       pinctrl-0 = <&pinctrl_i2c3>;
        status = "okay";
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx53-m53evk {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK       0x80000000
                                MX53_PAD_EIM_EB3__GPIO2_31              0x80000000
                                MX53_PAD_PATA_DA_0__GPIO7_6             0x80000000
-                               MX53_PAD_DISP0_DAT8__PWM1_PWMO          0x5
-
+                               MX53_PAD_GPIO_2__GPIO1_2                0x80000000
+                               MX53_PAD_GPIO_3__USBOH3_USBH1_OC        0x80000000
                        >;
                };
 
                                MX53_PAD_PATA_DATA9__GPIO2_9            0x80000000
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX53_AUDMUX_PINGRP2>;
+               };
+
+               pinctrl_can1: can1grp {
+                       fsl,pins = <MX53_CAN1_PINGRP3>;
+               };
+
+               pinctrl_can2: can2grp {
+                       fsl,pins = <MX53_CAN2_PINGRP1>;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <MX53_ESDHC1_PINGRP1>;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX53_FEC_PINGRP1>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX53_I2C1_PINGRP2>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX53_I2C2_PINGRP2>;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <MX53_I2C3_PINGRP1>;
+               };
+
+               pinctrl_ipu_disp1: ipudisp1grp {
+                       fsl,pins = <MX53_IPU_DISP1_PINGRP1>;
+               };
+
+               pinctrl_nand: nandgrp {
+                       fsl,pins = <MX53_NAND_PINGRP1>;
+               };
+
+               pinctrl_pwm1: pwm1grp {
+                       fsl,pins = <MX53_PWM1_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX53_UART1_PINGRP2>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX53_UART2_PINGRP1>;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <MX53_UART3_PINGRP1>;
+               };
        };
 };
 
 &nfc {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_nand_1>;
+       pinctrl-0 = <&pinctrl_nand>;
        nand-bus-width = <8>;
        nand-ecc-mode = "hw";
        status = "okay";
 
 &pwm1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_pwm1_1>;
+       pinctrl-0 = <&pinctrl_pwm1>;
+       status = "okay";
+};
+
+&sata {
        status = "okay";
 };
 
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_2>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_1>;
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usbh1_vbus>;
+       phy_type = "utmi";
+       status = "okay";
+};
+
+&usbotg {
+       dr_mode = "peripheral";
        status = "okay";
 };
index a630902679410f9a4f356ab430a3199bf3ac852b..0358366c5a175ec4d9a955d29820c88bebe6c8d5 100644 (file)
        model = "TQ MBa53 starter kit";
        compatible = "tq,mba53", "tq,tqma53", "fsl,imx53";
 
-       reg_backlight: fixed@0 {
-               compatible = "regulator-fixed";
-               regulator-name = "lcd-supply";
-               gpio = <&gpio2 5 0>;
-               startup-delay-us = <5000>;
-               enable-active-low;
-       };
-
        backlight {
                compatible = "pwm-backlight";
                pwms = <&pwm2 0 50000>;
                status = "disabled";
        };
 
-       reg_3p2v: 3p2v {
-               compatible = "regulator-fixed";
-               regulator-name = "3P2V";
-               regulator-min-microvolt = <3200000>;
-               regulator-max-microvolt = <3200000>;
-               regulator-always-on;
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_backlight: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "lcd-supply";
+                       gpio = <&gpio2 5 0>;
+                       startup-delay-us = <5000>;
+                       enable-active-low;
+               };
+
+               reg_3p2v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "3P2V";
+                       regulator-min-microvolt = <3200000>;
+                       regulator-max-microvolt = <3200000>;
+                       regulator-always-on;
+               };
        };
 
        sound {
 &audmux {
        status = "okay";
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
+       pinctrl-0 = <&pinctrl_audmux>;
 };
 
 &i2c2 {
        codec: sgtl5000@a {
                compatible = "fsl,sgtl5000";
                reg = <0x0a>;
-               clocks = <&clks 150>;
+               clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
                VDDA-supply = <&reg_3p2v>;
                VDDIO-supply = <&reg_3p2v>;
        };
diff --git a/arch/arm/boot/dts/imx53-pingrp.h b/arch/arm/boot/dts/imx53-pingrp.h
new file mode 100644 (file)
index 0000000..561bc1b
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX53_PINGRP_H
+#define __DTS_IMX53_PINGRP_H
+
+#define MX53_AUDMUX_PINGRP1 \
+       MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC              0x80000000 \
+       MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD              0x80000000 \
+       MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS             0x80000000 \
+       MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD              0x80000000
+
+#define MX53_AUDMUX_PINGRP2 \
+       MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC             0x80000000 \
+       MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD             0x80000000 \
+       MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS            0x80000000 \
+       MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD             0x80000000
+
+#define MX53_AUDMUX_PINGRP3 \
+       MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC             0x80000000 \
+       MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD             0x80000000 \
+       MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS            0x80000000 \
+       MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD             0x80000000
+
+#define MX53_CAN1_PINGRP1 \
+       MX53_PAD_PATA_INTRQ__CAN1_TXCAN                 0x80000000 \
+       MX53_PAD_PATA_DIOR__CAN1_RXCAN                  0x80000000
+
+#define MX53_CAN1_PINGRP2 \
+       MX53_PAD_KEY_COL2__CAN1_TXCAN                   0x80000000 \
+       MX53_PAD_KEY_ROW2__CAN1_RXCAN                   0x80000000
+
+#define MX53_CAN1_PINGRP3 \
+       MX53_PAD_GPIO_7__CAN1_TXCAN                     0x80000000 \
+       MX53_PAD_GPIO_8__CAN1_RXCAN                     0x80000000
+
+#define MX53_CAN2_PINGRP1 \
+       MX53_PAD_KEY_COL4__CAN2_TXCAN                   0x80000000 \
+       MX53_PAD_KEY_ROW4__CAN2_RXCAN                   0x80000000
+
+
+#define MX53_CSI_PINGRP1 \
+       MX53_PAD_CSI0_DATA_EN__IPU_CSI0_DATA_EN         0x1d5 \
+       MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC             0x1d5 \
+       MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC              0x1d5 \
+       MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK           0x1d5 \
+       MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19              0x1d5 \
+       MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18              0x1d5 \
+       MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17              0x1d5 \
+       MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16              0x1d5 \
+       MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15              0x1d5 \
+       MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14              0x1d5 \
+       MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13              0x1d5 \
+       MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12              0x1d5 \
+       MX53_PAD_CSI0_DAT11__IPU_CSI0_D_11              0x1d5 \
+       MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10              0x1d5 \
+       MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9                0x1d5 \
+       MX53_PAD_CSI0_DAT8__IPU_CSI0_D_8                0x1d5 \
+       MX53_PAD_CSI0_DAT7__IPU_CSI0_D_7                0x1d5 \
+       MX53_PAD_CSI0_DAT6__IPU_CSI0_D_6                0x1d5 \
+       MX53_PAD_CSI0_DAT5__IPU_CSI0_D_5                0x1d5 \
+       MX53_PAD_CSI0_DAT4__IPU_CSI0_D_4                0x1d5 \
+       MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK           0x1d5
+
+#define MX53_CSI_PINGRP2 \
+       MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC             0x1d5 \
+       MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC              0x1d5 \
+       MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK           0x1d5 \
+       MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19              0x1d5 \
+       MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18              0x1d5 \
+       MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17              0x1d5 \
+       MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16              0x1d5 \
+       MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15              0x1d5 \
+       MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14              0x1d5 \
+       MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13              0x1d5 \
+       MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12              0x1d5
+
+#define MX53_CSPI_PINGRP1 \
+       MX53_PAD_SD1_DATA0__CSPI_MISO                   0x1d5 \
+       MX53_PAD_SD1_CMD__CSPI_MOSI                     0x1d5 \
+       MX53_PAD_SD1_CLK__CSPI_SCLK                     0x1d5
+
+#define MX53_CSPI_PINGRP2 \
+       MX53_PAD_EIM_D22__CSPI_MISO                     0x1d5 \
+       MX53_PAD_EIM_D28__CSPI_MOSI                     0x1d5 \
+       MX53_PAD_EIM_D21__CSPI_SCLK                     0x1d5
+
+#define MX53_ECSPI1_PINGRP1 \
+       MX53_PAD_EIM_D16__ECSPI1_SCLK                   0x80000000 \
+       MX53_PAD_EIM_D17__ECSPI1_MISO                   0x80000000 \
+       MX53_PAD_EIM_D18__ECSPI1_MOSI                   0x80000000
+
+#define MX53_ECSPI1_PINGRP2 \
+       MX53_PAD_GPIO_19__ECSPI1_RDY                    0x80000000 \
+       MX53_PAD_EIM_EB2__ECSPI1_SS0                    0x80000000 \
+       MX53_PAD_EIM_D16__ECSPI1_SCLK                   0x80000000 \
+       MX53_PAD_EIM_D17__ECSPI1_MISO                   0x80000000 \
+       MX53_PAD_EIM_D18__ECSPI1_MOSI                   0x80000000 \
+       MX53_PAD_EIM_D19__ECSPI1_SS1                    0x80000000
+
+#define MX53_ECSPI2_PINGRP1 \
+       MX53_PAD_EIM_OE__ECSPI2_MISO                    0x80000000 \
+       MX53_PAD_EIM_CS1__ECSPI2_MOSI                   0x80000000 \
+       MX53_PAD_EIM_CS0__ECSPI2_SCLK                   0x80000000
+
+#define MX53_ESDHC1_PINGRP1 \
+       MX53_PAD_SD1_DATA0__ESDHC1_DAT0                 0x1d5 \
+       MX53_PAD_SD1_DATA1__ESDHC1_DAT1                 0x1d5 \
+       MX53_PAD_SD1_DATA2__ESDHC1_DAT2                 0x1d5 \
+       MX53_PAD_SD1_DATA3__ESDHC1_DAT3                 0x1d5 \
+       MX53_PAD_SD1_CMD__ESDHC1_CMD                    0x1d5 \
+       MX53_PAD_SD1_CLK__ESDHC1_CLK                    0x1d5
+
+#define MX53_ESDHC1_PINGRP2 \
+       MX53_PAD_SD1_DATA0__ESDHC1_DAT0                 0x1d5 \
+       MX53_PAD_SD1_DATA1__ESDHC1_DAT1                 0x1d5 \
+       MX53_PAD_SD1_DATA2__ESDHC1_DAT2                 0x1d5 \
+       MX53_PAD_SD1_DATA3__ESDHC1_DAT3                 0x1d5 \
+       MX53_PAD_PATA_DATA8__ESDHC1_DAT4                0x1d5 \
+       MX53_PAD_PATA_DATA9__ESDHC1_DAT5                0x1d5 \
+       MX53_PAD_PATA_DATA10__ESDHC1_DAT6               0x1d5 \
+       MX53_PAD_PATA_DATA11__ESDHC1_DAT7               0x1d5 \
+       MX53_PAD_SD1_CMD__ESDHC1_CMD                    0x1d5 \
+       MX53_PAD_SD1_CLK__ESDHC1_CLK                    0x1d5
+
+#define MX53_ESDHC2_PINGRP1 \
+       MX53_PAD_SD2_CMD__ESDHC2_CMD                    0x1d5 \
+       MX53_PAD_SD2_CLK__ESDHC2_CLK                    0x1d5 \
+       MX53_PAD_SD2_DATA0__ESDHC2_DAT0                 0x1d5 \
+       MX53_PAD_SD2_DATA1__ESDHC2_DAT1                 0x1d5 \
+       MX53_PAD_SD2_DATA2__ESDHC2_DAT2                 0x1d5 \
+       MX53_PAD_SD2_DATA3__ESDHC2_DAT3                 0x1d5
+
+#define MX53_ESDHC3_PINGRP1 \
+       MX53_PAD_PATA_DATA8__ESDHC3_DAT0                0x1d5 \
+       MX53_PAD_PATA_DATA9__ESDHC3_DAT1                0x1d5 \
+       MX53_PAD_PATA_DATA10__ESDHC3_DAT2               0x1d5 \
+       MX53_PAD_PATA_DATA11__ESDHC3_DAT3               0x1d5 \
+       MX53_PAD_PATA_DATA0__ESDHC3_DAT4                0x1d5 \
+       MX53_PAD_PATA_DATA1__ESDHC3_DAT5                0x1d5 \
+       MX53_PAD_PATA_DATA2__ESDHC3_DAT6                0x1d5 \
+       MX53_PAD_PATA_DATA3__ESDHC3_DAT7                0x1d5 \
+       MX53_PAD_PATA_RESET_B__ESDHC3_CMD               0x1d5 \
+       MX53_PAD_PATA_IORDY__ESDHC3_CLK                 0x1d5
+
+#define MX53_FEC_PINGRP1 \
+       MX53_PAD_FEC_MDC__FEC_MDC                       0x80000000 \
+       MX53_PAD_FEC_MDIO__FEC_MDIO                     0x80000000 \
+       MX53_PAD_FEC_REF_CLK__FEC_TX_CLK                0x80000000 \
+       MX53_PAD_FEC_RX_ER__FEC_RX_ER                   0x80000000 \
+       MX53_PAD_FEC_CRS_DV__FEC_RX_DV                  0x80000000 \
+       MX53_PAD_FEC_RXD1__FEC_RDATA_1                  0x80000000 \
+       MX53_PAD_FEC_RXD0__FEC_RDATA_0                  0x80000000 \
+       MX53_PAD_FEC_TX_EN__FEC_TX_EN                   0x80000000 \
+       MX53_PAD_FEC_TXD1__FEC_TDATA_1                  0x80000000 \
+       MX53_PAD_FEC_TXD0__FEC_TDATA_0                  0x80000000
+
+#define MX53_FEC_PINGRP2 \
+       MX53_PAD_FEC_MDC__FEC_MDC                       0x80000000 \
+       MX53_PAD_FEC_MDIO__FEC_MDIO                     0x80000000 \
+       MX53_PAD_FEC_REF_CLK__FEC_TX_CLK                0x80000000 \
+       MX53_PAD_FEC_RX_ER__FEC_RX_ER                   0x80000000 \
+       MX53_PAD_FEC_CRS_DV__FEC_RX_DV                  0x80000000 \
+       MX53_PAD_FEC_RXD1__FEC_RDATA_1                  0x80000000 \
+       MX53_PAD_FEC_RXD0__FEC_RDATA_0                  0x80000000 \
+       MX53_PAD_FEC_TX_EN__FEC_TX_EN                   0x80000000 \
+       MX53_PAD_FEC_TXD1__FEC_TDATA_1                  0x80000000 \
+       MX53_PAD_FEC_TXD0__FEC_TDATA_0                  0x80000000 \
+       MX53_PAD_KEY_ROW1__FEC_COL                      0x80000000 \
+       MX53_PAD_KEY_COL3__FEC_CRS                      0x80000000 \
+       MX53_PAD_KEY_COL2__FEC_RDATA_2                  0x80000000 \
+       MX53_PAD_KEY_COL0__FEC_RDATA_3                  0x80000000 \
+       MX53_PAD_KEY_COL1__FEC_RX_CLK                   0x80000000 \
+       MX53_PAD_KEY_ROW2__FEC_TDATA_2                  0x80000000 \
+       MX53_PAD_GPIO_19__FEC_TDATA_3                   0x80000000 \
+       MX53_PAD_KEY_ROW0__FEC_TX_ER                    0x80000000
+
+#define MX53_I2C1_PINGRP1 \
+       MX53_PAD_CSI0_DAT8__I2C1_SDA                    0xc0000000 \
+       MX53_PAD_CSI0_DAT9__I2C1_SCL                    0xc0000000
+
+#define MX53_I2C1_PINGRP2 \
+       MX53_PAD_EIM_D21__I2C1_SCL                      0xc0000000 \
+       MX53_PAD_EIM_D28__I2C1_SDA                      0xc0000000
+
+#define MX53_I2C2_PINGRP1 \
+       MX53_PAD_KEY_ROW3__I2C2_SDA                     0xc0000000 \
+       MX53_PAD_KEY_COL3__I2C2_SCL                     0xc0000000
+
+#define MX53_I2C2_PINGRP2 \
+       MX53_PAD_EIM_D16__I2C2_SDA                      0xc0000000 \
+       MX53_PAD_EIM_EB2__I2C2_SCL                      0xc0000000
+
+#define MX53_I2C3_PINGRP1 \
+       MX53_PAD_GPIO_6__I2C3_SDA                       0xc0000000 \
+       MX53_PAD_GPIO_5__I2C3_SCL                       0xc0000000
+
+#define MX53_I2C3_PINGRP2 \
+       MX53_PAD_GPIO_3__I2C3_SCL                       0xc0000000 \
+       MX53_PAD_GPIO_6__I2C3_SDA                       0xc0000000
+
+#define MX53_IPU_DISP0_PINGRP1 \
+       MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK         0x5 \
+       MX53_PAD_DI0_PIN15__IPU_DI0_PIN15               0x5 \
+       MX53_PAD_DI0_PIN2__IPU_DI0_PIN2                 0x5 \
+       MX53_PAD_DI0_PIN3__IPU_DI0_PIN3                 0x5 \
+       MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0            0x5 \
+       MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1            0x5 \
+       MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2            0x5 \
+       MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3            0x5 \
+       MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4            0x5 \
+       MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5            0x5 \
+       MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6            0x5 \
+       MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7            0x5 \
+       MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8            0x5 \
+       MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9            0x5 \
+       MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10          0x5 \
+       MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11          0x5 \
+       MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12          0x5 \
+       MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13          0x5 \
+       MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14          0x5 \
+       MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15          0x5 \
+       MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16          0x5 \
+       MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17          0x5 \
+       MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18          0x5 \
+       MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19          0x5 \
+       MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20          0x5 \
+       MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21          0x5 \
+       MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22          0x5 \
+       MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23          0x5
+
+#define MX53_IPU_DISP1_PINGRP1 \
+       MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0               0x5 \
+       MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1               0x5 \
+       MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2               0x5 \
+       MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3               0x5 \
+       MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4               0x5 \
+       MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5               0x5 \
+       MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6               0x5 \
+       MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7               0x5 \
+       MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8               0x5 \
+       MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9               0x5 \
+       MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10              0x5 \
+       MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11              0x5 \
+       MX53_PAD_EIM_A17__IPU_DISP1_DAT_12              0x5 \
+       MX53_PAD_EIM_A18__IPU_DISP1_DAT_13              0x5 \
+       MX53_PAD_EIM_A19__IPU_DISP1_DAT_14              0x5 \
+       MX53_PAD_EIM_A20__IPU_DISP1_DAT_15              0x5 \
+       MX53_PAD_EIM_A21__IPU_DISP1_DAT_16              0x5 \
+       MX53_PAD_EIM_A22__IPU_DISP1_DAT_17              0x5 \
+       MX53_PAD_EIM_A23__IPU_DISP1_DAT_18              0x5 \
+       MX53_PAD_EIM_A24__IPU_DISP1_DAT_19              0x5 \
+       MX53_PAD_EIM_D31__IPU_DISP1_DAT_20              0x5 \
+       MX53_PAD_EIM_D30__IPU_DISP1_DAT_21              0x5 \
+       MX53_PAD_EIM_D26__IPU_DISP1_DAT_22              0x5 \
+       MX53_PAD_EIM_D27__IPU_DISP1_DAT_23              0x5 \
+       MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK              0x5 \
+       MX53_PAD_EIM_DA13__IPU_DI1_D0_CS                0x5 \
+       MX53_PAD_EIM_DA14__IPU_DI1_D1_CS                0x5 \
+       MX53_PAD_EIM_DA15__IPU_DI1_PIN1                 0x5 \
+       MX53_PAD_EIM_DA11__IPU_DI1_PIN2                 0x5 \
+       MX53_PAD_EIM_DA12__IPU_DI1_PIN3                 0x5 \
+       MX53_PAD_EIM_A25__IPU_DI1_PIN12                 0x5 \
+       MX53_PAD_EIM_DA10__IPU_DI1_PIN15                0x5
+
+#define MX53_IPU_DISP2_PINGRP1 \
+       MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0             0x80000000 \
+       MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1             0x80000000 \
+       MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2             0x80000000 \
+       MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3             0x80000000 \
+       MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK             0x80000000 \
+       MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0             0x80000000 \
+       MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1             0x80000000 \
+       MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2             0x80000000 \
+       MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3             0x80000000 \
+       MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK             0x80000000
+
+#define MX53_NAND_PINGRP1 \
+       MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B             0x4 \
+       MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B             0x4 \
+       MX53_PAD_NANDF_CLE__EMI_NANDF_CLE               0x4 \
+       MX53_PAD_NANDF_ALE__EMI_NANDF_ALE               0x4 \
+       MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B             0xe0 \
+       MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0              0xe0 \
+       MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0              0x4 \
+       MX53_PAD_PATA_DATA0__EMI_NANDF_D_0              0xa4 \
+       MX53_PAD_PATA_DATA1__EMI_NANDF_D_1              0xa4 \
+       MX53_PAD_PATA_DATA2__EMI_NANDF_D_2              0xa4 \
+       MX53_PAD_PATA_DATA3__EMI_NANDF_D_3              0xa4 \
+       MX53_PAD_PATA_DATA4__EMI_NANDF_D_4              0xa4 \
+       MX53_PAD_PATA_DATA5__EMI_NANDF_D_5              0xa4 \
+       MX53_PAD_PATA_DATA6__EMI_NANDF_D_6              0xa4 \
+       MX53_PAD_PATA_DATA7__EMI_NANDF_D_7              0xa4
+
+#define MX53_OWIRE_PINGRP1 \
+       MX53_PAD_GPIO_18__OWIRE_LINE                    0x80000000
+
+#define MX53_PWM1_PINGRP1 \
+       MX53_PAD_DISP0_DAT8__PWM1_PWMO                  0x5
+
+#define MX53_PWM2_PINGRP1 \
+       MX53_PAD_GPIO_1__PWM2_PWMO                      0x80000000
+
+#define MX53_UART1_PINGRP1 \
+       MX53_PAD_CSI0_DAT10__UART1_TXD_MUX              0x1e4 \
+       MX53_PAD_CSI0_DAT11__UART1_RXD_MUX              0x1e4
+
+#define MX53_UART1_PINGRP2 \
+       MX53_PAD_PATA_DIOW__UART1_TXD_MUX               0x1e4 \
+       MX53_PAD_PATA_DMACK__UART1_RXD_MUX              0x1e4
+
+#define MX53_UART1_PINGRP3 \
+       MX53_PAD_PATA_RESET_B__UART1_CTS                0x1c5 \
+       MX53_PAD_PATA_IORDY__UART1_RTS                  0x1c5
+
+#define MX53_UART2_PINGRP1 \
+       MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX          0x1e4 \
+       MX53_PAD_PATA_DMARQ__UART2_TXD_MUX              0x1e4
+
+#define MX53_UART2_PINGRP2 \
+       MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX          0x1c5 \
+       MX53_PAD_PATA_DMARQ__UART2_TXD_MUX              0x1c5 \
+       MX53_PAD_PATA_DIOR__UART2_RTS                   0x1c5 \
+       MX53_PAD_PATA_INTRQ__UART2_CTS                  0x1c5
+
+#define MX53_UART3_PINGRP1 \
+       MX53_PAD_PATA_CS_0__UART3_TXD_MUX               0x1e4 \
+       MX53_PAD_PATA_CS_1__UART3_RXD_MUX               0x1e4 \
+       MX53_PAD_PATA_DA_1__UART3_CTS                   0x1e4 \
+       MX53_PAD_PATA_DA_2__UART3_RTS                   0x1e4
+
+#define MX53_UART3_PINGRP2 \
+       MX53_PAD_PATA_CS_0__UART3_TXD_MUX               0x1e4 \
+       MX53_PAD_PATA_CS_1__UART3_RXD_MUX               0x1e4
+
+#define MX53_UART4_PINGRP1 \
+       MX53_PAD_KEY_COL0__UART4_TXD_MUX                0x1e4 \
+       MX53_PAD_KEY_ROW0__UART4_RXD_MUX                0x1e4
+
+#define MX53_UART5_PINGRP1 \
+       MX53_PAD_KEY_COL1__UART5_TXD_MUX                0x1e4 \
+       MX53_PAD_KEY_ROW1__UART5_RXD_MUX                0x1e4
+
+#endif /* __DTS_IMX53_PINGRP_H */
index 91a5935a4aacd63879f2f2104f546d6f41bb7e60..aae06bbd821b58f6fb87baa52bdef22d0ed7fce5 100644 (file)
@@ -26,7 +26,7 @@
                crtcs = <&ipu 0>;
                interface-pix-fmt = "rgb565";
                pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ipu_disp0_1>;
+               pinctrl-0 = <&pinctrl_ipu_disp0>;
                status = "disabled";
                display-timings {
                        claawvga {
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p2v: 3p2v {
+               reg_3p2v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P2V";
                        regulator-min-microvolt = <3200000>;
                        regulator-max-microvolt = <3200000>;
                        regulator-always-on;
                };
 
-               reg_usb_vbus: usb_vbus {
+               reg_usb_vbus: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "usb_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        status = "okay";
 };
 
 
 &esdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc3_1>;
+       pinctrl-0 = <&pinctrl_esdhc3>;
        cd-gpios = <&gpio3 11 0>;
        wp-gpios = <&gpio3 12 0>;
        bus-width = <8>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx53-qsb {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000
                                MX53_PAD_PATA_DA_1__GPIO7_7 0x80000000
                        >;
                };
-       };
 
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX53_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <MX53_ESDHC1_PINGRP1>;
+               };
+
+               pinctrl_esdhc3: esdhc3grp {
+                       fsl,pins = <MX53_ESDHC3_PINGRP1>;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX53_FEC_PINGRP1>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX53_I2C1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX53_I2C2_PINGRP1>;
+               };
+
+               pinctrl_ipu_disp0: ipudisp0grp {
+                       fsl,pins = <MX53_IPU_DISP0_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX53_UART1_PINGRP1>;
+               };
+       };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        sgtl5000: codec@0a {
                reg = <0x0a>;
                VDDA-supply = <&reg_3p2v>;
                VDDIO-supply = <&reg_3p2v>;
-               clocks = <&clks 150>;
+               clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
        };
 };
 
 &i2c1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_1>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        accelerometer: mma8450@1c {
 
 &audmux {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
+       pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
 };
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        phy-reset-gpios = <&gpio7 6 0>;
        status = "okay";
index a9b6e10de0a5f52ebadb707e1f99179e6e19ae88..e84decfb05d0b9e64ed1374a0fd3ffdd390421fc 100644 (file)
@@ -40,7 +40,7 @@
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        cd-gpios = <&gpio3 13 0>;
        wp-gpios = <&gpio4 11 0>;
        status = "okay";
 
 &esdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc2_1>;
+       pinctrl-0 = <&pinctrl_esdhc2>;
        non-removable;
        status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_1>;
+       pinctrl-0 = <&pinctrl_uart3>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        fsl,spi-num-chipselects = <2>;
        cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>;
        status = "okay";
@@ -95,7 +95,7 @@
 
 &esdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc3_1>;
+       pinctrl-0 = <&pinctrl_esdhc3>;
        non-removable;
        status = "okay";
 };
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx53-smd {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX53_PAD_PATA_DATA14__GPIO2_14 0x80000000
                                MX53_PAD_PATA_DA_0__GPIO7_6    0x80000000
                        >;
                };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX53_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <MX53_ESDHC1_PINGRP1>;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <MX53_ESDHC2_PINGRP1>;
+               };
+
+               pinctrl_esdhc3: esdhc3grp {
+                       fsl,pins = <MX53_ESDHC3_PINGRP1>;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX53_FEC_PINGRP1>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX53_I2C1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX53_I2C2_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX53_UART1_PINGRP1>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX53_UART2_PINGRP1>;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <MX53_UART3_PINGRP1>;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        codec: sgtl5000@0a {
 
 &i2c1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_1>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        accelerometer: mma8450@1c {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        phy-reset-gpios = <&gpio7 6 0>;
        status = "okay";
index abd72af545bf0409ce9556afdb47dcffbf8fcea0..b6483c9a0b9994147ebd78798322ab804d41e13e 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
@@ -35,8 +38,8 @@
 
 &esdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc2_1>,
-                   <&pinctrl_tqma53_esdhc2_2>;
+       pinctrl-0 = <&pinctrl_esdhc2>,
+                   <&pinctrl_esdhc2_cdwp>;
        vmmc-supply = <&reg_3p3v>;
        wp-gpios = <&gpio1 2 0>;
        cd-gpios = <&gpio1 4 0>;
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_2>;
+       pinctrl-0 = <&pinctrl_uart3>;
        status = "disabled";
 };
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        fsl,spi-num-chipselects = <4>;
        cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>,
                   <&gpio3 24 0>, <&gpio3 25 0>;
@@ -60,7 +63,7 @@
 
 &esdhc3 { /* EMMC */
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc3_1>;
+       pinctrl-0 = <&pinctrl_esdhc3>;
        vmmc-supply = <&reg_3p3v>;
        non-removable;
        bus-width = <8>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       esdhc2_2 {
-               pinctrl_tqma53_esdhc2_2: esdhc2-tqma53-grp2 {
-                       fsl,pins = <
-                               MX53_PAD_GPIO_4__GPIO1_4        0x80000000 /* SD2_CD */
-                               MX53_PAD_GPIO_2__GPIO1_2        0x80000000 /* SD2_WP */
-                       >;
-               };
-       };
-
-       i2s {
-               pinctrl_i2s_1: i2s-grp1 {
-                       fsl,pins = <
-                                MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC  0x80000000 /* I2S_SCLK */
-                                MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD  0x80000000 /* I2S_DOUT */
-                                MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000 /* I2S_LRCLK */
-                                MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD  0x80000000 /* I2S_DIN */
-                       >;
-               };
-       };
-
-       hog {
+       imx53-tqma53 {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                 MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000 /* SSI_MCLK */
                                 MX53_PAD_GPIO_1__PWM2_PWMO      0x80000000 /* LCD_CONTRAST */
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX53_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_can1: can1grp {
+                       fsl,pins = <MX53_CAN1_PINGRP2>;
+               };
+
+               pinctrl_can2: can2grp {
+                       fsl,pins = <MX53_CAN2_PINGRP1>;
+               };
+
+               pinctrl_cspi: cspigrp {
+                       fsl,pins = <MX53_CSPI_PINGRP1>;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX53_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <MX53_ESDHC2_PINGRP1>;
+               };
+
+               pinctrl_esdhc2_cdwp: esdhc2cdwp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_4__GPIO1_4        0x80000000 /* SD2_CD */
+                               MX53_PAD_GPIO_2__GPIO1_2        0x80000000 /* SD2_WP */
+                       >;
+               };
+
+               pinctrl_esdhc3: esdhc3grp {
+                       fsl,pins = <MX53_ESDHC3_PINGRP1>;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX53_FEC_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX53_I2C2_PINGRP1>;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <MX53_I2C3_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX53_UART1_PINGRP2>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX53_UART2_PINGRP1>;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,ps = <MX53_UART3_PINGRP2>;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_2>;
+       pinctrl-0 = <&pinctrl_uart1>;
        fsl,uart-has-rtscts;
        status = "disabled";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "disabled";
 };
 
 &can1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can1_2>;
+       pinctrl-0 = <&pinctrl_can1>;
        status = "disabled";
 };
 
 &can2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can2_1>;
+       pinctrl-0 = <&pinctrl_can2>;
        status = "disabled";
 };
 
 &i2c3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c3_1>;
+       pinctrl-0 = <&pinctrl_i2c3>;
        status = "disabled";
 };
 
 &cspi {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_cspi_1>;
+       pinctrl-0 = <&pinctrl_cspi>;
        fsl,spi-num-chipselects = <3>;
        cs-gpios = <&gpio1 18 0>, <&gpio1 19 0>,
                   <&gpio1 21 0>;
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        pmic: mc34708@8 {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        status = "disabled";
 };
index f494766700a3d7b48e735ce1dc79fa550036c7a2..db4255c8e7e8a8dc42643da5ec2fa97599ef6bde 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/imx53-voipac-bsb.dts b/arch/arm/boot/dts/imx53-voipac-bsb.dts
new file mode 100644 (file)
index 0000000..61244cf
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2013 Rostislav Lisovy <lisovy@gmail.com>, PiKRON s.r.o.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx53-voipac-dmm-668.dtsi"
+
+/ {
+       sound {
+               compatible = "fsl,imx53-voipac-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx53-voipac-sgtl5000";
+               ssi-controller = <&ssi2>;
+               audio-codec = <&sgtl5000>;
+               audio-routing =
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <2>;
+               mux-ext-port = <5>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pin_gpio>;
+
+               led1 {
+                       label = "led-red";
+                       gpios = <&gpio3 29 0>;
+                       default-state = "off";
+               };
+
+               led2 {
+                       label = "led-orange";
+                       gpios = <&gpio2 31 0>;
+                       default-state = "off";
+               };
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx53-voipac {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               /* SD2_CD */
+                               MX53_PAD_EIM_D25__GPIO3_25      0x80000000
+                               /* SD2_WP */
+                               MX53_PAD_EIM_A19__GPIO2_19      0x80000000
+                       >;
+               };
+
+               led_pin_gpio: led_gpio {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D29__GPIO3_29      0x80000000
+                               MX53_PAD_EIM_EB3__GPIO2_31      0x80000000
+                       >;
+               };
+
+               /* Keyboard controller */
+               pinctrl_kpp_1: kppgrp-1 {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_9__KPP_COL_6      0xe8
+                               MX53_PAD_GPIO_4__KPP_COL_7      0xe8
+                               MX53_PAD_KEY_COL2__KPP_COL_2    0xe8
+                               MX53_PAD_KEY_COL3__KPP_COL_3    0xe8
+                               MX53_PAD_KEY_COL4__KPP_COL_4    0xe8
+                               MX53_PAD_GPIO_2__KPP_ROW_6      0xe0
+                               MX53_PAD_GPIO_5__KPP_ROW_7      0xe0
+                               MX53_PAD_KEY_ROW2__KPP_ROW_2    0xe0
+                               MX53_PAD_KEY_ROW3__KPP_ROW_3    0xe0
+                               MX53_PAD_KEY_ROW4__KPP_ROW_4    0xe0
+                       >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX53_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <MX53_ESDHC2_PINGRP1>;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <MX53_I2C3_PINGRP2>;
+               };
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>; /* SSI1 */
+       status = "okay";
+};
+
+&esdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc2>;
+       cd-gpios = <&gpio3 25 0>;
+       wp-gpios = <&gpio2 19 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       sgtl5000: codec@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_3p3v>;
+               VDDIO-supply = <&reg_3p3v>;
+               clocks = <&clks 150>;
+       };
+};
+
+&kpp {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_kpp_1>;
+       linux,keymap = <
+                       0x0203003b      /* KEY_F1 */
+                       0x0603003c      /* KEY_F2 */
+                       0x0207003d      /* KEY_F3 */
+                       0x0607003e      /* KEY_F4 */
+                       >;
+       keypad,num-rows = <8>;
+       keypad,num-columns = <1>;
+       status = "okay";
+};
+
+&ssi2 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi b/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi
new file mode 100644 (file)
index 0000000..04a2895
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2013 Rostislav Lisovy <lisovy@gmail.com>, PiKRON s.r.o.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "imx53.dtsi"
+
+/ {
+       model = "Voipac i.MX53 X53-DMM-668";
+       compatible = "voipac,imx53-dmm-668", "fsl,imx53";
+
+       memory@70000000 {
+               device_type = "memory";
+               reg = <0x70000000 0x20000000>;
+       };
+
+       memory@b0000000 {
+               device_type = "memory";
+               reg = <0xb0000000 0x20000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 31 0>; /* PEN */
+                       enable-active-high;
+               };
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx53-voipac {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               /* Make DA9053 regulator functional */
+                               MX53_PAD_GPIO_16__GPIO7_11      0x80000000
+                               /* FEC Power enable */
+                               MX53_PAD_GPIO_11__GPIO4_1       0x80000000
+                               /* FEC RST */
+                               MX53_PAD_GPIO_12__GPIO4_2       0x80000000
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX53_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX53_FEC_PINGRP1>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX53_I2C1_PINGRP2>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX53_UART1_PINGRP2>;
+               };
+
+               pinctrl_nand: nandgrp {
+                       fsl,pins = <MX53_NAND_PINGRP1>;
+               };
+       };
+};
+
+&ecspi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       fsl,spi-num-chipselects = <4>;
+       cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>, <&gpio2 16 0>, <&gpio2 17 0>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       phy-mode = "rmii";
+       phy-reset-gpios = <&gpio4 2 0>;
+       status = "okay";
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic: dialog@48 {
+               compatible = "dlg,da9053-aa", "dlg,da9052";
+               reg = <0x48>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <11 0x8>; /* low-level active IRQ at GPIO7_11 */
+
+               regulators {
+                       buck1_reg: buck1 {
+                               regulator-name = "BUCKCORE";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1400000>;
+                               regulator-always-on;
+                       };
+
+                       buck2_reg: buck2 {
+                               regulator-name = "BUCKPRO";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                       };
+
+                       buck3_reg: buck3 {
+                               regulator-name = "BUCKMEM";
+                               regulator-min-microvolt = <1420000>;
+                               regulator-max-microvolt = <1580000>;
+                               regulator-always-on;
+                       };
+
+                       buck4_reg: buck4 {
+                               regulator-name = "BUCKPERI";
+                               regulator-min-microvolt = <2370000>;
+                               regulator-max-microvolt = <2630000>;
+                               regulator-always-on;
+                       };
+
+                       ldo1_reg: ldo1 {
+                               regulator-name = "ldo1_1v3";
+                               regulator-min-microvolt = <1250000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2_reg: ldo2 {
+                               regulator-name = "ldo2_1v3";
+                               regulator-min-microvolt = <1250000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                       };
+
+                       ldo3_reg: ldo3 {
+                               regulator-name = "ldo3_3v3";
+                               regulator-min-microvolt = <3250000>;
+                               regulator-max-microvolt = <3350000>;
+                               regulator-always-on;
+                       };
+
+                       ldo4_reg: ldo4 {
+                               regulator-name = "ldo4_2v775";
+                               regulator-min-microvolt = <2770000>;
+                               regulator-max-microvolt = <2780000>;
+                               regulator-always-on;
+                       };
+
+                       ldo5_reg: ldo5 {
+                               regulator-name = "ldo5_3v3";
+                               regulator-min-microvolt = <3250000>;
+                               regulator-max-microvolt = <3350000>;
+                               regulator-always-on;
+                       };
+
+                       ldo6_reg: ldo6 {
+                               regulator-name = "ldo6_1v3";
+                               regulator-min-microvolt = <1250000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                       };
+
+                       ldo7_reg: ldo7 {
+                               regulator-name = "ldo7_2v75";
+                               regulator-min-microvolt = <2700000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-always-on;
+                       };
+
+                       ldo8_reg: ldo8 {
+                               regulator-name = "ldo8_1v8";
+                               regulator-min-microvolt = <1750000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-always-on;
+                       };
+
+                       ldo9_reg: ldo9 {
+                               regulator-name = "ldo9_1v5";
+                               regulator-min-microvolt = <1450000>;
+                               regulator-max-microvolt = <1550000>;
+                               regulator-always-on;
+                       };
+
+                       ldo10_reg: ldo10 {
+                               regulator-name = "ldo10_1v3";
+                               regulator-min-microvolt = <1250000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&nfc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_nand>;
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_vbus>;
+       phy_type = "utmi";
+       status = "okay";
+};
index 4307e80b2d2e386e53d48ee2080ca66df625565f..885dbbdcdcd7c384827fde2daacff36263b6ab5f 100644 (file)
@@ -12,6 +12,8 @@
 
 #include "skeleton.dtsi"
 #include "imx53-pinfunc.h"
+#include "imx53-pingrp.h"
+#include <dt-bindings/clock/imx5-clock.h>
 
 / {
        aliases {
                interrupt-parent = <&tzic>;
                ranges;
 
+               sata: sata@10000000 {
+                       compatible = "fsl,imx53-ahci";
+                       reg = <0x10000000 0x1000>;
+                       interrupts = <28>;
+                       clocks = <&clks IMX5_CLK_SATA_GATE>,
+                                <&clks IMX5_CLK_SATA_REF>,
+                                <&clks IMX5_CLK_AHB>;
+                       clock-names = "sata_gate", "sata_ref", "ahb";
+                       status = "disabled";
+               };
+
                ipu: ipu@18000000 {
                        #crtc-cells = <1>;
                        compatible = "fsl,imx53-ipu";
                        reg = <0x18000000 0x080000000>;
                        interrupts = <11 10>;
-                       clocks = <&clks 59>, <&clks 110>, <&clks 61>;
+                       clocks = <&clks IMX5_CLK_IPU_GATE>,
+                                <&clks IMX5_CLK_IPU_DI0_GATE>,
+                                <&clks IMX5_CLK_IPU_DI1_GATE>;
                        clock-names = "bus", "di0", "di1";
                        resets = <&src 2>;
                };
                                        compatible = "fsl,imx53-esdhc";
                                        reg = <0x50004000 0x4000>;
                                        interrupts = <1>;
-                                       clocks = <&clks 44>, <&clks 0>, <&clks 71>;
+                                       clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC1_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx53-esdhc";
                                        reg = <0x50008000 0x4000>;
                                        interrupts = <2>;
-                                       clocks = <&clks 45>, <&clks 0>, <&clks 72>;
+                                       clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC2_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                        reg = <0x5000c000 0x4000>;
                                        interrupts = <33>;
-                                       clocks = <&clks 32>, <&clks 33>;
+                                       clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
+                                                <&clks IMX5_CLK_UART3_PER_GATE>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                };
                                        compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x50010000 0x4000>;
                                        interrupts = <36>;
-                                       clocks = <&clks 51>, <&clks 52>;
+                                       clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
+                                                <&clks IMX5_CLK_ECSPI1_PER_GATE>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                };
                                        compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
                                        reg = <0x50014000 0x4000>;
                                        interrupts = <30>;
-                                       clocks = <&clks 49>;
-                                       dmas = <&sdma 24 1 0>,
-                                              <&sdma 25 1 0>;
+                                       clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>;
+                                       dmas = <&sdma 24 22 0>,
+                                              <&sdma 25 22 0>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <15>;
                                        fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
                                        compatible = "fsl,imx53-esdhc";
                                        reg = <0x50020000 0x4000>;
                                        interrupts = <3>;
-                                       clocks = <&clks 46>, <&clks 0>, <&clks 73>;
+                                       clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC3_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx53-esdhc";
                                        reg = <0x50024000 0x4000>;
                                        interrupts = <4>;
-                                       clocks = <&clks 47>, <&clks 0>, <&clks 74>;
+                                       clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC4_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
 
                        usbphy0: usbphy@0 {
                                compatible = "usb-nop-xceiv";
-                               clocks = <&clks 124>;
+                               clocks = <&clks IMX5_CLK_USB_PHY1_GATE>;
                                clock-names = "main_clk";
                                status = "okay";
                        };
 
                        usbphy1: usbphy@1 {
                                compatible = "usb-nop-xceiv";
-                               clocks = <&clks 125>;
+                               clocks = <&clks IMX5_CLK_USB_PHY2_GATE>;
                                clock-names = "main_clk";
                                status = "okay";
                        };
                                compatible = "fsl,imx53-usb", "fsl,imx27-usb";
                                reg = <0x53f80000 0x0200>;
                                interrupts = <18>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 0>;
                                fsl,usbphy = <&usbphy0>;
                                status = "disabled";
                                compatible = "fsl,imx53-usb", "fsl,imx27-usb";
                                reg = <0x53f80200 0x0200>;
                                interrupts = <14>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 1>;
                                fsl,usbphy = <&usbphy1>;
                                status = "disabled";
                                compatible = "fsl,imx53-usb", "fsl,imx27-usb";
                                reg = <0x53f80400 0x0200>;
                                interrupts = <16>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 2>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-usb", "fsl,imx27-usb";
                                reg = <0x53f80600 0x0200>;
                                interrupts = <17>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 3>;
                                status = "disabled";
                        };
                                #index-cells = <1>;
                                compatible = "fsl,imx53-usbmisc";
                                reg = <0x53f80800 0x200>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                        };
 
                        gpio1: gpio@53f84000 {
                                #interrupt-cells = <2>;
                        };
 
+                       kpp: kpp@53f94000 {
+                               compatible = "fsl,imx53-kpp", "fsl,imx21-kpp";
+                               reg = <0x53f94000 0x4000>;
+                               interrupts = <60>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
+                               status = "disabled";
+                       };
+
                        wdog1: wdog@53f98000 {
                                compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
                                reg = <0x53f98000 0x4000>;
                                interrupts = <58>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                        };
 
                        wdog2: wdog@53f9c000 {
                                compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
                                reg = <0x53f9c000 0x4000>;
                                interrupts = <59>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-gpt", "fsl,imx31-gpt";
                                reg = <0x53fa0000 0x4000>;
                                interrupts = <39>;
-                               clocks = <&clks 36>, <&clks 41>;
+                               clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
+                                        <&clks IMX5_CLK_GPT_HF_GATE>;
                                clock-names = "ipg", "per";
                        };
 
                        iomuxc: iomuxc@53fa8000 {
                                compatible = "fsl,imx53-iomuxc";
                                reg = <0x53fa8000 0x4000>;
-
-                               audmux {
-                                       pinctrl_audmux_1: audmuxgrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC  0x80000000
-                                                       MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD  0x80000000
-                                                       MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000
-                                                       MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD  0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_audmux_2: audmuxgrp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC     0x80000000
-                                                       MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD     0x80000000
-                                                       MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS    0x80000000
-                                                       MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD     0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_audmux_3: audmuxgrp-3 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC     0x80000000
-                                                       MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD     0x80000000
-                                                       MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS    0x80000000
-                                                       MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD     0x80000000
-                                               >;
-                                       };
-                               };
-
-                               fec {
-                                       pinctrl_fec_1: fecgrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_FEC_MDC__FEC_MDC        0x80000000
-                                                       MX53_PAD_FEC_MDIO__FEC_MDIO      0x80000000
-                                                       MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
-                                                       MX53_PAD_FEC_RX_ER__FEC_RX_ER    0x80000000
-                                                       MX53_PAD_FEC_CRS_DV__FEC_RX_DV   0x80000000
-                                                       MX53_PAD_FEC_RXD1__FEC_RDATA_1   0x80000000
-                                                       MX53_PAD_FEC_RXD0__FEC_RDATA_0   0x80000000
-                                                       MX53_PAD_FEC_TX_EN__FEC_TX_EN    0x80000000
-                                                       MX53_PAD_FEC_TXD1__FEC_TDATA_1   0x80000000
-                                                       MX53_PAD_FEC_TXD0__FEC_TDATA_0   0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_fec_2: fecgrp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_FEC_MDC__FEC_MDC        0x80000000
-                                                       MX53_PAD_FEC_MDIO__FEC_MDIO      0x80000000
-                                                       MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
-                                                       MX53_PAD_FEC_RX_ER__FEC_RX_ER    0x80000000
-                                                       MX53_PAD_FEC_CRS_DV__FEC_RX_DV   0x80000000
-                                                       MX53_PAD_FEC_RXD1__FEC_RDATA_1   0x80000000
-                                                       MX53_PAD_FEC_RXD0__FEC_RDATA_0   0x80000000
-                                                       MX53_PAD_FEC_TX_EN__FEC_TX_EN    0x80000000
-                                                       MX53_PAD_FEC_TXD1__FEC_TDATA_1   0x80000000
-                                                       MX53_PAD_FEC_TXD0__FEC_TDATA_0   0x80000000
-                                                       MX53_PAD_KEY_ROW1__FEC_COL       0x80000000
-                                                       MX53_PAD_KEY_COL3__FEC_CRS       0x80000000
-                                                       MX53_PAD_KEY_COL2__FEC_RDATA_2   0x80000000
-                                                       MX53_PAD_KEY_COL0__FEC_RDATA_3   0x80000000
-                                                       MX53_PAD_KEY_COL1__FEC_RX_CLK    0x80000000
-                                                       MX53_PAD_KEY_ROW2__FEC_TDATA_2   0x80000000
-                                                       MX53_PAD_GPIO_19__FEC_TDATA_3    0x80000000
-                                                       MX53_PAD_KEY_ROW0__FEC_TX_ER     0x80000000
-                                               >;
-                                       };
-                               };
-
-                               csi {
-                                       pinctrl_csi_1: csigrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_DATA_EN__IPU_CSI0_DATA_EN 0x1d5
-                                                       MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC     0x1d5
-                                                       MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC      0x1d5
-                                                       MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK   0x1d5
-                                                       MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19      0x1d5
-                                                       MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18      0x1d5
-                                                       MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17      0x1d5
-                                                       MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16      0x1d5
-                                                       MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15      0x1d5
-                                                       MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14      0x1d5
-                                                       MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13      0x1d5
-                                                       MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12      0x1d5
-                                                       MX53_PAD_CSI0_DAT11__IPU_CSI0_D_11      0x1d5
-                                                       MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10      0x1d5
-                                                       MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9        0x1d5
-                                                       MX53_PAD_CSI0_DAT8__IPU_CSI0_D_8        0x1d5
-                                                       MX53_PAD_CSI0_DAT7__IPU_CSI0_D_7        0x1d5
-                                                       MX53_PAD_CSI0_DAT6__IPU_CSI0_D_6        0x1d5
-                                                       MX53_PAD_CSI0_DAT5__IPU_CSI0_D_5        0x1d5
-                                                       MX53_PAD_CSI0_DAT4__IPU_CSI0_D_4        0x1d5
-                                                       MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK   0x1d5
-                                               >;
-                                       };
-
-                                       pinctrl_csi_2: csigrp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC     0x1d5
-                                                       MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC      0x1d5
-                                                       MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK   0x1d5
-                                                       MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19      0x1d5
-                                                       MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18      0x1d5
-                                                       MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17      0x1d5
-                                                       MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16      0x1d5
-                                                       MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15      0x1d5
-                                                       MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14      0x1d5
-                                                       MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13      0x1d5
-                                                       MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12      0x1d5
-                                               >;
-                                       };
-                               };
-
-                               cspi {
-                                       pinctrl_cspi_1: cspigrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD1_DATA0__CSPI_MISO 0x1d5
-                                                       MX53_PAD_SD1_CMD__CSPI_MOSI   0x1d5
-                                                       MX53_PAD_SD1_CLK__CSPI_SCLK   0x1d5
-                                               >;
-                                       };
-
-                                       pinctrl_cspi_2: cspigrp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_D22__CSPI_MISO 0x1d5
-                                                       MX53_PAD_EIM_D28__CSPI_MOSI 0x1d5
-                                                       MX53_PAD_EIM_D21__CSPI_SCLK 0x1d5
-                                               >;
-                                       };
-                               };
-
-                               ecspi1 {
-                                       pinctrl_ecspi1_1: ecspi1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_D16__ECSPI1_SCLK 0x80000000
-                                                       MX53_PAD_EIM_D17__ECSPI1_MISO 0x80000000
-                                                       MX53_PAD_EIM_D18__ECSPI1_MOSI 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_ecspi1_2: ecspi1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_19__ECSPI1_RDY    0x80000000
-                                                       MX53_PAD_EIM_EB2__ECSPI1_SS0    0x80000000
-                                                       MX53_PAD_EIM_D16__ECSPI1_SCLK   0x80000000
-                                                       MX53_PAD_EIM_D17__ECSPI1_MISO   0x80000000
-                                                       MX53_PAD_EIM_D18__ECSPI1_MOSI   0x80000000
-                                                       MX53_PAD_EIM_D19__ECSPI1_SS1    0x80000000
-                                               >;
-                                       };
-                               };
-
-                               ecspi2 {
-                                       pinctrl_ecspi2_1: ecspi2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_OE__ECSPI2_MISO  0x80000000
-                                                       MX53_PAD_EIM_CS1__ECSPI2_MOSI 0x80000000
-                                                       MX53_PAD_EIM_CS0__ECSPI2_SCLK 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               esdhc1 {
-                                       pinctrl_esdhc1_1: esdhc1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5
-                                                       MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5
-                                                       MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5
-                                                       MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5
-                                                       MX53_PAD_SD1_CMD__ESDHC1_CMD    0x1d5
-                                                       MX53_PAD_SD1_CLK__ESDHC1_CLK    0x1d5
-                                               >;
-                                       };
-
-                                       pinctrl_esdhc1_2: esdhc1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD1_DATA0__ESDHC1_DAT0   0x1d5
-                                                       MX53_PAD_SD1_DATA1__ESDHC1_DAT1   0x1d5
-                                                       MX53_PAD_SD1_DATA2__ESDHC1_DAT2   0x1d5
-                                                       MX53_PAD_SD1_DATA3__ESDHC1_DAT3   0x1d5
-                                                       MX53_PAD_PATA_DATA8__ESDHC1_DAT4  0x1d5
-                                                       MX53_PAD_PATA_DATA9__ESDHC1_DAT5  0x1d5
-                                                       MX53_PAD_PATA_DATA10__ESDHC1_DAT6 0x1d5
-                                                       MX53_PAD_PATA_DATA11__ESDHC1_DAT7 0x1d5
-                                                       MX53_PAD_SD1_CMD__ESDHC1_CMD      0x1d5
-                                                       MX53_PAD_SD1_CLK__ESDHC1_CLK      0x1d5
-                                               >;
-                                       };
-                               };
-
-                               esdhc2 {
-                                       pinctrl_esdhc2_1: esdhc2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD2_CMD__ESDHC2_CMD    0x1d5
-                                                       MX53_PAD_SD2_CLK__ESDHC2_CLK    0x1d5
-                                                       MX53_PAD_SD2_DATA0__ESDHC2_DAT0 0x1d5
-                                                       MX53_PAD_SD2_DATA1__ESDHC2_DAT1 0x1d5
-                                                       MX53_PAD_SD2_DATA2__ESDHC2_DAT2 0x1d5
-                                                       MX53_PAD_SD2_DATA3__ESDHC2_DAT3 0x1d5
-                                               >;
-                                       };
-                               };
-
-                               esdhc3 {
-                                       pinctrl_esdhc3_1: esdhc3grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_DATA8__ESDHC3_DAT0  0x1d5
-                                                       MX53_PAD_PATA_DATA9__ESDHC3_DAT1  0x1d5
-                                                       MX53_PAD_PATA_DATA10__ESDHC3_DAT2 0x1d5
-                                                       MX53_PAD_PATA_DATA11__ESDHC3_DAT3 0x1d5
-                                                       MX53_PAD_PATA_DATA0__ESDHC3_DAT4  0x1d5
-                                                       MX53_PAD_PATA_DATA1__ESDHC3_DAT5  0x1d5
-                                                       MX53_PAD_PATA_DATA2__ESDHC3_DAT6  0x1d5
-                                                       MX53_PAD_PATA_DATA3__ESDHC3_DAT7  0x1d5
-                                                       MX53_PAD_PATA_RESET_B__ESDHC3_CMD 0x1d5
-                                                       MX53_PAD_PATA_IORDY__ESDHC3_CLK   0x1d5
-                                               >;
-                                       };
-                               };
-
-                               can1 {
-                                       pinctrl_can1_1: can1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_INTRQ__CAN1_TXCAN 0x80000000
-                                                       MX53_PAD_PATA_DIOR__CAN1_RXCAN  0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_can1_2: can1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL2__CAN1_TXCAN 0x80000000
-                                                       MX53_PAD_KEY_ROW2__CAN1_RXCAN 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_can1_3: can1grp-3 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_7__CAN1_TXCAN     0x80000000
-                                                       MX53_PAD_GPIO_8__CAN1_RXCAN     0x80000000
-                                               >;
-                                       };
-                               };
-
-                               can2 {
-                                       pinctrl_can2_1: can2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL4__CAN2_TXCAN 0x80000000
-                                                       MX53_PAD_KEY_ROW4__CAN2_RXCAN 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               i2c1 {
-                                       pinctrl_i2c1_1: i2c1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_DAT8__I2C1_SDA 0xc0000000
-                                                       MX53_PAD_CSI0_DAT9__I2C1_SCL 0xc0000000
-                                               >;
-                                       };
-
-                                       pinctrl_i2c1_2: i2c1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_D21__I2C1_SCL      0xc0000000
-                                                       MX53_PAD_EIM_D28__I2C1_SDA      0xc0000000
-                                               >;
-                                       };
-                               };
-
-                               i2c2 {
-                                       pinctrl_i2c2_1: i2c2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_ROW3__I2C2_SDA 0xc0000000
-                                                       MX53_PAD_KEY_COL3__I2C2_SCL 0xc0000000
-                                               >;
-                                       };
-
-                                       pinctrl_i2c2_2: i2c2grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_D16__I2C2_SDA      0xc0000000
-                                                       MX53_PAD_EIM_EB2__I2C2_SCL      0xc0000000
-                                               >;
-                                       };
-                               };
-
-                               i2c3 {
-                                       pinctrl_i2c3_1: i2c3grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_6__I2C3_SDA 0xc0000000
-                                                       MX53_PAD_GPIO_5__I2C3_SCL 0xc0000000
-                                               >;
-                                       };
-                               };
-
-                               ipu_disp0 {
-                                       pinctrl_ipu_disp0_1: ipudisp0grp-1 {
-                                               fsl,pins = <
-                                               MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 0x5
-                                               MX53_PAD_DI0_PIN15__IPU_DI0_PIN15               0x5
-                                               MX53_PAD_DI0_PIN2__IPU_DI0_PIN2         0x5
-                                               MX53_PAD_DI0_PIN3__IPU_DI0_PIN3                 0x5
-                                               MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0            0x5
-                                               MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1            0x5
-                                               MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2            0x5
-                                               MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3            0x5
-                                               MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4            0x5
-                                               MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5            0x5
-                                               MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6            0x5
-                                               MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7            0x5
-                                               MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8            0x5
-                                               MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9            0x5
-                                               MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10          0x5
-                                               MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11          0x5
-                                               MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12          0x5
-                                               MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13          0x5
-                                               MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14          0x5
-                                               MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15          0x5
-                                               MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16          0x5
-                                               MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17          0x5
-                                               MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18          0x5
-                                               MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19          0x5
-                                               MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20          0x5
-                                               MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21          0x5
-                                               MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22          0x5
-                                               MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23          0x5
-                                               >;
-                                       };
-                               };
-
-                               ipu_disp1 {
-                                       pinctrl_ipu_disp1_1: ipudisp1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0       0x5
-                                                       MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1       0x5
-                                                       MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2       0x5
-                                                       MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3       0x5
-                                                       MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4       0x5
-                                                       MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5       0x5
-                                                       MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6       0x5
-                                                       MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7       0x5
-                                                       MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8       0x5
-                                                       MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9       0x5
-                                                       MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10      0x5
-                                                       MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11      0x5
-                                                       MX53_PAD_EIM_A17__IPU_DISP1_DAT_12      0x5
-                                                       MX53_PAD_EIM_A18__IPU_DISP1_DAT_13      0x5
-                                                       MX53_PAD_EIM_A19__IPU_DISP1_DAT_14      0x5
-                                                       MX53_PAD_EIM_A20__IPU_DISP1_DAT_15      0x5
-                                                       MX53_PAD_EIM_A21__IPU_DISP1_DAT_16      0x5
-                                                       MX53_PAD_EIM_A22__IPU_DISP1_DAT_17      0x5
-                                                       MX53_PAD_EIM_A23__IPU_DISP1_DAT_18      0x5
-                                                       MX53_PAD_EIM_A24__IPU_DISP1_DAT_19      0x5
-                                                       MX53_PAD_EIM_D31__IPU_DISP1_DAT_20      0x5
-                                                       MX53_PAD_EIM_D30__IPU_DISP1_DAT_21      0x5
-                                                       MX53_PAD_EIM_D26__IPU_DISP1_DAT_22      0x5
-                                                       MX53_PAD_EIM_D27__IPU_DISP1_DAT_23      0x5
-                                                       MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK      0x5
-                                                       MX53_PAD_EIM_DA13__IPU_DI1_D0_CS        0x5
-                                                       MX53_PAD_EIM_DA14__IPU_DI1_D1_CS        0x5
-                                                       MX53_PAD_EIM_DA15__IPU_DI1_PIN1         0x5
-                                                       MX53_PAD_EIM_DA11__IPU_DI1_PIN2         0x5
-                                                       MX53_PAD_EIM_DA12__IPU_DI1_PIN3         0x5
-                                                       MX53_PAD_EIM_A25__IPU_DI1_PIN12         0x5
-                                                       MX53_PAD_EIM_DA10__IPU_DI1_PIN15        0x5
-                                               >;
-                                       };
-                               };
-
-                               ipu_disp2 {
-                                       pinctrl_ipu_disp2_1: ipudisp2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0     0x80000000
-                                                       MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1     0x80000000
-                                                       MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2     0x80000000
-                                                       MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3     0x80000000
-                                                       MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK     0x80000000
-                                                       MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0     0x80000000
-                                                       MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1     0x80000000
-                                                       MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2     0x80000000
-                                                       MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3     0x80000000
-                                                       MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK     0x80000000
-                                               >;
-                                       };
-                               };
-
-                               nand {
-                                       pinctrl_nand_1: nandgrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B     0x4
-                                                       MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B     0x4
-                                                       MX53_PAD_NANDF_CLE__EMI_NANDF_CLE       0x4
-                                                       MX53_PAD_NANDF_ALE__EMI_NANDF_ALE       0x4
-                                                       MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B     0xe0
-                                                       MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0      0xe0
-                                                       MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0      0x4
-                                                       MX53_PAD_PATA_DATA0__EMI_NANDF_D_0      0xa4
-                                                       MX53_PAD_PATA_DATA1__EMI_NANDF_D_1      0xa4
-                                                       MX53_PAD_PATA_DATA2__EMI_NANDF_D_2      0xa4
-                                                       MX53_PAD_PATA_DATA3__EMI_NANDF_D_3      0xa4
-                                                       MX53_PAD_PATA_DATA4__EMI_NANDF_D_4      0xa4
-                                                       MX53_PAD_PATA_DATA5__EMI_NANDF_D_5      0xa4
-                                                       MX53_PAD_PATA_DATA6__EMI_NANDF_D_6      0xa4
-                                                       MX53_PAD_PATA_DATA7__EMI_NANDF_D_7      0xa4
-                                               >;
-                                       };
-                               };
-
-                               owire {
-                                       pinctrl_owire_1: owiregrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_18__OWIRE_LINE 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               pwm1 {
-                                       pinctrl_pwm1_1: pwm1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_DISP0_DAT8__PWM1_PWMO  0x5
-                                               >;
-                                       };
-                               };
-
-                               pwm2 {
-                                       pinctrl_pwm2_1: pwm2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_1__PWM2_PWMO      0x80000000
-                                               >;
-                                       };
-                               };
-
-                               uart1 {
-                                       pinctrl_uart1_1: uart1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_DAT10__UART1_TXD_MUX 0x1e4
-                                                       MX53_PAD_CSI0_DAT11__UART1_RXD_MUX 0x1e4
-                                               >;
-                                       };
-
-                                       pinctrl_uart1_2: uart1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_DIOW__UART1_TXD_MUX  0x1e4
-                                                       MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1e4
-                                               >;
-                                       };
-
-                                       pinctrl_uart1_3: uart1grp-3 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_RESET_B__UART1_CTS 0x1c5
-                                                       MX53_PAD_PATA_IORDY__UART1_RTS   0x1c5
-                                               >;
-                                       };
-                               };
-
-                               uart2 {
-                                       pinctrl_uart2_1: uart2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x1e4
-                                                       MX53_PAD_PATA_DMARQ__UART2_TXD_MUX     0x1e4
-                                               >;
-                                       };
-
-                                       pinctrl_uart2_2: uart2grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX  0x1c5
-                                                       MX53_PAD_PATA_DMARQ__UART2_TXD_MUX      0x1c5
-                                                       MX53_PAD_PATA_DIOR__UART2_RTS           0x1c5
-                                                       MX53_PAD_PATA_INTRQ__UART2_CTS          0x1c5
-                                               >;
-                                       };
-                               };
-
-                               uart3 {
-                                       pinctrl_uart3_1: uart3grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
-                                                       MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
-                                                       MX53_PAD_PATA_DA_1__UART3_CTS     0x1e4
-                                                       MX53_PAD_PATA_DA_2__UART3_RTS     0x1e4
-                                               >;
-                                       };
-
-                                       pinctrl_uart3_2: uart3grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
-                                                       MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
-                                               >;
-                                       };
-
-                               };
-
-                               uart4 {
-                                       pinctrl_uart4_1: uart4grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL0__UART4_TXD_MUX 0x1e4
-                                                       MX53_PAD_KEY_ROW0__UART4_RXD_MUX 0x1e4
-                                               >;
-                                       };
-                               };
-
-                               uart5 {
-                                       pinctrl_uart5_1: uart5grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL1__UART5_TXD_MUX 0x1e4
-                                                       MX53_PAD_KEY_ROW1__UART5_RXD_MUX 0x1e4
-                                               >;
-                                       };
-                               };
                        };
 
                        gpr: iomuxc-gpr@53fa8000 {
                                compatible = "fsl,imx53-ldb";
                                reg = <0x53fa8008 0x4>;
                                gpr = <&gpr>;
-                               clocks = <&clks 122>, <&clks 120>,
-                                        <&clks 115>, <&clks 116>,
-                                        <&clks 123>, <&clks 85>;
+                               clocks = <&clks IMX5_CLK_LDB_DI0_SEL>,
+                                        <&clks IMX5_CLK_LDB_DI1_SEL>,
+                                        <&clks IMX5_CLK_IPU_DI0_SEL>,
+                                        <&clks IMX5_CLK_IPU_DI1_SEL>,
+                                        <&clks IMX5_CLK_LDB_DI0_GATE>,
+                                        <&clks IMX5_CLK_LDB_DI1_GATE>;
                                clock-names = "di0_pll", "di1_pll",
                                              "di0_sel", "di1_sel",
                                              "di0", "di1";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
                                reg = <0x53fb4000 0x4000>;
-                               clocks = <&clks 37>, <&clks 38>;
+                               clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM1_HF_GATE>;
                                clock-names = "ipg", "per";
                                interrupts = <61>;
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
                                reg = <0x53fb8000 0x4000>;
-                               clocks = <&clks 39>, <&clks 40>;
+                               clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM2_HF_GATE>;
                                clock-names = "ipg", "per";
                                interrupts = <94>;
                        };
                                compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                reg = <0x53fbc000 0x4000>;
                                interrupts = <31>;
-                               clocks = <&clks 28>, <&clks 29>;
+                               clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART1_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                reg = <0x53fc0000 0x4000>;
                                interrupts = <32>;
-                               clocks = <&clks 30>, <&clks 31>;
+                               clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART2_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
                                reg = <0x53fc8000 0x4000>;
                                interrupts = <82>;
-                               clocks = <&clks 158>, <&clks 157>;
+                               clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>,
+                                        <&clks IMX5_CLK_CAN1_SERIAL_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
                                reg = <0x53fcc000 0x4000>;
                                interrupts = <83>;
-                               clocks = <&clks 87>, <&clks 86>;
+                               clocks = <&clks IMX5_CLK_CAN2_IPG_GATE>,
+                                        <&clks IMX5_CLK_CAN2_SERIAL_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
                                reg = <0x53fec000 0x4000>;
                                interrupts = <64>;
-                               clocks = <&clks 88>;
+                               clocks = <&clks IMX5_CLK_I2C3_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                reg = <0x53ff0000 0x4000>;
                                interrupts = <13>;
-                               clocks = <&clks 65>, <&clks 66>;
+                               clocks = <&clks IMX5_CLK_UART4_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART4_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-iim", "fsl,imx27-iim";
                                reg = <0x63f98000 0x4000>;
                                interrupts = <69>;
-                               clocks = <&clks 107>;
+                               clocks = <&clks IMX5_CLK_IIM_GATE>;
                        };
 
                        uart5: serial@63f90000 {
                                compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                reg = <0x63f90000 0x4000>;
                                interrupts = <86>;
-                               clocks = <&clks 67>, <&clks 68>;
+                               clocks = <&clks IMX5_CLK_UART5_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART5_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                        owire: owire@63fa4000 {
                                compatible = "fsl,imx53-owire", "fsl,imx21-owire";
                                reg = <0x63fa4000 0x4000>;
-                               clocks = <&clks 159>;
+                               clocks = <&clks IMX5_CLK_OWIRE_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
                                reg = <0x63fac000 0x4000>;
                                interrupts = <37>;
-                               clocks = <&clks 53>, <&clks 54>;
+                               clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
+                                        <&clks IMX5_CLK_ECSPI2_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-sdma", "fsl,imx35-sdma";
                                reg = <0x63fb0000 0x4000>;
                                interrupts = <6>;
-                               clocks = <&clks 56>, <&clks 56>;
+                               clocks = <&clks IMX5_CLK_SDMA_GATE>,
+                                        <&clks IMX5_CLK_SDMA_GATE>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
                                compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
                                reg = <0x63fc0000 0x4000>;
                                interrupts = <38>;
-                               clocks = <&clks 55>, <&clks 55>;
+                               clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
+                                        <&clks IMX5_CLK_CSPI_IPG_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
                                reg = <0x63fc4000 0x4000>;
                                interrupts = <63>;
-                               clocks = <&clks 35>;
+                               clocks = <&clks IMX5_CLK_I2C2_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
                                reg = <0x63fc8000 0x4000>;
                                interrupts = <62>;
-                               clocks = <&clks 34>;
+                               clocks = <&clks IMX5_CLK_I2C1_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
                                reg = <0x63fcc000 0x4000>;
                                interrupts = <29>;
-                               clocks = <&clks 48>;
+                               clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>;
                                dmas = <&sdma 28 0 0>,
                                       <&sdma 29 0 0>;
                                dma-names = "rx", "tx";
                                compatible = "fsl,imx53-nand";
                                reg = <0x63fdb000 0x1000 0xf7ff0000 0x10000>;
                                interrupts = <8>;
-                               clocks = <&clks 60>;
+                               clocks = <&clks IMX5_CLK_NFC_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
                                reg = <0x63fe8000 0x4000>;
                                interrupts = <96>;
-                               clocks = <&clks 50>;
+                               clocks = <&clks IMX5_CLK_SSI3_IPG_GATE>;
                                dmas = <&sdma 46 0 0>,
                                       <&sdma 47 0 0>;
                                dma-names = "rx", "tx";
                                compatible = "fsl,imx53-fec", "fsl,imx25-fec";
                                reg = <0x63fec000 0x4000>;
                                interrupts = <87>;
-                               clocks = <&clks 42>, <&clks 42>, <&clks 42>;
+                               clocks = <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>;
                                clock-names = "ipg", "ahb", "ptp";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-tve";
                                reg = <0x63ff0000 0x1000>;
                                interrupts = <92>;
-                               clocks = <&clks 69>, <&clks 116>;
+                               clocks = <&clks IMX5_CLK_TVE_GATE>,
+                                        <&clks IMX5_CLK_IPU_DI1_SEL>;
                                clock-names = "tve", "di_sel";
                                crtcs = <&ipu 1>;
                                status = "disabled";
                                compatible = "fsl,imx53-vpu";
                                reg = <0x63ff4000 0x1000>;
                                interrupts = <9>;
-                               clocks = <&clks 63>, <&clks 63>;
+                               clocks = <&clks IMX5_CLK_VPU_GATE>,
+                                        <&clks IMX5_CLK_VPU_GATE>;
                                clock-names = "per", "ahb";
                                iram = <&ocram>;
                                status = "disabled";
                ocram: sram@f8000000 {
                        compatible = "mmio-sram";
                        reg = <0xf8000000 0x20000>;
-                       clocks = <&clks 186>;
+                       clocks = <&clks IMX5_CLK_OCRAM>;
                };
        };
 };
diff --git a/arch/arm/boot/dts/imx6dl-gw51xx.dts b/arch/arm/boot/dts/imx6dl-gw51xx.dts
new file mode 100644 (file)
index 0000000..4bd055f
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw51xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite GW51XX";
+       compatible = "gw,imx6dl-gw51xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw52xx.dts b/arch/arm/boot/dts/imx6dl-gw52xx.dts
new file mode 100644 (file)
index 0000000..c913605
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw52xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite GW52XX";
+       compatible = "gw,imx6dl-gw52xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw53xx.dts b/arch/arm/boot/dts/imx6dl-gw53xx.dts
new file mode 100644 (file)
index 0000000..61818a1
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw53xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite GW53XX";
+       compatible = "gw,imx6dl-gw53xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw54xx.dts b/arch/arm/boot/dts/imx6dl-gw54xx.dts
new file mode 100644 (file)
index 0000000..ab38b67
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw54xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite GW54XX";
+       compatible = "gw,imx6dl-gw54xx", "gw,ventana", "fsl,imx6dl";
+};
index b81a7a4ebab6758926143ebd51d59b033a51df23..7499eee1dc923f3d28698bb173ae458711a9b62d 100644 (file)
 #define MX6QDL_PAD_RGMII_TXC__GPIO6_IO19            0x2d8 0x6c0 0x000 0x5 0x0
 #define MX6QDL_PAD_RGMII_TXC__XTALOSC_REF_CLK_24M   0x2d8 0x6c0 0x000 0x7 0x0
 #define MX6QDL_PAD_SD1_CLK__SD1_CLK                 0x2dc 0x6c4 0x928 0x0 0x1
+#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT          0x2dc 0x6c4 0x000 0x2 0x0
 #define MX6QDL_PAD_SD1_CLK__GPT_CLKIN               0x2dc 0x6c4 0x000 0x3 0x0
 #define MX6QDL_PAD_SD1_CLK__GPIO1_IO20              0x2dc 0x6c4 0x000 0x5 0x0
 #define MX6QDL_PAD_SD1_CMD__SD1_CMD                 0x2e0 0x6c8 0x000 0x0 0x0
index 9e8ae118fdd4e6c6c1df48a0b4a66c20e0504ae6..b2f2699e6dcaa0cfa3dd7bbaad1e678ee3993b5d 100644 (file)
@@ -8,7 +8,9 @@
  *
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "imx6dl-pinfunc.h"
+#include "imx6qdl-pingrp.h"
 #include "imx6qdl.dtsi"
 
 / {
 
                        pxp: pxp@020f0000 {
                                reg = <0x020f0000 0x4000>;
-                               interrupts = <0 98 0x04>;
+                               interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        epdc: epdc@020f4000 {
                                reg = <0x020f4000 0x4000>;
-                               interrupts = <0 97 0x04>;
+                               interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        lcdif: lcdif@020f8000 {
                                reg = <0x020f8000 0x4000>;
-                               interrupts = <0 39 0x04>;
+                               interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
                        };
                };
 
@@ -65,7 +67,7 @@
                                #size-cells = <0>;
                                compatible = "fsl,imx1-i2c";
                                reg = <0x021f8000 0x4000>;
-                               interrupts = <0 35 0x04>;
+                               interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
                                status = "disabled";
                        };
                };
index edf1bd9671642e9230b61d71c55a18a7b7c2a554..9c00b739dc3024371263c0195909647eff1369ae 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
+
+               reg_usb_otg_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
        };
 
        leds {
@@ -46,7 +59,7 @@
 
 &gpmi {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
        status = "disabled"; /* gpmi nand conflicts with SD */
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6q-arm2 {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x80000000
                        >;
                };
-       };
 
-       arm2 {
-               pinctrl_usdhc3_arm2: usdhc3grp-arm2 {
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP2>;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <MX6QDL_GPMI_NAND_PINGRP1>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX6QDL_UART2_PINGRP2>;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <MX6QDL_UART4_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D8>;
+               };
+
+               pinctrl_usdhc3_cdwp: usdhc3cdwp {
                        fsl,pins = <
                                MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
                                MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
                        >;
                };
+
+               pinctrl_usdhc4: usdhc4grp {
+                       fsl,pins = <MX6QDL_USDHC4_PINGRP_D8>;
+               };
        };
 };
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_2>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        status = "okay";
 };
 
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
 &usdhc3 {
        cd-gpios = <&gpio6 11 0>;
        wp-gpios = <&gpio6 14 0>;
        vmmc-supply = <&reg_3p3v>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_1
-                    &pinctrl_usdhc3_arm2>;
+       pinctrl-0 = <&pinctrl_usdhc3
+                    &pinctrl_usdhc3_cdwp>;
        status = "okay";
 };
 
        non-removable;
        vmmc-supply = <&reg_3p3v>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc4_1>;
+       pinctrl-0 = <&pinctrl_usdhc4>;
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_2>;
+       pinctrl-0 = <&pinctrl_uart2>;
        fsl,dte-mode;
        fsl,uart-has-rtscts;
        status = "okay";
 
 &uart4 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart4_1>;
+       pinctrl-0 = <&pinctrl_uart4>;
        status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts
new file mode 100644 (file)
index 0000000..1a8ee79
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2013 CompuLab Ltd.
+ *
+ * Author: Valentin Raevsky <valentin@compulab.co.il>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+       model = "CompuLab CM-FX6";
+       compatible = "compulab,cm-fx6", "fsl,imx6q";
+
+       memory {
+               reg = <0x10000000 0x80000000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               heartbeat-led {
+                       label = "Heartbeat";
+                       gpios = <&gpio2 31 0>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&iomuxc {
+       imx6q-cm-fx6 {
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <MX6QDL_GPMI_NAND_PINGRP1>;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <MX6QDL_UART4_PINGRP1>;
+               };
+       };
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
new file mode 100644 (file)
index 0000000..84f5143
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2013 Data Modul AG
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+
+/ {
+       model = "Data Modul eDM-QMX6 Board";
+       compatible = "dmo,imx6q-edmqmx6", "fsl,imx6q";
+
+       aliases {
+               gpio7 = &stmpe_gpio;
+       };
+
+       memory {
+               reg = <0x10000000 0x80000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio7 12 0>;
+               };
+
+               reg_usb_host1: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_host1_en";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio3 31 0>;
+                       enable-active-high;
+               };
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio3 23 0>;
+       status = "okay";
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2
+                    &pinctrl_stmpe>;
+       status = "okay";
+
+       stmpe: stmpe1601@40 {
+               compatible = "st,stmpe1601";
+               reg = <0x40>;
+               interrupts = <30 0>;
+               interrupt-parent = <&gpio3>;
+
+               stmpe_gpio: stmpe_gpio {
+                       compatible = "st,stmpe-gpio";
+               };
+       };
+
+       temp1: ad7414@4c {
+               compatible = "ad,ad7414";
+               reg = <0x4c>;
+       };
+
+       temp2: ad7414@4d {
+               compatible = "ad,ad7414";
+               reg = <0x4d>;
+       };
+
+       rtc: m41t62@68 {
+               compatible = "stm,m41t62";
+               reg = <0x68>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6q-dmo-edmqmx6 {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x80000000
+                               MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x80000000
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX6QDL_I2C2_PINGRP3>;
+               };
+
+               pinctrl_stmpe: stmpegrp {
+                       fsl,pins = <MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x80000000>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6QDL_UART1_PINGRP2>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX6QDL_UART2_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_host1>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw51xx.dts b/arch/arm/boot/dts/imx6q-gw51xx.dts
new file mode 100644 (file)
index 0000000..af4929a
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw54xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Quad GW51XX";
+       compatible = "gw,imx6q-gw51xx", "gw,ventana", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw52xx.dts b/arch/arm/boot/dts/imx6q-gw52xx.dts
new file mode 100644 (file)
index 0000000..5f71ddb
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw52xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Quad GW52XX";
+       compatible = "gw,imx6q-gw52xx", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw53xx.dts b/arch/arm/boot/dts/imx6q-gw53xx.dts
new file mode 100644 (file)
index 0000000..360c316
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw53xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Quad GW53XX";
+       compatible = "gw,imx6q-gw53xx", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts
new file mode 100644 (file)
index 0000000..5f76342
--- /dev/null
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+       model = "Gateworks Ventana GW5400-A";
+       compatible = "gw,imx6q-gw5400-a", "gw,ventana", "fsl,imx6q";
+
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               ethernet0 = &fec;
+               ethernet1 = &eth1;
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+               sky2 = &eth1;
+               ssi0 = &ssi1;
+               spi0 = &ecspi1;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+               usdhc2 = &usdhc3;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 10 0>; /* 106 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 5 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_1p0v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "1P0V";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_h1_vbus: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_h1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&ecspi1 {
+       fsl,spi-num-chipselects = <1>;
+       cs-gpios = <&gpio3 19 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       status = "okay";
+
+       flash: m25p80@0 {
+               compatible = "sst,w25q256";
+               spi-max-frequency = <30000000>;
+               reg = <0>;
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pmic: pfuze100@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3b_reg: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+
+       pciswitch: pex8609@3f {
+               compatible = "plx,pex8609";
+               reg = <0x3f>;
+       };
+
+       pciclkgen: si52147@6b {
+               compatible = "sil,si52147";
+               reg = <0x6b>;
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accelerometer: mma8450@1c {
+               compatible = "fsl,mma8450";
+               reg = <0x1c>;
+       };
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 201>;
+               VDDA-supply = <&sw4_reg>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+
+       hdmiin: adv7611@4c {
+               compatible = "adi,adv7611";
+               reg = <0x4c>;
+       };
+
+       touchscreen: egalax_ts@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <12 2>; /* gpio7_12 active low */
+               wakeup-gpios = <&gpio7 12 0>;
+       };
+
+       videoout: adv7393@2a {
+               compatible = "adi,adv7393";
+               reg = <0x2a>;
+       };
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6q-gw5400-a {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22    0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_EIM_D19__GPIO3_IO19    0x80000000 /* SPINOR_CS0# */
+                               MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
+                               MX6QDL_PAD_ENET_TXD1__GPIO1_IO29  0x80000000 /* PCIE RST */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1      0x000130b0 /* AUD4_MCK */
+                               MX6QDL_PAD_GPIO_5__GPIO1_IO05     0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_GPIO_17__GPIO7_IO12    0x80000000 /* TOUCH_IRQ# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06   0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_COL2__GPIO4_IO10   0x80000000 /* user2 led */
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15   0x80000000 /* user3 led */
+                               MX6QDL_PAD_SD1_DAT0__GPIO1_IO16   0x80000000 /* USBHUB_RST# */
+                               MX6QDL_PAD_SD1_DAT3__GPIO1_IO21   0x80000000 /* MIPI_DIO */
+                        >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX6QDL_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX6QDL_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX6QDL_I2C1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX6QDL_I2C2_PINGRP2>;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <MX6QDL_I2C3_PINGRP2>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6QDL_UART1_PINGRP2>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX6QDL_UART2_PINGRP3>;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <MX6QDL_UART5_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+       lvds-channel@0 {
+               crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 29 0>;
+       status = "okay";
+
+       eth1: sky2@8 { /* MAC/PHY on bus 8 */
+               compatible = "marvell,sky2";
+       };
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_h1_vbus>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw54xx.dts b/arch/arm/boot/dts/imx6q-gw54xx.dts
new file mode 100644 (file)
index 0000000..ab518d6
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw54xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Quad GW54XX";
+       compatible = "gw,imx6q-gw54xx", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+       status = "okay";
+};
index 1a3b50d4d8fa4632afb7e8bc28a215b389f50e26..05b4796b1318d9b865cb60ca16114b7a92f05682 100644 (file)
@@ -22,7 +22,7 @@
 
 &ecspi3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi3_1>;
+       pinctrl-0 = <&pinctrl_ecspi3>;
        status = "okay";
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio4 24 0>;
@@ -36,7 +36,7 @@
 
 &i2c1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_1>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        eeprom@50 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6q-phytec-pfla02 {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
                                MX6QDL_PAD_DI0_PIN15__GPIO4_IO17  0x80000000 /* PMIC interrupt */
                        >;
                };
-       };
 
-       pfla02 {
-               pinctrl_usdhc3_pfla02: usdhc3grp-pfla02 {
+               pinctrl_ecspi3: ecspi3grp {
+                       fsl,pins = <MX6QDL_ECSPI3_PINGRP1>;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP3>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX6QDL_I2C1_PINGRP1>;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <MX6QDL_UART4_PINGRP1>;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <MX6QDL_USDHC2_PINGRP_D4>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
+
+               pinctrl_usdhc3_cdwp: usdhc3cdwp {
                        fsl,pins = <
                                MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
                                MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_3>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        phy-reset-gpios = <&gpio3 23 0>;
        status = "disabled";
 
 &uart4 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart4_1>;
+       pinctrl-0 = <&pinctrl_uart4>;
        status = "disabled";
 };
 
 &usdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2_2>;
+       pinctrl-0 = <&pinctrl_usdhc2>;
        cd-gpios = <&gpio1 4 0>;
        wp-gpios = <&gpio1 2 0>;
        status = "disabled";
 
 &usdhc3 {
         pinctrl-names = "default";
-        pinctrl-0 = <&pinctrl_usdhc3_2
-                    &pinctrl_usdhc3_pfla02>;
+        pinctrl-0 = <&pinctrl_usdhc3
+                    &pinctrl_usdhc3_cdwp>;
         cd-gpios = <&gpio1 27 0>;
         wp-gpios = <&gpio1 29 0>;
         status = "disabled";
index 97ed0816a6e0c749b5bccd2562b2cbe8655ff326..e5834b2110cf40dc0e2830c23512732a65602573 100644 (file)
 #define MX6QDL_PAD_SD1_DAT2__WDOG1_RESET_B_DEB      0x34c 0x734 0x000 0x6 0x0
 #define MX6QDL_PAD_SD1_CLK__SD1_CLK                 0x350 0x738 0x000 0x0 0x0
 #define MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK             0x350 0x738 0x828 0x1 0x0
+#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT          0x350 0x738 0x000 0x2 0x0
 #define MX6QDL_PAD_SD1_CLK__GPT_CLKIN               0x350 0x738 0x000 0x3 0x0
 #define MX6QDL_PAD_SD1_CLK__GPIO1_IO20              0x350 0x738 0x000 0x5 0x0
 #define MX6QDL_PAD_SD2_CLK__SD2_CLK                 0x354 0x73c 0x000 0x0 0x0
index f004913f7d80a1f2c0df7b229f7a011b17399818..fca8f22091466d204f2670081af858b04d3a477e 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_2p5v: 2p5v {
+               reg_2p5v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "2P5V";
                        regulator-min-microvolt = <2500000>;
                        regulator-max-microvolt = <2500000>;
                        regulator-always-on;
                };
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
 
-               reg_usb_otg_vbus: usb_otg_vbus {
+               reg_usb_otg_vbus: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "usb_otg_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
 };
 
 &audmux {
-       status = "okay";
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
 };
 
 &ecspi1 {
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio3 19 0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        status = "okay";
 
        flash: m25p80@0 {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_1>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        phy-reset-gpios = <&gpio3 23 0>;
        status = "okay";
 };
 
 &i2c1 {
-       status = "okay";
        clock-frequency = <100000>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_1>;
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
 
        codec: sgtl5000@0a {
                compatible = "fsl,sgtl5000";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6q-sabrelite {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x80000000
                                MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000
                                MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0
                                MX6QDL_PAD_GPIO_0__CCM_CLKO1    0x80000000
-                               MX6QDL_PAD_EIM_D23__GPIO3_IO23  0x80000000
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX6QDL_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX6QDL_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX6QDL_I2C1_PINGRP1>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX6QDL_UART2_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
+
+               pinctrl_usdhc4: usdhc4grp {
+                       fsl,pins = <MX6QDL_USDHC4_PINGRP_D4>;
+               };
        };
 };
 
 };
 
 &uart2 {
-       status = "okay";
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
 };
 
 &usbh1 {
 &usbotg {
        vbus-supply = <&reg_usb_otg_vbus>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg_1>;
+       pinctrl-0 = <&pinctrl_usbotg>;
        disable-over-current;
        status = "okay";
 };
 
 &usdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_2>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
        cd-gpios = <&gpio7 0 0>;
        wp-gpios = <&gpio7 1 0>;
        vmmc-supply = <&reg_3p3v>;
 
 &usdhc4 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc4_2>;
+       pinctrl-0 = <&pinctrl_usdhc4>;
        cd-gpios = <&gpio2 6 0>;
        wp-gpios = <&gpio2 7 0>;
        vmmc-supply = <&reg_3p3v>;
index ee6addf149af988aa560ee3fdc54a3dc27817c36..852675a489ac7899dafbc8b26b3fb9b19acc4a3f 100644 (file)
        };
 };
 
+
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_1>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        status = "okay";
 };
 
+&iomuxc {
+       imx6q-sbc6x {
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6QDL_UART1_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
+       };
+};
+
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &usbotg {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg_1>;
+       pinctrl-0 = <&pinctrl_usbotg>;
        disable-over-current;
        status = "okay";
 };
 
 &usdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_2>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
        status = "okay";
 };
index 6e1ccdc019a74c1c5416ac06fbc01c4c17b5f489..47a5eda0770717c25eb7e742c787b49c34999cf2 100644 (file)
        };
 };
 
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       status = "okay";
+};
+
+&iomuxc {
+       imx6q-udoo {
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX6QDL_UART2_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
+       };
+};
+
 &sata {
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &usdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_2>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
        non-removable;
        status = "okay";
 };
index f024ef28b34b9373895dbbb913c475eebb33298a..101c434660d28b93dc62236a0661b79ced0d9dff 100644 (file)
@@ -8,7 +8,9 @@
  *
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "imx6q-pinfunc.h"
+#include "imx6qdl-pingrp.h"
 #include "imx6qdl.dtsi"
 
 / {
@@ -74,7 +76,7 @@
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02018000 0x4000>;
-                                       interrupts = <0 35 0x04>;
+                                       interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 116>, <&clks 116>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                sata: sata@02200000 {
                        compatible = "fsl,imx6q-ahci";
                        reg = <0x02200000 0x4000>;
-                       interrupts = <0 39 0x04>;
+                       interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
                        clocks =  <&clks 154>, <&clks 187>, <&clks 105>;
                        clock-names = "sata", "sata_ref", "ahb";
                        status = "disabled";
                        #crtc-cells = <1>;
                        compatible = "fsl,imx6q-ipu";
                        reg = <0x02800000 0x400000>;
-                       interrupts = <0 8 0x4 0 7 0x4>;
+                       interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 7 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clks 133>, <&clks 134>, <&clks 137>;
                        clock-names = "bus", "di0", "di1";
                        resets = <&src 4>;
diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
new file mode 100644 (file)
index 0000000..fb29da0
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               can0 = &can1;
+               ethernet0 = &fec;
+               led0 = &led0;
+               led1 = &led1;
+               nand = &gpmi;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x20000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 26 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_5p0v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "5P0V";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pmic: ltc3676@3c {
+               compatible = "ltc,ltc3676";
+               reg = <0x3c>;
+
+               regulators {
+                       sw1_reg: ltc3676__sw1 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw2_reg: ltc3676__sw2 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3_reg: ltc3676__sw3 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: ltc3676__sw4 {
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2_reg: ltc3676__ldo2 {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo4_reg: ltc3676__ldo4 {
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+               };
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6qdl-gw51xx {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_A19__GPIO2_IO19   0x80000000 /* MEZZ_DIO0 */
+                               MX6QDL_PAD_EIM_A20__GPIO2_IO18   0x80000000 /* MEZZ_DIO1 */
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22   0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
+                               MX6QDL_PAD_GPIO_0__GPIO1_IO00    0x80000000 /* PCIE_RST# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06  0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_ROW0__GPIO4_IO07  0x80000000 /* user2 led */
+                        >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <MX6QDL_GPMI_NAND_PINGRP1_NODQS>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX6QDL_I2C1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX6QDL_I2C2_PINGRP2>;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <MX6QDL_I2C3_PINGRP2>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6QDL_UART1_PINGRP2>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX6QDL_UART2_PINGRP3>;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <MX6QDL_UART3_PINGRP3>;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <MX6QDL_UART5_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 0 0>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
new file mode 100644 (file)
index 0000000..a6c77b5
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               ethernet0 = &fec;
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+               nand = &gpmi;
+               ssi0 = &ssi1;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+               usdhc2 = &usdhc3;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 1>; /* 111 - MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x20000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 26 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_1p0v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "1P0V";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-always-on;
+               };
+
+               /* remove this fixed regulator once ltc3676__sw2 driver available */
+               reg_1p8v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "1P8V";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_5p0v: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "5P0V";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pciswitch: pex8609@3f {
+               compatible = "plx,pex8609";
+               reg = <0x3f>;
+       };
+
+       pmic: ltc3676@3c {
+               compatible = "ltc,ltc3676";
+               reg = <0x3c>;
+
+               regulators {
+                       sw1_reg: ltc3676__sw1 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw2_reg: ltc3676__sw2 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3_reg: ltc3676__sw3 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: ltc3676__sw4 {
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2_reg: ltc3676__ldo2 {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo3_reg: ltc3676__ldo3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo4_reg: ltc3676__ldo4 {
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+               };
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accelerometer: fxos8700@1e {
+               compatible = "fsl,fxos8700";
+               reg = <0x13>;
+       };
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 169>;
+               VDDA-supply = <&reg_1p8v>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+
+       touchscreen: egalax_ts@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <12 2>; /* gpio7_12 active low */
+               wakeup-gpios = <&gpio7 12 0>;
+       };
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6qdl-gw52xx {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_A19__GPIO2_IO19   0x80000000 /* MEZZ_DIO0 */
+                               MX6QDL_PAD_EIM_A20__GPIO2_IO18   0x80000000 /* MEZZ_DIO1 */
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22   0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_EIM_D31__GPIO3_IO31   0x80000000 /* VIDDEC_PDN# */
+                               MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
+                               MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE_RST# */
+                               MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000 /* GPS_PWDN */
+                               MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1     0x000130b0 /* AUD4_MCK */
+                               MX6QDL_PAD_GPIO_2__GPIO1_IO02    0x80000000 /* USB_SEL_PCI */
+                               MX6QDL_PAD_GPIO_17__GPIO7_IO12   0x80000000 /* TOUCH_IRQ# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06  0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_ROW0__GPIO4_IO07  0x80000000 /* user2 led */
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15  0x80000000 /* user3 led */
+                               MX6QDL_PAD_SD2_CMD__GPIO1_IO11   0x80000000 /* LVDS_TCH# */
+                               MX6QDL_PAD_SD3_DAT5__GPIO7_IO00  0x80000000 /* SD3_CD# */
+                               MX6QDL_PAD_SD4_DAT3__GPIO2_IO11  0x80000000 /* UART2_EN# */
+                        >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX6QDL_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <MX6QDL_GPMI_NAND_PINGRP1_NODQS>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX6QDL_I2C1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX6QDL_I2C2_PINGRP2>;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <MX6QDL_I2C3_PINGRP2>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6QDL_UART1_PINGRP2>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX6QDL_UART2_PINGRP3>;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <MX6QDL_UART5_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+       lvds-channel@0 {
+               crtcs = <&ipu1 0>, <&ipu1 1>;
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 29 0>;
+       status = "okay";
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
new file mode 100644 (file)
index 0000000..35028a5
--- /dev/null
@@ -0,0 +1,484 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               can0 = &can1;
+               ethernet0 = &fec;
+               ethernet1 = &eth1;
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+               nand = &gpmi;
+               sky2 = &eth1;
+               ssi0 = &ssi1;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+               usdhc2 = &usdhc3;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 26 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_1p0v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "1P0V";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-always-on;
+               };
+
+               /* remove when pmic 1p8 regulator available */
+               reg_1p8v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "1P8V";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_h1_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "usb_h1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pciclkgen: si53156@6b {
+               compatible = "sil,si53156";
+               reg = <0x6b>;
+       };
+
+       pciswitch: pex8606@3f {
+               compatible = "plx,pex8606";
+               reg = <0x3f>;
+       };
+
+       pmic: ltc3676@3c {
+               compatible = "ltc,ltc3676";
+               reg = <0x3c>;
+
+               regulators {
+                       /* VDD_SOC */
+                       sw1_reg: ltc3676__sw1 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_1P8 */
+                       sw2_reg: ltc3676__sw2 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_ARM */
+                       sw3_reg: ltc3676__sw3 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_DDR */
+                       sw4_reg: ltc3676__sw4 {
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_2P5 */
+                       ldo2_reg: ltc3676__ldo2 {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_1P8 */
+                       ldo3_reg: ltc3676__ldo3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_HIGH */
+                       ldo4_reg: ltc3676__ldo4 {
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+               };
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accelerometer: fxos8700@1e {
+               compatible = "fsl,fxos8700";
+               reg = <0x1e>;
+       };
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 201>;
+               VDDA-supply = <&reg_1p8v>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+
+       hdmiin: adv7611@4c {
+               compatible = "adi,adv7611";
+               reg = <0x4c>;
+       };
+
+       touchscreen: egalax_ts@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <11 2>; /* gpio1_11 active low */
+               wakeup-gpios = <&gpio1 11 0>;
+       };
+
+       videoout: adv7393@2a {
+               compatible = "adi,adv7393";
+               reg = <0x2a>;
+       };
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6qdl-gw53xx {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_A19__GPIO2_IO19    0x80000000 /* PCIE6EXP_DIO0 */
+                               MX6QDL_PAD_EIM_A20__GPIO2_IO18    0x80000000 /* PCIE6EXP_DIO1 */
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22    0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_ENET_RXD0__GPIO1_IO27  0x80000000 /* GPS_SHDN */
+                               MX6QDL_PAD_ENET_RXD1__GPIO1_IO26  0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
+                               MX6QDL_PAD_ENET_TXD1__GPIO1_IO29  0x80000000 /* PCIE RST */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1      0x000130b0 /* AUD4_MCK */
+                               MX6QDL_PAD_GPIO_2__GPIO1_IO02     0x80000000 /* CAN_STBY */
+                               MX6QDL_PAD_GPIO_8__GPIO1_IO08     0x80000000 /* PMIC_IRQ# */
+                               MX6QDL_PAD_GPIO_9__GPIO1_IO09     0x80000000 /* HUB_RST# */
+                               MX6QDL_PAD_GPIO_17__GPIO7_IO12    0x80000000 /* PCIE_WDIS# */
+                               MX6QDL_PAD_GPIO_19__GPIO4_IO05    0x80000000 /* ACCEL_IRQ# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06   0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_COL4__GPIO4_IO14   0x80000000 /* USBOTG_OC# */
+                               MX6QDL_PAD_KEY_ROW0__GPIO4_IO07   0x80000000 /* user2 led */
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15   0x80000000 /* user3 led */
+                               MX6QDL_PAD_SD2_CMD__GPIO1_IO11    0x80000000 /* TOUCH_IRQ# */
+                               MX6QDL_PAD_SD3_DAT5__GPIO7_IO00   0x80000000 /* SD3_DET# */
+                        >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX6QDL_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_flexcan1: flexcan1grp {
+                       fsl,pins = <MX6QDL_FLEXCAN1_PINGRP1>;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <MX6QDL_GPMI_NAND_PINGRP1_NODQS>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX6QDL_I2C1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX6QDL_I2C2_PINGRP2>;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <MX6QDL_I2C3_PINGRP2>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6QDL_UART1_PINGRP2>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX6QDL_UART2_PINGRP3>;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <MX6QDL_UART5_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+
+       lvds-channel@1 {
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               status = "okay";
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vfront-porch = <7>;
+                               hsync-len = <60>;
+                               vsync-len = <10>;
+                       };
+               };
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 29 0>;
+       status = "okay";
+
+       eth1: sky2@8 { /* MAC/PHY on bus 8 */
+               compatible = "marvell,sky2";
+       };
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_h1_vbus>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
new file mode 100644 (file)
index 0000000..34b26b9
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               can0 = &can1;
+               ethernet0 = &fec;
+               ethernet1 = &eth1;
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+               nand = &gpmi;
+               sky2 = &eth1;
+               ssi0 = &ssi1;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+               usdhc2 = &usdhc3;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 26 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_1p0v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "1P0V";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_h1_vbus: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_h1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>; /* AUD4<->sgtl5000 */
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pmic: pfuze100@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3b_reg: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+
+       pciswitch: pex8609@3f {
+               compatible = "plx,pex8609";
+               reg = <0x3f>;
+       };
+
+       pciclkgen: si52147@6b {
+               compatible = "sil,si52147";
+               reg = <0x6b>;
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accelerometer: fxos8700@1e {
+               compatible = "fsl,fxos8700";
+               reg = <0x1e>;
+       };
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 201>;
+               VDDA-supply = <&sw4_reg>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+
+       hdmiin: adv7611@4c {
+               compatible = "adi,adv7611";
+               reg = <0x4c>;
+       };
+
+       touchscreen: egalax_ts@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <12 2>; /* gpio7_12 active low */
+               wakeup-gpios = <&gpio7 12 0>;
+       };
+
+       videoout: adv7393@2a {
+               compatible = "adi,adv7393";
+               reg = <0x2a>;
+       };
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6qdl-gw54xx {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22    0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_EIM_D19__GPIO3_IO19    0x80000000 /* SPINOR_CS0# */
+                               MX6QDL_PAD_ENET_RXD1__GPIO1_IO26  0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
+                               MX6QDL_PAD_ENET_TXD1__GPIO1_IO29  0x80000000 /* PCIE RST */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1      0x000130b0 /* AUD4_MCK */
+                               MX6QDL_PAD_GPIO_2__GPIO1_IO02     0x80000000 /* CAN_STBY */
+                               MX6QDL_PAD_GPIO_17__GPIO7_IO12    0x80000000 /* TOUCH_IRQ# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06   0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_ROW0__GPIO4_IO07   0x80000000 /* user2 led */
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15   0x80000000 /* user3 led */
+                               MX6QDL_PAD_SD1_DAT0__GPIO1_IO16   0x80000000 /* USBHUB_RST# */
+                               MX6QDL_PAD_SD1_DAT3__GPIO1_IO21   0x80000000 /* MIPI_DIO */
+                        >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX6QDL_AUDMUX_PINGRP1>;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_flexcan1: flexcan1grp {
+                       fsl,pins = <MX6QDL_FLEXCAN1_PINGRP1>;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <MX6QDL_GPMI_NAND_PINGRP1_NODQS>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX6QDL_I2C1_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX6QDL_I2C2_PINGRP2>;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <MX6QDL_I2C3_PINGRP2>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6QDL_UART1_PINGRP2>;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <MX6QDL_UART2_PINGRP3>;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <MX6QDL_UART5_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+
+       lvds-channel@1 {
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               status = "okay";
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vfront-porch = <7>;
+                               hsync-len = <60>;
+                               vsync-len = <10>;
+                       };
+               };
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 29 0>;
+       status = "okay";
+
+       eth1: sky2@8 { /* MAC/PHY on bus 8 */
+               compatible = "marvell,sky2";
+       };
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&ssi2 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_h1_vbus>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-pingrp.h b/arch/arm/boot/dts/imx6qdl-pingrp.h
new file mode 100644 (file)
index 0000000..8d71b13
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX6QDL_PINGRP_H
+#define __DTS_IMX6QDL_PINGRP_H
+
+#define MX6QDL_AUDMUX_PINGRP1 \
+       MX6QDL_PAD_SD2_DAT0__AUD4_RXD                   0x130b0 \
+       MX6QDL_PAD_SD2_DAT3__AUD4_TXC                   0x130b0 \
+       MX6QDL_PAD_SD2_DAT2__AUD4_TXD                   0x110b0 \
+       MX6QDL_PAD_SD2_DAT1__AUD4_TXFS                  0x130b0
+
+#define MX6QDL_AUDMUX_PINGRP2 \
+       MX6QDL_PAD_CSI0_DAT7__AUD3_RXD                  0x130b0 \
+       MX6QDL_PAD_CSI0_DAT4__AUD3_TXC                  0x130b0 \
+       MX6QDL_PAD_CSI0_DAT5__AUD3_TXD                  0x110b0 \
+       MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS                 0x130b0
+
+#define MX6QDL_AUDMUX_PINGRP3 \
+       MX6QDL_PAD_DISP0_DAT16__AUD5_TXC                0x130b0 \
+       MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS               0x130b0 \
+       MX6QDL_PAD_DISP0_DAT19__AUD5_RXD                0x130b0 \
+
+#define MX6QDL_AUDMUX_PINGRP4 \
+       MX6QDL_PAD_EIM_D24__AUD5_RXFS                   0x130b0 \
+       MX6QDL_PAD_EIM_D25__AUD5_RXC                    0x130b0 \
+       MX6QDL_PAD_DISP0_DAT19__AUD5_RXD                0x130b0
+
+#define MX6QDL_ECSPI1_PINGRP1 \
+       MX6QDL_PAD_EIM_D17__ECSPI1_MISO                 0x100b1 \
+       MX6QDL_PAD_EIM_D18__ECSPI1_MOSI                 0x100b1 \
+       MX6QDL_PAD_EIM_D16__ECSPI1_SCLK                 0x100b1
+
+#define MX6QDL_ECSPI1_PINGRP2 \
+       MX6QDL_PAD_KEY_COL1__ECSPI1_MISO                0x100b1 \
+       MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI                0x100b1 \
+       MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK                0x100b1
+
+#define MX6QDL_ECSPI3_PINGRP1 \
+       MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO              0x100b1 \
+       MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI              0x100b1 \
+       MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK              0x100b1
+
+#define MX6QDL_ENET_PINGRP1 \
+       MX6QDL_PAD_ENET_MDIO__ENET_MDIO                 0x1b0b0 \
+       MX6QDL_PAD_ENET_MDC__ENET_MDC                   0x1b0b0 \
+       MX6QDL_PAD_RGMII_TXC__RGMII_TXC                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD0__RGMII_TD0                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD1__RGMII_TD1                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD2__RGMII_TD2                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD3__RGMII_TD3                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL           0x1b0b0 \
+       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK            0x1b0b0 \
+       MX6QDL_PAD_RGMII_RXC__RGMII_RXC                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD0__RGMII_RD0                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD1__RGMII_RD1                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD2__RGMII_RD2                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD3__RGMII_RD3                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL           0x1b0b0 \
+       MX6QDL_PAD_GPIO_16__ENET_REF_CLK                0x4001b0a8
+
+#define MX6QDL_ENET_PINGRP2 \
+       MX6QDL_PAD_KEY_COL1__ENET_MDIO                  0x1b0b0 \
+       MX6QDL_PAD_KEY_COL2__ENET_MDC                   0x1b0b0 \
+       MX6QDL_PAD_RGMII_TXC__RGMII_TXC                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD0__RGMII_TD0                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD1__RGMII_TD1                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD2__RGMII_TD2                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD3__RGMII_TD3                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL           0x1b0b0 \
+       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK            0x1b0b0 \
+       MX6QDL_PAD_RGMII_RXC__RGMII_RXC                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD0__RGMII_RD0                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD1__RGMII_RD1                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD2__RGMII_RD2                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD3__RGMII_RD3                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL           0x1b0b0
+
+#define MX6QDL_ENET_PINGRP3 \
+       MX6QDL_PAD_ENET_MDIO__ENET_MDIO                 0x1b0b0 \
+       MX6QDL_PAD_ENET_MDC__ENET_MDC                   0x1b0b0 \
+       MX6QDL_PAD_RGMII_TXC__RGMII_TXC                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD0__RGMII_TD0                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD1__RGMII_TD1                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD2__RGMII_TD2                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TD3__RGMII_TD3                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL           0x1b0b0 \
+       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK            0x1b0b0 \
+       MX6QDL_PAD_RGMII_RXC__RGMII_RXC                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD0__RGMII_RD0                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD1__RGMII_RD1                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD2__RGMII_RD2                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RD3__RGMII_RD3                 0x1b0b0 \
+       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL           0x1b0b0 \
+       MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN               0x1b0b0
+
+#define MX6QDL_ESAI_PINGRP1 \
+       MX6QDL_PAD_ENET_RXD0__ESAI_TX_HF_CLK            0x1b030 \
+       MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK             0x1b030 \
+       MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS                0x1b030 \
+       MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2             0x1b030 \
+       MX6QDL_PAD_ENET_TXD1__ESAI_TX2_RX3              0x1b030 \
+       MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1              0x1b030 \
+       MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0               0x1b030 \
+       MX6QDL_PAD_NANDF_CS2__ESAI_TX0                  0x1b030 \
+       MX6QDL_PAD_NANDF_CS3__ESAI_TX1                  0x1b030
+
+#define MX6QDL_ESAI_PINGRP2 \
+       MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK             0x1b030 \
+       MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS                0x1b030 \
+       MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2             0x1b030 \
+       MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3                 0x1b030 \
+       MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1              0x1b030 \
+       MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0               0x1b030 \
+       MX6QDL_PAD_GPIO_17__ESAI_TX0                    0x1b030 \
+       MX6QDL_PAD_NANDF_CS3__ESAI_TX1                  0x1b030 \
+       MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK               0x1b030 \
+       MX6QDL_PAD_GPIO_9__ESAI_RX_FS                   0x1b030
+
+#define MX6QDL_FLEXCAN1_PINGRP1 \
+       MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX                0x80000000 \
+       MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX                0x80000000
+
+#define MX6QDL_FLEXCAN1_PINGRP2 \
+       MX6QDL_PAD_GPIO_7__FLEXCAN1_TX                  0x80000000 \
+       MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX                0x80000000
+
+#define MX6QDL_FLEXCAN2_PINGRP1 \
+       MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX                0x80000000 \
+       MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX                0x80000000
+
+#define MX6QDL_GPMI_NAND_PINGRP1 \
+       MX6QDL_PAD_NANDF_CLE__NAND_CLE                  0xb0b1 \
+       MX6QDL_PAD_NANDF_ALE__NAND_ALE                  0xb0b1 \
+       MX6QDL_PAD_NANDF_WP_B__NAND_WP_B                0xb0b1 \
+       MX6QDL_PAD_NANDF_RB0__NAND_READY_B              0xb000 \
+       MX6QDL_PAD_NANDF_CS0__NAND_CE0_B                0xb0b1 \
+       MX6QDL_PAD_NANDF_CS1__NAND_CE1_B                0xb0b1 \
+       MX6QDL_PAD_SD4_CMD__NAND_RE_B                   0xb0b1 \
+       MX6QDL_PAD_SD4_CLK__NAND_WE_B                   0xb0b1 \
+       MX6QDL_PAD_NANDF_D0__NAND_DATA00                0xb0b1 \
+       MX6QDL_PAD_NANDF_D1__NAND_DATA01                0xb0b1 \
+       MX6QDL_PAD_NANDF_D2__NAND_DATA02                0xb0b1 \
+       MX6QDL_PAD_NANDF_D3__NAND_DATA03                0xb0b1 \
+       MX6QDL_PAD_NANDF_D4__NAND_DATA04                0xb0b1 \
+       MX6QDL_PAD_NANDF_D5__NAND_DATA05                0xb0b1 \
+       MX6QDL_PAD_NANDF_D6__NAND_DATA06                0xb0b1 \
+       MX6QDL_PAD_NANDF_D7__NAND_DATA07                0xb0b1 \
+       MX6QDL_PAD_SD4_DAT0__NAND_DQS                   0x00b1
+
+#define MX6QDL_GPMI_NAND_PINGRP1_NODQS \
+       MX6QDL_PAD_NANDF_CLE__NAND_CLE                  0xb0b1 \
+       MX6QDL_PAD_NANDF_ALE__NAND_ALE                  0xb0b1 \
+       MX6QDL_PAD_NANDF_WP_B__NAND_WP_B                0xb0b1 \
+       MX6QDL_PAD_NANDF_RB0__NAND_READY_B              0xb000 \
+       MX6QDL_PAD_NANDF_CS0__NAND_CE0_B                0xb0b1 \
+       MX6QDL_PAD_NANDF_CS1__NAND_CE1_B                0xb0b1 \
+       MX6QDL_PAD_SD4_CMD__NAND_RE_B                   0xb0b1 \
+       MX6QDL_PAD_SD4_CLK__NAND_WE_B                   0xb0b1 \
+       MX6QDL_PAD_NANDF_D0__NAND_DATA00                0xb0b1 \
+       MX6QDL_PAD_NANDF_D1__NAND_DATA01                0xb0b1 \
+       MX6QDL_PAD_NANDF_D2__NAND_DATA02                0xb0b1 \
+       MX6QDL_PAD_NANDF_D3__NAND_DATA03                0xb0b1 \
+       MX6QDL_PAD_NANDF_D4__NAND_DATA04                0xb0b1 \
+       MX6QDL_PAD_NANDF_D5__NAND_DATA05                0xb0b1 \
+       MX6QDL_PAD_NANDF_D6__NAND_DATA06                0xb0b1 \
+       MX6QDL_PAD_NANDF_D7__NAND_DATA07                0xb0b1
+
+#define MX6QDL_HDMI_HDCP_PINGRP1 \
+       MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL            0x4001b8b1 \
+       MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA            0x4001b8b1
+
+#define MX6QDL_HDMI_HDCP_PINGRP2 \
+       MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL             0x4001b8b1 \
+       MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA             0x4001b8b1
+
+#define MX6QDL_HDMI_HDCP_PINGRP3 \
+       MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL             0x4001b8b1 \
+       MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA            0x4001b8b1
+
+#define MX6QDL_HDMI_CEC_PINGRP1 \
+       MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE            0x1f8b0
+
+#define MX6QDL_HDMI_CEC_PINGRP2 \
+       MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE           0x1f8b0
+
+#define MX6QDL_I2C1_PINGRP1 \
+       MX6QDL_PAD_EIM_D21__I2C1_SCL                    0x4001b8b1 \
+       MX6QDL_PAD_EIM_D28__I2C1_SDA                    0x4001b8b1
+
+#define MX6QDL_I2C1_PINGRP2 \
+       MX6QDL_PAD_CSI0_DAT8__I2C1_SDA                  0x4001b8b1 \
+       MX6QDL_PAD_CSI0_DAT9__I2C1_SCL                  0x4001b8b1
+
+#define MX6QDL_I2C2_PINGRP1 \
+       MX6QDL_PAD_EIM_EB2__I2C2_SCL                    0x4001b8b1 \
+       MX6QDL_PAD_EIM_D16__I2C2_SDA                    0x4001b8b1
+
+#define MX6QDL_I2C2_PINGRP2 \
+       MX6QDL_PAD_KEY_COL3__I2C2_SCL                   0x4001b8b1 \
+       MX6QDL_PAD_KEY_ROW3__I2C2_SDA                   0x4001b8b1
+
+#define MX6QDL_I2C2_PINGRP3 \
+       MX6QDL_PAD_EIM_EB2__I2C2_SCL                    0x4001b8b1 \
+       MX6QDL_PAD_KEY_ROW3__I2C2_SDA                   0x4001b8b1
+
+#define MX6QDL_I2C3_PINGRP1 \
+       MX6QDL_PAD_EIM_D17__I2C3_SCL                    0x4001b8b1 \
+       MX6QDL_PAD_EIM_D18__I2C3_SDA                    0x4001b8b1
+
+#define MX6QDL_I2C3_PINGRP2 \
+       MX6QDL_PAD_GPIO_3__I2C3_SCL                     0x4001b8b1 \
+       MX6QDL_PAD_GPIO_6__I2C3_SDA                     0x4001b8b1
+
+#define MX6QDL_I2C3_PINGRP3 \
+       MX6QDL_PAD_GPIO_5__I2C3_SCL                     0x4001b8b1 \
+       MX6QDL_PAD_GPIO_16__I2C3_SDA                    0x4001b8b1
+
+#define MX6QDL_I2C3_PINGRP4 \
+       MX6QDL_PAD_GPIO_3__I2C3_SCL                     0x4001b8b1 \
+       MX6QDL_PAD_EIM_D18__I2C3_SDA                    0x4001b8b1
+
+#define MX6QDL_IPU1_PINGRP1 \
+       MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK      0x10 \
+       MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15            0x10 \
+       MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02             0x10 \
+       MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03             0x10 \
+       MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04             0x80000000 \
+       MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00        0x10 \
+       MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01        0x10 \
+       MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02        0x10 \
+       MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03        0x10 \
+       MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04        0x10 \
+       MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05        0x10 \
+       MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06        0x10 \
+       MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07        0x10 \
+       MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08        0x10 \
+       MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09        0x10 \
+       MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10       0x10 \
+       MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11       0x10 \
+       MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12       0x10 \
+       MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13       0x10 \
+       MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14       0x10 \
+       MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15       0x10 \
+       MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16       0x10 \
+       MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17       0x10 \
+       MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18       0x10 \
+       MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19       0x10 \
+       MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20       0x10 \
+       MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21       0x10 \
+       MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22       0x10 \
+       MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23       0x10
+
+/* parallel camera */
+#define MX6QDL_IPU1_PINGRP2 \
+       MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19         0x80000000 \
+       MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN      0x80000000 \
+       MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK        0x80000000 \
+       MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC           0x80000000 \
+       MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC          0x80000000
+
+/* parallel port 16-bit */
+#define MX6QDL_IPU1_PINGRP3 \
+       MX6QDL_PAD_CSI0_DAT4__IPU1_CSI0_DATA04          0x80000000 \
+       MX6QDL_PAD_CSI0_DAT5__IPU1_CSI0_DATA05          0x80000000 \
+       MX6QDL_PAD_CSI0_DAT6__IPU1_CSI0_DATA06          0x80000000 \
+       MX6QDL_PAD_CSI0_DAT7__IPU1_CSI0_DATA07          0x80000000 \
+       MX6QDL_PAD_CSI0_DAT8__IPU1_CSI0_DATA08          0x80000000 \
+       MX6QDL_PAD_CSI0_DAT9__IPU1_CSI0_DATA09          0x80000000 \
+       MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18         0x80000000 \
+       MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19         0x80000000 \
+       MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK        0x80000000 \
+       MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC           0x80000000 \
+       MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC          0x80000000
+
+#define MX6QDL_MLB_PINGRP1 \
+       MX6QDL_PAD_GPIO_3__MLB_CLK                      0x71 \
+       MX6QDL_PAD_GPIO_6__MLB_SIG                      0x71 \
+       MX6QDL_PAD_GPIO_2__MLB_DATA                     0x71
+
+#define MX6QDL_MLB_PINGRP2 \
+       MX6QDL_PAD_ENET_TXD1__MLB_CLK                   0x71 \
+       MX6QDL_PAD_GPIO_6__MLB_SIG                      0x71 \
+       MX6QDL_PAD_GPIO_2__MLB_DATA                     0x71
+
+#define MX6QDL_PWM1_PINGRP1 \
+       MX6QDL_PAD_SD1_DAT3__PWM1_OUT                   0x1b0b1
+
+#define MX6QDL_PWM3_PINGRP1 \
+       MX6QDL_PAD_SD4_DAT1__PWM3_OUT                   0x1b0b1
+
+#define MX6QDL_SPDIF_PINGRP1 \
+       MX6QDL_PAD_KEY_COL3__SPDIF_IN                   0x1b0b0
+
+#define MX6QDL_SPDIF_PINGRP2 \
+       MX6QDL_PAD_GPIO_16__SPDIF_IN                    0x1b0b0 \
+       MX6QDL_PAD_GPIO_17__SPDIF_OUT                   0x1b0b0
+
+#define MX6QDL_SPDIF_PINGRP3 \
+       MX6QDL_PAD_ENET_RXD0__SPDIF_OUT                 0x1b0b0
+
+#define MX6QDL_UART1_PINGRP1 \
+       MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA            0x1b0b1 \
+       MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA            0x1b0b1
+
+#define MX6QDL_UART1_PINGRP2 \
+       MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA              0x1b0b1 \
+       MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA              0x1b0b1
+
+#define MX6QDL_UART2_PINGRP1 \
+       MX6QDL_PAD_EIM_D26__UART2_TX_DATA               0x1b0b1 \
+       MX6QDL_PAD_EIM_D27__UART2_RX_DATA               0x1b0b1
+
+/* DTE mode */
+#define MX6QDL_UART2_PINGRP2 \
+       MX6QDL_PAD_EIM_D26__UART2_RX_DATA               0x1b0b1 \
+       MX6QDL_PAD_EIM_D27__UART2_TX_DATA               0x1b0b1 \
+       MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B             0x1b0b1 \
+       MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B             0x1b0b1
+
+#define MX6QDL_UART2_PINGRP3 \
+       MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA              0x1b0b1 \
+       MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA              0x1b0b1
+
+#define MX6QDL_UART3_PINGRP1 \
+       MX6QDL_PAD_SD4_CLK__UART3_RX_DATA               0x1b0b1 \
+       MX6QDL_PAD_SD4_CMD__UART3_TX_DATA               0x1b0b1 \
+       MX6QDL_PAD_EIM_D30__UART3_CTS_B                 0x1b0b1 \
+       MX6QDL_PAD_EIM_EB3__UART3_RTS_B                 0x1b0b1
+
+#define MX6QDL_UART3_PINGRP2 \
+       MX6QDL_PAD_EIM_D24__UART3_TX_DATA               0x1b0b1 \
+       MX6QDL_PAD_EIM_D25__UART3_RX_DATA               0x1b0b1 \
+       MX6QDL_PAD_EIM_D23__UART3_CTS_B                 0x1b0b1 \
+       MX6QDL_PAD_EIM_EB3__UART3_RTS_B                 0x1b0b1
+
+#define MX6QDL_UART3_PINGRP3 \
+       MX6QDL_PAD_EIM_D24__UART3_TX_DATA               0x1b0b1 \
+       MX6QDL_PAD_EIM_D25__UART3_RX_DATA               0x1b0b1
+
+#define MX6QDL_UART4_PINGRP1 \
+       MX6QDL_PAD_KEY_COL0__UART4_TX_DATA              0x1b0b1 \
+       MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA              0x1b0b1
+
+#define MX6QDL_UART5_PINGRP1 \
+       MX6QDL_PAD_KEY_COL1__UART5_TX_DATA              0x1b0b1 \
+       MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA              0x1b0b1
+
+#define MX6QDL_USBOTG_PINGRP1 \
+       MX6QDL_PAD_GPIO_1__USB_OTG_ID                   0x17059
+
+#define MX6QDL_USBOTG_PINGRP2 \
+       MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID               0x17059
+
+#define MX6QDL_USBH2_PINGRP1 \
+       MX6QDL_PAD_RGMII_TXC__USB_H2_DATA               0x40013030 \
+       MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE          0x40013030
+
+#define MX6QDL_USBH2_PINGRP2 \
+       MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE          0x40017030
+
+#define MX6QDL_USBH3_PINGRP1 \
+       MX6QDL_PAD_RGMII_RX_CTL__USB_H3_DATA            0x40013030 \
+       MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE             0x40013030
+
+#define MX6QDL_USBH3_PINGRP2 \
+       MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE             0x40017030
+
+#define MX6QDL_USDHC1_D4(pad, pad_data3, pad_clk)      \
+       MX6QDL_PAD_SD1_CMD__SD1_CMD                     pad \
+       MX6QDL_PAD_SD1_CLK__SD1_CLK                     pad_clk \
+       MX6QDL_PAD_SD1_DAT0__SD1_DATA0                  pad \
+       MX6QDL_PAD_SD1_DAT1__SD1_DATA1                  pad \
+       MX6QDL_PAD_SD1_DAT2__SD1_DATA2                  pad \
+       MX6QDL_PAD_SD1_DAT3__SD1_DATA3                  pad_data3
+
+#define MX6QDL_USDHC1_D8(pad, pad_data3, pad_clk)      \
+       MX6QDL_USDHC1_D4(pad, pad_data3, pad_clk)       \
+       MX6QDL_PAD_NANDF_D0__SD1_DATA4                  pad \
+       MX6QDL_PAD_NANDF_D1__SD1_DATA5                  pad \
+       MX6QDL_PAD_NANDF_D2__SD1_DATA6                  pad \
+       MX6QDL_PAD_NANDF_D3__SD1_DATA7                  pad
+
+#define MX6QDL_USDHC2_D4(pad, pad_data3, pad_clk)      \
+       MX6QDL_PAD_SD2_CMD__SD2_CMD                     pad \
+       MX6QDL_PAD_SD2_CLK__SD2_CLK                     pad_clk \
+       MX6QDL_PAD_SD2_DAT0__SD2_DATA0                  pad \
+       MX6QDL_PAD_SD2_DAT1__SD2_DATA1                  pad \
+       MX6QDL_PAD_SD2_DAT2__SD2_DATA2                  pad \
+       MX6QDL_PAD_SD2_DAT3__SD2_DATA3                  pad_data3
+
+#define MX6QDL_USDHC2_D8(pad, pad_data3, pad_clk)      \
+       MX6QDL_USDHC2_D4(pad, pad_data3, pad_clk)       \
+       MX6QDL_PAD_NANDF_D4__SD2_DATA4                  pad \
+       MX6QDL_PAD_NANDF_D5__SD2_DATA5                  pad \
+       MX6QDL_PAD_NANDF_D6__SD2_DATA6                  pad \
+       MX6QDL_PAD_NANDF_D7__SD2_DATA7                  pad
+
+#define MX6QDL_USDHC3_D4(pad, pad_data3, pad_clk)      \
+       MX6QDL_PAD_SD3_CMD__SD3_CMD                     pad \
+       MX6QDL_PAD_SD3_CLK__SD3_CLK                     pad_clk \
+       MX6QDL_PAD_SD3_DAT0__SD3_DATA0                  pad \
+       MX6QDL_PAD_SD3_DAT1__SD3_DATA1                  pad \
+       MX6QDL_PAD_SD3_DAT2__SD3_DATA2                  pad \
+       MX6QDL_PAD_SD3_DAT3__SD3_DATA3                  pad_data3
+
+#define MX6QDL_USDHC3_D8(pad, pad_data3, pad_clk)      \
+       MX6QDL_USDHC3_D4(pad, pad_data3, pad_clk)       \
+       MX6QDL_PAD_SD3_DAT4__SD3_DATA4                  pad \
+       MX6QDL_PAD_SD3_DAT5__SD3_DATA5                  pad \
+       MX6QDL_PAD_SD3_DAT6__SD3_DATA6                  pad \
+       MX6QDL_PAD_SD3_DAT7__SD3_DATA7                  pad
+
+#define MX6QDL_USDHC4_D4(pad, pad_data3, pad_clk)      \
+       MX6QDL_PAD_SD4_CMD__SD4_CMD                     pad \
+       MX6QDL_PAD_SD4_CLK__SD4_CLK                     pad_clk \
+       MX6QDL_PAD_SD4_DAT0__SD4_DATA0                  pad \
+       MX6QDL_PAD_SD4_DAT1__SD4_DATA1                  pad \
+       MX6QDL_PAD_SD4_DAT2__SD4_DATA2                  pad \
+       MX6QDL_PAD_SD4_DAT3__SD4_DATA3                  pad_data3
+
+#define MX6QDL_USDHC4_D8(pad, pad_data3, pad_clk)      \
+       MX6QDL_USDHC4_D4(pad, pad_data3, pad_clk)       \
+       MX6QDL_PAD_SD4_DAT4__SD4_DATA4                  pad \
+       MX6QDL_PAD_SD4_DAT5__SD4_DATA5                  pad \
+       MX6QDL_PAD_SD4_DAT6__SD4_DATA6                  pad \
+       MX6QDL_PAD_SD4_DAT7__SD4_DATA7                  pad
+
+#define MX6QDL_USDHC1_PINGRP_D4               MX6QDL_USDHC1_D4(0x17059,0x17059,0x10059)
+#define MX6QDL_USDHC1_PINGRP_D4_100MHZ MX6QDL_USDHC1_D4(0x170b9,0x170b9,0x100b9)
+#define MX6QDL_USDHC1_PINGRP_D4_200MHZ MX6QDL_USDHC1_D4(0x170f9,0x170f9,0x100f9)
+#define MX6QDL_USDHC1_PINGRP_D8               MX6QDL_USDHC1_D8(0x17059,0x17059,0x10059)
+#define MX6QDL_USDHC1_PINGRP_D8_100MHZ MX6QDL_USDHC1_D8(0x170b9,0x170b9,0x100b9)
+#define MX6QDL_USDHC1_PINGRP_D8_200MHZ MX6QDL_USDHC1_D8(0x170f9,0x170f9,0x100f9)
+
+#define MX6QDL_USDHC2_PINGRP_D4               MX6QDL_USDHC2_D4(0x17059,0x17059,0x10059)
+#define MX6QDL_USDHC2_PINGRP_D4_100MHZ MX6QDL_USDHC2_D4(0x170b9,0x170b9,0x100b9)
+#define MX6QDL_USDHC2_PINGRP_D4_200MHZ MX6QDL_USDHC2_D4(0x170f9,0x170f9,0x100f9)
+#define MX6QDL_USDHC2_PINGRP_D8               MX6QDL_USDHC2_D8(0x17059,0x17059,0x10059)
+#define MX6QDL_USDHC2_PINGRP_D8_100MHZ MX6QDL_USDHC2_D8(0x170b9,0x170b9,0x100b9)
+#define MX6QDL_USDHC2_PINGRP_D8_200MHZ MX6QDL_USDHC2_D8(0x170f9,0x170f9,0x100f9)
+
+#define MX6QDL_USDHC3_PINGRP_D4               MX6QDL_USDHC3_D4(0x17059,0x17059,0x10059)
+#define MX6QDL_USDHC3_PINGRP_D4_100MHZ MX6QDL_USDHC3_D4(0x170b9,0x170b9,0x100b9)
+#define MX6QDL_USDHC3_PINGRP_D4_200MHZ MX6QDL_USDHC3_D4(0x170f9,0x170f9,0x100f9)
+#define MX6QDL_USDHC3_PINGRP_D8               MX6QDL_USDHC3_D8(0x17059,0x17059,0x10059)
+#define MX6QDL_USDHC3_PINGRP_D8_100MHZ MX6QDL_USDHC3_D8(0x170b9,0x170b9,0x100b9)
+#define MX6QDL_USDHC3_PINGRP_D8_200MHZ MX6QDL_USDHC3_D8(0x170f9,0x170f9,0x100f9)
+
+#define MX6QDL_USDHC4_PINGRP_D4               MX6QDL_USDHC4_D4(0x17059,0x17059,0x10059)
+#define MX6QDL_USDHC4_PINGRP_D4_100MHZ MX6QDL_USDHC4_D4(0x170b9,0x170b9,0x100b9)
+#define MX6QDL_USDHC4_PINGRP_D4_200MHZ MX6QDL_USDHC4_D4(0x170f9,0x170f9,0x100f9)
+#define MX6QDL_USDHC4_PINGRP_D8               MX6QDL_USDHC4_D8(0x17059,0x17059,0x10059)
+#define MX6QDL_USDHC4_PINGRP_D8_100MHZ MX6QDL_USDHC4_D8(0x170b9,0x170b9,0x100b9)
+#define MX6QDL_USDHC4_PINGRP_D8_200MHZ MX6QDL_USDHC4_D8(0x170f9,0x170f9,0x100f9)
+
+#define MX6QDL_WEIM_CS0_PINGRP1 \
+       MX6QDL_PAD_EIM_CS0__EIM_CS0_B                   0xb0b1
+
+#define MX6QDL_WEIM_NOR_PINGRP1 \
+       MX6QDL_PAD_EIM_OE__EIM_OE_B                     0xb0b1 \
+       MX6QDL_PAD_EIM_RW__EIM_RW                       0xb0b1 \
+       MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B                 0xb060 \
+       MX6QDL_PAD_EIM_D16__EIM_DATA16                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D17__EIM_DATA17                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D18__EIM_DATA18                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D19__EIM_DATA19                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D20__EIM_DATA20                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D21__EIM_DATA21                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D22__EIM_DATA22                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D23__EIM_DATA23                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D24__EIM_DATA24                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D25__EIM_DATA25                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D26__EIM_DATA26                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D27__EIM_DATA27                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D28__EIM_DATA28                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D29__EIM_DATA29                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D30__EIM_DATA30                  0x1b0b0 \
+       MX6QDL_PAD_EIM_D31__EIM_DATA31                  0x1b0b0 \
+       MX6QDL_PAD_EIM_A23__EIM_ADDR23                  0xb0b1 \
+       MX6QDL_PAD_EIM_A22__EIM_ADDR22                  0xb0b1 \
+       MX6QDL_PAD_EIM_A21__EIM_ADDR21                  0xb0b1 \
+       MX6QDL_PAD_EIM_A20__EIM_ADDR20                  0xb0b1 \
+       MX6QDL_PAD_EIM_A19__EIM_ADDR19                  0xb0b1 \
+       MX6QDL_PAD_EIM_A18__EIM_ADDR18                  0xb0b1 \
+       MX6QDL_PAD_EIM_A17__EIM_ADDR17                  0xb0b1 \
+       MX6QDL_PAD_EIM_A16__EIM_ADDR16                  0xb0b1 \
+       MX6QDL_PAD_EIM_DA15__EIM_AD15                   0xb0b1 \
+       MX6QDL_PAD_EIM_DA14__EIM_AD14                   0xb0b1 \
+       MX6QDL_PAD_EIM_DA13__EIM_AD13                   0xb0b1 \
+       MX6QDL_PAD_EIM_DA12__EIM_AD12                   0xb0b1 \
+       MX6QDL_PAD_EIM_DA11__EIM_AD11                   0xb0b1 \
+       MX6QDL_PAD_EIM_DA10__EIM_AD10                   0xb0b1 \
+       MX6QDL_PAD_EIM_DA9__EIM_AD09                    0xb0b1 \
+       MX6QDL_PAD_EIM_DA8__EIM_AD08                    0xb0b1 \
+       MX6QDL_PAD_EIM_DA7__EIM_AD07                    0xb0b1 \
+       MX6QDL_PAD_EIM_DA6__EIM_AD06                    0xb0b1 \
+       MX6QDL_PAD_EIM_DA5__EIM_AD05                    0xb0b1 \
+       MX6QDL_PAD_EIM_DA4__EIM_AD04                    0xb0b1 \
+       MX6QDL_PAD_EIM_DA3__EIM_AD03                    0xb0b1 \
+       MX6QDL_PAD_EIM_DA2__EIM_AD02                    0xb0b1 \
+       MX6QDL_PAD_EIM_DA1__EIM_AD01                    0xb0b1 \
+       MX6QDL_PAD_EIM_DA0__EIM_AD00                    0xb0b1
+
+#endif /* __DTS_IMX6QDL_PINGRP_H */
index ff6f1e8f2dd9bfa54a6387998421f1ac8877c841..a526796fdaacc6ecf6ebfe03342cf9f81a00acbe 100644 (file)
@@ -20,7 +20,7 @@
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio3 19 0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_sabreauto>;
+       pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
        status = "disabled"; /* pin conflict with WEIM NOR */
 
        flash: m25p80@0 {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_2>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        status = "okay";
 };
 
 &gpmi {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
        status = "okay";
 };
 
@@ -49,7 +49,7 @@
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6qdl-sabreauto {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
                                MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x17059
                        >;
                };
-       };
 
-       ecspi1 {
-               pinctrl_ecspi1_sabreauto: ecspi1-sabreauto {
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX6QDL_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_ecspi1_cs: ecspi1cs {
                        fsl,pins = <
                                MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
                        >;
                };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP2>;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <MX6QDL_GPMI_NAND_PINGRP1>;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <MX6QDL_UART4_PINGRP1>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D8>;
+               };
+
+               pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D8_100MHZ>;
+               };
+
+               pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D8_200MHZ>;
+               };
+
+               pinctrl_weim_cs0: weimcs0grp {
+                       fsl,pins = <MX6QDL_WEIM_CS0_PINGRP1>;
+               };
+
+               pinctrl_weim_nor: weimnorgrp {
+                       fsl,pins = <MX6QDL_WEIM_NOR_PINGRP1>;
+               };
        };
 };
 
 &uart4 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart4_1>;
+       pinctrl-0 = <&pinctrl_uart4>;
        status = "okay";
 };
 
 &usdhc3 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc3_1>;
-       pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
        cd-gpios = <&gpio6 15 0>;
        wp-gpios = <&gpio1 13 0>;
        status = "okay";
 
 &weim {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_weim_nor_1 &pinctrl_weim_cs0_1>;
+       pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>;
        #address-cells = <2>;
        #size-cells = <1>;
        ranges = <0 0 0x08000000 0x08000000>;
index e75e11b36dffec5ea9e695c01d8f66ac35b83dee..570767f8c8313c74ce4a163848c1988e1d2e65aa 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb_otg_vbus: usb_otg_vbus {
+               reg_usb_otg_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb_otg_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -27,8 +30,9 @@
                        enable-active-high;
                };
 
-               reg_usb_h1_vbus: usb_h1_vbus {
+               reg_usb_h1_vbus: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "usb_h1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -36,8 +40,9 @@
                        enable-active-high;
                };
 
-               reg_audio: wm8962_supply {
+               reg_audio: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "wm8962-supply";
                        gpio = <&gpio4 10 0>;
                        enable-active-high;
@@ -92,7 +97,7 @@
 
 &audmux {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_2>;
+       pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
 };
 
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio4 9 0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_2>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        status = "okay";
 
        flash: m25p80@0 {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_1>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        phy-reset-gpios = <&gpio1 25 0>;
        status = "okay";
 &i2c1 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_2>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        codec: wm8962@1a {
 &i2c3 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c3_2>;
+       pinctrl-0 = <&pinctrl_i2c3>;
        status = "okay";
 
        egalax_ts@04 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6qdl-sabresd {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_GPIO_4__GPIO1_IO04   0x80000000
                                MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX6QDL_AUDMUX_PINGRP2>;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX6QDL_ECSPI1_PINGRP2>;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <MX6QDL_I2C1_PINGRP2>;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <MX6QDL_I2C3_PINGRP2>;
+               };
+
+               pinctrl_pwm1: pwm1grp {
+                       fsl,pins = <MX6QDL_PWM1_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6QDL_UART1_PINGRP1>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP2>;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <MX6QDL_USDHC2_PINGRP_D8>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D8>;
+               };
        };
 };
 
 
 &pwm1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_pwm0_1>;
+       pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &usbotg {
        vbus-supply = <&reg_usb_otg_vbus>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg_2>;
+       pinctrl-0 = <&pinctrl_usbotg>;
        disable-over-current;
        status = "okay";
 };
 
 &usdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2_1>;
+       pinctrl-0 = <&pinctrl_usdhc2>;
        bus-width = <8>;
        cd-gpios = <&gpio2 2 0>;
        wp-gpios = <&gpio2 3 0>;
 
 &usdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_1>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
        bus-width = <8>;
        cd-gpios = <&gpio2 0 0>;
        wp-gpios = <&gpio2 1 0>;
index 35f54792916795dd85d77624289d94ee3ab97811..88894b13ccd23e96702b27501c012a8f3aa1921a 100644 (file)
 / {
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_2p5v: 2p5v {
+               reg_2p5v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "2P5V";
                        regulator-min-microvolt = <2500000>;
                        regulator-max-microvolt = <2500000>;
                        regulator-always-on;
                };
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
 
 &audmux {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_2>;
+       pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
 };
 
 &i2c2 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_2>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        codec: sgtl5000@0a {
@@ -77,7 +81,7 @@
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6qdl-wandboard {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_GPIO_0__CCM_CLKO1     0x130b0
                                MX6QDL_PAD_EIM_D29__GPIO3_IO29   0x80000000
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <MX6QDL_AUDMUX_PINGRP2>;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <MX6QDL_ENET_PINGRP1>;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <MX6QDL_I2C2_PINGRP2>;
+               };
+
+               pinctrl_spdif: spdifgrp {
+                       fsl,pins = <MX6QDL_SPDIF_PINGRP3>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6QDL_UART1_PINGRP1>;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <MX6QDL_UART3_PINGRP2>;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
+               };
+
+               pinctrl_usdhc1: usdhc1grp {
+                       fsl,pins = <MX6QDL_USDHC1_PINGRP_D4>;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <MX6QDL_USDHC2_PINGRP_D4>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+               };
        };
 };
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_1>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        phy-reset-gpios = <&gpio3 29 0>;
        status = "okay";
 
 &spdif {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_spdif_3>;
+       pinctrl-0 = <&pinctrl_spdif>;
        status = "okay";
 };
 
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_2>;
+       pinctrl-0 = <&pinctrl_uart3>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
 
 &usbotg {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg_1>;
+       pinctrl-0 = <&pinctrl_usbotg>;
        disable-over-current;
        dr_mode = "peripheral";
        status = "okay";
 
 &usdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc1_2>;
+       pinctrl-0 = <&pinctrl_usdhc1>;
        cd-gpios = <&gpio1 2 0>;
        status = "okay";
 };
 
 &usdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2_2>;
+       pinctrl-0 = <&pinctrl_usdhc2>;
        non-removable;
        status = "okay";
 };
 
 &usdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_2>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
        cd-gpios = <&gpio3 9 0>;
        status = "okay";
 };
index 59154dc15fe4ee441c80fd17d9c9141a16ee5e60..16f69741177e78bec158f064fa963f7c3b7cfe6b 100644 (file)
                dma_apbh: dma-apbh@00110000 {
                        compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
                        reg = <0x00110000 0x2000>;
-                       interrupts = <0 13 0x04>, <0 13 0x04>, <0 13 0x04>, <0 13 0x04>;
+                       interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 13 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 13 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 13 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
                        #dma-cells = <1>;
                        dma-channels = <4>;
@@ -88,7 +91,7 @@
                        #size-cells = <1>;
                        reg = <0x00112000 0x2000>, <0x00114000 0x2000>;
                        reg-names = "gpmi-nand", "bch";
-                       interrupts = <0 15 0x04>;
+                       interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "bch";
                        clocks = <&clks 152>, <&clks 153>, <&clks 151>,
                                 <&clks 150>, <&clks 149>;
                L2: l2-cache@00a02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00a02000 0x1000>;
-                       interrupts = <0 92 0x04>;
+                       interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
                        cache-unified;
                        cache-level = <2>;
                        arm,tag-latency = <4 2 3>;
                                  0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
                                  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
                        num-lanes = <1>;
-                       interrupts = <0 123 0x04>;
+                       interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
                        clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
                        status = "disabled";
 
                pmu {
                        compatible = "arm,cortex-a9-pmu";
-                       interrupts = <0 94 0x04>;
+                       interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                aips-bus@02000000 { /* AIPS1 */
                                spdif: spdif@02004000 {
                                        compatible = "fsl,imx35-spdif";
                                        reg = <0x02004000 0x4000>;
-                                       interrupts = <0 52 0x04>;
+                                       interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
                                        dmas = <&sdma 14 18 0>,
                                               <&sdma 15 18 0>;
                                        dma-names = "rx", "tx";
                                        clocks = <&clks 197>, <&clks 3>,
                                                 <&clks 197>, <&clks 107>,
                                                 <&clks 0>,   <&clks 118>,
-                                                <&clks 62>,  <&clks 139>,
+                                                <&clks 0>,  <&clks 139>,
                                                 <&clks 0>;
                                        clock-names = "core",  "rxtx0",
                                                      "rxtx1", "rxtx2",
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02008000 0x4000>;
-                                       interrupts = <0 31 0x04>;
+                                       interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 112>, <&clks 112>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x0200c000 0x4000>;
-                                       interrupts = <0 32 0x04>;
+                                       interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 113>, <&clks 113>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02010000 0x4000>;
-                                       interrupts = <0 33 0x04>;
+                                       interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 114>, <&clks 114>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02014000 0x4000>;
-                                       interrupts = <0 34 0x04>;
+                                       interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 115>, <&clks 115>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                uart1: serial@02020000 {
                                        compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02020000 0x4000>;
-                                       interrupts = <0 26 0x04>;
+                                       interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 160>, <&clks 161>;
                                        clock-names = "ipg", "per";
                                        dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
 
                                esai: esai@02024000 {
                                        reg = <0x02024000 0x4000>;
-                                       interrupts = <0 51 0x04>;
+                                       interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
                                };
 
                                ssi1: ssi@02028000 {
                                        compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
                                        reg = <0x02028000 0x4000>;
-                                       interrupts = <0 46 0x04>;
+                                       interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 178>;
-                                       dmas = <&sdma 37 1 0>,
-                                              <&sdma 38 1 0>;
+                                       dmas = <&sdma 37 22 0>,
+                                              <&sdma 38 22 0>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <15>;
                                        fsl,ssi-dma-events = <38 37>;
                                ssi2: ssi@0202c000 {
                                        compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
                                        reg = <0x0202c000 0x4000>;
-                                       interrupts = <0 47 0x04>;
+                                       interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 179>;
-                                       dmas = <&sdma 41 1 0>,
-                                              <&sdma 42 1 0>;
+                                       dmas = <&sdma 41 22 0>,
+                                              <&sdma 42 22 0>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <15>;
                                        fsl,ssi-dma-events = <42 41>;
                                ssi3: ssi@02030000 {
                                        compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
                                        reg = <0x02030000 0x4000>;
-                                       interrupts = <0 48 0x04>;
+                                       interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 180>;
-                                       dmas = <&sdma 45 1 0>,
-                                              <&sdma 46 1 0>;
+                                       dmas = <&sdma 45 22 0>,
+                                              <&sdma 46 22 0>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <15>;
                                        fsl,ssi-dma-events = <46 45>;
 
                                asrc: asrc@02034000 {
                                        reg = <0x02034000 0x4000>;
-                                       interrupts = <0 50 0x04>;
+                                       interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
                                };
 
                                spba@0203c000 {
 
                        vpu: vpu@02040000 {
                                reg = <0x02040000 0x3c000>;
-                               interrupts = <0 3 0x04 0 12 0x04>;
+                               interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 12 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        aipstz@0207c000 { /* AIPSTZ1 */
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x02080000 0x4000>;
-                               interrupts = <0 83 0x04>;
+                               interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 62>, <&clks 145>;
                                clock-names = "ipg", "per";
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x02084000 0x4000>;
-                               interrupts = <0 84 0x04>;
+                               interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 62>, <&clks 146>;
                                clock-names = "ipg", "per";
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x02088000 0x4000>;
-                               interrupts = <0 85 0x04>;
+                               interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 62>, <&clks 147>;
                                clock-names = "ipg", "per";
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x0208c000 0x4000>;
-                               interrupts = <0 86 0x04>;
+                               interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 62>, <&clks 148>;
                                clock-names = "ipg", "per";
                        };
                        can1: flexcan@02090000 {
                                compatible = "fsl,imx6q-flexcan";
                                reg = <0x02090000 0x4000>;
-                               interrupts = <0 110 0x04>;
+                               interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 108>, <&clks 109>;
                                clock-names = "ipg", "per";
+                               status = "disabled";
                        };
 
                        can2: flexcan@02094000 {
                                compatible = "fsl,imx6q-flexcan";
                                reg = <0x02094000 0x4000>;
-                               interrupts = <0 111 0x04>;
+                               interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 110>, <&clks 111>;
                                clock-names = "ipg", "per";
+                               status = "disabled";
                        };
 
                        gpt: gpt@02098000 {
                                compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
                                reg = <0x02098000 0x4000>;
-                               interrupts = <0 55 0x04>;
+                               interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 119>, <&clks 120>;
                                clock-names = "ipg", "per";
                        };
                        gpio1: gpio@0209c000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x0209c000 0x4000>;
-                               interrupts = <0 66 0x04 0 67 0x04>;
+                               interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 67 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio2: gpio@020a0000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020a0000 0x4000>;
-                               interrupts = <0 68 0x04 0 69 0x04>;
+                               interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 69 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio3: gpio@020a4000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020a4000 0x4000>;
-                               interrupts = <0 70 0x04 0 71 0x04>;
+                               interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 71 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio4: gpio@020a8000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020a8000 0x4000>;
-                               interrupts = <0 72 0x04 0 73 0x04>;
+                               interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 73 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio5: gpio@020ac000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020ac000 0x4000>;
-                               interrupts = <0 74 0x04 0 75 0x04>;
+                               interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 75 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio6: gpio@020b0000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020b0000 0x4000>;
-                               interrupts = <0 76 0x04 0 77 0x04>;
+                               interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 77 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio7: gpio@020b4000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020b4000 0x4000>;
-                               interrupts = <0 78 0x04 0 79 0x04>;
+                               interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 79 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
 
                        kpp: kpp@020b8000 {
                                reg = <0x020b8000 0x4000>;
-                               interrupts = <0 82 0x04>;
+                               interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        wdog1: wdog@020bc000 {
                                compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
                                reg = <0x020bc000 0x4000>;
-                               interrupts = <0 80 0x04>;
+                               interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 0>;
                        };
 
                        wdog2: wdog@020c0000 {
                                compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
                                reg = <0x020c0000 0x4000>;
-                               interrupts = <0 81 0x04>;
+                               interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 0>;
                                status = "disabled";
                        };
                        clks: ccm@020c4000 {
                                compatible = "fsl,imx6q-ccm";
                                reg = <0x020c4000 0x4000>;
-                               interrupts = <0 87 0x04 0 88 0x04>;
+                               interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 88 IRQ_TYPE_LEVEL_HIGH>;
                                #clock-cells = <1>;
                        };
 
                        anatop: anatop@020c8000 {
                                compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
                                reg = <0x020c8000 0x1000>;
-                               interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
+                               interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 54 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 127 IRQ_TYPE_LEVEL_HIGH>;
 
                                regulator-1p1@110 {
                                        compatible = "fsl,anatop-regulator";
 
                        tempmon: tempmon {
                                compatible = "fsl,imx6q-tempmon";
-                               interrupts = <0 49 0x04>;
+                               interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
                                fsl,tempmon = <&anatop>;
                                fsl,tempmon-data = <&ocotp>;
                        };
                        usbphy1: usbphy@020c9000 {
                                compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
                                reg = <0x020c9000 0x1000>;
-                               interrupts = <0 44 0x04>;
+                               interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 182>;
                        };
 
                        usbphy2: usbphy@020ca000 {
                                compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
                                reg = <0x020ca000 0x1000>;
-                               interrupts = <0 45 0x04>;
+                               interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 183>;
                        };
 
                                snvs-rtc-lp@34 {
                                        compatible = "fsl,sec-v4.0-mon-rtc-lp";
                                        reg = <0x34 0x58>;
-                                       interrupts = <0 19 0x04 0 20 0x04>;
+                                       interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
+                                                    <0 20 IRQ_TYPE_LEVEL_HIGH>;
                                };
                        };
 
                        epit1: epit@020d0000 { /* EPIT1 */
                                reg = <0x020d0000 0x4000>;
-                               interrupts = <0 56 0x04>;
+                               interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        epit2: epit@020d4000 { /* EPIT2 */
                                reg = <0x020d4000 0x4000>;
-                               interrupts = <0 57 0x04>;
+                               interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        src: src@020d8000 {
                                compatible = "fsl,imx6q-src", "fsl,imx51-src";
                                reg = <0x020d8000 0x4000>;
-                               interrupts = <0 91 0x04 0 96 0x04>;
+                               interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 96 IRQ_TYPE_LEVEL_HIGH>;
                                #reset-cells = <1>;
                        };
 
                        gpc: gpc@020dc000 {
                                compatible = "fsl,imx6q-gpc";
                                reg = <0x020dc000 0x4000>;
-                               interrupts = <0 89 0x04 0 90 0x04>;
+                               interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 90 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        gpr: iomuxc-gpr@020e0000 {
                        iomuxc: iomuxc@020e0000 {
                                compatible = "fsl,imx6dl-iomuxc", "fsl,imx6q-iomuxc";
                                reg = <0x020e0000 0x4000>;
-
-                               audmux {
-                                       pinctrl_audmux_1: audmux-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD2_DAT0__AUD4_RXD  0x80000000
-                                                       MX6QDL_PAD_SD2_DAT3__AUD4_TXC  0x80000000
-                                                       MX6QDL_PAD_SD2_DAT2__AUD4_TXD  0x80000000
-                                                       MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_audmux_2: audmux-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT7__AUD3_RXD  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT4__AUD3_TXC  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT5__AUD3_TXD  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_audmux_3: audmux-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_DISP0_DAT16__AUD5_TXC  0x80000000
-                                                       MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x80000000
-                                                       MX6QDL_PAD_DISP0_DAT19__AUD5_RXD  0x80000000
-                                               >;
-                                       };
-                               };
-
-                               ecspi1 {
-                                       pinctrl_ecspi1_1: ecspi1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
-                                                       MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
-                                                       MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
-                                               >;
-                                       };
-
-                                       pinctrl_ecspi1_2: ecspi1grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
-                                                       MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
-                                                       MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
-                                               >;
-                                       };
-                               };
-
-                               ecspi3 {
-                                       pinctrl_ecspi3_1: ecspi3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
-                                                       MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
-                                                       MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
-                                               >;
-                                       };
-                               };
-
-                               enet {
-                                       pinctrl_enet_1: enetgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO       0x1b0b0
-                                                       MX6QDL_PAD_ENET_MDC__ENET_MDC         0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK  0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK      0x4001b0a8
-                                               >;
-                                       };
-
-                                       pinctrl_enet_2: enetgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL1__ENET_MDIO        0x1b0b0
-                                                       MX6QDL_PAD_KEY_COL2__ENET_MDC         0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK  0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
-                                               >;
-                                       };
-
-                                       pinctrl_enet_3: enetgrp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO       0x1b0b0
-                                                       MX6QDL_PAD_ENET_MDC__ENET_MDC         0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK  0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN     0x1b0b0
-                                               >;
-                                       };
-                               };
-
-                               esai {
-                                       pinctrl_esai_1: esaigrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_RXD0__ESAI_TX_HF_CLK 0x1b030
-                                                       MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK  0x1b030
-                                                       MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS     0x1b030
-                                                       MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2  0x1b030
-                                                       MX6QDL_PAD_ENET_TXD1__ESAI_TX2_RX3   0x1b030
-                                                       MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1   0x1b030
-                                                       MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0    0x1b030
-                                                       MX6QDL_PAD_NANDF_CS2__ESAI_TX0       0x1b030
-                                                       MX6QDL_PAD_NANDF_CS3__ESAI_TX1       0x1b030
-                                               >;
-                                       };
-
-                                       pinctrl_esai_2: esaigrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
-                                                       MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS    0x1b030
-                                                       MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
-                                                       MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3     0x1b030
-                                                       MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1  0x1b030
-                                                       MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0   0x1b030
-                                                       MX6QDL_PAD_GPIO_17__ESAI_TX0        0x1b030
-                                                       MX6QDL_PAD_NANDF_CS3__ESAI_TX1      0x1b030
-                                                       MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK   0x1b030
-                                                       MX6QDL_PAD_GPIO_9__ESAI_RX_FS       0x1b030
-                                               >;
-                                       };
-                               };
-
-                               flexcan1 {
-                                       pinctrl_flexcan1_1: flexcan1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
-                                                       MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_flexcan1_2: flexcan1grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_7__FLEXCAN1_TX   0x80000000
-                                                       MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               flexcan2 {
-                                       pinctrl_flexcan2_1: flexcan2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x80000000
-                                                       MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               gpmi-nand {
-                                       pinctrl_gpmi_nand_1: gpmi-nand-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_NANDF_CLE__NAND_CLE     0xb0b1
-                                                       MX6QDL_PAD_NANDF_ALE__NAND_ALE     0xb0b1
-                                                       MX6QDL_PAD_NANDF_WP_B__NAND_WP_B   0xb0b1
-                                                       MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
-                                                       MX6QDL_PAD_NANDF_CS0__NAND_CE0_B   0xb0b1
-                                                       MX6QDL_PAD_NANDF_CS1__NAND_CE1_B   0xb0b1
-                                                       MX6QDL_PAD_SD4_CMD__NAND_RE_B      0xb0b1
-                                                       MX6QDL_PAD_SD4_CLK__NAND_WE_B      0xb0b1
-                                                       MX6QDL_PAD_NANDF_D0__NAND_DATA00   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D1__NAND_DATA01   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D2__NAND_DATA02   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D3__NAND_DATA03   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D4__NAND_DATA04   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D5__NAND_DATA05   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D6__NAND_DATA06   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D7__NAND_DATA07   0xb0b1
-                                                       MX6QDL_PAD_SD4_DAT0__NAND_DQS      0x00b1
-                                               >;
-                                       };
-                               };
-
-                               hdmi_hdcp {
-                                       pinctrl_hdmi_hdcp_1: hdmihdcpgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_hdmi_hdcp_2: hdmihdcpgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_hdmi_hdcp_3: hdmihdcpgrp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL  0x4001b8b1
-                                                       MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
-                                               >;
-                                       };
-                               };
-
-                               hdmi_cec {
-                                       pinctrl_hdmi_cec_1: hdmicecgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x1f8b0
-                                               >;
-                                       };
-
-                                       pinctrl_hdmi_cec_2: hdmicecgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
-                                               >;
-                                       };
-                               };
-
-                               i2c1 {
-                                       pinctrl_i2c1_1: i2c1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c1_2: i2c1grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
-                                                       MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
-                                               >;
-                                       };
-                               };
-
-                               i2c2 {
-                                       pinctrl_i2c2_1: i2c2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c2_2: i2c2grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c2_3: i2c2grp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_EB2__I2C2_SCL  0x4001b8b1
-                                                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
-                                               >;
-                                       };
-                               };
-
-                               i2c3 {
-                                       pinctrl_i2c3_1: i2c3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c3_2: i2c3grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c3_3: i2c3grp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_5__I2C3_SCL  0x4001b8b1
-                                                       MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c3_4: i2c3grp-4 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_3__I2C3_SCL  0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
-                                               >;
-                                       };
-                               };
-
-                               ipu1 {
-                                       pinctrl_ipu1_1: ipu1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
-                                                       MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15       0x10
-                                                       MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02        0x10
-                                                       MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03        0x10
-                                                       MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04        0x80000000
-                                                       MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00   0x10
-                                                       MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01   0x10
-                                                       MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02   0x10
-                                                       MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03   0x10
-                                                       MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04   0x10
-                                                       MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05   0x10
-                                                       MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06   0x10
-                                                       MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07   0x10
-                                                       MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08   0x10
-                                                       MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09   0x10
-                                                       MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10  0x10
-                                                       MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11  0x10
-                                                       MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12  0x10
-                                                       MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13  0x10
-                                                       MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14  0x10
-                                                       MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15  0x10
-                                                       MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16  0x10
-                                                       MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17  0x10
-                                                       MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18  0x10
-                                                       MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19  0x10
-                                                       MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20  0x10
-                                                       MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21  0x10
-                                                       MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22  0x10
-                                                       MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23  0x10
-                                               >;
-                                       };
-
-                                       pinctrl_ipu1_2: ipu1grp-2 { /* parallel camera */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19    0x80000000
-                                                       MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x80000000
-                                                       MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK   0x80000000
-                                                       MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC      0x80000000
-                                                       MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC     0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_ipu1_3: ipu1grp-3 { /* parallel port 16-bit */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT4__IPU1_CSI0_DATA04   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT5__IPU1_CSI0_DATA05   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT6__IPU1_CSI0_DATA06   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT7__IPU1_CSI0_DATA07   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT8__IPU1_CSI0_DATA08   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT9__IPU1_CSI0_DATA09   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19  0x80000000
-                                                       MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
-                                                       MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC    0x80000000
-                                                       MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC   0x80000000
-                                               >;
-                                       };
-                               };
-
-                               mlb {
-                                       pinctrl_mlb_1: mlbgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_3__MLB_CLK  0x71
-                                                       MX6QDL_PAD_GPIO_6__MLB_SIG  0x71
-                                                       MX6QDL_PAD_GPIO_2__MLB_DATA 0x71
-                                               >;
-                                       };
-
-                                       pinctrl_mlb_2: mlbgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_TXD1__MLB_CLK 0x71
-                                                       MX6QDL_PAD_GPIO_6__MLB_SIG    0x71
-                                                       MX6QDL_PAD_GPIO_2__MLB_DATA   0x71
-                                               >;
-                                       };
-                               };
-
-                               pwm0 {
-                                       pinctrl_pwm0_1: pwm0grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               pwm3 {
-                                       pinctrl_pwm3_1: pwm3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               spdif {
-                                       pinctrl_spdif_1: spdifgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
-                                               >;
-                                       };
-
-                                       pinctrl_spdif_2: spdifgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_16__SPDIF_IN  0x1b0b0
-                                                       MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0
-                                               >;
-                                       };
-
-                                       pinctrl_spdif_3: spdifgrp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
-                                               >;
-                                       };
-                               };
-
-                               uart1 {
-                                       pinctrl_uart1_1: uart1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               uart2 {
-                                       pinctrl_uart2_1: uart2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
-                                               >;
-                                       };
-
-                                       pinctrl_uart2_2: uart2grp-2 { /* DTE mode */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D26__UART2_RX_DATA   0x1b0b1
-                                                       MX6QDL_PAD_EIM_D27__UART2_TX_DATA   0x1b0b1
-                                                       MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               uart3 {
-                                       pinctrl_uart3_1: uart3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D30__UART3_CTS_B   0x1b0b1
-                                                       MX6QDL_PAD_EIM_EB3__UART3_RTS_B   0x1b0b1
-                                               >;
-                                       };
-
-                                       pinctrl_uart3_2: uart3grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D23__UART3_CTS_B   0x1b0b1
-                                                       MX6QDL_PAD_EIM_EB3__UART3_RTS_B   0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               uart4 {
-                                       pinctrl_uart4_1: uart4grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               usbotg {
-                                       pinctrl_usbotg_1: usbotggrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg_2: usbotggrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usbh2 {
-                                       pinctrl_usbh2_1: usbh2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_RGMII_TXC__USB_H2_DATA      0x40013030
-                                                       MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40013030
-                                               >;
-                                       };
-
-                                       pinctrl_usbh2_2: usbh2grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40017030
-                                               >;
-                                       };
-                               };
-
-                               usbh3 {
-                                       pinctrl_usbh3_1: usbh3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_RGMII_RX_CTL__USB_H3_DATA 0x40013030
-                                                       MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE  0x40013030
-                                               >;
-                                       };
-
-                                       pinctrl_usbh3_2: usbh3grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40017030
-                                               >;
-                                       };
-                               };
-
-                               usdhc1 {
-                                       pinctrl_usdhc1_1: usdhc1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD1_CMD__SD1_CMD    0x17059
-                                                       MX6QDL_PAD_SD1_CLK__SD1_CLK    0x10059
-                                                       MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
-                                                       MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
-                                                       MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
-                                                       MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
-                                                       MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x17059
-                                                       MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x17059
-                                                       MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x17059
-                                                       MX6QDL_PAD_NANDF_D3__SD1_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc1_2: usdhc1grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD1_CMD__SD1_CMD    0x17059
-                                                       MX6QDL_PAD_SD1_CLK__SD1_CLK    0x10059
-                                                       MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
-                                                       MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
-                                                       MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
-                                                       MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usdhc2 {
-                                       pinctrl_usdhc2_1: usdhc2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD2_CMD__SD2_CMD    0x17059
-                                                       MX6QDL_PAD_SD2_CLK__SD2_CLK    0x10059
-                                                       MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
-                                                       MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
-                                                       MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
-                                                       MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
-                                                       MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
-                                                       MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
-                                                       MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
-                                                       MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc2_2: usdhc2grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD2_CMD__SD2_CMD    0x17059
-                                                       MX6QDL_PAD_SD2_CLK__SD2_CLK    0x10059
-                                                       MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
-                                                       MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
-                                                       MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
-                                                       MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usdhc3 {
-                                       pinctrl_usdhc3_1: usdhc3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD3_CMD__SD3_CMD    0x17059
-                                                       MX6QDL_PAD_SD3_CLK__SD3_CLK    0x10059
-                                                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
-                                                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
-                                                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
-                                                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
-                                                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
-                                                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
-                                                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
-                                                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz { /* 100Mhz */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
-                                                       MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
-                                                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz { /* 200Mhz */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
-                                                       MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
-                                                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_2: usdhc3grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD3_CMD__SD3_CMD    0x17059
-                                                       MX6QDL_PAD_SD3_CLK__SD3_CLK    0x10059
-                                                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
-                                                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
-                                                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
-                                                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usdhc4 {
-                                       pinctrl_usdhc4_1: usdhc4grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD4_CMD__SD4_CMD    0x17059
-                                                       MX6QDL_PAD_SD4_CLK__SD4_CLK    0x10059
-                                                       MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
-                                                       MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
-                                                       MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
-                                                       MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
-                                                       MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
-                                                       MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
-                                                       MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
-                                                       MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc4_2: usdhc4grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD4_CMD__SD4_CMD    0x17059
-                                                       MX6QDL_PAD_SD4_CLK__SD4_CLK    0x10059
-                                                       MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
-                                                       MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
-                                                       MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
-                                                       MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
-                                               >;
-                                       };
-                               };
-
-                               weim {
-                                       pinctrl_weim_cs0_1: weim_cs0grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_CS0__EIM_CS0_B   0xb0b1
-                                               >;
-                                       };
-
-                                       pinctrl_weim_nor_1: weim_norgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_OE__EIM_OE_B     0xb0b1
-                                                       MX6QDL_PAD_EIM_RW__EIM_RW       0xb0b1
-                                                       MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
-                                                       /* data */
-                                                       MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
-                                                       /* address */
-                                                       MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
-                                                       MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
-                                                       MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
-                                                       MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
-                                                       MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
-                                                       MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
-                                                       MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
-                                                       MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
-                                                       MX6QDL_PAD_EIM_DA15__EIM_AD15  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA14__EIM_AD14  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA13__EIM_AD13  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA12__EIM_AD12  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA11__EIM_AD11  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA10__EIM_AD10  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA9__EIM_AD09   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA8__EIM_AD08   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA7__EIM_AD07   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA6__EIM_AD06   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA5__EIM_AD05   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA4__EIM_AD04   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA3__EIM_AD03   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA2__EIM_AD02   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA1__EIM_AD01   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA0__EIM_AD00   0xb0b1
-                                               >;
-                                       };
-                               };
                        };
 
                        ldb: ldb@020e0008 {
 
                        dcic1: dcic@020e4000 {
                                reg = <0x020e4000 0x4000>;
-                               interrupts = <0 124 0x04>;
+                               interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        dcic2: dcic@020e8000 {
                                reg = <0x020e8000 0x4000>;
-                               interrupts = <0 125 0x04>;
+                               interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        sdma: sdma@020ec000 {
                                compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
                                reg = <0x020ec000 0x4000>;
-                               interrupts = <0 2 0x04>;
+                               interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 155>, <&clks 155>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
 
                        caam@02100000 {
                                reg = <0x02100000 0x40000>;
-                               interrupts = <0 105 0x04 0 106 0x04>;
+                               interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 106 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        aipstz@0217c000 { /* AIPSTZ2 */
                        usbotg: usb@02184000 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184000 0x200>;
-                               interrupts = <0 43 0x04>;
+                               interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 162>;
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
                        usbh1: usb@02184200 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184200 0x200>;
-                               interrupts = <0 40 0x04>;
+                               interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 162>;
                                fsl,usbphy = <&usbphy2>;
                                fsl,usbmisc = <&usbmisc 1>;
                        usbh2: usb@02184400 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184400 0x200>;
-                               interrupts = <0 41 0x04>;
+                               interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 162>;
                                fsl,usbmisc = <&usbmisc 2>;
                                status = "disabled";
                        usbh3: usb@02184600 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184600 0x200>;
-                               interrupts = <0 42 0x04>;
+                               interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 162>;
                                fsl,usbmisc = <&usbmisc 3>;
                                status = "disabled";
                        fec: ethernet@02188000 {
                                compatible = "fsl,imx6q-fec";
                                reg = <0x02188000 0x4000>;
-                               interrupts = <0 118 0x04 0 119 0x04>;
+                               interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 119 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 117>, <&clks 117>, <&clks 190>;
                                clock-names = "ipg", "ahb", "ptp";
                                status = "disabled";
 
                        mlb@0218c000 {
                                reg = <0x0218c000 0x4000>;
-                               interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
+                               interrupts = <0 53 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 117 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 126 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        usdhc1: usdhc@02190000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x02190000 0x4000>;
-                               interrupts = <0 22 0x04>;
+                               interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 163>, <&clks 163>, <&clks 163>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <4>;
                        usdhc2: usdhc@02194000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x02194000 0x4000>;
-                               interrupts = <0 23 0x04>;
+                               interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 164>, <&clks 164>, <&clks 164>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <4>;
                        usdhc3: usdhc@02198000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x02198000 0x4000>;
-                               interrupts = <0 24 0x04>;
+                               interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 165>, <&clks 165>, <&clks 165>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <4>;
                        usdhc4: usdhc@0219c000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x0219c000 0x4000>;
-                               interrupts = <0 25 0x04>;
+                               interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 166>, <&clks 166>, <&clks 166>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <4>;
                                #size-cells = <0>;
                                compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
                                reg = <0x021a0000 0x4000>;
-                               interrupts = <0 36 0x04>;
+                               interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 125>;
                                status = "disabled";
                        };
                                #size-cells = <0>;
                                compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
                                reg = <0x021a4000 0x4000>;
-                               interrupts = <0 37 0x04>;
+                               interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 126>;
                                status = "disabled";
                        };
                                #size-cells = <0>;
                                compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
                                reg = <0x021a8000 0x4000>;
-                               interrupts = <0 38 0x04>;
+                               interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 127>;
                                status = "disabled";
                        };
                        weim: weim@021b8000 {
                                compatible = "fsl,imx6q-weim";
                                reg = <0x021b8000 0x4000>;
-                               interrupts = <0 14 0x04>;
+                               interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 196>;
                        };
 
 
                        tzasc@021d0000 { /* TZASC1 */
                                reg = <0x021d0000 0x4000>;
-                               interrupts = <0 108 0x04>;
+                               interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        tzasc@021d4000 { /* TZASC2 */
                                reg = <0x021d4000 0x4000>;
-                               interrupts = <0 109 0x04>;
+                               interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        audmux: audmux@021d8000 {
                                status = "disabled";
                        };
 
-                       mipi@021dc000 { /* MIPI-CSI */
+                       mipi_csi: mipi@021dc000 {
                                reg = <0x021dc000 0x4000>;
                        };
 
 
                        vdoa@021e4000 {
                                reg = <0x021e4000 0x4000>;
-                               interrupts = <0 18 0x04>;
+                               interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        uart2: serial@021e8000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021e8000 0x4000>;
-                               interrupts = <0 27 0x04>;
+                               interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 160>, <&clks 161>;
                                clock-names = "ipg", "per";
                                dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
                        uart3: serial@021ec000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021ec000 0x4000>;
-                               interrupts = <0 28 0x04>;
+                               interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 160>, <&clks 161>;
                                clock-names = "ipg", "per";
                                dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
                        uart4: serial@021f0000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021f0000 0x4000>;
-                               interrupts = <0 29 0x04>;
+                               interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 160>, <&clks 161>;
                                clock-names = "ipg", "per";
                                dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
                        uart5: serial@021f4000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021f4000 0x4000>;
-                               interrupts = <0 30 0x04>;
+                               interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 160>, <&clks 161>;
                                clock-names = "ipg", "per";
                                dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
                        #crtc-cells = <1>;
                        compatible = "fsl,imx6q-ipu";
                        reg = <0x02400000 0x400000>;
-                       interrupts = <0 6 0x4 0 5 0x4>;
+                       interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 5 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clks 130>, <&clks 131>, <&clks 132>;
                        clock-names = "bus", "di0", "di1";
                        resets = <&src 2>;
index cc68e19c51631666e8241fbc1d4965a18605ca28..f5e4513ebfc3be074263d633cba08b04fba428af 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb_otg1_vbus: usb_otg1_vbus {
+               reg_usb_otg1_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb_otg1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -30,8 +33,9 @@
                        enable-active-high;
                };
 
-               reg_usb_otg2_vbus: usb_otg2_vbus {
+               reg_usb_otg2_vbus: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "usb_otg2_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -45,7 +49,7 @@
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio4 11 0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        status = "okay";
 
        flash: m25p80@0 {
@@ -59,7 +63,7 @@
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        status = "okay";
 };
@@ -68,7 +72,7 @@
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6sl-evk {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6SL_PAD_KEY_ROW7__GPIO4_IO07    0x17059
                                MX6SL_PAD_KEY_COL5__GPIO4_IO02  0x80000000
                        >;
                };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <MX6SL_ECSPI1_PINGRP1>;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <MX6SL_FEC_PINGRP1>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <MX6SL_UART1_PINGRP1>;
+               };
+
+               pinctrl_usbotg1: usbotg1grp {
+                       fsl,pins = <MX6SL_USBOTG1_PINGRP1>;
+               };
+
+               pinctrl_usdhc1: usdhc1grp {
+                       fsl,pins = <MX6SL_USDHC1_PINGRP_D8>;
+               };
+
+               pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+                       fsl,pins = <MX6SL_USDHC1_PINGRP_D8_100MHZ>;
+               };
+
+               pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+                       fsl,pins = <MX6SL_USDHC1_PINGRP_D8_200MHZ>;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <MX6SL_USDHC2_PINGRP_D4>;
+               };
+
+               pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+                       fsl,pins = <MX6SL_USDHC2_PINGRP_D4_100MHZ>;
+               };
+
+               pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+                       fsl,pins = <MX6SL_USDHC2_PINGRP_D4_200MHZ>;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <MX6SL_USDHC3_PINGRP_D4>;
+               };
+
+               pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+                       fsl,pins = <MX6SL_USDHC3_PINGRP_D4_100MHZ>;
+               };
+
+               pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+                       fsl,pins = <MX6SL_USDHC3_PINGRP_D4_200MHZ>;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &usbotg1 {
        vbus-supply = <&reg_usb_otg1_vbus>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg1_1>;
+       pinctrl-0 = <&pinctrl_usbotg1>;
        disable-over-current;
        status = "okay";
 };
 
 &usdhc1 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc1_1>;
-       pinctrl-1 = <&pinctrl_usdhc1_1_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc1_1_200mhz>;
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
        bus-width = <8>;
        cd-gpios = <&gpio4 7 0>;
        wp-gpios = <&gpio4 6 0>;
 
 &usdhc2 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc2_1>;
-       pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>;
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
        cd-gpios = <&gpio5 0 0>;
        wp-gpios = <&gpio4 29 0>;
        status = "okay";
 
 &usdhc3 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc3_1>;
-       pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
        cd-gpios = <&gpio3 22 0>;
        status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx6sl-pingrp.h b/arch/arm/boot/dts/imx6sl-pingrp.h
new file mode 100644 (file)
index 0000000..ead26d4
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX6SL_PINGRP_H
+#define __DTS_IMX6SL_PINGRP_H
+
+#define MX6SL_ECSPI1_PINGRP1 \
+       MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO              0x100b1 \
+       MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI              0x100b1 \
+       MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK              0x100b1
+
+#define MX6SL_FEC_PINGRP1 \
+       MX6SL_PAD_FEC_MDC__FEC_MDC                      0x1b0b0 \
+       MX6SL_PAD_FEC_MDIO__FEC_MDIO                    0x1b0b0 \
+       MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV                 0x1b0b0 \
+       MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0                0x1b0b0 \
+       MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1                0x1b0b0 \
+       MX6SL_PAD_FEC_TX_EN__FEC_TX_EN                  0x1b0b0 \
+       MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0                0x1b0b0 \
+       MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1                0x1b0b0 \
+       MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT              0x4001b0a8
+
+#define MX6SL_UART1_PINGRP1 \
+       MX6SL_PAD_UART1_RXD__UART1_RX_DATA              0x1b0b1 \
+       MX6SL_PAD_UART1_TXD__UART1_TX_DATA              0x1b0b1
+
+#define MX6SL_USBOTG1_PINGRP1 \
+       MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID              0x17059
+
+#define MX6SL_USBOTG1_PINGRP2 \
+       MX6SL_PAD_FEC_RXD0__USB_OTG1_ID                 0x17059
+
+#define MX6SL_USBOTG1_PINGRP3 \
+       MX6SL_PAD_LCD_DAT1__USB_OTG1_ID                 0x17059
+
+#define MX6SL_USBOTG1_PINGRP4 \
+       MX6SL_PAD_REF_CLK_32K__USB_OTG1_ID              0x17059
+
+#define MX6SL_USBOTG1_PINGRP5 \
+       MX6SL_PAD_SD3_DAT0__USB_OTG1_ID                 0x17059
+
+#define MX6SL_USBOTG2_PINGRP1 \
+       MX6SL_PAD_ECSPI1_SCLK__USB_OTG2_OC              0x17059
+
+#define MX6SL_USBOTG2_PINGRP2 \
+       MX6SL_PAD_ECSPI2_SCLK__USB_OTG2_OC              0x17059
+
+#define MX6SL_USBOTG2_PINGRP3 \
+       MX6SL_PAD_KEY_ROW5__USB_OTG2_OC                 0x17059
+
+#define MX6SL_USBOTG2_PINGRP4 \
+       MX6SL_PAD_SD3_DAT2__USB_OTG2_OC                 0x17059
+
+#define MX6SL_USDHC1_D4(pad, pad_data3, pad_clk)       \
+       MX6SL_PAD_SD1_CMD__SD1_CMD                      pad \
+       MX6SL_PAD_SD1_CLK__SD1_CLK                      pad_clk \
+       MX6SL_PAD_SD1_DAT0__SD1_DATA0                   pad \
+       MX6SL_PAD_SD1_DAT1__SD1_DATA1                   pad \
+       MX6SL_PAD_SD1_DAT2__SD1_DATA2                   pad \
+       MX6SL_PAD_SD1_DAT3__SD1_DATA3                   pad_data3
+
+#define MX6SL_USDHC1_D8(pad, pad_data3, pad_clk)       \
+       MX6SL_USDHC1_D4(pad, pad_data3, pad_clk)        \
+       MX6SL_PAD_SD1_DAT4__SD1_DATA4                   pad \
+       MX6SL_PAD_SD1_DAT5__SD1_DATA5                   pad \
+       MX6SL_PAD_SD1_DAT6__SD1_DATA6                   pad \
+       MX6SL_PAD_SD1_DAT7__SD1_DATA7                   pad
+
+#define MX6SL_USDHC2_D4(pad, pad_data3, pad_clk)       \
+       MX6SL_PAD_SD2_CMD__SD2_CMD                      pad \
+       MX6SL_PAD_SD2_CLK__SD2_CLK                      pad_clk \
+       MX6SL_PAD_SD2_DAT0__SD2_DATA0                   pad \
+       MX6SL_PAD_SD2_DAT1__SD2_DATA1                   pad \
+       MX6SL_PAD_SD2_DAT2__SD2_DATA2                   pad \
+       MX6SL_PAD_SD2_DAT3__SD2_DATA3                   pad_data3
+
+#define MX6SL_USDHC2_D8(pad, pad_data3, pad_clk)       \
+       MX6SL_USDHC2_D4(pad, pad_data3, pad_clk)        \
+       MX6SL_PAD_SD2_DAT4__SD2_DATA4                   pad \
+       MX6SL_PAD_SD2_DAT5__SD2_DATA5                   pad \
+       MX6SL_PAD_SD2_DAT6__SD2_DATA6                   pad \
+       MX6SL_PAD_SD2_DAT7__SD2_DATA7                   pad
+
+#define MX6SL_USDHC3_D4(pad, pad_data3, pad_clk)       \
+       MX6SL_PAD_SD3_CMD__SD3_CMD                      pad \
+       MX6SL_PAD_SD3_CLK__SD3_CLK                      pad_clk \
+       MX6SL_PAD_SD3_DAT0__SD3_DATA0                   pad \
+       MX6SL_PAD_SD3_DAT1__SD3_DATA1                   pad \
+       MX6SL_PAD_SD3_DAT2__SD3_DATA2                   pad \
+       MX6SL_PAD_SD3_DAT3__SD3_DATA3                   pad_data3
+
+#define MX6SL_USDHC3_D8(pad, pad_data3, pad_clk)       \
+       MX6SL_USDHC3_D4(pad, pad_data3, pad_clk)        \
+       MX6SL_PAD_SD2_DAT4__SD3_DATA4                   pad \
+       MX6SL_PAD_SD2_DAT5__SD3_DATA5                   pad \
+       MX6SL_PAD_SD2_DAT6__SD3_DATA6                   pad \
+       MX6SL_PAD_SD2_DAT7__SD3_DATA7                   pad
+
+#define MX6SL_USDHC4_D4(pad, pad_data3, pad_clk)       \
+       MX6SL_PAD_EPDC_BDR1__SD4_CMD                    pad \
+       MX6SL_PAD_EPDC_BDR0__SD4_CLK                    pad_clk \
+       MX6SL_PAD_EPDC_PWRCOM__SD4_DATA0                pad \
+       MX6SL_PAD_EPDC_PWRINT__SD4_DATA1                pad \
+       MX6SL_PAD_EPDC_PWRSTAT__SD4_DATA2               pad \
+       MX6SL_PAD_EPDC_PWRWAKEUP__SD4_DATA3             pad_data3
+
+#define MX6SL_USDHC4_D8(pad, pad_data3, pad_clk)       \
+       MX6SL_USDHC4_D4(pad, pad_data3, pad_clk)        \
+       MX6SL_PAD_KEY_COL7__SD4_DATA4                   pad \
+       MX6SL_PAD_KEY_ROW7__SD4_DATA5                   pad \
+       MX6SL_PAD_KEY_COL3__SD4_DATA6                   pad \
+       MX6SL_PAD_KEY_ROW3__SD4_DATA7                   pad
+
+#define MX6SL_USDHC1_PINGRP_D4       MX6SL_USDHC1_D4(0x17059, 0x17059, 0x10059)
+#define MX6SL_USDHC1_PINGRP_D4_100MHZ MX6SL_USDHC1_D4(0x170b9, 0x170b9, 0x100b9)
+#define MX6SL_USDHC1_PINGRP_D4_200MHZ MX6SL_USDHC1_D4(0x170f9, 0x170f9, 0x100f9)
+#define MX6SL_USDHC1_PINGRP_D8       MX6SL_USDHC1_D8(0x17059, 0x17059, 0x10059)
+#define MX6SL_USDHC1_PINGRP_D8_100MHZ MX6SL_USDHC1_D8(0x170b9, 0x170b9, 0x100b9)
+#define MX6SL_USDHC1_PINGRP_D8_200MHZ MX6SL_USDHC1_D8(0x170f9, 0x170f9, 0x100f9)
+
+#define MX6SL_USDHC2_PINGRP_D4       MX6SL_USDHC2_D4(0x17059, 0x17059, 0x10059)
+#define MX6SL_USDHC2_PINGRP_D4_100MHZ MX6SL_USDHC2_D4(0x170b9, 0x170b9, 0x100b9)
+#define MX6SL_USDHC2_PINGRP_D4_200MHZ MX6SL_USDHC2_D4(0x170f9, 0x170f9, 0x100f9)
+#define MX6SL_USDHC2_PINGRP_D8       MX6SL_USDHC2_D8(0x17059, 0x17059, 0x10059)
+#define MX6SL_USDHC2_PINGRP_D8_100MHZ MX6SL_USDHC2_D8(0x170b9, 0x170b9, 0x100b9)
+#define MX6SL_USDHC2_PINGRP_D8_200MHZ MX6SL_USDHC2_D8(0x170f9, 0x170f9, 0x100f9)
+
+#define MX6SL_USDHC3_PINGRP_D4       MX6SL_USDHC3_D4(0x17059, 0x17059, 0x10059)
+#define MX6SL_USDHC3_PINGRP_D4_100MHZ MX6SL_USDHC3_D4(0x170b9, 0x170b9, 0x100b9)
+#define MX6SL_USDHC3_PINGRP_D4_200MHZ MX6SL_USDHC3_D4(0x170f9, 0x170f9, 0x100f9)
+#define MX6SL_USDHC3_PINGRP_D8       MX6SL_USDHC3_D8(0x17059, 0x17059, 0x10059)
+#define MX6SL_USDHC3_PINGRP_D8_100MHZ MX6SL_USDHC3_D8(0x170b9, 0x170b9, 0x100b9)
+#define MX6SL_USDHC3_PINGRP_D8_200MHZ MX6SL_USDHC3_D8(0x170f9, 0x170f9, 0x100f9)
+
+#define MX6SL_USDHC4_PINGRP_D4       MX6SL_USDHC4_D4(0x17059, 0x17059, 0x10059)
+#define MX6SL_USDHC4_PINGRP_D4_100MHZ MX6SL_USDHC4_D4(0x170b9, 0x170b9, 0x100b9)
+#define MX6SL_USDHC4_PINGRP_D4_200MHZ MX6SL_USDHC4_D4(0x170f9, 0x170f9, 0x100f9)
+#define MX6SL_USDHC4_PINGRP_D8       MX6SL_USDHC4_D8(0x17059, 0x17059, 0x10059)
+#define MX6SL_USDHC4_PINGRP_D8_100MHZ MX6SL_USDHC4_D8(0x170b9, 0x170b9, 0x100b9)
+#define MX6SL_USDHC4_PINGRP_D8_200MHZ MX6SL_USDHC4_D8(0x170f9, 0x170f9, 0x100f9)
+
+#endif /* __DTS_IMX6SL_PINGRP_H */
index 28558f1aaf2da8e67cb6b191f2d11e7964518b59..b526118b6fe92da9f69344ed80481d8c77d6ffb1 100644 (file)
@@ -7,8 +7,10 @@
  *
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "skeleton.dtsi"
 #include "imx6sl-pinfunc.h"
+#include "imx6sl-pingrp.h"
 #include <dt-bindings/clock/imx6sl-clock.h>
 
 / {
@@ -76,7 +78,7 @@
                L2: l2-cache@00a02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00a02000 0x1000>;
-                       interrupts = <0 92 0x04>;
+                       interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
                        cache-unified;
                        cache-level = <2>;
                        arm,tag-latency = <4 2 3>;
@@ -85,7 +87,7 @@
 
                pmu {
                        compatible = "arm,cortex-a9-pmu";
-                       interrupts = <0 94 0x04>;
+                       interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                aips1: aips-bus@02000000 {
 
                                spdif: spdif@02004000 {
                                        reg = <0x02004000 0x4000>;
-                                       interrupts = <0 52 0x04>;
+                                       interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
                                };
 
                                ecspi1: ecspi@02008000 {
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02008000 0x4000>;
-                                       interrupts = <0 31 0x04>;
+                                       interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_ECSPI1>,
                                                 <&clks IMX6SL_CLK_ECSPI1>;
                                        clock-names = "ipg", "per";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x0200c000 0x4000>;
-                                       interrupts = <0 32 0x04>;
+                                       interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_ECSPI2>,
                                                 <&clks IMX6SL_CLK_ECSPI2>;
                                        clock-names = "ipg", "per";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02010000 0x4000>;
-                                       interrupts = <0 33 0x04>;
+                                       interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_ECSPI3>,
                                                 <&clks IMX6SL_CLK_ECSPI3>;
                                        clock-names = "ipg", "per";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02014000 0x4000>;
-                                       interrupts = <0 34 0x04>;
+                                       interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_ECSPI4>,
                                                 <&clks IMX6SL_CLK_ECSPI4>;
                                        clock-names = "ipg", "per";
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02018000 0x4000>;
-                                       interrupts = <0 30 0x04>;
+                                       interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02020000 0x4000>;
-                                       interrupts = <0 26 0x04>;
+                                       interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02024000 0x4000>;
-                                       interrupts = <0 27 0x04>;
+                                       interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                ssi1: ssi@02028000 {
                                        compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
                                        reg = <0x02028000 0x4000>;
-                                       interrupts = <0 46 0x04>;
+                                       interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_SSI1>;
-                                       dmas = <&sdma 37 1 0>,
-                                              <&sdma 38 1 0>;
+                                       dmas = <&sdma 37 22 0>,
+                                              <&sdma 38 22 0>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <15>;
                                        status = "disabled";
                                ssi2: ssi@0202c000 {
                                        compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
                                        reg = <0x0202c000 0x4000>;
-                                       interrupts = <0 47 0x04>;
+                                       interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_SSI2>;
-                                       dmas = <&sdma 41 1 0>,
-                                              <&sdma 42 1 0>;
+                                       dmas = <&sdma 41 22 0>,
+                                              <&sdma 42 22 0>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <15>;
                                        status = "disabled";
                                ssi3: ssi@02030000 {
                                        compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
                                        reg = <0x02030000 0x4000>;
-                                       interrupts = <0 48 0x04>;
+                                       interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_SSI3>;
-                                       dmas = <&sdma 45 1 0>,
-                                              <&sdma 46 1 0>;
+                                       dmas = <&sdma 45 22 0>,
+                                              <&sdma 46 22 0>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <15>;
                                        status = "disabled";
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02034000 0x4000>;
-                                       interrupts = <0 28 0x04>;
+                                       interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02038000 0x4000>;
-                                       interrupts = <0 29 0x04>;
+                                       interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
                                reg = <0x02080000 0x4000>;
-                               interrupts = <0 83 0x04>;
+                               interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_PWM1>,
                                         <&clks IMX6SL_CLK_PWM1>;
                                clock-names = "ipg", "per";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
                                reg = <0x02084000 0x4000>;
-                               interrupts = <0 84 0x04>;
+                               interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_PWM2>,
                                         <&clks IMX6SL_CLK_PWM2>;
                                clock-names = "ipg", "per";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
                                reg = <0x02088000 0x4000>;
-                               interrupts = <0 85 0x04>;
+                               interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_PWM3>,
                                         <&clks IMX6SL_CLK_PWM3>;
                                clock-names = "ipg", "per";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
                                reg = <0x0208c000 0x4000>;
-                               interrupts = <0 86 0x04>;
+                               interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_PWM4>,
                                         <&clks IMX6SL_CLK_PWM4>;
                                clock-names = "ipg", "per";
                        gpt: gpt@02098000 {
                                compatible = "fsl,imx6sl-gpt";
                                reg = <0x02098000 0x4000>;
-                               interrupts = <0 55 0x04>;
+                               interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_GPT>,
                                         <&clks IMX6SL_CLK_GPT_SERIAL>;
                                clock-names = "ipg", "per";
                        gpio1: gpio@0209c000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x0209c000 0x4000>;
-                               interrupts = <0 66 0x04 0 67 0x04>;
+                               interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 67 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio2: gpio@020a0000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x020a0000 0x4000>;
-                               interrupts = <0 68 0x04 0 69 0x04>;
+                               interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 69 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio3: gpio@020a4000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x020a4000 0x4000>;
-                               interrupts = <0 70 0x04 0 71 0x04>;
+                               interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 71 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio4: gpio@020a8000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x020a8000 0x4000>;
-                               interrupts = <0 72 0x04 0 73 0x04>;
+                               interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 73 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio5: gpio@020ac000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x020ac000 0x4000>;
-                               interrupts = <0 74 0x04 0 75 0x04>;
+                               interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 75 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
 
                        kpp: kpp@020b8000 {
                                reg = <0x020b8000 0x4000>;
-                               interrupts = <0 82 0x04>;
+                               interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        wdog1: wdog@020bc000 {
                                compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
                                reg = <0x020bc000 0x4000>;
-                               interrupts = <0 80 0x04>;
+                               interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_DUMMY>;
                        };
 
                        wdog2: wdog@020c0000 {
                                compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
                                reg = <0x020c0000 0x4000>;
-                               interrupts = <0 81 0x04>;
+                               interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_DUMMY>;
                                status = "disabled";
                        };
                        clks: ccm@020c4000 {
                                compatible = "fsl,imx6sl-ccm";
                                reg = <0x020c4000 0x4000>;
-                               interrupts = <0 87 0x04 0 88 0x04>;
+                               interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 88 IRQ_TYPE_LEVEL_HIGH>;
                                #clock-cells = <1>;
                        };
 
                                             "fsl,imx6q-anatop",
                                             "syscon", "simple-bus";
                                reg = <0x020c8000 0x1000>;
-                               interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
+                               interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 54 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 127 IRQ_TYPE_LEVEL_HIGH>;
 
                                regulator-1p1@110 {
                                        compatible = "fsl,anatop-regulator";
                        usbphy1: usbphy@020c9000 {
                                compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
                                reg = <0x020c9000 0x1000>;
-                               interrupts = <0 44 0x04>;
+                               interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBPHY1>;
                        };
 
                        usbphy2: usbphy@020ca000 {
                                compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
                                reg = <0x020ca000 0x1000>;
-                               interrupts = <0 45 0x04>;
+                               interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBPHY2>;
                        };
 
                                snvs-rtc-lp@34 {
                                        compatible = "fsl,sec-v4.0-mon-rtc-lp";
                                        reg = <0x34 0x58>;
-                                       interrupts = <0 19 0x04 0 20 0x04>;
+                                       interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
+                                                    <0 20 IRQ_TYPE_LEVEL_HIGH>;
                                };
                        };
 
                        epit1: epit@020d0000 {
                                reg = <0x020d0000 0x4000>;
-                               interrupts = <0 56 0x04>;
+                               interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        epit2: epit@020d4000 {
                                reg = <0x020d4000 0x4000>;
-                               interrupts = <0 57 0x04>;
+                               interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        src: src@020d8000 {
                                compatible = "fsl,imx6sl-src", "fsl,imx51-src";
                                reg = <0x020d8000 0x4000>;
-                               interrupts = <0 91 0x04 0 96 0x04>;
+                               interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 96 IRQ_TYPE_LEVEL_HIGH>;
                                #reset-cells = <1>;
                        };
 
                        gpc: gpc@020dc000 {
                                compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
                                reg = <0x020dc000 0x4000>;
-                               interrupts = <0 89 0x04>;
+                               interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        gpr: iomuxc-gpr@020e0000 {
                        iomuxc: iomuxc@020e0000 {
                                compatible = "fsl,imx6sl-iomuxc";
                                reg = <0x020e0000 0x4000>;
-
-                               ecspi1 {
-                                       pinctrl_ecspi1_1: ecspi1grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
-                                                       MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
-                                                       MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
-                                               >;
-                                       };
-                               };
-
-                               fec {
-                                       pinctrl_fec_1: fecgrp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_FEC_MDC__FEC_MDC         0x1b0b0
-                                                       MX6SL_PAD_FEC_MDIO__FEC_MDIO       0x1b0b0
-                                                       MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV    0x1b0b0
-                                                       MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0   0x1b0b0
-                                                       MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1   0x1b0b0
-                                                       MX6SL_PAD_FEC_TX_EN__FEC_TX_EN     0x1b0b0
-                                                       MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0   0x1b0b0
-                                                       MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1   0x1b0b0
-                                                       MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
-                                               >;
-                                       };
-                               };
-
-                               uart1 {
-                                       pinctrl_uart1_1: uart1grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
-                                                       MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               usbotg1 {
-                                       pinctrl_usbotg1_1: usbotg1grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg1_2: usbotg1grp-2 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_FEC_RXD0__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg1_3: usbotg1grp-3 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_LCD_DAT1__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg1_4: usbotg1grp-4 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_REF_CLK_32K__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg1_5: usbotg1grp-5 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_DAT0__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usbotg2 {
-                                       pinctrl_usbotg2_1: usbotg2grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_ECSPI1_SCLK__USB_OTG2_OC 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg2_2: usbotg2grp-2 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_ECSPI2_SCLK__USB_OTG2_OC 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg2_3: usbotg2grp-3 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_KEY_ROW5__USB_OTG2_OC 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg2_4: usbotg2grp-4 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_DAT2__USB_OTG2_OC 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usdhc1 {
-                                       pinctrl_usdhc1_1: usdhc1grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD1_CMD__SD1_CMD    0x17059
-                                                       MX6SL_PAD_SD1_CLK__SD1_CLK    0x10059
-                                                       MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
-                                                       MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
-                                                       MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
-                                                       MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
-                                                       MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
-                                                       MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
-                                                       MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
-                                                       MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc1_1_100mhz: usdhc1grp-1-100mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9
-                                                       MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9
-                                                       MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9
-                                                       MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9
-                                                       MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9
-                                                       MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9
-                                                       MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9
-                                                       MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9
-                                                       MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9
-                                                       MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc1_1_200mhz: usdhc1grp-1-200mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9
-                                                       MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9
-                                                       MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
-                                                       MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
-                                                       MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
-                                                       MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
-                                                       MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9
-                                                       MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9
-                                                       MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9
-                                                       MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9
-                                               >;
-                                       };
-
-
-                               };
-
-                               usdhc2 {
-                                       pinctrl_usdhc2_1: usdhc2grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD2_CMD__SD2_CMD    0x17059
-                                                       MX6SL_PAD_SD2_CLK__SD2_CLK    0x10059
-                                                       MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
-                                                       MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
-                                                       MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
-                                                       MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc2_1_100mhz: usdhc2grp-1-100mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD2_CMD__SD2_CMD    0x170b9
-                                                       MX6SL_PAD_SD2_CLK__SD2_CLK    0x100b9
-                                                       MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
-                                                       MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
-                                                       MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
-                                                       MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc2_1_200mhz: usdhc2grp-1-200mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD2_CMD__SD2_CMD    0x170f9
-                                                       MX6SL_PAD_SD2_CLK__SD2_CLK    0x100f9
-                                                       MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
-                                                       MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
-                                                       MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
-                                                       MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
-                                               >;
-                                       };
-
-                               };
-
-                               usdhc3 {
-                                       pinctrl_usdhc3_1: usdhc3grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_CMD__SD3_CMD    0x17059
-                                                       MX6SL_PAD_SD3_CLK__SD3_CLK    0x10059
-                                                       MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
-                                                       MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
-                                                       MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
-                                                       MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_CMD__SD3_CMD    0x170b9
-                                                       MX6SL_PAD_SD3_CLK__SD3_CLK    0x100b9
-                                                       MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
-                                                       MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
-                                                       MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
-                                                       MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_CMD__SD3_CMD    0x170f9
-                                                       MX6SL_PAD_SD3_CLK__SD3_CLK    0x100f9
-                                                       MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
-                                                       MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
-                                                       MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
-                                                       MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
-                                               >;
-                                       };
-                               };
                        };
 
                        csi: csi@020e4000 {
                                reg = <0x020e4000 0x4000>;
-                               interrupts = <0 7 0x04>;
+                               interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        spdc: spdc@020e8000 {
                                reg = <0x020e8000 0x4000>;
-                               interrupts = <0 6 0x04>;
+                               interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        sdma: sdma@020ec000 {
                                compatible = "fsl,imx6sl-sdma", "fsl,imx35-sdma";
                                reg = <0x020ec000 0x4000>;
-                               interrupts = <0 2 0x04>;
+                               interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_SDMA>,
                                         <&clks IMX6SL_CLK_SDMA>;
                                clock-names = "ipg", "ahb";
 
                        pxp: pxp@020f0000 {
                                reg = <0x020f0000 0x4000>;
-                               interrupts = <0 98 0x04>;
+                               interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        epdc: epdc@020f4000 {
                                reg = <0x020f4000 0x4000>;
-                               interrupts = <0 97 0x04>;
+                               interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        lcdif: lcdif@020f8000 {
                                reg = <0x020f8000 0x4000>;
-                               interrupts = <0 39 0x04>;
+                               interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        dcp: dcp@020fc000 {
                                reg = <0x020fc000 0x4000>;
-                               interrupts = <0 99 0x04>;
+                               interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>;
                        };
                };
 
                        usbotg1: usb@02184000 {
                                compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
                                reg = <0x02184000 0x200>;
-                               interrupts = <0 43 0x04>;
+                               interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
                        usbotg2: usb@02184200 {
                                compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
                                reg = <0x02184200 0x200>;
-                               interrupts = <0 42 0x04>;
+                               interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy2>;
                                fsl,usbmisc = <&usbmisc 1>;
                        usbh: usb@02184400 {
                                compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
                                reg = <0x02184400 0x200>;
-                               interrupts = <0 40 0x04>;
+                               interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbmisc = <&usbmisc 2>;
                                status = "disabled";
                        fec: ethernet@02188000 {
                                compatible = "fsl,imx6sl-fec", "fsl,imx25-fec";
                                reg = <0x02188000 0x4000>;
-                               interrupts = <0 114 0x04>;
+                               interrupts = <0 114 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_ENET_REF>,
                                         <&clks IMX6SL_CLK_ENET_REF>;
                                clock-names = "ipg", "ahb";
                        usdhc1: usdhc@02190000 {
                                compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
                                reg = <0x02190000 0x4000>;
-                               interrupts = <0 22 0x04>;
+                               interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USDHC1>,
                                         <&clks IMX6SL_CLK_USDHC1>,
                                         <&clks IMX6SL_CLK_USDHC1>;
                        usdhc2: usdhc@02194000 {
                                compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
                                reg = <0x02194000 0x4000>;
-                               interrupts = <0 23 0x04>;
+                               interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USDHC2>,
                                         <&clks IMX6SL_CLK_USDHC2>,
                                         <&clks IMX6SL_CLK_USDHC2>;
                        usdhc3: usdhc@02198000 {
                                compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
                                reg = <0x02198000 0x4000>;
-                               interrupts = <0 24 0x04>;
+                               interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USDHC3>,
                                         <&clks IMX6SL_CLK_USDHC3>,
                                         <&clks IMX6SL_CLK_USDHC3>;
                        usdhc4: usdhc@0219c000 {
                                compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
                                reg = <0x0219c000 0x4000>;
-                               interrupts = <0 25 0x04>;
+                               interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USDHC4>,
                                         <&clks IMX6SL_CLK_USDHC4>,
                                         <&clks IMX6SL_CLK_USDHC4>;
                                #size-cells = <0>;
                                compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
                                reg = <0x021a0000 0x4000>;
-                               interrupts = <0 36 0x04>;
+                               interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_I2C1>;
                                status = "disabled";
                        };
                                #size-cells = <0>;
                                compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
                                reg = <0x021a4000 0x4000>;
-                               interrupts = <0 37 0x04>;
+                               interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_I2C2>;
                                status = "disabled";
                        };
                                #size-cells = <0>;
                                compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
                                reg = <0x021a8000 0x4000>;
-                               interrupts = <0 38 0x04>;
+                               interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_I2C3>;
                                status = "disabled";
                        };
 
                        rngb: rngb@021b4000 {
                                reg = <0x021b4000 0x4000>;
-                               interrupts = <0 5 0x04>;
+                               interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        weim: weim@021b8000 {
                                reg = <0x021b8000 0x4000>;
-                               interrupts = <0 14 0x04>;
+                               interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        ocotp: ocotp@021bc000 {
index 650ef30e1856f9591f32a445f279489c82b22b68..e4e1968dfca8abe05defd5ebe6ced71cbe88df95 100644 (file)
@@ -97,6 +97,8 @@
                        reg = <0x90000 0x200>;
                        interrupts = <28>;
                        clocks = <&gate_clk 4>;
+                       pinctrl-0 = <&pmx_sdio>;
+                       pinctrl-names = "default";
                        bus-width = <4>;
                        cap-sdio-irq;
                        cap-sd-highspeed;
index 3933a331ddc2ed8d8f71b58c4cc7389e7e860220..f010c21220bf8dd485cb1dd3cdee0f881223b23f 100644 (file)
                        reg = <0x90000 0x200>;
                        interrupts = <28>;
                        clocks = <&gate_clk 4>;
+                       pinctrl-0 = <&pmx_sdio>;
+                       pinctrl-names = "default";
                        bus-width = <4>;
                        cap-sdio-irq;
                        cap-sd-highspeed;
index e112ca62d978e9ccdedfb37d06bec0b8fe036de8..ff13b9397c8a72b17fd772db76d06450aa62b754 100644 (file)
@@ -25,7 +25,7 @@
                blue-power {
                        label = "dns320:blue:power";
                        gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
                blue-usb {
                        label = "dns320:blue:usb";
index 5119fb8a8eb6203c5743294246bdd62731da7523..f4330434b6fff84726ce4200e06d11c44ae005f9 100644 (file)
@@ -25,7 +25,7 @@
                white-power {
                        label = "dns325:white:power";
                        gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
                white-usb {
                        label = "dns325:white:usb";
index 33ff368fbfa5696353353fc5151b4fefd7cc6198..a5f1e3942f57f5a047be1f6b98abdcdca3c886e0 100644 (file)
@@ -43,7 +43,7 @@
                health {
                        label = "status:green:health";
                        gpios = <&gpio1 14 1>;
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
                fault {
                        label = "status:orange:fault";
index a43bebb251102fbbfcde84e58f1955ce52f5de5b..a9e98c9796545728628f0a22dd346510819a692b 100644 (file)
@@ -86,7 +86,7 @@
                health {
                        label = "status:green:health";
                        gpios = <&gpio1 14 1>;
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
                fault {
                        label = "status:orange:fault";
index d30a91a5047d6939c2dfdd69989bde39c359f9b7..4d2a70fcdcc4b1f38665334362c74adfeae9e941 100644 (file)
                        nr-ports = <1>;
                };
 
+               /* AzureWave AW-GH381 WiFi/BT */
                mvsdio@90000 {
                        status = "okay";
-                       /* No CD or WP GPIOs */
-                       broken-cd;
+                       non-removable;
                };
        };
 
index c5fb02f7ebc3e33107ac067d46a6394d6c21b27d..dbc90330c8736eb4a346db16d6196cbe35548334 100644 (file)
@@ -82,7 +82,7 @@
                green-os {
                        label = "ib62x0:green:os";
                        gpios = <&gpio0 25 0>;
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
                red-os {
                        label = "ib62x0:red:os";
index 4a62b206f680b4c1261a404ce16ce26fb498f6c0..399fb0caf5ab3c7e61cac7b0a4e5e8e3810f2de7 100644 (file)
                led-level {
                        label = "led_level";
                        gpios = <&gpio1 9 0>;
-                       linux,default-trigger = "default-on";
+                       default-state = "on";
                };
                power-blue {
                        label = "power:blue";
                        gpios = <&gpio1 10 0>;
-                       linux,default-trigger = "timer";
+                       default-state = "keep";
                };
                power-red {
                        label = "power:red";
index d15395d671ededf4caf501518bb1e33ffba0cba8..b9de441919e29d785c38e6e7ae10e9695dcc89d8 100644 (file)
                power_led {
                        label = "status:white:power_led";
                        gpios = <&gpio0 16 0>;
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
                rebuild_led {
                        label = "status:white:rebuild_led";
index 4e8f9e42c5929135e05109142bcec7100ed83d02..bc34a609a1952c46adc3e1f3c6ca39f53b48a6fa 100644 (file)
                led@4 {
                        label = "lsxl:blue:power";
                        gpios = <&gpio1 7 1>;
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
 
                led@5 {
index e6a102cf424cd646d9e121acd2b821ea46bb81be..3b1a365c9a8ee52042b3e00a7bc8ef65ff118ece 100644 (file)
@@ -1,5 +1,18 @@
+/*
+ * Device Tree file for NETGEAR ReadyNAS Duo v2
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * 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.
+ */
+
 /dts-v1/;
 
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
 #include "kirkwood.dtsi"
 #include "kirkwood-6282.dtsi"
 
                                marvell,pins = "mpp47";
                                marvell,function = "gpio";
                        };
+
                        pmx_button_backup: pmx-button-backup {
                                marvell,pins = "mpp45";
                                marvell,function = "gpio";
                        };
+
                        pmx_button_reset: pmx-button-reset {
                                marvell,pins = "mpp13";
                                marvell,function = "gpio";
                        };
+
                        pmx_led_blue_power: pmx-led-blue-power {
                                marvell,pins = "mpp31";
                                marvell,function = "gpio";
                        };
+
                        pmx_led_blue_activity: pmx-led-blue-activity {
                                marvell,pins = "mpp38";
                                marvell,function = "gpio";
                        };
+
                        pmx_led_blue_disk1: pmx-led-blue-disk1 {
                                marvell,pins = "mpp23";
                                marvell,function = "gpio";
                        };
+
                        pmx_led_blue_disk2: pmx-led-blue-disk2 {
                                marvell,pins = "mpp22";
                                marvell,function = "gpio";
                        };
+
                        pmx_led_blue_backup: pmx-led-blue-backup {
                                marvell,pins = "mpp29";
                                marvell,function = "gpio";
                        };
+
+                       pmx_poweroff: pmx-poweroff {
+                               marvell,pins = "mpp30";
+                               marvell,function = "gpio";
+                       };
                };
 
                clocks {
-                      #address-cells = <1>;
-                      #size-cells = <0>;
-
-                      g762_clk: fixedclk {
+                      g762_clk: g762-oscillator {
                                 compatible = "fixed-clock";
                                 #clock-cells = <0>;
                                 clock-frequency = <8192>;
 
                power_led {
                        label = "status:blue:power_led";
-                       gpios = <&gpio0 31 1>;   /* GPIO 31 Active Low */
-                       linux,default-trigger = "default-on";
+                       gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+                       default-state = "keep";
                };
+
                activity_led {
                        label = "status:blue:activity_led";
-                       gpios = <&gpio1 6 1>;    /* GPIO 38 Active Low */
+                       gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
                };
+
                disk1_led {
                        label = "status:blue:disk1_led";
-                       gpios = <&gpio0 23 1>;   /* GPIO 23 Active Low */
+                       gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
                };
+
                disk2_led {
                        label = "status:blue:disk2_led";
-                       gpios = <&gpio0 22 1>;   /* GPIO 22 Active Low */
+                       gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
                };
+
                backup_led {
                        label = "status:blue:backup_led";
-                       gpios = <&gpio0 29 1>;   /* GPIO 29 Active Low*/
+                       gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
                };
        };
 
-       gpio_keys {
+       gpio-keys {
                compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
                pinctrl-0 = <&pmx_button_power &pmx_button_backup
                             &pmx_button_reset>;
                pinctrl-names = "default";
 
-               button@1 {
+               power-button {
                        label = "Power Button";
-                       linux,code = <116>;     /* KEY_POWER */
-                       gpios = <&gpio1 15 1>;
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
                };
-               button@2 {
+
+               reset-button {
                        label = "Reset Button";
-                       linux,code = <0x198>;   /* KEY_RESTART */
-                       gpios = <&gpio0 13 1>;
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
                };
-               button@3 {
+
+               backup-button {
                        label = "Backup Button";
-                       linux,code = <133>;     /* KEY_COPY */
-                       gpios = <&gpio1 13 1>;
+                       linux,code = <KEY_COPY>;
+                       gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
                };
        };
 
-        regulators {
-                compatible = "simple-bus";
-                #address-cells = <1>;
-                #size-cells = <0>;
-
-                usb_power: regulator@1 {
-                        compatible = "regulator-fixed";
-                        reg = <1>;
-                        regulator-name = "USB 3.0 Power";
-                        regulator-min-microvolt = <5000000>;
-                        regulator-max-microvolt = <5000000>;
-                        enable-active-high;
-                        regulator-always-on;
-                        regulator-boot-on;
-                        gpio = <&gpio1 14 0>;
-                };
-        };
+       gpio-poweroff {
+               compatible = "gpio-poweroff";
+               pinctrl-0 = <&pmx_poweroff>;
+               pinctrl-names = "default";
+               gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               usb3_regulator: usb3-regulator {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "USB 3.0 Power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+               };
+       };
 };
 
 &nand {
 &mdio {
        status = "okay";
 
-       ethphy0: ethernet-phy@0 {
+       ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
                device_type = "ethernet-phy";
                reg = <0>;
        };
diff --git a/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts b/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts
new file mode 100644 (file)
index 0000000..72a3883
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * Device Tree file for NETGEAR ReadyNAS NV+ v2
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+
+/ {
+       model = "NETGEAR ReadyNAS NV+ v2";
+       compatible = "netgear,readynas-nv+-v2", "netgear,readynas", "marvell,kirkwood-88f6282", "marvell,kirkwood";
+
+       memory { /* 256 MB */
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8 earlyprintk";
+       };
+
+       mbus {
+               pcie-controller {
+                       status = "okay";
+
+                       /* Connected to NEC uPD720200 USB 3.0 controller */
+                       pcie@1,0 {
+                               /* Port 0, Lane 0 */
+                               status = "okay";
+                       };
+               };
+       };
+
+       ocp@f1000000 {
+               pinctrl: pinctrl@10000 {
+                       pmx_button_power: pmx-button-power {
+                               marvell,pins = "mpp47";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_button_backup: pmx-button-backup {
+                               marvell,pins = "mpp45";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_button_reset: pmx-button-reset {
+                               marvell,pins = "mpp13";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_blue_power: pmx-led-blue-power {
+                               marvell,pins = "mpp31";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_blue_backup: pmx-led-blue-backup {
+                               marvell,pins = "mpp22";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_blue_disk1: pmx-led-blue-disk1 {
+                               marvell,pins = "mpp20";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_blue_disk2: pmx-led-blue-disk2 {
+                               marvell,pins = "mpp23";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_blue_disk3: pmx-led-blue-disk3 {
+                               marvell,pins = "mpp24";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_blue_disk4: pmx-led-blue-disk4 {
+                               marvell,pins = "mpp29";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_poweroff: pmx-poweroff {
+                               marvell,pins = "mpp30";
+                               marvell,function = "gpio";
+                       };
+               };
+
+               clocks {
+                      g762_clk: g762-oscillator {
+                                compatible = "fixed-clock";
+                                #clock-cells = <0>;
+                                clock-frequency = <8192>;
+                      };
+               };
+
+               i2c@11000 {
+                       status = "okay";
+
+                       rs5c372a: rs5c372a@32 {
+                               compatible = "ricoh,rs5c372a";
+                               reg = <0x32>;
+                       };
+
+                       g762: g762@3e {
+                               compatible = "gmt,g762";
+                               reg = <0x3e>;
+                               clocks = <&g762_clk>; /* input clock */
+                               fan_gear_mode = <0>;
+                               fan_startv = <1>;
+                               pwm_polarity = <0>;
+                       };
+               };
+
+               serial@12000 {
+                       pinctrl-0 = <&pmx_uart0>;
+                       pinctrl-names = "default";
+                       status = "okay";
+               };
+
+               sata@80000 { /* Connected to Marvell 88SM4140 SATA port multiplier */
+                       status = "okay";
+                       nr-ports = <1>;
+               };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = < &pmx_led_blue_power &pmx_led_blue_backup
+                             &pmx_led_blue_disk1 &pmx_led_blue_disk2
+                             &pmx_led_blue_disk3 &pmx_led_blue_disk3 >;
+               pinctrl-names = "default";
+
+               power_led {
+                       label = "status:blue:power_led";
+                       gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "default-on";
+               };
+
+               backup_led {
+                       label = "status:blue:backup_led";
+                       gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+               };
+
+               disk1_led {
+                       label = "status:blue:disk1_led";
+                       gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+               };
+
+               disk2_led {
+                       label = "status:blue:disk2_led";
+                       gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+               };
+
+               disk3_led {
+                       label = "status:blue:disk3_led";
+                       gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+               };
+
+               disk4_led {
+                       label = "status:blue:disk4_led";
+                       gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-0 = <&pmx_button_power &pmx_button_backup
+                            &pmx_button_reset>;
+               pinctrl-names = "default";
+
+               power-button {
+                       label = "Power Button";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+               };
+
+               reset-button {
+                       label = "Reset Button";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+               };
+
+               backup-button {
+                       label = "Backup Button";
+                       linux,code = <KEY_COPY>;
+                       gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-poweroff {
+               compatible = "gpio-poweroff";
+               pinctrl-0 = <&pmx_poweroff>;
+               pinctrl-names = "default";
+               gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               usb3_regulator: usb3-regulator {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "USB 3.0 Power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+               };
+       };
+};
+
+&nand {
+       status = "okay";
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x0000000 0x180000>;
+               read-only;
+       };
+
+       partition@180000 {
+               label = "u-boot-env";
+               reg = <0x180000 0x20000>;
+       };
+
+       partition@200000 {
+               label = "uImage";
+               reg = <0x0200000 0x600000>;
+       };
+
+       partition@800000 {
+               label = "minirootfs";
+               reg = <0x0800000 0x1000000>;
+       };
+
+       partition@1800000 {
+               label = "jffs2";
+               reg = <0x1800000 0x6800000>;
+       };
+};
+
+&mdio {
+       status = "okay";
+
+       ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
+               device_type = "ethernet-phy";
+               reg = <0>;
+       };
+};
+
+&eth0 {
+       status = "okay";
+
+       ethernet0-port@0 {
+               phy-handle = <&ethphy0>;
+       };
+};
index 279607093cdbdbda0c0c80207256ab156272e334..7cea2a44719c56e6bcf09ef22bc83959c5f6a3a3 100644 (file)
@@ -26,7 +26,7 @@
                blue-sata {
                        label = "ns2:blue:sata";
                        gpios = <&gpio0 30 1>;
-                       linux,default-trigger = "default-on";
+                       linux,default-trigger = "ide-disk";
                };
        };
 };
index 1173d7fb31b23f9e11565a45592fcb99f17e41bf..7b1cd993e891126fdc4f08e445b7371f890e1ff3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * kirkwood-sheevaplug-common.dts - Common parts for Sheevaplugs
+ * kirkwood-sheevaplug-common.dtsi - Common parts for Sheevaplugs
  *
  * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
  *
index eac6a21f3b1f0b2402bf58c341b96f25945e455a..ce9b3be237f981511db3bb11e7ca42b4ed48bde1 100644 (file)
@@ -37,7 +37,7 @@
                health {
                        label = "sheevaplug:blue:health";
                        gpios = <&gpio1 17 1>;
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
        };
 };
index bb61918313dbf8c495b546273b34b6401c3ba8be..c01f9c765aa248b49befff551a9fb10b97ede721 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * kirkwood-sheevaplug-esata.dts - Device tree file for Sheevaplug
+ * kirkwood-sheevaplug.dts - Device tree file for Sheevaplug
  *
  * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
  *
@@ -32,7 +32,7 @@
                health {
                        label = "sheevaplug:blue:health";
                        gpios = <&gpio1 17 1>;
-                       linux,default-trigger = "default-on";
+                       default-state = "keep";
                };
 
                misc {
index 02df1914a47c8f971cbe8fb852cea0963833bcff..928f6eef2d592cc6b0fe0318c275cd3c98e75583 100644 (file)
                                status = "okay";
                        };
 
+                       watchdog@fffffd40 {
+                               timeout-sec = <15>;
+                               atmel,max-heartbeat-sec = <16>;
+                               atmel,min-heartbeat-sec = <0>;
+                               status = "okay";
+                       };
                };
 
                nand0: nand@40000000 {
index b0ee342598f070b508770074d6f474589503628e..68221fab978d40a2e92c5b089e0e4fd1494e39e4 100644 (file)
@@ -13,7 +13,7 @@
         * they probably share the same GPIO IRQ
         * REVISIT: Add timing support from slls644g.pdf
         */
-       8250@3,0 {
+       uart@3,0 {
                compatible = "ns16550a";
                reg = <3 0 0x100>;
                bank-width = <2>;
index a2bfcde858a6ec68f96fd123c515747f3c053004..d0c5b37e248c76734d8c58bc54660f65fc6f877a 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/omap.h>
 
 #include "skeleton.dtsi"
@@ -21,6 +22,8 @@
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
        };
 
        cpus {
                ranges;
                ti,hwmods = "l3_main";
 
+               aes: aes@480a6000 {
+                       compatible = "ti,omap2-aes";
+                       ti,hwmods = "aes";
+                       reg = <0x480a6000 0x50>;
+                       dmas = <&sdma 9 &sdma 10>;
+                       dma-names = "tx", "rx";
+               };
+
+               hdq1w: 1w@480b2000 {
+                       compatible = "ti,omap2420-1w";
+                       ti,hwmods = "hdq1w";
+                       reg = <0x480b2000 0x1000>;
+                       interrupts = <58>;
+               };
+
+               mailbox: mailbox@48094000 {
+                       compatible = "ti,omap2-mailbox";
+                       ti,hwmods = "mailbox";
+                       reg = <0x48094000 0x200>;
+                       interrupts = <26>;
+               };
+
                intc: interrupt-controller@1 {
                        compatible = "ti,omap2-intc";
                        interrupt-controller;
@@ -63,6 +88,7 @@
 
                sdma: dma-controller@48056000 {
                        compatible = "ti,omap2430-sdma", "ti,omap2420-sdma";
+                       ti,hwmods = "dma";
                        reg = <0x48056000 0x1000>;
                        interrupts = <12>,
                                     <13>,
                        #dma-requests = <64>;
                };
 
+               i2c1: i2c@48070000 {
+                       compatible = "ti,omap2-i2c";
+                       ti,hwmods = "i2c1";
+                       reg = <0x48070000 0x80>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <56>;
+                       dmas = <&sdma 27 &sdma 28>;
+                       dma-names = "tx", "rx";
+               };
+
+               i2c2: i2c@48072000 {
+                       compatible = "ti,omap2-i2c";
+                       ti,hwmods = "i2c2";
+                       reg = <0x48072000 0x80>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <57>;
+                       dmas = <&sdma 29 &sdma 30>;
+                       dma-names = "tx", "rx";
+               };
+
+               mcspi1: mcspi@48098000 {
+                       compatible = "ti,omap2-mcspi";
+                       ti,hwmods = "mcspi1";
+                       reg = <0x48098000 0x100>;
+                       interrupts = <65>;
+                       dmas = <&sdma 35 &sdma 36 &sdma 37 &sdma 38
+                               &sdma 39 &sdma 40 &sdma 41 &sdma 42>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1",
+                                   "tx2", "rx2", "tx3", "rx3";
+               };
+
+               mcspi2: mcspi@4809a000 {
+                       compatible = "ti,omap2-mcspi";
+                       ti,hwmods = "mcspi2";
+                       reg = <0x4809a000 0x100>;
+                       interrupts = <66>;
+                       dmas = <&sdma 43 &sdma 44 &sdma 45 &sdma 46>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1";
+               };
+
+               rng: rng@480a0000 {
+                       compatible = "ti,omap2-rng";
+                       ti,hwmods = "rng";
+                       reg = <0x480a0000 0x50>;
+                       interrupts = <36>;
+               };
+
+               sham: sham@480a4000 {
+                       compatible = "ti,omap2-sham";
+                       ti,hwmods = "sham";
+                       reg = <0x480a4000 0x64>;
+                       interrupts = <51>;
+                       dmas = <&sdma 13>;
+                       dma-names = "rx";
+               };
+
                uart1: serial@4806a000 {
                        compatible = "ti,omap2-uart";
                        ti,hwmods = "uart1";
+                       reg = <0x4806a000 0x2000>;
+                       interrupts = <72>;
+                       dmas = <&sdma 49 &sdma 50>;
+                       dma-names = "tx", "rx";
                        clock-frequency = <48000000>;
                };
 
                uart2: serial@4806c000 {
                        compatible = "ti,omap2-uart";
                        ti,hwmods = "uart2";
+                       reg = <0x4806c000 0x400>;
+                       interrupts = <73>;
+                       dmas = <&sdma 51 &sdma 52>;
+                       dma-names = "tx", "rx";
                        clock-frequency = <48000000>;
                };
 
                uart3: serial@4806e000 {
                        compatible = "ti,omap2-uart";
                        ti,hwmods = "uart3";
+                       reg = <0x4806e000 0x400>;
+                       interrupts = <74>;
+                       dmas = <&sdma 53 &sdma 54>;
+                       dma-names = "tx", "rx";
                        clock-frequency = <48000000>;
                };
 
index c8f9c55169ead249c9f95add2f15ab99527dd01c..60c605de22ddcdfb9f7220669c12c443a4c218fa 100644 (file)
                        dma-names = "tx", "rx";
                };
 
+               msdi1: mmc@4809c000 {
+                       compatible = "ti,omap2420-mmc";
+                       ti,hwmods = "msdi1";
+                       reg = <0x4809c000 0x80>;
+                       interrupts = <83>;
+                       dmas = <&sdma 61 &sdma 62>;
+                       dma-names = "tx", "rx";
+               };
+
                timer1: timer@48028000 {
                        compatible = "ti,omap2420-timer";
                        reg = <0x48028000 0x400>;
                        ti,hwmods = "timer1";
                        ti,timer-alwon;
                };
+
+               wd_timer2: wdt@48022000 {
+                       compatible = "ti,omap2-wdt";
+                       ti,hwmods = "wd_timer2";
+                       reg = <0x48022000 0x80>;
+               };
        };
 };
+
+&i2c1 {
+       compatible = "ti,omap2420-i2c";
+};
+
+&i2c2 {
+       compatible = "ti,omap2420-i2c";
+};
index c535a5a2b27f9aa95b313c768893520b82d3a6c7..d624345666f56a1468c9e628ae1f3b971fb5d43a 100644 (file)
                        dma-names = "tx", "rx";
                };
 
+               mmc1: mmc@4809c000 {
+                       compatible = "ti,omap2-hsmmc";
+                       reg = <0x4809c000 0x200>;
+                       interrupts = <83>;
+                       ti,hwmods = "mmc1";
+                       ti,dual-volt;
+                       dmas = <&sdma 61>, <&sdma 62>;
+                       dma-names = "tx", "rx";
+               };
+
+               mmc2: mmc@480b4000 {
+                       compatible = "ti,omap2-hsmmc";
+                       reg = <0x480b4000 0x200>;
+                       interrupts = <86>;
+                       ti,hwmods = "mmc2";
+                       dmas = <&sdma 47>, <&sdma 48>;
+                       dma-names = "tx", "rx";
+               };
+
                timer1: timer@49018000 {
                        compatible = "ti,omap2420-timer";
                        reg = <0x49018000 0x400>;
                        ti,hwmods = "timer1";
                        ti,timer-alwon;
                };
+
+               mcspi3: mcspi@480b8000 {
+                       compatible = "ti,omap2-mcspi";
+                       ti,hwmods = "mcspi3";
+                       reg = <0x480b8000 0x100>;
+                       interrupts = <91>;
+                       dmas = <&sdma 15 &sdma 16 &sdma 23 &sdma 24>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1";
+               };
+
+               usb_otg_hs: usb_otg_hs@480ac000 {
+                       compatible = "ti,omap2-musb";
+                       ti,hwmods = "usb_otg_hs";
+                       reg = <0x480ac000 0x1000>;
+                       interrupts = <93>;
+               };
+
+               wd_timer2: wdt@49016000 {
+                       compatible = "ti,omap2-wdt";
+                       ti,hwmods = "wd_timer2";
+                       reg = <0x49016000 0x80>;
+               };
        };
 };
+
+&i2c1 {
+       compatible = "ti,omap2430-i2c";
+};
+
+&i2c2 {
+       compatible = "ti,omap2430-i2c";
+};
index 31a632f7effbf239f298ff3619cdacdc5587356e..df33a50bc070b508fd8dacd8a3c72f645c18d3e0 100644 (file)
 &usbhsehci {
        phys = <0 &hsusb2_phy>;
 };
+
+&vaux2 {
+       regulator-name = "usb_1v8";
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-always-on;
+};
index fa532aaacc68943989241b92a6e31743e3e854fe..4e384fcc6ad51aca87e8373e83cfb4c8e5bfaf81 100644 (file)
        mode = <3>;
        power = <50>;
 };
+
+&vaux2 {
+       regulator-name = "vdd_ehci";
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-always-on;
+};
index ba1e58b7b7e35ddbdf4825853cf72cef6a951939..165aaf7591ba8ef51856474d85db8754710a33ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Device Tree Source for IGEP Technology devices
+ * Common device tree for IGEP boards based on AM/DM37x
  *
  * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
  * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
@@ -10,7 +10,7 @@
  */
 /dts-v1/;
 
-#include "omap34xx.dtsi"
+#include "omap36xx.dtsi"
 
 / {
        memory {
                ti,mcbsp = <&mcbsp2>;
                ti,codec = <&twl_audio>;
        };
+
+       vdd33: regulator-vdd33 {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd33";
+               regulator-always-on;
+       };
+
+       lbee1usjyc_vmmc: lbee1usjyc_vmmc {
+               pinctrl-names = "default";
+               pinctrl-0 = <&lbee1usjyc_pins>;
+               compatible = "regulator-fixed";
+               regulator-name = "regulator-lbee1usjyc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>;    /* gpio_138 WIFI_PDN */
+               startup-delay-us = <10000>;
+               enable-active-high;
+               vin-supply = <&vdd33>;
+       };
 };
 
 &omap3_pmx_core {
                >;
        };
 
+       /* WiFi/BT combo */
+       lbee1usjyc_pins: pinmux_lbee1usjyc_pins {
+               pinctrl-single,pins = <
+                       0x136 (PIN_OUTPUT | MUX_MODE4)  /* sdmmc2_dat5.gpio_137 */
+                       0x138 (PIN_OUTPUT | MUX_MODE4)  /* sdmmc2_dat6.gpio_138 */
+                       0x13a (PIN_OUTPUT | MUX_MODE4)  /* sdmmc2_dat7.gpio_139 */
+               >;
+       };
+
        mcbsp2_pins: pinmux_mcbsp2_pins {
                pinctrl-single,pins = <
                        0x10c (PIN_INPUT | MUX_MODE0)           /* mcbsp2_fsx.mcbsp2_fsx */
                        0x11a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat1.sdmmc1_dat1 */
                        0x11c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat2.sdmmc1_dat2 */
                        0x11e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat3.sdmmc1_dat3 */
-                       0x120 (PIN_INPUT | MUX_MODE0)           /* sdmmc1_dat4.sdmmc1_dat4 */
-                       0x122 (PIN_INPUT | MUX_MODE0)           /* sdmmc1_dat5.sdmmc1_dat5 */
-                       0x124 (PIN_INPUT | MUX_MODE0)           /* sdmmc1_dat6.sdmmc1_dat6 */
-                       0x126 (PIN_INPUT | MUX_MODE0)           /* sdmmc1_dat7.sdmmc1_dat7 */
+               >;
+       };
+
+       mmc2_pins: pinmux_mmc2_pins {
+               pinctrl-single,pins = <
+                       0x128 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_clk.sdmmc2_clk */
+                       0x12a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_cmd.sdmmc2_cmd */
+                       0x12c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat0.sdmmc2_dat0 */
+                       0x12e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat1.sdmmc2_dat1 */
+                       0x130 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat2.sdmmc2_dat2 */
+                       0x132 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat3.sdmmc2_dat3 */
                >;
        };
 
                >;
        };
 
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       0x18a (PIN_INPUT | MUX_MODE0)   /* i2c1_scl.i2c1_scl */
+                       0x18c (PIN_INPUT | MUX_MODE0)   /* i2c1_sda.i2c1_sda */
+               >;
+       };
+
+       i2c2_pins: pinmux_i2c2_pins {
+               pinctrl-single,pins = <
+                       0x18e (PIN_INPUT | MUX_MODE0)   /* i2c2_scl.i2c2_scl */
+                       0x190 (PIN_INPUT | MUX_MODE0)   /* i2c2_sda.i2c2_sda */
+               >;
+       };
+
+       i2c3_pins: pinmux_i2c3_pins {
+               pinctrl-single,pins = <
+                       0x192 (PIN_INPUT | MUX_MODE0)   /* i2c3_scl.i2c3_scl */
+                       0x194 (PIN_INPUT | MUX_MODE0)   /* i2c3_sda.i2c3_sda */
+               >;
+       };
+
        leds_pins: pinmux_leds_pins { };
 };
 
 &i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
        clock-frequency = <2600000>;
 
        twl: twl@48 {
 #include "twl4030_omap3.dtsi"
 
 &i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
        clock-frequency = <400000>;
 };
 
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins>;
+};
+
 &mcbsp2 {
        pinctrl-names = "default";
        pinctrl-0 = <&mcbsp2_pins>;
       pinctrl-0 = <&mmc1_pins>;
       vmmc-supply = <&vmmc1>;
       vmmc_aux-supply = <&vsim>;
-      bus-width = <8>;
+      bus-width = <4>;
 };
 
 &mmc2 {
-       status = "disabled";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&lbee1usjyc_vmmc>;
+       bus-width = <4>;
+       non-removable;
 };
 
 &mmc3 {
index d5cc792672501012f2a368b4d27b17bbb7669d95..1c7e74d2d2bc7bd03f1a970cea9442f715c0f3eb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Device Tree Source for IGEPv2 board
+ * Device Tree Source for IGEPv2 Rev. (TI OMAP AM/DM37x)
  *
  * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
  * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
@@ -13,7 +13,7 @@
 #include "omap-gpmc-smsc911x.dtsi"
 
 / {
-       model = "IGEPv2";
+       model = "IGEPv2 (TI OMAP AM/DM37x)";
        compatible = "isee,omap3-igep0020", "ti,omap3";
 
        leds {
@@ -67,6 +67,8 @@
        pinctrl-names = "default";
        pinctrl-0 = <
                &hsusbb1_pins
+               &tfp410_pins
+               &dss_pins
        >;
 
        hsusbb1_pins: pinmux_hsusbb1_pins {
                        0x5ba (PIN_INPUT_PULLDOWN | MUX_MODE3)  /* etk_d7.hsusb1_data3 */
                >;
        };
+
+       tfp410_pins: tfp410_dvi_pins {
+               pinctrl-single,pins = <
+                       0x196 (PIN_OUTPUT | MUX_MODE4)   /* hdq_sio.gpio_170 */
+               >;
+       };
+
+       dss_pins: pinmux_dss_dvi_pins {
+               pinctrl-single,pins = <
+                       0x0a4 (PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
+                       0x0a6 (PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
+                       0x0a8 (PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
+                       0x0aa (PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
+                       0x0ac (PIN_OUTPUT | MUX_MODE0)   /* dss_data0.dss_data0 */
+                       0x0ae (PIN_OUTPUT | MUX_MODE0)   /* dss_data1.dss_data1 */
+                       0x0b0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data2.dss_data2 */
+                       0x0b2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data3.dss_data3 */
+                       0x0b4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data4.dss_data4 */
+                       0x0b6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data5.dss_data5 */
+                       0x0b8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
+                       0x0ba (PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
+                       0x0bc (PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
+                       0x0be (PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
+                       0x0c0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
+                       0x0c2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
+                       0x0c4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
+                       0x0c6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
+                       0x0c8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
+                       0x0ca (PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
+                       0x0cc (PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
+                       0x0ce (PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
+                       0x0d0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data18.dss_data18 */
+                       0x0d2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data19.dss_data19 */
+                       0x0d4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data20.dss_data20 */
+                       0x0d6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data21.dss_data21 */
+                       0x0d8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data22.dss_data22 */
+                       0x0da (PIN_OUTPUT | MUX_MODE0)   /* dss_data23.dss_data23 */
+               >;
+       };
 };
 
 &leds_pins {
 &usbhsehci {
        phys = <&hsusb1_phy>;
 };
+
+&vpll2 {
+        /* Needed for DSS */
+        regulator-name = "vdds_dsi";
+};
index 525e6d9b09784c721b4660554a17abdda14273e9..02a23f8a3384255abca5d54ecf53417226a8347f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Device Tree Source for IGEP COM Module
+ * Device Tree Source for IGEP COM MODULE (TI OMAP AM/DM37x)
  *
  * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
  * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
@@ -12,7 +12,7 @@
 #include "omap3-igep.dtsi"
 
 / {
-       model = "IGEP COM Module";
+       model = "IGEP COM MODULE (TI OMAP AM/DM37x)";
        compatible = "isee,omap3-igep0030", "ti,omap3";
 
        leds {
index c4f20bfe4cce15e641af5ef08c92ca939973b9c3..c2c306d13b87fcc19434f545268e69d94cbda945 100644 (file)
                >;
        };
 
+       mmc2_pins: pinmux_mmc2_pins {
+               pinctrl-single,pins = <
+                       0x128 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_clk */
+                       0x12a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_cmd */
+                       0x12c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat0 */
+                       0x12e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat1 */
+                       0x130 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat2 */
+                       0x132 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat3 */
+                       0x134 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat4 */
+                       0x136 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat5 */
+                       0x138 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat6 */
+                       0x13a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat7 */
+               >;
+       };
+
        display_pins: pinmux_display_pins {
                pinctrl-single,pins = <
                        0x0d4 (PIN_OUTPUT | MUX_MODE4)          /* RX51_LCD_RESET_GPIO */
        cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */
 };
 
+/* most boards use vaux3, only some old versions use vmmc2 instead */
 &mmc2 {
-       status = "disabled";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&vaux3>;
+       vmmc_aux-supply = <&vsim>;
+       bus-width = <8>;
+       non-removable;
 };
 
 &mmc3 {
index f3a0c26ed0c2bcd6d6df65dcecc3f18329abec18..daabf99d402a8e4ff645824dcad9d56fc693b17d 100644 (file)
                ranges;
                ti,hwmods = "l3_main";
 
+               aes: aes@480c5000 {
+                       compatible = "ti,omap3-aes";
+                       ti,hwmods = "aes";
+                       reg = <0x480c5000 0x50>;
+                       interrupts = <0>;
+               };
+
                counter32k: counter@48320000 {
                        compatible = "ti,omap-counter32k";
                        reg = <0x48320000 0x20>;
                        ti,hwmods = "i2c3";
                };
 
+               mailbox: mailbox@48094000 {
+                       compatible = "ti,omap3-mailbox";
+                       ti,hwmods = "mailbox";
+                       reg = <0x48094000 0x200>;
+                       interrupts = <26>;
+               };
+
                mcspi1: spi@48098000 {
                        compatible = "ti,omap2-mcspi";
                        reg = <0x48098000 0x100>;
                        dma-names = "tx", "rx";
                };
 
+               mmu_isp: mmu@480bd400 {
+                       compatible = "ti,omap3-mmu-isp";
+                       ti,hwmods = "mmu_isp";
+                       reg = <0x480bd400 0x80>;
+                       interrupts = <8>;
+               };
+
                wdt2: wdt@48314000 {
                        compatible = "ti,omap3-wdt";
                        reg = <0x48314000 0x80>;
                        dma-names = "tx", "rx";
                };
 
+               sham: sham@480c3000 {
+                       compatible = "ti,omap3-sham";
+                       ti,hwmods = "sham";
+                       reg = <0x480c3000 0x64>;
+                       interrupts = <49>;
+               };
+
+               smartreflex_core: smartreflex@480cb000 {
+                       compatible = "ti,omap3-smartreflex-core";
+                       ti,hwmods = "smartreflex_core";
+                       reg = <0x480cb000 0x400>;
+                       interrupts = <19>;
+               };
+
+               smartreflex_mpu_iva: smartreflex@480c9000 {
+                       compatible = "ti,omap3-smartreflex-iva";
+                       ti,hwmods = "smartreflex_mpu_iva";
+                       reg = <0x480c9000 0x400>;
+                       interrupts = <18>;
+               };
+
                timer1: timer@48318000 {
                        compatible = "ti,omap3430-timer";
                        reg = <0x48318000 0x400>;
index aed83deaa991c9b8856218ef0792f1c3f51cc2b4..fcc5bb63f03a949cd80ed090a66f8a901614899f 100644 (file)
@@ -58,7 +58,7 @@
        status = "okay";
 
        ethphy: ethernet-phy {
-               device-type = "ethernet-phy";
+               device_type = "ethernet-phy";
                reg = <8>;
        };
 };
index 1fb20f2333cc80a8a89ae1c15485c6f60fc64572..b1deaf7e2e06826b1893925e19812420aa46eeec 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /dts-v1/;
-/include/ "r7s72100.dtsi"
+#include "r7s72100.dtsi"
 
 / {
        model = "Genmai";
index 9443e93d3cac7f07cfdca4fa24b825424ab310a2..70b1fff8f4a3592a69bf889455504fa1d553adde 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /dts-v1/;
-/include/ "r8a73a4.dtsi"
+#include "r8a73a4.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 
 / {
                reg = <0 0x40000000 0 0x40000000>;
        };
 
+       memory@200000000 {
+               device_type = "memory";
+               reg = <2 0x00000000 0 0x40000000>;
+       };
+
        vcc_mmc0: regulator@0 {
                compatible = "regulator-fixed";
                regulator-name = "MMC0 Vcc";
        pinctrl-0 = <&scifa0_pins>;
        pinctrl-names = "default";
 
-       scifa0_pins: scifa0 {
+       scifa0_pins: serial0 {
                renesas,groups = "scifa0_data";
                renesas,function = "scifa0";
        };
 
-       mmc0_pins: mmcif {
+       mmc0_pins: mmc {
                renesas,groups = "mmc0_data8", "mmc0_ctrl";
                renesas,function = "mmc0";
        };
 
-       sdhi0_pins: sdhi0 {
+       sdhi0_pins: sd0 {
                renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd";
                renesas,function = "sdhi0";
        };
 
-       sdhi1_pins: sdhi1 {
+       sdhi1_pins: sd1 {
                renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
                renesas,function = "sdhi1";
        };
index 91436b58016f1d48fa5cd12c3946377500b9d70a..ce085fa444a12ae24230ac87ff1e55a8efd43e9f 100644 (file)
@@ -9,7 +9,8 @@
  */
 
 /dts-v1/;
-/include/ "r8a73a4.dtsi"
+#include "r8a73a4.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        model = "APE6EVM";
                reg = <0 0x40000000 0 0x40000000>;
        };
 
+       memory@200000000 {
+               device_type = "memory";
+               reg = <2 0x00000000 0 0x40000000>;
+       };
+
        ape6evm_fixed_3v3: fixedregulator@0 {
                compatible = "regulator-fixed";
                regulator-name = "3V3";
@@ -40,7 +46,7 @@
                        compatible = "smsc,lan9118", "smsc,lan9115";
                        reg = <0x08000000 0x1000>;
                        interrupt-parent = <&irqc1>;
-                       interrupts = <8 0x4>;
+                       interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
                        phy-mode = "mii";
                        reg-io-width = <4>;
                        smsc,irq-active-high;
index 287e047592a03d28e009cc0500c27ab6a18e6de1..b4a6c3b43ee933403b854b509600edf3bcaf46ac 100644 (file)
@@ -9,6 +9,9 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
 / {
        compatible = "renesas,r8a73a4";
        interrupt-parent = <&gic>;
                        <0 0xf1002000 0 0x1000>,
                        <0 0xf1004000 0 0x2000>,
                        <0 0xf1006000 0 0x2000>;
-               interrupts = <1 9 0xf04>;
+               interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
        };
 
        timer {
                compatible = "arm,armv7-timer";
-               interrupts = <1 13 0xf08>,
-                               <1 14 0xf08>,
-                               <1 11 0xf08>,
-                               <1 10 0xf08>;
+               interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
 
        irqc0: interrupt-controller@e61c0000 {
                interrupt-controller;
                reg = <0 0xe61c0000 0 0x200>;
                interrupt-parent = <&gic>;
-               interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>,
-                               <0 4 4>, <0 5 4>, <0 6 4>, <0 7 4>,
-                               <0 8 4>, <0 9 4>, <0 10 4>, <0 11 4>,
-                               <0 12 4>, <0 13 4>, <0 14 4>, <0 15 4>,
-                               <0 16 4>, <0 17 4>, <0 18 4>, <0 19 4>,
-                               <0 20 4>, <0 21 4>, <0 22 4>, <0 23 4>,
-                               <0 24 4>, <0 25 4>, <0 26 4>, <0 27 4>,
-                               <0 28 4>, <0 29 4>, <0 30 4>, <0 31 4>;
+               interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 1 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 2 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 3 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 4 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 5 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 6 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 7 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 8 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 9 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 10 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 11 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 12 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 13 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 14 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 15 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 16 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 17 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 18 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 19 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 20 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 21 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 22 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 23 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 24 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 25 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 26 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 27 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 28 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 29 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 30 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 31 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        irqc1: interrupt-controller@e61c0200 {
                interrupt-controller;
                reg = <0 0xe61c0200 0 0x200>;
                interrupt-parent = <&gic>;
-               interrupts = <0 32 4>, <0 33 4>, <0 34 4>, <0 35 4>,
-                               <0 36 4>, <0 37 4>, <0 38 4>, <0 39 4>,
-                               <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>,
-                               <0 44 4>, <0 45 4>, <0 46 4>, <0 47 4>,
-                               <0 48 4>, <0 49 4>, <0 50 4>, <0 51 4>,
-                               <0 52 4>, <0 53 4>, <0 54 4>, <0 55 4>,
-                               <0 56 4>, <0 57 4>;
+               interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 33 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 34 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 35 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 36 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 37 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 38 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 39 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 40 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 41 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 42 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 43 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 44 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 45 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 46 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 47 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 48 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 49 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 50 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 51 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 52 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 53 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 54 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 55 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 56 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 57 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        dmac: dma-multiplexer@0 {
                reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>,
                         <0 0xe61f0200 0 0x38>, <0 0xe61f0300 0 0x38>;
                interrupt-parent = <&gic>;
-               interrupts = <0 69 4>;
+               interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        i2c0: i2c@e6500000 {
                compatible = "renesas,rmobile-iic";
                reg = <0 0xe6540000 0 0x428>;
                interrupt-parent = <&gic>;
-               interrupts = <0 178 0x4>;
+               interrupts = <0 178 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rmobile-iic";
                reg = <0 0xe60b0000 0 0x428>;
                interrupt-parent = <&gic>;
-               interrupts = <0 179 0x4>;
+               interrupts = <0 179 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rmobile-iic";
                reg = <0 0xe6550000 0 0x428>;
                interrupt-parent = <&gic>;
-               interrupts = <0 184 0x4>;
+               interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rmobile-iic";
                reg = <0 0xe6560000 0 0x428>;
                interrupt-parent = <&gic>;
-               interrupts = <0 185 0x4>;
+               interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rmobile-iic";
                reg = <0 0xe6570000 0 0x428>;
                interrupt-parent = <&gic>;
-               interrupts = <0 173 0x4>;
+               interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       mmcif0: mmcif@ee200000 {
+       mmcif0: mmc@ee200000 {
                compatible = "renesas,sh-mmcif";
                reg = <0 0xee200000 0 0x80>;
                interrupt-parent = <&gic>;
-               interrupts = <0 169 0x4>;
+               interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
                reg-io-width = <4>;
                status = "disabled";
        };
 
-       mmcif1: mmcif@ee220000 {
+       mmcif1: mmc@ee220000 {
                compatible = "renesas,sh-mmcif";
                reg = <0 0xee220000 0 0x80>;
                interrupt-parent = <&gic>;
-               interrupts = <0 170 0x4>;
+               interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
                reg-io-width = <4>;
                status = "disabled";
        };
                #gpio-cells = <2>;
        };
 
-       sdhi0: sdhi@ee100000 {
+       sdhi0: sd@ee100000 {
                compatible = "renesas,sdhi-r8a73a4";
                reg = <0 0xee100000 0 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 165 4>;
+               interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                status = "disabled";
        };
 
-       sdhi1: sdhi@ee120000 {
+       sdhi1: sd@ee120000 {
                compatible = "renesas,sdhi-r8a73a4";
                reg = <0 0xee120000 0 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 166 4>;
+               interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                status = "disabled";
        };
 
-       sdhi2: sdhi@ee140000 {
+       sdhi2: sd@ee140000 {
                compatible = "renesas,sdhi-r8a73a4";
                reg = <0 0xee140000 0 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 167 4>;
+               interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                status = "disabled";
        };
index 1c56c5e56950846217471ae98ee00c5bed4922ac..7b80f19129e3f4301a9760dc5f1fabb83ec6291c 100644 (file)
@@ -9,8 +9,9 @@
  */
 
 /dts-v1/;
-/include/ "r8a7740.dtsi"
+#include "r8a7740.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pwm/pwm.h>
 
 / {
 
 &i2c0 {
        status = "okay";
-       touchscreen: st1232@55 {
+       touchscreen@55 {
                compatible = "sitronix,st1232";
                reg = <0x55>;
                interrupt-parent = <&irqpin1>;
-               interrupts = <2 0>; /* IRQ10: hwirq 2 on irqpin1 */
+               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
                pinctrl-0 = <&st1232_pins>;
                pinctrl-names = "default";
                gpios = <&pfc 166 GPIO_ACTIVE_LOW>;
        pinctrl-0 = <&scifa1_pins>;
        pinctrl-names = "default";
 
-       scifa1_pins: scifa1 {
+       scifa1_pins: serial1 {
                renesas,groups = "scifa1_data";
                renesas,function = "scifa1";
        };
 
-       st1232_pins: st1232 {
+       st1232_pins: touchscreen {
                renesas,groups = "intc_irq10";
                renesas,function = "intc";
        };
                renesas,function = "mmc0";
        };
 
-       sdhi0_pins: sdhi0 {
+       sdhi0_pins: sd0 {
                renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_wp";
                renesas,function = "sdhi0";
        };
index 426cd9c3e1c430fc214651809be12c489b2765b9..a06a11e1a84026efaf0cc39914e7629c1fde72a1 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /dts-v1/;
-/include/ "r8a7740.dtsi"
+#include "r8a7740.dtsi"
 
 / {
        model = "armadillo 800 eva";
index ae1e230f711ddf243168abc55cfc6cd3e3095cf8..b1c2ed961eedc7f3728d2c8557870a160ae14d0d 100644 (file)
@@ -10,6 +10,8 @@
 
 /include/ "skeleton.dtsi"
 
+#include <dt-bindings/interrupt-controller/irq.h>
+
 / {
        compatible = "renesas,r8a7740";
 
@@ -34,7 +36,7 @@
 
        pmu {
                compatible = "arm,cortex-a9-pmu";
-               interrupts = <0 83 4>;
+               interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        /* irqpin0: IRQ0 - IRQ7 */
                        <0xe6900040 1>,
                        <0xe6900060 1>;
                interrupt-parent = <&gic>;
-               interrupts = <0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4>;
+               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        /* irqpin1: IRQ8 - IRQ15 */
                        <0xe6900044 1>,
                        <0xe6900064 1>;
                interrupt-parent = <&gic>;
-               interrupts = <0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4>;
+               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        /* irqpin2: IRQ16 - IRQ23 */
                        <0xe6900048 1>,
                        <0xe6900068 1>;
                interrupt-parent = <&gic>;
-               interrupts = <0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4>;
+               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        /* irqpin3: IRQ24 - IRQ31 */
                        <0xe690004c 1>,
                        <0xe690006c 1>;
                interrupt-parent = <&gic>;
-               interrupts = <0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4
-                             0 149 0x4>;
+               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH
+                             0 149 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        i2c0: i2c@fff20000 {
                compatible = "renesas,rmobile-iic";
                reg = <0xfff20000 0x425>;
                interrupt-parent = <&gic>;
-               interrupts = <0 201 0x4
-                             0 202 0x4
-                             0 203 0x4
-                             0 204 0x4>;
+               interrupts = <0 201 IRQ_TYPE_LEVEL_HIGH
+                             0 202 IRQ_TYPE_LEVEL_HIGH
+                             0 203 IRQ_TYPE_LEVEL_HIGH
+                             0 204 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rmobile-iic";
                reg = <0xe6c20000 0x425>;
                interrupt-parent = <&gic>;
-               interrupts = <0 70 0x4
-                             0 71 0x4
-                             0 72 0x4
-                             0 73 0x4>;
+               interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH
+                             0 71 IRQ_TYPE_LEVEL_HIGH
+                             0 72 IRQ_TYPE_LEVEL_HIGH
+                             0 73 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                #pwm-cells = <3>;
        };
 
-       mmcif0: mmcif@e6bd0000 {
+       mmcif0: mmc@e6bd0000 {
                compatible = "renesas,sh-mmcif";
                reg = <0xe6bd0000 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 56 4
-                               0 57 4>;
+               interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH
+                             0 57 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       sdhi0: sdhi@e6850000 {
+       sdhi0: sd@e6850000 {
                compatible = "renesas,sdhi-r8a7740";
                reg = <0xe6850000 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 117 4
-                               0 118 4
-                               0 119 4>;
+               interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH
+                             0 118 IRQ_TYPE_LEVEL_HIGH
+                             0 119 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                cap-sdio-irq;
                status = "disabled";
        };
 
-       sdhi1: sdhi@e6860000 {
+       sdhi1: sd@e6860000 {
                compatible = "renesas,sdhi-r8a7740";
                reg = <0xe6860000 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 121 4
-                               0 122 4
-                               0 123 4>;
+               interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH
+                             0 122 IRQ_TYPE_LEVEL_HIGH
+                             0 123 IRQ_TYPE_LEVEL_HIGH>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
+       };
+
+       sdhi2: sd@e6870000 {
+               compatible = "renesas,sdhi-r8a7740";
+               reg = <0xe6870000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH
+                             0 126 IRQ_TYPE_LEVEL_HIGH
+                             0 127 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                cap-sdio-irq;
                status = "disabled";
index 969e386e852c443f0b5bb95440a0e595d491c04e..bb62c7a906f47c7b52b8563aedcaf6ae56e46197 100644 (file)
@@ -15,7 +15,8 @@
  */
 
 /dts-v1/;
-/include/ "r8a7778.dtsi"
+#include "r8a7778.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        model = "bockw";
 
                phy-mode = "mii";
                interrupt-parent = <&irqpin>;
-               interrupts = <0 0>; /* IRQ0: hwirq 0 on irqpin */
+               interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
                reg-io-width = <4>;
                vddvario-supply = <&fixedregulator3v3>;
                vdd33a-supply = <&fixedregulator3v3>;
        };
+
+};
+
+&mmcif {
+       pinctrl-0 = <&mmc_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&fixedregulator3v3>;
+       bus-width = <8>;
+       broken-cd;
+       status = "okay";
 };
 
 &irqpin {
        status = "okay";
 };
+
+&pfc {
+       pinctrl-0 = <&scif0_pins>;
+       pinctrl-names = "default";
+
+       scif0_pins: serial0 {
+               renesas,groups = "scif0_data_a", "scif0_ctrl";
+               renesas,function = "scif0";
+       };
+
+       mmc_pins: mmc {
+               renesas,groups = "mmc_data8", "mmc_ctrl";
+               renesas,function = "mmc";
+       };
+
+       sdhi0_pins: sd0 {
+               renesas,groups = "sdhi0_data4", "sdhi0_ctrl",
+                                 "sdhi0_cd", "sdhi0_wp";
+               renesas,function = "sdhi0";
+       };
+
+       hspi0_pins: hspi0 {
+               renesas,groups = "hspi0_a";
+               renesas,function = "hspi0";
+       };
+};
+
+&sdhi0 {
+       pinctrl-0 = <&sdhi0_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&fixedregulator3v3>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&hspi0 {
+       pinctrl-0 = <&hspi0_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
index 12bbebc9c95594bcbcc7093c472c42a4b0a492ca..46a884d4517566959992b98901d6a13b94064798 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 /dts-v1/;
-/include/ "r8a7778.dtsi"
+#include "r8a7778.dtsi"
 
 / {
        model = "bockw";
index a6308a399e2d2dbbf4fed33ee943b37f98ed0991..3314e0aeccf509c4844104c6d1f32e2a9ab09521 100644 (file)
@@ -16,6 +16,8 @@
 
 /include/ "skeleton.dtsi"
 
+#include <dt-bindings/interrupt-controller/irq.h>
+
 / {
        compatible = "renesas,r8a7778";
 
                };
        };
 
+       aliases {
+               spi0 = &hspi0;
+               spi1 = &hspi1;
+               spi2 = &hspi2;
+       };
+
        gic: interrupt-controller@fe438000 {
                compatible = "arm,cortex-a9-gic";
                #interrupt-cells = <3>;
                        <0xfe780044 4>,
                        <0xfe780064 4>;
                interrupt-parent = <&gic>;
-               interrupts =   <0 27 0x4
-                               0 28 0x4
-                               0 29 0x4
-                               0 30 0x4>;
+               interrupts =   <0 27 IRQ_TYPE_LEVEL_HIGH
+                               0 28 IRQ_TYPE_LEVEL_HIGH
+                               0 29 IRQ_TYPE_LEVEL_HIGH
+                               0 30 IRQ_TYPE_LEVEL_HIGH>;
                sense-bitfield-width = <2>;
        };
 
@@ -56,7 +64,7 @@
                compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
                reg = <0xffc40000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 103 0x4>;
+               interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 0 32>;
@@ -68,7 +76,7 @@
                compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
                reg = <0xffc41000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 103 0x4>;
+               interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 32 32>;
@@ -80,7 +88,7 @@
                compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
                reg = <0xffc42000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 103 0x4>;
+               interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 64 32>;
                compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
                reg = <0xffc43000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 103 0x4>;
+               interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 96 32>;
                compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar";
                reg = <0xffc44000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 103 0x4>;
+               interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 128 27>;
 
        pfc: pfc@fffc0000 {
                compatible = "renesas,pfc-r8a7778";
-               reg = <0xfffc000 0x118>;
+               reg = <0xfffc0000 0x118>;
+       };
+
+       i2c0: i2c@ffc70000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7778";
+               reg = <0xffc70000 0x1000>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       i2c1: i2c@ffc71000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7778";
+               reg = <0xffc71000 0x1000>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       i2c2: i2c@ffc72000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7778";
+               reg = <0xffc72000 0x1000>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       i2c3: i2c@ffc73000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7778";
+               reg = <0xffc73000 0x1000>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       mmcif: mmc@ffe4e000 {
+               compatible = "renesas,sh-mmcif";
+               reg = <0xffe4e000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       sdhi0: sd@ffe4c000 {
+               compatible = "renesas,sdhi-r8a7778";
+               reg = <0xffe4c000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
+       };
+
+       sdhi1: sd@ffe4d000 {
+               compatible = "renesas,sdhi-r8a7778";
+               reg = <0xffe4d000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
+       };
+
+       sdhi2: sd@ffe4f000 {
+               compatible = "renesas,sdhi-r8a7778";
+               reg = <0xffe4f000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
+       };
+
+       i2c0: i2c@ffc70000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7778";
+               reg = <0xffc70000 0x1000>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       i2c1: i2c@ffc71000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7778";
+               reg = <0xffc71000 0x1000>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       i2c2: i2c@ffc72000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7778";
+               reg = <0xffc72000 0x1000>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       i2c3: i2c@ffc73000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7778";
+               reg = <0xffc73000 0x1000>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       hspi0: spi@fffc7000 {
+               compatible = "renesas,hspi";
+               reg = <0xfffc7000 0x18>;
+               interrupt-controller = <&gic>;
+               interrupts = <0 63 4>;
+               status = "disabled";
+       };
+
+       hspi1: spi@fffc8000 {
+               compatible = "renesas,hspi";
+               reg = <0xfffc8000 0x18>;
+               interrupt-controller = <&gic>;
+               interrupts = <0 84 4>;
+               status = "disabled";
+       };
+
+       hspi2: spi@fffc6000 {
+               compatible = "renesas,hspi";
+               reg = <0xfffc6000 0x18>;
+               interrupt-controller = <&gic>;
+               interrupts = <0 85 4>;
+               status = "disabled";
        };
 };
index ab4110aa3c3b5a4ad31f1600959195099f8ace9c..918085c375d9af586cd0d069b45e6d5a56768c89 100644 (file)
@@ -10,8 +10,9 @@
  */
 
 /dts-v1/;
-/include/ "r8a7779.dtsi"
+#include "r8a7779.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        model = "marzen";
@@ -43,7 +44,7 @@
 
                phy-mode = "mii";
                interrupt-parent = <&irqpin0>;
-               interrupts = <1 0>; /* IRQ1: hwirq 1 on irqpin0 */
+               interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
                reg-io-width = <4>;
                vddvario-supply = <&fixedregulator3v3>;
                vdd33a-supply = <&fixedregulator3v3>;
@@ -68,7 +69,7 @@
 };
 
 &pfc {
-       pinctrl-0 = <&scif2_pins &scif4_pins &sdhi0_pins>;
+       pinctrl-0 = <&scif2_pins &scif4_pins>;
        pinctrl-names = "default";
 
        lan0_pins: lan0 {
                };
        };
 
-       scif2_pins: scif2 {
+       scif2_pins: serial2 {
                renesas,groups = "scif2_data_c";
                renesas,function = "scif2";
        };
 
-       scif4_pins: scif4 {
+       scif4_pins: serial4 {
                renesas,groups = "scif4_data";
                renesas,function = "scif4";
        };
 
-       sdhi0_pins: sdhi0 {
-               renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd",
-                                "sdhi0_wp";
+       sdhi0_pins: sd0 {
+               renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd";
                renesas,function = "sdhi0";
        };
 };
+
+&sdhi0 {
+       pinctrl-0 = <&sdhi0_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&fixedregulator3v3>;
+       bus-width = <4>;
+       status = "okay";
+};
index f3f7f79997360d65c7a8d5bfeeba9d23e76168d3..a7af2c2371f2581b6e9f8e1e43a064eef46bc60e 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "r8a7779.dtsi"
+#include "r8a7779.dtsi"
 
 / {
        model = "marzen";
index 19faeac3fd2e1b74f5d289948dd486f473f931de..b2b418a8ab2ddb3cb47e136829ec1802bda77d2b 100644 (file)
@@ -11,6 +11,8 @@
 
 /include/ "skeleton.dtsi"
 
+#include <dt-bindings/interrupt-controller/irq.h>
+
 / {
        compatible = "renesas,r8a7779";
 
@@ -52,7 +54,7 @@
                compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
                reg = <0xffc40000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 141 0x4>;
+               interrupts = <0 141 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 0 32>;
@@ -64,7 +66,7 @@
                compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
                reg = <0xffc41000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 142 0x4>;
+               interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 32 32>;
@@ -76,7 +78,7 @@
                compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
                reg = <0xffc42000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 143 0x4>;
+               interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 64 32>;
@@ -88,7 +90,7 @@
                compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
                reg = <0xffc43000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 144 0x4>;
+               interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 96 32>;
                compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
                reg = <0xffc44000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 145 0x4>;
+               interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 128 32>;
                compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
                reg = <0xffc45000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 146 0x4>;
+               interrupts = <0 146 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 160 32>;
                compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
                reg = <0xffc46000 0x2c>;
                interrupt-parent = <&gic>;
-               interrupts = <0 147 0x4>;
+               interrupts = <0 147 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 192 9>;
                        <0xfe780044 4>,
                        <0xfe780064 4>;
                interrupt-parent = <&gic>;
-               interrupts = <0 27 0x4
-                               0 28 0x4
-                               0 29 0x4
-                               0 30 0x4>;
+               interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH
+                             0 28 IRQ_TYPE_LEVEL_HIGH
+                             0 29 IRQ_TYPE_LEVEL_HIGH
+                             0 30 IRQ_TYPE_LEVEL_HIGH>;
                sense-bitfield-width = <2>;
        };
 
        i2c0: i2c@ffc70000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,i2c-r8a7779";
                reg = <0xffc70000 0x1000>;
                interrupt-parent = <&gic>;
-               interrupts = <0 79 0x4>;
+               interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
        i2c1: i2c@ffc71000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,i2c-r8a7779";
                reg = <0xffc71000 0x1000>;
                interrupt-parent = <&gic>;
-               interrupts = <0 82 0x4>;
+               interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
        i2c2: i2c@ffc72000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,i2c-r8a7779";
                reg = <0xffc72000 0x1000>;
                interrupt-parent = <&gic>;
-               interrupts = <0 80 0x4>;
+               interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
        i2c3: i2c@ffc73000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,i2c-r8a7779";
                reg = <0xffc73000 0x1000>;
                interrupt-parent = <&gic>;
-               interrupts = <0 81 0x4>;
+               interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rcar-sata";
                reg = <0xfc600000 0x2000>;
                interrupt-parent = <&gic>;
-               interrupts = <0 100 0x4>;
+               interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       sdhi0: sd@ffe4c000 {
+               compatible = "renesas,sdhi-r8a7779";
+               reg = <0xffe4c000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
+       };
+
+       sdhi1: sd@ffe4d000 {
+               compatible = "renesas,sdhi-r8a7779";
+               reg = <0xffe4d000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
+       };
+
+       sdhi2: sd@ffe4e000 {
+               compatible = "renesas,sdhi-r8a7779";
+               reg = <0xffe4e000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
+       };
+
+       sdhi3: sd@ffe4f000 {
+               compatible = "renesas,sdhi-r8a7779";
+               reg = <0xffe4f000 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+               cap-sd-highspeed;
+               cap-sdio-irq;
+               status = "disabled";
        };
 };
index c462ef138922b260666434bc65a9f1d9f1fb31fe..dfedc0ea82e1c89e6ea6b1fea5a7c8d5a45a8ea0 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /dts-v1/;
-/include/ "r8a7790.dtsi"
+#include "r8a7790.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 
 / {
                reg = <0 0x40000000 0 0x80000000>;
        };
 
+       memory@180000000 {
+               device_type = "memory";
+               reg = <1 0x80000000 0 0x80000000>;
+       };
+
        lbsc {
                #address-cells = <1>;
                #size-cells = <1>;
                        gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>;
                };
        };
+
+       fixedregulator3v3: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&pfc {
+       pinctrl-0 = <&scif0_pins &scif1_pins>;
+       pinctrl-names = "default";
+
+       scif0_pins: serial0 {
+               renesas,groups = "scif0_data";
+               renesas,function = "scif0";
+       };
+
+       scif1_pins: serial1 {
+               renesas,groups = "scif1_data";
+               renesas,function = "scif1";
+       };
+
+       mmc1_pins: mmc1 {
+               renesas,groups = "mmc1_data8", "mmc1_ctrl";
+               renesas,function = "mmc1";
+       };
+};
+
+&mmcif1 {
+       pinctrl-0 = <&mmc1_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&fixedregulator3v3>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
 };
index 203bd089af29d83355ed9b2ebdc029045012320f..10e6a08164e58998602da8d62f4487c75ee39673 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /dts-v1/;
-/include/ "r8a7790.dtsi"
+#include "r8a7790.dtsi"
 
 / {
        model = "Lager";
                reg = <0 0x40000000 0 0x80000000>;
        };
 
+       memory@180000000 {
+               device_type = "memory";
+               reg = <1 0x80000000 0 0x80000000>;
+       };
+
        lbsc {
                #address-cells = <1>;
                #size-cells = <1>;
index ee845fad939b895a1bfb907c6597f9f916d926f8..68b7b87e535f6343bd20ff6d1156ed60877f9cf5 100644 (file)
@@ -8,6 +8,9 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
 / {
        compatible = "renesas,r8a7790";
        interrupt-parent = <&gic>;
                        <0 0xf1002000 0 0x1000>,
                        <0 0xf1004000 0 0x2000>,
                        <0 0xf1006000 0 0x2000>;
-               interrupts = <1 9 0xf04>;
+               interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
        };
 
-       gpio0: gpio@ffc40000 {
+       gpio0: gpio@e6050000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
-               reg = <0 0xffc40000 0 0x2c>;
+               reg = <0 0xe6050000 0 0x50>;
                interrupt-parent = <&gic>;
-               interrupts = <0 4 0x4>;
+               interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 0 32>;
                interrupt-controller;
        };
 
-       gpio1: gpio@ffc41000 {
+       gpio1: gpio@e6051000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
-               reg = <0 0xffc41000 0 0x2c>;
+               reg = <0 0xe6051000 0 0x50>;
                interrupt-parent = <&gic>;
-               interrupts = <0 5 0x4>;
+               interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 32 32>;
                interrupt-controller;
        };
 
-       gpio2: gpio@ffc42000 {
+       gpio2: gpio@e6052000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
-               reg = <0 0xffc42000 0 0x2c>;
+               reg = <0 0xe6052000 0 0x50>;
                interrupt-parent = <&gic>;
-               interrupts = <0 6 0x4>;
+               interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 64 32>;
                interrupt-controller;
        };
 
-       gpio3: gpio@ffc43000 {
+       gpio3: gpio@e6053000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
-               reg = <0 0xffc43000 0 0x2c>;
+               reg = <0 0xe6053000 0 0x50>;
                interrupt-parent = <&gic>;
-               interrupts = <0 7 0x4>;
+               interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 96 32>;
                interrupt-controller;
        };
 
-       gpio4: gpio@ffc44000 {
+       gpio4: gpio@e6054000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
-               reg = <0 0xffc44000 0 0x2c>;
+               reg = <0 0xe6054000 0 0x50>;
                interrupt-parent = <&gic>;
-               interrupts = <0 8 0x4>;
+               interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 128 32>;
                interrupt-controller;
        };
 
-       gpio5: gpio@ffc45000 {
+       gpio5: gpio@e6055000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
-               reg = <0 0xffc45000 0 0x2c>;
+               reg = <0 0xe6055000 0 0x50>;
                interrupt-parent = <&gic>;
-               interrupts = <0 9 0x4>;
+               interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
                gpio-ranges = <&pfc 0 160 32>;
                interrupt-controller;
        };
 
+       thermal@e61f0000 {
+               compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal";
+               reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
        timer {
                compatible = "arm,armv7-timer";
-               interrupts = <1 13 0xf08>,
-                               <1 14 0xf08>,
-                               <1 11 0xf08>,
-                               <1 10 0xf08>;
+               interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
 
        irqc0: interrupt-controller@e61c0000 {
-               compatible = "renesas,irqc";
+               compatible = "renesas,irqc-r8a7790", "renesas,irqc";
                #interrupt-cells = <2>;
                interrupt-controller;
                reg = <0 0xe61c0000 0 0x200>;
                interrupt-parent = <&gic>;
-               interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>;
+               interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 1 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 2 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 3 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        i2c0: i2c@e6508000 {
                compatible = "renesas,i2c-r8a7790";
                reg = <0 0xe6508000 0 0x40>;
                interrupt-parent = <&gic>;
-               interrupts = <0 287 0x4>;
+               interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,i2c-r8a7790";
                reg = <0 0xe6518000 0 0x40>;
                interrupt-parent = <&gic>;
-               interrupts = <0 288 0x4>;
+               interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,i2c-r8a7790";
                reg = <0 0xe6530000 0 0x40>;
                interrupt-parent = <&gic>;
-               interrupts = <0 286 0x4>;
+               interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,i2c-r8a7790";
                reg = <0 0xe6540000 0 0x40>;
                interrupt-parent = <&gic>;
-               interrupts = <0 290 0x4>;
+               interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
        mmcif0: mmcif@ee200000 {
-               compatible = "renesas,sh-mmcif";
+               compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
                reg = <0 0xee200000 0 0x80>;
                interrupt-parent = <&gic>;
-               interrupts = <0 169 0x4>;
+               interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
                reg-io-width = <4>;
                status = "disabled";
        };
 
-       mmcif1: mmcif@ee220000 {
-               compatible = "renesas,sh-mmcif";
+       mmcif1: mmc@ee220000 {
+               compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
                reg = <0 0xee220000 0 0x80>;
                interrupt-parent = <&gic>;
-               interrupts = <0 170 0x4>;
+               interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
                reg-io-width = <4>;
                status = "disabled";
        };
                reg = <0 0xe6060000 0 0x250>;
        };
 
-       sdhi0: sdhi@ee100000 {
+       sdhi0: sd@ee100000 {
                compatible = "renesas,sdhi-r8a7790";
                reg = <0 0xee100000 0 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 165 4>;
+               interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                status = "disabled";
        };
 
-       sdhi1: sdhi@ee120000 {
+       sdhi1: sd@ee120000 {
                compatible = "renesas,sdhi-r8a7790";
                reg = <0 0xee120000 0 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 166 4>;
+               interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                status = "disabled";
        };
 
-       sdhi2: sdhi@ee140000 {
+       sdhi2: sd@ee140000 {
                compatible = "renesas,sdhi-r8a7790";
                reg = <0 0xee140000 0 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 167 4>;
+               interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                status = "disabled";
        };
 
-       sdhi3: sdhi@ee160000 {
+       sdhi3: sd@ee160000 {
                compatible = "renesas,sdhi-r8a7790";
                reg = <0 0xee160000 0 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 168 4>;
+               interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                status = "disabled";
        };
diff --git a/arch/arm/boot/dts/r8a7791-koelsch-reference.dts b/arch/arm/boot/dts/r8a7791-koelsch-reference.dts
new file mode 100644 (file)
index 0000000..1919273
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Device Tree Source for the Koelsch board
+ *
+ * Copyright (C) 2013 Renesas Electronics Corporation
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7791.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Koelsch";
+       compatible = "renesas,koelsch-reference", "renesas,r8a7791";
+
+       chosen {
+               bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+       };
+
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0 0x40000000 0 0x80000000>;
+       };
+
+       lbsc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               led6 {
+                       gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+               };
+               led7 {
+                       gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+               };
+               led8 {
+                       gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+               };
+       };
+};
+
+&pfc {
+       pinctrl-0 = <&scif0_pins &scif1_pins>;
+       pinctrl-names = "default";
+
+       scif0_pins: serial0 {
+               renesas,groups = "scif0_data_d";
+               renesas,function = "scif0";
+       };
+
+       scif1_pins: serial1 {
+               renesas,groups = "scif1_data_d";
+               renesas,function = "scif1";
+       };
+};
index 1ce5250ec278fef727fa46c2a09c9cc09007b259..c4e8b3a0cd13af0ff201f3df89a8d9821c2452dc 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "r8a7791.dtsi"
+#include "r8a7791.dtsi"
 
 / {
        model = "Koelsch";
index fea5cfef4691c3656b7b34560eedccaee38ef0b1..a349aff54c76c333139962d16c4ba6bbc566b8ef 100644 (file)
@@ -9,6 +9,9 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
 / {
        compatible = "renesas,r8a7791";
        interrupt-parent = <&gic>;
                        <0 0xf1002000 0 0x1000>,
                        <0 0xf1004000 0 0x2000>,
                        <0 0xf1006000 0 0x2000>;
-               interrupts = <1 9 0xf04>;
+               interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       gpio0: gpio@e6050000 {
+               compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+               reg = <0 0xe6050000 0 0x50>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 0 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       gpio1: gpio@e6051000 {
+               compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+               reg = <0 0xe6051000 0 0x50>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 32 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       gpio2: gpio@e6052000 {
+               compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+               reg = <0 0xe6052000 0 0x50>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 64 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       gpio3: gpio@e6053000 {
+               compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+               reg = <0 0xe6053000 0 0x50>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 96 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       gpio4: gpio@e6054000 {
+               compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+               reg = <0 0xe6054000 0 0x50>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 128 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       gpio5: gpio@e6055000 {
+               compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+               reg = <0 0xe6055000 0 0x50>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 160 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       gpio6: gpio@e6055400 {
+               compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+               reg = <0 0xe6055400 0 0x50>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 192 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       gpio7: gpio@e6055800 {
+               compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
+               reg = <0 0xe6055800 0 0x50>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 224 26>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       thermal@e61f0000 {
+               compatible = "renesas,thermal-r8a7791", "renesas,rcar-thermal";
+               reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        timer {
                compatible = "arm,armv7-timer";
-               interrupts = <1 13 0xf08>,
-                               <1 14 0xf08>,
-                               <1 11 0xf08>,
-                               <1 10 0xf08>;
+               interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
 
        irqc0: interrupt-controller@e61c0000 {
-               compatible = "renesas,irqc";
+               compatible = "renesas,irqc-r8a7791", "renesas,irqc";
                #interrupt-cells = <2>;
                interrupt-controller;
                reg = <0 0xe61c0000 0 0x200>;
                interrupt-parent = <&gic>;
-               interrupts = <0 0 4>,
-                             <0 1 4>,
-                             <0 2 4>,
-                             <0 3 4>,
-                             <0 12 4>,
-                             <0 13 4>,
-                             <0 14 4>,
-                             <0 15 4>,
-                             <0 16 4>,
-                             <0 17 4>;
+               interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 1 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 2 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 3 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 12 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 13 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 14 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 15 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 16 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 17 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       pfc: pfc@e6060000 {
+               compatible = "renesas,pfc-r8a7791";
+               reg = <0 0xe6060000 0 0x250>;
+               #gpio-range-cells = <3>;
        };
 };
index 5cdaba4cea8653d8db51616f443a4d8ee2d79ef4..cbc7c8ecdeaa9b8bdb25a6629044bbde8be4247a 100644 (file)
                        watchdog@fffffe40 {
                                compatible = "atmel,at91sam9260-wdt";
                                reg = <0xfffffe40 0x10>;
+                               interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
+                               atmel,watchdog-type = "hardware";
+                               atmel,reset-type = "all";
+                               atmel,dbg-halt;
+                               atmel,idle-halt;
                                status = "disabled";
                        };
 
index 8acf51e0cdae8b10bdda5d875a61f4c9e543e19c..a759a276c9a972d4174e519240e4f9ed7d720fd0 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /dts-v1/;
-/include/ "sh7372.dtsi"
+#include "sh7372.dtsi"
 
 / {
        model = "Mackerel (AP4 EVM 2nd)";
index 8ee06dd81799da98cbe14ed6c43973e4d4bd513f..5bb593daab529301cf64d1ef9b0c9c9ffc2fbec4 100644 (file)
@@ -12,8 +12,9 @@
  */
 
 /dts-v1/;
-/include/ "sh73a0.dtsi"
+#include "sh73a0.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        model = "KZM-A9-GT";
@@ -82,7 +83,7 @@
                reg = <0x10000000 0x100>;
                phy-mode = "mii";
                interrupt-parent = <&irqpin0>;
-               interrupts = <3 0>;     /* active low */
+               interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
                reg-io-width = <4>;
                smsc,irq-push-pull;
                smsc,save-mac-address;
                        gpios = <&pfc 23 GPIO_ACTIVE_LOW>;
                };
        };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               back-key {
+                       gpios = <&pcf8575 8 GPIO_ACTIVE_LOW>;
+                       linux,code = <158>;
+                       label = "SW3";
+               };
+
+               right-key {
+                       gpios = <&pcf8575 9 GPIO_ACTIVE_LOW>;
+                       linux,code = <106>;
+                       label = "SW2-R";
+               };
+
+               left-key {
+                       gpios = <&pcf8575 10 GPIO_ACTIVE_LOW>;
+                       linux,code = <105>;
+                       label = "SW2-L";
+               };
+
+               enter-key {
+                       gpios = <&pcf8575 11 GPIO_ACTIVE_LOW>;
+                       linux,code = <28>;
+                       label = "SW2-P";
+               };
+
+               up-key {
+                       gpios = <&pcf8575 12 GPIO_ACTIVE_LOW>;
+                       linux,code = <103>;
+                       label = "SW2-U";
+               };
+
+               down-key {
+                       gpios = <&pcf8575 13 GPIO_ACTIVE_LOW>;
+                       linux,code = <108>;
+                       label = "SW2-D";
+               };
+
+               home-key {
+                       gpios = <&pcf8575 14 GPIO_ACTIVE_LOW>;
+                       linux,code = <102>;
+                       label = "SW1";
+               };
+       };
 };
 
 &i2c0 {
        pinctrl-0 = <&i2c3_pins>;
        pinctrl-names = "default";
        status = "okay";
+
+       pcf8575: gpio@20 {
+               compatible = "nxp,pcf8575";
+               reg = <0x20>;
+               interrupt-parent = <&irqpin2>;
+               interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
 };
 
 &mmcif {
                renesas,function = "i2c3";
        };
 
-       mmcif_pins: mmcif {
+       mmcif_pins: mmc {
                mux {
                        renesas,groups = "mmc0_data8_0", "mmc0_ctrl_0";
                        renesas,function = "mmc0";
                };
        };
 
-       scifa4_pins: scifa4 {
+       scifa4_pins: serial4 {
                renesas,groups = "scifa4_data", "scifa4_ctrl";
                renesas,function = "scifa4";
        };
 
-       sdhi0_pins: sdhi0 {
+       sdhi0_pins: sd0 {
                renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd", "sdhi0_wp";
                renesas,function = "sdhi0";
        };
 
-       sdhi2_pins: sdhi2 {
+       sdhi2_pins: sd2 {
                renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
                renesas,function = "sdhi2";
        };
index 0f1ca7792c46acebbbce831371e04200aa89846d..27c5f426d172f03d53801875ec5a5293c4f45b88 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /dts-v1/;
-/include/ "sh73a0.dtsi"
+#include "sh73a0.dtsi"
 
 / {
        model = "KZM-A9-GT";
index fcf26889a8a0aacb380d980fb6cccdd36ee36dff..29d2ee6e36c6f41d1d2daab0cfedff994ee89105 100644 (file)
@@ -10,6 +10,8 @@
 
 /include/ "skeleton.dtsi"
 
+#include <dt-bindings/interrupt-controller/irq.h>
+
 / {
        compatible = "renesas,sh73a0";
 
@@ -40,8 +42,8 @@
 
        pmu {
                compatible = "arm,cortex-a9-pmu";
-               interrupts = <0 55 4>,
-                            <0 56 4>;
+               interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 56 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        irqpin0: irqpin@e6900000 {
                        <0xe6900040 1>,
                        <0xe6900060 1>;
                interrupt-parent = <&gic>;
-               interrupts = <0 1 0x4
-                             0 2 0x4
-                             0 3 0x4
-                             0 4 0x4
-                             0 5 0x4
-                             0 6 0x4
-                             0 7 0x4
-                             0 8 0x4>;
+               interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH
+                             0 2 IRQ_TYPE_LEVEL_HIGH
+                             0 3 IRQ_TYPE_LEVEL_HIGH
+                             0 4 IRQ_TYPE_LEVEL_HIGH
+                             0 5 IRQ_TYPE_LEVEL_HIGH
+                             0 6 IRQ_TYPE_LEVEL_HIGH
+                             0 7 IRQ_TYPE_LEVEL_HIGH
+                             0 8 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        irqpin1: irqpin@e6900004 {
                        <0xe6900044 1>,
                        <0xe6900064 1>;
                interrupt-parent = <&gic>;
-               interrupts = <0 9 0x4
-                             0 10 0x4
-                             0 11 0x4
-                             0 12 0x4
-                             0 13 0x4
-                             0 14 0x4
-                             0 15 0x4
-                             0 16 0x4>;
+               interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH
+                             0 10 IRQ_TYPE_LEVEL_HIGH
+                             0 11 IRQ_TYPE_LEVEL_HIGH
+                             0 12 IRQ_TYPE_LEVEL_HIGH
+                             0 13 IRQ_TYPE_LEVEL_HIGH
+                             0 14 IRQ_TYPE_LEVEL_HIGH
+                             0 15 IRQ_TYPE_LEVEL_HIGH
+                             0 16 IRQ_TYPE_LEVEL_HIGH>;
                control-parent;
        };
 
                        <0xe6900048 1>,
                        <0xe6900068 1>;
                interrupt-parent = <&gic>;
-               interrupts = <0 17 0x4
-                             0 18 0x4
-                             0 19 0x4
-                             0 20 0x4
-                             0 21 0x4
-                             0 22 0x4
-                             0 23 0x4
-                             0 24 0x4>;
+               interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH
+                             0 18 IRQ_TYPE_LEVEL_HIGH
+                             0 19 IRQ_TYPE_LEVEL_HIGH
+                             0 20 IRQ_TYPE_LEVEL_HIGH
+                             0 21 IRQ_TYPE_LEVEL_HIGH
+                             0 22 IRQ_TYPE_LEVEL_HIGH
+                             0 23 IRQ_TYPE_LEVEL_HIGH
+                             0 24 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        irqpin3: irqpin@e690000c {
                        <0xe690004c 1>,
                        <0xe690006c 1>;
                interrupt-parent = <&gic>;
-               interrupts = <0 25 0x4
-                             0 26 0x4
-                             0 27 0x4
-                             0 28 0x4
-                             0 29 0x4
-                             0 30 0x4
-                             0 31 0x4
-                             0 32 0x4>;
+               interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH
+                             0 26 IRQ_TYPE_LEVEL_HIGH
+                             0 27 IRQ_TYPE_LEVEL_HIGH
+                             0 28 IRQ_TYPE_LEVEL_HIGH
+                             0 29 IRQ_TYPE_LEVEL_HIGH
+                             0 30 IRQ_TYPE_LEVEL_HIGH
+                             0 31 IRQ_TYPE_LEVEL_HIGH
+                             0 32 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        i2c0: i2c@e6820000 {
                compatible = "renesas,rmobile-iic";
                reg = <0xe6820000 0x425>;
                interrupt-parent = <&gic>;
-               interrupts = <0 167 0x4
-                             0 168 0x4
-                             0 169 0x4
-                             0 170 0x4>;
+               interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH
+                             0 168 IRQ_TYPE_LEVEL_HIGH
+                             0 169 IRQ_TYPE_LEVEL_HIGH
+                             0 170 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rmobile-iic";
                reg = <0xe6822000 0x425>;
                interrupt-parent = <&gic>;
-               interrupts = <0 51 0x4
-                             0 52 0x4
-                             0 53 0x4
-                             0 54 0x4>;
+               interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH
+                             0 52 IRQ_TYPE_LEVEL_HIGH
+                             0 53 IRQ_TYPE_LEVEL_HIGH
+                             0 54 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rmobile-iic";
                reg = <0xe6824000 0x425>;
                interrupt-parent = <&gic>;
-               interrupts = <0 171 0x4
-                             0 172 0x4
-                             0 173 0x4
-                             0 174 0x4>;
+               interrupts = <0 171 IRQ_TYPE_LEVEL_HIGH
+                             0 172 IRQ_TYPE_LEVEL_HIGH
+                             0 173 IRQ_TYPE_LEVEL_HIGH
+                             0 174 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rmobile-iic";
                reg = <0xe6826000 0x425>;
                interrupt-parent = <&gic>;
-               interrupts = <0 183 0x4
-                             0 184 0x4
-                             0 185 0x4
-                             0 186 0x4>;
+               interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH
+                             0 184 IRQ_TYPE_LEVEL_HIGH
+                             0 185 IRQ_TYPE_LEVEL_HIGH
+                             0 186 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
                compatible = "renesas,rmobile-iic";
                reg = <0xe6828000 0x425>;
                interrupt-parent = <&gic>;
-               interrupts = <0 187 0x4
-                             0 188 0x4
-                             0 189 0x4
-                             0 190 0x4>;
+               interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH
+                             0 188 IRQ_TYPE_LEVEL_HIGH
+                             0 189 IRQ_TYPE_LEVEL_HIGH
+                             0 190 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       mmcif: mmcif@e6bd0000 {
+       mmcif: mmc@e6bd0000 {
                compatible = "renesas,sh-mmcif";
                reg = <0xe6bd0000 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 140 0x4
-                             0 141 0x4>;
+               interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH
+                             0 141 IRQ_TYPE_LEVEL_HIGH>;
                reg-io-width = <4>;
                status = "disabled";
        };
 
-       sdhi0: sdhi@ee100000 {
-               compatible = "renesas,sdhi-r8a7740";
+       sdhi0: sd@ee100000 {
+               compatible = "renesas,sdhi-sh73a0";
                reg = <0xee100000 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 83 4
-                               0 84 4
-                               0 85 4>;
+               interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH
+                             0 84 IRQ_TYPE_LEVEL_HIGH
+                             0 85 IRQ_TYPE_LEVEL_HIGH>;
                cap-sd-highspeed;
                status = "disabled";
        };
 
        /* SDHI1 and SDHI2 have no CD pins, no need for CD IRQ */
-       sdhi1: sdhi@ee120000 {
-               compatible = "renesas,sdhi-r8a7740";
+       sdhi1: sd@ee120000 {
+               compatible = "renesas,sdhi-sh73a0";
                reg = <0xee120000 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 88 4
-                               0 89 4>;
+               interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH
+                             0 89 IRQ_TYPE_LEVEL_HIGH>;
                toshiba,mmc-wrprotect-disable;
                cap-sd-highspeed;
                status = "disabled";
        };
 
-       sdhi2: sdhi@ee140000 {
-               compatible = "renesas,sdhi-r8a7740";
+       sdhi2: sd@ee140000 {
+               compatible = "renesas,sdhi-sh73a0";
                reg = <0xee140000 0x100>;
                interrupt-parent = <&gic>;
-               interrupts = <0 104 4
-                               0 105 4>;
+               interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH
+                             0 105 IRQ_TYPE_LEVEL_HIGH>;
                toshiba,mmc-wrprotect-disable;
                cap-sd-highspeed;
                status = "disabled";
index 1ce39940795d9ebddb81509e84577b6be88e23ed..cb26c62dc7228a47335f79e50f32029721cc8bf5 100644 (file)
@@ -13,7 +13,7 @@ CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
 # CONFIG_BLOCK is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_R8A73A4=y
 CONFIG_MACH_APE6EVM=y
 # CONFIG_ARM_THUMB is not set
index fae939d3d7f0a863b5284e95778fbc2f6c67f9c4..5abf1a2e31603e9570207d43fa1a4bbdaf7a0f2a 100644 (file)
@@ -15,7 +15,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_R8A7740=y
 CONFIG_MACH_ARMADILLO800EVA=y
 # CONFIG_SH_TIMER_TMU is not set
index b38cd107f82dfe5b1efffb4075e04fc39f9f41c5..80cff50beb34ab930709077d03d9a69d72481f5b 100644 (file)
@@ -8,7 +8,7 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_R8A7778=y
 CONFIG_MACH_BOCKW=y
 CONFIG_MEMORY_START=0x60000000
@@ -27,12 +27,12 @@ CONFIG_HIGHMEM=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
-CONFIG_CMDLINE="console=ttySC0,115200 ignore_loglevel root=/dev/nfs ip=dhcp"
-CONFIG_CMDLINE_FORCE=y
+CONFIG_VFP=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_SUSPEND is not set
 CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
+CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
@@ -44,8 +44,6 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -82,6 +80,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 # CONFIG_HWMON is not set
 CONFIG_I2C=y
 CONFIG_I2C_RCAR=y
+CONFIG_REGULATOR=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
@@ -108,11 +107,12 @@ CONFIG_MMC_SDHI=y
 CONFIG_MMC_SH_MMCIF=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_RX8581=y
+CONFIG_DMADEVICES=y
+CONFIG_RCAR_HPB_DMAE=y
 CONFIG_UIO=y
 CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_IOMMU_SUPPORT is not set
 # CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY_USER is not set
 CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
diff --git a/arch/arm/configs/genmai_defconfig b/arch/arm/configs/genmai_defconfig
new file mode 100644 (file)
index 0000000..aa0b704
--- /dev/null
@@ -0,0 +1,116 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE_LEGACY=y
+CONFIG_ARCH_R7S72100=y
+CONFIG_MACH_GENMAI=y
+# CONFIG_SH_TIMER_CMT is not set
+# CONFIG_SH_TIMER_MTU2 is not set
+# CONFIG_SH_TIMER_TMU is not set
+# CONFIG_EM_TIMER_STI is not set
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_458693=y
+CONFIG_ARM_ERRATA_460075=y
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_KEXEC=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CORE is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_SH_ETH=y
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=10
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_RCAR_THERMAL=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_DRM=y
+CONFIG_DRM_RCAR_DU=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SH_MMCIF=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_SH_DMAE=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
index e958ebe7977984be0a2a30746b2acefcfadfecca..6309ee52ccfcb3d74563f8ea6d5bfe396daf546c 100644 (file)
@@ -91,6 +91,7 @@ CONFIG_SMSC911X=y
 CONFIG_SMSC_PHY=y
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_IMX=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
@@ -118,6 +119,7 @@ CONFIG_IMX2_WDT=y
 CONFIG_MFD_MC13XXX_SPI=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
 CONFIG_MEDIA_SUPPORT=y
index 8d0c5a018ed72b720f0b235be8dff2ee9bf1e77a..f338fd6370ad0f045fb74baf63de3cad783249cb 100644 (file)
@@ -42,6 +42,7 @@ CONFIG_VMSPLIT_2G=y
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
 CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
 CONFIG_VFP=y
 CONFIG_NEON=y
@@ -129,6 +130,8 @@ CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_EGALAX=y
 CONFIG_TOUCHSCREEN_MC13783=y
+CONFIG_TOUCHSCREEN_TSC2007=y
+CONFIG_TOUCHSCREEN_STMPE=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MMA8450=y
 CONFIG_SERIO_SERPORT=m
@@ -156,6 +159,7 @@ CONFIG_IMX2_WDT=y
 CONFIG_MFD_DA9052_I2C=y
 CONFIG_MFD_MC13XXX_SPI=y
 CONFIG_MFD_MC13XXX_I2C=y
+CONFIG_MFD_STMPE=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ANATOP=y
index 0ae0eaebf6b22ea7c71ed5746ee448029346af9f..2e762d94e94b31501c1e7e3ea16965c72d3d9b9c 100644 (file)
@@ -27,6 +27,7 @@ CONFIG_PCI_MVEBU=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CPU_FREQ=y
index 825c16dee8a002689b6498ad94c0421ea19aef13..7fd65a01ec7ee2636a179d955cebd5ab90bd30c4 100644 (file)
@@ -9,7 +9,7 @@ CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
 # CONFIG_BLOCK is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_R8A7791=y
 CONFIG_MACH_KOELSCH=y
 # CONFIG_SWP_EMULATE is not set
index 6c37f4a98eb82b3dbabdecf9a2f60dceb5737aa4..e42ce3756af3e9cac163fca222fcbcb3c30fb440 100644 (file)
@@ -13,7 +13,7 @@ CONFIG_SLAB=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_EMEV2=y
 CONFIG_MACH_KZM9D=y
 CONFIG_MEMORY_START=0x40000000
@@ -32,6 +32,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
+CONFIG_AUTO_ZRELADDR=y
 CONFIG_VFP=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_PM_RUNTIME=y
index 1ad028023a6460e3b665b4044c6994232b9b3ca1..9934dbc23d64f7892d09e213720cbf0ff6b581c8 100644 (file)
@@ -22,7 +22,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_SH73A0=y
 CONFIG_MACH_KZM9G=y
 CONFIG_MEMORY_START=0x41000000
index 35bff5e0d57a26b799e4554497859dcf1f029e9b..35dc8b2be47f64ed73f43128dfe61c9aacd24a0a 100644 (file)
@@ -12,7 +12,7 @@ CONFIG_SLAB=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_R8A7790=y
 CONFIG_MACH_LAGER=y
 # CONFIG_SH_TIMER_TMU is not set
index 9fb11895b2e27f73663b547a7abb4719adeece34..a61e1653fc5e07c728b5cc17048968818ed53117 100644 (file)
@@ -14,7 +14,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_SH7372=y
 CONFIG_MACH_MACKEREL=y
 CONFIG_MEMORY_SIZE=0x10000000
index 5cc6360340b1c683dfe5b31c15a54c61e457963a..f21bd405cc2a4f3d756bc11cae91f8f332f41732 100644 (file)
@@ -9,7 +9,7 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_R8A7779=y
 CONFIG_MACH_MARZEN=y
 CONFIG_MEMORY_START=0x60000000
@@ -30,12 +30,12 @@ CONFIG_HIGHMEM=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
-CONFIG_CMDLINE="console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel root=/dev/nfs ip=on"
-CONFIG_CMDLINE_FORCE=y
+CONFIG_VFP=y
 CONFIG_KEXEC=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
+CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
@@ -43,8 +43,6 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -61,7 +59,6 @@ CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_MICREL is not set
 # CONFIG_NET_VENDOR_NATSEMI is not set
 # CONFIG_NET_VENDOR_SEEQ is not set
-CONFIG_SMC911X=y
 CONFIG_SMSC911X=y
 # CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
@@ -106,11 +103,12 @@ CONFIG_USB_STORAGE=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
+CONFIG_DMADEVICES=y
+CONFIG_RCAR_HPB_DMAE=y
 CONFIG_UIO=y
 CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_IOMMU_SUPPORT is not set
 # CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY_USER is not set
 CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
index 594d706b641f8df1de256c875d638795acaa054f..6fcb5c88a6435f2ccb57174db713fbe5382f0a62 100644 (file)
@@ -69,6 +69,7 @@ CONFIG_USB_XHCI_HCD=y
 CONFIG_MMC=y
 CONFIG_MMC_MVSDIO=y
 CONFIG_NEW_LEDS=y
+CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_CLASS=m
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
index 98a50c309b90ad72b710fdeddc4117208fa6c29c..bfa80a11e8c76304c800f2df62090f1f50d089c1 100644 (file)
@@ -173,6 +173,7 @@ CONFIG_MFD_PALMAS=y
 CONFIG_MFD_TPS65217=y
 CONFIG_MFD_TPS65910=y
 CONFIG_TWL6040_CORE=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_PALMAS=y
 CONFIG_REGULATOR_TPS65023=y
 CONFIG_REGULATOR_TPS6507X=y
index ac632cc38f249767bcedfc1232a4e4b8e6bc70d9..c6ebc184bf68201c69a0791ed83f0bbfc64b4348 100644 (file)
@@ -22,6 +22,7 @@ CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8"
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
+CONFIG_ARM_U8500_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_PM_RUNTIME=y
@@ -109,6 +110,8 @@ CONFIG_EXT2_FS_SECURITY=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
 CONFIG_VFAT_FS=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_MISC_FILESYSTEMS is not set
index ee753f1749cd795b03557273afdb3d0832d6fc8e..e9a49fe0284e41c2f6d6d9448fb73e9a2ad99ead 100644 (file)
@@ -481,4 +481,9 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
        : : : "r0","r1","r2","r3","r4","r5","r6","r7", \
              "r9","r10","lr","memory" )
 
+int set_memory_ro(unsigned long addr, int numpages);
+int set_memory_rw(unsigned long addr, int numpages);
+int set_memory_x(unsigned long addr, int numpages);
+int set_memory_nx(unsigned long addr, int numpages);
+
 #endif
index 3c597c222ef278a8eb170a4169b5e54dcc158ac0..fbeb39c869e9fdcedace1d61688247c14141cab3 100644 (file)
@@ -329,7 +329,7 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
  */
 #define ioremap(cookie,size)           __arm_ioremap((cookie), (size), MT_DEVICE)
 #define ioremap_nocache(cookie,size)   __arm_ioremap((cookie), (size), MT_DEVICE)
-#define ioremap_cached(cookie,size)    __arm_ioremap((cookie), (size), MT_DEVICE_CACHED)
+#define ioremap_cache(cookie,size)     __arm_ioremap((cookie), (size), MT_DEVICE_CACHED)
 #define ioremap_wc(cookie,size)                __arm_ioremap((cookie), (size), MT_DEVICE_WC)
 #define iounmap                                __arm_iounmap
 
index 2fe141fcc8d63311b63a2be06a0289a31b0174a3..f98c7f32c9c8aefb256c7c7a287c6c2d69602011 100644 (file)
@@ -22,18 +22,21 @@ struct map_desc {
 };
 
 /* types 0-3 are defined in asm/io.h */
-#define MT_UNCACHED            4
-#define MT_CACHECLEAN          5
-#define MT_MINICLEAN           6
-#define MT_LOW_VECTORS         7
-#define MT_HIGH_VECTORS                8
-#define MT_MEMORY              9
-#define MT_ROM                 10
-#define MT_MEMORY_NONCACHED    11
-#define MT_MEMORY_DTCM         12
-#define MT_MEMORY_ITCM         13
-#define MT_MEMORY_SO           14
-#define MT_MEMORY_DMA_READY    15
+enum {
+       MT_UNCACHED = 4,
+       MT_CACHECLEAN,
+       MT_MINICLEAN,
+       MT_LOW_VECTORS,
+       MT_HIGH_VECTORS,
+       MT_MEMORY_RWX,
+       MT_MEMORY_RW,
+       MT_ROM,
+       MT_MEMORY_RWX_NONCACHED,
+       MT_MEMORY_RW_DTCM,
+       MT_MEMORY_RWX_ITCM,
+       MT_MEMORY_RW_SO,
+       MT_MEMORY_DMA_READY,
+};
 
 #ifdef CONFIG_MMU
 extern void iotable_init(struct map_desc *, int);
index 86a659a19526c75a2ba3b91ce839925cc52d26de..dfff709fda3ccdddbc0d67f3ff1a04c702c85ad6 100644 (file)
@@ -160,6 +160,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
        return (pmd_t *)pud;
 }
 
+#define pmd_large(pmd)         (pmd_val(pmd) & 2)
 #define pmd_bad(pmd)           (pmd_val(pmd) & 2)
 
 #define copy_pmd(pmdpd,pmdps)          \
index 4f9503908dca4a7dc536324514801bcbd03d32fd..03243f7eeddfc57beebb8100132dae059f96af77 100644 (file)
                                                 PMD_TYPE_TABLE)
 #define pmd_sect(pmd)          ((pmd_val(pmd) & PMD_TYPE_MASK) == \
                                                 PMD_TYPE_SECT)
+#define pmd_large(pmd)         pmd_sect(pmd)
 
 #define pud_clear(pudp)                        \
        do {                            \
index be956dbf6baea3a7481baa11c58233d0741702d1..7d59b524f2af3c48480762a9b41f36fefb04e546 100644 (file)
@@ -61,7 +61,7 @@ extern void __pgd_error(const char *file, int line, pgd_t);
  * mapping to be mapped at.  This is particularly important for
  * non-high vector CPUs.
  */
-#define FIRST_USER_ADDRESS     PAGE_SIZE
+#define FIRST_USER_ADDRESS     (PAGE_SIZE * 2)
 
 /*
  * Use TASK_SIZE as the ceiling argument for free_pgtables() and
@@ -254,6 +254,8 @@ PTE_BIT_FUNC(mkclean,   &= ~L_PTE_DIRTY);
 PTE_BIT_FUNC(mkdirty,   |= L_PTE_DIRTY);
 PTE_BIT_FUNC(mkold,     &= ~L_PTE_YOUNG);
 PTE_BIT_FUNC(mkyoung,   |= L_PTE_YOUNG);
+PTE_BIT_FUNC(mkexec,   &= ~L_PTE_XN);
+PTE_BIT_FUNC(mknexec,   |= L_PTE_XN);
 
 static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
 
index 75579a9d6f76cba3cc84ad61d01ed103269378bd..3759cacdd7f8601322b98ffed6598d97ee8bd016 100644 (file)
@@ -117,6 +117,6 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
        return __set_phys_to_machine(pfn, mfn);
 }
 
-#define xen_remap(cookie, size) ioremap_cached((cookie), (size));
+#define xen_remap(cookie, size) ioremap_cache((cookie), (size));
 
 #endif /* _ASM_ARM_XEN_PAGE_H */
index 29da84e183f4a7939ff9e9bb69c96f1b93f68538..42b823cd2d22ffd119b303610ea865880253eb4d 100644 (file)
 #define IMX35_UART_BASE_ADDR(n)        IMX35_UART##n##_BASE_ADDR
 #define IMX35_UART_BASE(n)     IMX35_UART_BASE_ADDR(n)
 
+#define IMX50_UART1_BASE_ADDR  0x53fbc000
+#define IMX50_UART2_BASE_ADDR  0x53fc0000
+#define IMX50_UART3_BASE_ADDR  0x5000c000
+#define IMX50_UART4_BASE_ADDR  0x53ff0000
+#define IMX50_UART5_BASE_ADDR  0x63f90000
+#define IMX50_UART_BASE_ADDR(n)        IMX50_UART##n##_BASE_ADDR
+#define IMX50_UART_BASE(n)     IMX50_UART_BASE_ADDR(n)
+
 #define IMX51_UART1_BASE_ADDR  0x73fbc000
 #define IMX51_UART2_BASE_ADDR  0x73fc0000
 #define IMX51_UART3_BASE_ADDR  0x7000c000
@@ -85,6 +93,8 @@
 #define UART_PADDR     IMX_DEBUG_UART_BASE(IMX31)
 #elif defined(CONFIG_DEBUG_IMX35_UART)
 #define UART_PADDR     IMX_DEBUG_UART_BASE(IMX35)
+#elif defined(CONFIG_DEBUG_IMX50_UART)
+#define UART_PADDR     IMX_DEBUG_UART_BASE(IMX50)
 #elif defined(CONFIG_DEBUG_IMX51_UART)
 #define UART_PADDR     IMX_DEBUG_UART_BASE(IMX51)
 #elif defined(CONFIG_DEBUG_IMX53_UART)
index 52b26432c9a9941e8281a4483dd7aed148a99995..2260f1855820fa2d2961025b2683c2e30982a8e0 100644 (file)
@@ -14,8 +14,6 @@
 #include <asm/thread_notify.h>
 #include <asm/v7m.h>
 
-#include <mach/entry-macro.S>
-
 #include "entry-header.S"
 
 #ifdef CONFIG_TRACE_IRQFLAGS
index 8ff0ecdc637fd3bd2b41c0d129715acad13152e2..131a6ab5f35504dfc70c6f9e1421632c25d5feae 100644 (file)
@@ -385,7 +385,6 @@ out:
        return ret;
 
 out_unmap:
-       amba_set_drvdata(dev, NULL);
        iounmap(t->etb_regs);
 
 out_release:
@@ -398,8 +397,6 @@ static int etb_remove(struct amba_device *dev)
 {
        struct tracectx *t = amba_get_drvdata(dev);
 
-       amba_set_drvdata(dev, NULL);
-
        iounmap(t->etb_regs);
        t->etb_regs = NULL;
 
@@ -588,7 +585,6 @@ out:
        return ret;
 
 out_unmap:
-       amba_set_drvdata(dev, NULL);
        iounmap(t->etm_regs);
 
 out_release:
@@ -601,8 +597,6 @@ static int etm_remove(struct amba_device *dev)
 {
        struct tracectx *t = amba_get_drvdata(dev);
 
-       amba_set_drvdata(dev, NULL);
-
        iounmap(t->etm_regs);
        t->etm_regs = NULL;
 
index 57221e349a7ce0eec03445cd56de2845e5d23358..f0d180d8b29f4e22558a98fdf9366ebaf1c0c0cb 100644 (file)
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
+#include <asm/fncpy.h>
 #include <asm/mach-types.h>
 #include <asm/smp_plat.h>
 #include <asm/system_misc.h>
 
-extern const unsigned char relocate_new_kernel[];
+extern void relocate_new_kernel(void);
 extern const unsigned int relocate_new_kernel_size;
 
 extern unsigned long kexec_start_address;
@@ -142,6 +143,8 @@ void machine_kexec(struct kimage *image)
 {
        unsigned long page_list;
        unsigned long reboot_code_buffer_phys;
+       unsigned long reboot_entry = (unsigned long)relocate_new_kernel;
+       unsigned long reboot_entry_phys;
        void *reboot_code_buffer;
 
        /*
@@ -168,16 +171,16 @@ void machine_kexec(struct kimage *image)
 
 
        /* copy our kernel relocation code to the control code page */
-       memcpy(reboot_code_buffer,
-              relocate_new_kernel, relocate_new_kernel_size);
+       reboot_entry = fncpy(reboot_code_buffer,
+                            reboot_entry,
+                            relocate_new_kernel_size);
+       reboot_entry_phys = (unsigned long)reboot_entry +
+               (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer);
 
-
-       flush_icache_range((unsigned long) reboot_code_buffer,
-                          (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
        printk(KERN_INFO "Bye!\n");
 
        if (kexec_reinit)
                kexec_reinit();
 
-       soft_restart(reboot_code_buffer_phys);
+       soft_restart(reboot_entry_phys);
 }
index d0cdedf4864dc52092355e105f3ba04bba5c5704..95858966d84ec0f10d392a3356cb0367fcee0b85 100644 (file)
@@ -2,10 +2,12 @@
  * relocate_kernel.S - put the kernel image in place to boot
  */
 
+#include <linux/linkage.h>
 #include <asm/kexec.h>
 
-       .globl relocate_new_kernel
-relocate_new_kernel:
+       .align  3       /* not needed for this code, but keeps fncpy() happy */
+
+ENTRY(relocate_new_kernel)
 
        ldr     r0,kexec_indirection_page
        ldr     r1,kexec_start_address
@@ -79,6 +81,8 @@ kexec_mach_type:
 kexec_boot_atags:
        .long   0x0
 
+ENDPROC(relocate_new_kernel)
+
 relocate_new_kernel_end:
 
        .globl relocate_new_kernel_size
index 3c5d0f2170fd7ee309260c2d2c0a6108a24e54f8..b84d0cb13682ccd42e41a22894cb8d2c1821496d 100644 (file)
  * snippets.
  */
 
+/*
+ * In CPU_THUMBONLY case kernel arm opcodes are not allowed.
+ * Note in this case codes skips those instructions but it uses .org
+ * directive to keep correct layout of sigreturn_codes array.
+ */
+#ifndef CONFIG_CPU_THUMBONLY
+#define ARM_OK(code...)        code
+#else
+#define ARM_OK(code...)
+#endif
+
+       .macro arm_slot n
+       .org    sigreturn_codes + 12 * (\n)
+ARM_OK(        .arm    )
+       .endm
+
+       .macro thumb_slot n
+       .org    sigreturn_codes + 12 * (\n) + 8
+       .thumb
+       .endm
+
 #if __LINUX_ARM_ARCH__ <= 4
        /*
         * Note we manually set minimally required arch that supports
        .global sigreturn_codes
        .type   sigreturn_codes, #object
 
-       .arm
+       .align
 
 sigreturn_codes:
 
        /* ARM sigreturn syscall code snippet */
-       mov     r7, #(__NR_sigreturn - __NR_SYSCALL_BASE)
-       swi     #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)
+       arm_slot 0
+ARM_OK(        mov     r7, #(__NR_sigreturn - __NR_SYSCALL_BASE)       )
+ARM_OK(        swi     #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)      )
 
        /* Thumb sigreturn syscall code snippet */
-       .thumb
+       thumb_slot 0
        movs    r7, #(__NR_sigreturn - __NR_SYSCALL_BASE)
        swi     #0
 
        /* ARM sigreturn_rt syscall code snippet */
-       .arm
-       mov     r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE)
-       swi     #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)
+       arm_slot 1
+ARM_OK(        mov     r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE)    )
+ARM_OK(        swi     #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)   )
 
        /* Thumb sigreturn_rt syscall code snippet */
-       .thumb
+       thumb_slot 1
        movs    r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE)
        swi     #0
 
@@ -74,7 +96,7 @@ sigreturn_codes:
         * it is thumb case or not, so we need additional
         * word after real last entry.
         */
-       .arm
+       arm_slot 2
        .space  4
 
        .size   sigreturn_codes, . - sigreturn_codes
index f50f19e5c138839bede270baf3531a41aa5af7c4..7a3be1d4d0b13b7ca984721403aafda47ecb574c 100644 (file)
@@ -52,7 +52,7 @@ static struct map_desc dtcm_iomap[] __initdata = {
                .virtual        = DTCM_OFFSET,
                .pfn            = __phys_to_pfn(DTCM_OFFSET),
                .length         = 0,
-               .type           = MT_MEMORY_DTCM
+               .type           = MT_MEMORY_RW_DTCM
        }
 };
 
@@ -61,7 +61,7 @@ static struct map_desc itcm_iomap[] __initdata = {
                .virtual        = ITCM_OFFSET,
                .pfn            = __phys_to_pfn(ITCM_OFFSET),
                .length         = 0,
-               .type           = MT_MEMORY_ITCM
+               .type           = MT_MEMORY_RWX_ITCM,
        }
 };
 
index dbf0923e8d76bda9392b902e0c8e500025d70402..1861240d12f39e951666904c783fdaa74254eedf 100644 (file)
@@ -56,7 +56,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
 void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
 {
 #ifdef CONFIG_KALLSYMS
-       printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
+       printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
 #else
        printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
 #endif
index cd07b5814c2304f0908342b04291af09388790b7..4102be617fce0644434e3aa7f7fec65c09fcb5e7 100644 (file)
@@ -80,14 +80,14 @@ for_each_frame:     tst     frame, mask             @ Check for address exceptions
 
                ldr     r1, [sv_pc, #-4]        @ if stmfd sp!, {args} exists,
                ldr     r3, .Ldsi+4
-               teq     r3, r1, lsr #10
+               teq     r3, r1, lsr #11
                ldreq   r0, [frame, #-8]        @ get sp
                subeq   r0, r0, #4              @ point at the last arg
                bleq    .Ldumpstm               @ dump saved registers
 
 1004:          ldr     r1, [sv_pc, #0]         @ if stmfd sp!, {..., fp, ip, lr, pc}
                ldr     r3, .Ldsi               @ instruction exists,
-               teq     r3, r1, lsr #10
+               teq     r3, r1, lsr #11
                subeq   r0, frame, #16
                bleq    .Ldumpstm               @ dump saved registers
 
@@ -128,11 +128,11 @@ ENDPROC(c_backtrace)
                beq     2f
                add     r7, r7, #1
                teq     r7, #6
-               moveq   r7, #1
-               moveq   r1, #'\n'
-               movne   r1, #' '
-               ldr     r3, [stack], #-4
-               mov     r2, reg
+               moveq   r7, #0
+               adr     r3, .Lcr
+               addne   r3, r3, #1              @ skip newline
+               ldr     r2, [stack], #-4
+               mov     r1, reg
                adr     r0, .Lfp
                bl      printk
 2:             subs    reg, reg, #1
@@ -142,11 +142,11 @@ ENDPROC(c_backtrace)
                blne    printk
                ldmfd   sp!, {instr, reg, stack, r7, pc}
 
-.Lfp:          .asciz  "%cr%d:%08x"
+.Lfp:          .asciz  " r%d:%08x%s"
 .Lcr:          .asciz  "\n"
 .Lbad:         .asciz  "Backtrace aborted due to bad frame pointer <%p>\n"
                .align
-.Ldsi:         .word   0xe92dd800 >> 10        @ stmfd sp!, {... fp, ip, lr, pc}
-               .word   0xe92d0000 >> 10        @ stmfd sp!, {}
+.Ldsi:         .word   0xe92dd800 >> 11        @ stmfd sp!, {... fp, ip, lr, pc}
+               .word   0xe92d0000 >> 11        @ stmfd sp!, {}
 
 #endif
index 36b668d8e121ee7450c8beffb5e9661923102038..bc1033b897b44510b16a8ab202f0c1b989cc15e5 100644 (file)
@@ -40,6 +40,7 @@ ENTRY(__loop_const_udelay)                    @ 0 <= r0 <= 0x7fffff06
 /*
  * loops = r0 * HZ * loops_per_jiffy / 1000000
  */
+               .align 3
 
 @ Delay routine
 ENTRY(__loop_delay)
index f607deb40f4da6a88a0778b203cdcfbbc8518ecc..bc7b363a3083bfdab31591786fe38991c199e2dc 100644 (file)
@@ -174,7 +174,6 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
 static struct clock_event_device clkevt = {
        .name           = "at91_tick",
        .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .shift          = 32,
        .rating         = 150,
        .set_next_event = clkevt32k_next_event,
        .set_mode       = clkevt32k_mode,
@@ -265,11 +264,9 @@ void __init at91rm9200_timer_init(void)
        at91_st_write(AT91_ST_RTMR, 1);
 
        /* Setup timer clockevent, with minimum of two ticks (important!!) */
-       clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift);
-       clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt);
-       clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1;
        clkevt.cpumask = cpumask_of(0);
-       clockevents_register_device(&clkevt);
+       clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK,
+                                       2, AT91_ST_ALMV);
 
        /* register clocksource */
        clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
index 094b3459c288e37700c42ea85a57ced905323eda..2742e00ec5d6c82a8e4abd1b6b3560e3588407c6 100644 (file)
@@ -81,7 +81,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
 
        desc->pfn = __phys_to_pfn(base);
        desc->length = length;
-       desc->type = MT_MEMORY_NONCACHED;
+       desc->type = MT_MEMORY_RWX_NONCACHED;
 
        pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n",
                base, length, desc->virtual);
index c122bcff9f7c91647a3251266348bef2c531a12b..0d1a89298ece95518c43e07c2c32aa0b15147c69 100644 (file)
@@ -162,7 +162,7 @@ void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 /*****************************************************************************
  * SoC RTC
  ****************************************************************************/
-void __init dove_rtc_init(void)
+static void __init dove_rtc_init(void)
 {
        orion_rtc_init(DOVE_RTC_PHYS_BASE, IRQ_DOVE_RTC);
 }
@@ -256,19 +256,10 @@ void __init dove_timer_init(void)
                        IRQ_DOVE_BRIDGE, dove_tclk);
 }
 
-/*****************************************************************************
- * Cryptographic Engines and Security Accelerator (CESA)
- ****************************************************************************/
-void __init dove_crypto_init(void)
-{
-       orion_crypto_init(DOVE_CRYPT_PHYS_BASE, DOVE_CESA_PHYS_BASE,
-                         DOVE_CESA_SIZE, IRQ_DOVE_CRYPTO);
-}
-
 /*****************************************************************************
  * XOR 0
  ****************************************************************************/
-void __init dove_xor0_init(void)
+static void __init dove_xor0_init(void)
 {
        orion_xor0_init(DOVE_XOR0_PHYS_BASE, DOVE_XOR0_HIGH_PHYS_BASE,
                        IRQ_DOVE_XOR_00, IRQ_DOVE_XOR_01);
@@ -277,7 +268,7 @@ void __init dove_xor0_init(void)
 /*****************************************************************************
  * XOR 1
  ****************************************************************************/
-void __init dove_xor1_init(void)
+static void __init dove_xor1_init(void)
 {
        orion_xor1_init(DOVE_XOR1_PHYS_BASE, DOVE_XOR1_HIGH_PHYS_BASE,
                        IRQ_DOVE_XOR_10, IRQ_DOVE_XOR_11);
index 93e54fd4e3d55900192f62e573d6d97a2919aa4b..bec570ae6494d0bfacd8b479ee9876fbc61dbfeb 100644 (file)
@@ -5,6 +5,7 @@ menu "Cirrus EP93xx Implementation Options"
 config EP93XX_SOC_COMMON
        bool
        default y
+       select SOC_BUS
        select LEDS_GPIO_REGISTER
 
 config CRUNCH
index d95ee28a616a3ed53c776dda2df2fa5da6f229f1..157ba88433c949c1db4595400cfbea3cc29a5c47 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/sys_soc.h>
 #include <linux/timex.h>
 #include <linux/irq.h>
 #include <linux/io.h>
@@ -44,6 +45,7 @@
 #include <linux/platform_data/spi-ep93xx.h>
 #include <mach/gpio-ep93xx.h>
 
+#include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
@@ -137,7 +139,7 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction ep93xx_timer_irq = {
        .name           = "ep93xx timer",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = ep93xx_timer_interrupt,
 };
 
@@ -925,8 +927,108 @@ void ep93xx_ide_release_gpio(struct platform_device *pdev)
 }
 EXPORT_SYMBOL(ep93xx_ide_release_gpio);
 
-void __init ep93xx_init_devices(void)
+/*************************************************************************
+ * EP93xx Security peripheral
+ *************************************************************************/
+
+/*
+ * The Maverick Key is 256 bits of micro fuses blown at the factory during
+ * manufacturing to uniquely identify a part.
+ *
+ * See: http://arm.cirrus.com/forum/viewtopic.php?t=486&highlight=maverick+key
+ */
+#define EP93XX_SECURITY_REG(x)         (EP93XX_SECURITY_BASE + (x))
+#define EP93XX_SECURITY_SECFLG         EP93XX_SECURITY_REG(0x2400)
+#define EP93XX_SECURITY_FUSEFLG                EP93XX_SECURITY_REG(0x2410)
+#define EP93XX_SECURITY_UNIQID         EP93XX_SECURITY_REG(0x2440)
+#define EP93XX_SECURITY_UNIQCHK                EP93XX_SECURITY_REG(0x2450)
+#define EP93XX_SECURITY_UNIQVAL                EP93XX_SECURITY_REG(0x2460)
+#define EP93XX_SECURITY_SECID1         EP93XX_SECURITY_REG(0x2500)
+#define EP93XX_SECURITY_SECID2         EP93XX_SECURITY_REG(0x2504)
+#define EP93XX_SECURITY_SECCHK1                EP93XX_SECURITY_REG(0x2520)
+#define EP93XX_SECURITY_SECCHK2                EP93XX_SECURITY_REG(0x2524)
+#define EP93XX_SECURITY_UNIQID2                EP93XX_SECURITY_REG(0x2700)
+#define EP93XX_SECURITY_UNIQID3                EP93XX_SECURITY_REG(0x2704)
+#define EP93XX_SECURITY_UNIQID4                EP93XX_SECURITY_REG(0x2708)
+#define EP93XX_SECURITY_UNIQID5                EP93XX_SECURITY_REG(0x270c)
+
+static char ep93xx_soc_id[33];
+
+static const char __init *ep93xx_get_soc_id(void)
 {
+       unsigned int id, id2, id3, id4, id5;
+
+       if (__raw_readl(EP93XX_SECURITY_UNIQVAL) != 1)
+               return "bad Hamming code";
+
+       id = __raw_readl(EP93XX_SECURITY_UNIQID);
+       id2 = __raw_readl(EP93XX_SECURITY_UNIQID2);
+       id3 = __raw_readl(EP93XX_SECURITY_UNIQID3);
+       id4 = __raw_readl(EP93XX_SECURITY_UNIQID4);
+       id5 = __raw_readl(EP93XX_SECURITY_UNIQID5);
+
+       if (id != id2)
+               return "invalid";
+
+       snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id),
+                "%08x%08x%08x%08x", id2, id3, id4, id5);
+
+       return ep93xx_soc_id;
+}
+
+static const char __init *ep93xx_get_soc_rev(void)
+{
+       int rev = ep93xx_chip_revision();
+
+       switch (rev) {
+       case EP93XX_CHIP_REV_D0:
+               return "D0";
+       case EP93XX_CHIP_REV_D1:
+               return "D1";
+       case EP93XX_CHIP_REV_E0:
+               return "E0";
+       case EP93XX_CHIP_REV_E1:
+               return "E1";
+       case EP93XX_CHIP_REV_E2:
+               return "E2";
+       default:
+               return "unknown";
+       }
+}
+
+static const char __init *ep93xx_get_machine_name(void)
+{
+       return kasprintf(GFP_KERNEL,"%s", machine_desc->name);
+}
+
+static struct device __init *ep93xx_init_soc(void)
+{
+       struct soc_device_attribute *soc_dev_attr;
+       struct soc_device *soc_dev;
+
+       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+       if (!soc_dev_attr)
+               return NULL;
+
+       soc_dev_attr->machine = ep93xx_get_machine_name();
+       soc_dev_attr->family = "Cirrus Logic EP93xx";
+       soc_dev_attr->revision = ep93xx_get_soc_rev();
+       soc_dev_attr->soc_id = ep93xx_get_soc_id();
+
+       soc_dev = soc_device_register(soc_dev_attr);
+       if (IS_ERR(soc_dev)) {
+               kfree(soc_dev_attr->machine);
+               kfree(soc_dev_attr);
+               return NULL;
+       }
+
+       return soc_device_to_device(soc_dev);
+}
+
+struct device __init *ep93xx_init_devices(void)
+{
+       struct device *parent;
+
        /* Disallow access to MaverickCrunch initially */
        ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
 
@@ -937,6 +1039,8 @@ void __init ep93xx_init_devices(void)
                               EP93XX_SYSCON_DEVCFG_GONIDE |
                               EP93XX_SYSCON_DEVCFG_HONIDE);
 
+       parent = ep93xx_init_soc();
+
        /* Get the GPIO working early, other devices need it */
        platform_device_register(&ep93xx_gpio_device);
 
@@ -949,6 +1053,8 @@ void __init ep93xx_init_devices(void)
        platform_device_register(&ep93xx_wdt_device);
 
        gpio_led_register_device(-1, &ep93xx_led_data);
+
+       return parent;
 }
 
 void ep93xx_restart(enum reboot_mode mode, const char *cmd)
index e256e0baec2ec729344333d198004a637f20123f..4c0bbd97f741c7a6ab90de0260a77e9c4877fb82 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/reboot.h>
 
+struct device;
 struct i2c_gpio_platform_data;
 struct i2c_board_info;
 struct spi_board_info;
@@ -54,7 +55,7 @@ void ep93xx_register_ide(void);
 int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
 void ep93xx_ide_release_gpio(struct platform_device *pdev);
 
-void ep93xx_init_devices(void);
+struct device *ep93xx_init_devices(void);
 extern void ep93xx_timer_init(void);
 
 void ep93xx_restart(enum reboot_mode, const char *);
index 2739ca2c13346f1ed4bdce26916ae4e2270900ad..e0091685fd4861c8eb6f41b00c5f316865c1668b 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
+#include <video/vga.h>
 
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -196,6 +197,8 @@ void __init footbridge_map_io(void)
                iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
                pci_map_io_early(__phys_to_pfn(DC21285_PCI_IO));
        }
+
+       vga_base = PCIMEM_BASE;
 }
 
 void footbridge_restart(enum reboot_mode mode, const char *cmd)
index 3490a24f969e4a0b450ef146cee72f37e1cb6c9f..7c2fdae9a38b63454523277a005dcf6c5c1c65ab 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
-#include <video/vga.h>
 
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
@@ -291,7 +290,6 @@ void __init dc21285_preinit(void)
        int cfn_mode;
 
        pcibios_min_mem = 0x81000000;
-       vga_base = PCIMEM_BASE;
 
        mem_size = (unsigned int)high_memory - PAGE_OFFSET;
        for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)
index b08243500e2e9bc8f7196d6e6c5484b3ba7dadb4..1a7235fb52acb3cb8ae784dbeeda4fb3c940594a 100644 (file)
@@ -30,21 +30,24 @@ static const struct {
        const char *name;
        const char *trigger;
 } ebsa285_leds[] = {
-       { "ebsa285:amber", "heartbeat", },
-       { "ebsa285:green", "cpu0", },
+       { "ebsa285:amber", "cpu0", },
+       { "ebsa285:green", "heartbeat", },
        { "ebsa285:red",},
 };
 
+static unsigned char hw_led_state;
+
 static void ebsa285_led_set(struct led_classdev *cdev,
                enum led_brightness b)
 {
        struct ebsa285_led *led = container_of(cdev,
                        struct ebsa285_led, cdev);
 
-       if (b != LED_OFF)
-               *XBUS_LEDS |= led->mask;
+       if (b == LED_OFF)
+               hw_led_state |= led->mask;
        else
-               *XBUS_LEDS &= ~led->mask;
+               hw_led_state &= ~led->mask;
+       *XBUS_LEDS = hw_led_state;
 }
 
 static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
@@ -52,18 +55,19 @@ static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
        struct ebsa285_led *led = container_of(cdev,
                        struct ebsa285_led, cdev);
 
-       return (*XBUS_LEDS & led->mask) ? LED_FULL : LED_OFF;
+       return hw_led_state & led->mask ? LED_OFF : LED_FULL;
 }
 
 static int __init ebsa285_leds_init(void)
 {
        int i;
 
-       if (machine_is_ebsa285())
+       if (!machine_is_ebsa285())
                return -ENODEV;
 
-       /* 3 LEDS All ON */
-       *XBUS_LEDS |= XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED;
+       /* 3 LEDS all off */
+       hw_led_state = XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED;
+       *XBUS_LEDS = hw_led_state;
 
        for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) {
                struct ebsa285_led *led;
index 7a6e6f71006893a9c2a54d4a17166762c4647977..d511e05465466b3d11dff8f21f4b2175b36cf3fd 100644 (file)
@@ -11,6 +11,7 @@ config ARCH_MXC
        select GENERIC_IRQ_CHIP
        select MIGHT_HAVE_CACHE_L2X0 if ARCH_MULTI_V6_V7
        select MULTI_IRQ_HANDLER
+       select PINCTRL
        select SOC_BUS
        select SPARSE_IRQ
        select USE_OF
@@ -20,16 +21,6 @@ config ARCH_MXC
 menu "Freescale i.MX support"
        depends on ARCH_MXC
 
-config MXC_IRQ_PRIOR
-       bool "Use IRQ priority"
-       help
-         Select this if you want to use prioritized IRQ handling.
-         This feature prevents higher priority ISR to be interrupted
-         by lower priority IRQ.
-         This may be useful in embedded applications, where are strong
-         requirements for timing.
-         Say N here, unless you have a specialized requirement.
-
 config MXC_TZIC
        bool
 
@@ -109,6 +100,7 @@ config SOC_IMX25
        select ARCH_MXC_IOMUX_V3
        select CPU_ARM926T
        select MXC_AVIC
+       select PINCTRL_IMX25
 
 config SOC_IMX27
        bool
@@ -118,6 +110,7 @@ config SOC_IMX27
        select IMX_HAVE_IOMUX_V1
        select MACH_MX27
        select MXC_AVIC
+       select PINCTRL_IMX27
 
 config SOC_IMX31
        bool
@@ -145,7 +138,6 @@ config SOC_IMX5
 config SOC_IMX51
        bool
        select HAVE_IMX_SRC
-       select PINCTRL
        select PINCTRL_IMX51
        select SOC_IMX5
 
@@ -766,11 +758,19 @@ endchoice
 
 comment "Device tree only"
 
+config SOC_IMX50
+       bool "i.MX50 support"
+       select HAVE_IMX_SRC
+       select PINCTRL_IMX50
+       select SOC_IMX5
+
+       help
+         This enables support for Freescale i.MX50 processor.
+
 config SOC_IMX53
        bool "i.MX53 support"
        select HAVE_IMX_SRC
        select IMX_HAVE_PLATFORM_IMX2_WDT
-       select PINCTRL
        select PINCTRL_IMX53
        select SOC_IMX5
 
@@ -796,7 +796,6 @@ config SOC_IMX6Q
        select MFD_SYSCON
        select MIGHT_HAVE_PCI
        select PCI_DOMAINS if PCI
-       select PINCTRL
        select PINCTRL_IMX6Q
        select PL310_ERRATA_588369 if CACHE_PL310
        select PL310_ERRATA_727915 if CACHE_PL310
@@ -817,7 +816,6 @@ config SOC_IMX6SL
        select HAVE_IMX_MMDC
        select HAVE_IMX_SRC
        select MFD_SYSCON
-       select PINCTRL
        select PINCTRL_IMX6SL
        select PL310_ERRATA_588369 if CACHE_PL310
        select PL310_ERRATA_727915 if CACHE_PL310
@@ -831,7 +829,6 @@ config SOC_VF610
        select CPU_V7
        select ARM_GIC
        select CLKSRC_OF
-       select PINCTRL
        select PINCTRL_VF610
        select VF_PIT_TIMER
        select PL310_ERRATA_588369 if CACHE_PL310
index 1789e2b3190389f287a4ce79a747b17c1072a48d..0db16972839630f8c47fa7987f547bc66f1a9091 100644 (file)
@@ -112,6 +112,7 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += mach-cpuimx51sd.o
 obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd51-baseboard.o
 
 obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
+obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
 obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
 
 obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o
index e163ec7a8441170151493adc38146dadf4115b39..8d1df2e4b7ac23a5bea5a101342bd8fa313686b7 100644 (file)
 static void __iomem *avic_base;
 static struct irq_domain *domain;
 
-#ifdef CONFIG_MXC_IRQ_PRIOR
-static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
-{
-       struct irq_data *d = irq_get_irq_data(irq);
-       unsigned int temp;
-       unsigned int mask = 0x0F << irq % 8 * 4;
-
-       irq = d->hwirq;
-
-       if (irq >= AVIC_NUM_IRQS)
-               return -EINVAL;
-
-       temp = __raw_readl(avic_base + AVIC_NIPRIORITY(irq / 8));
-       temp &= ~mask;
-       temp |= prio & mask;
-
-       __raw_writel(temp, avic_base + AVIC_NIPRIORITY(irq / 8));
-
-       return 0;
-}
-#endif
-
 #ifdef CONFIG_FIQ
 static int avic_set_irq_fiq(unsigned int irq, unsigned int type)
 {
@@ -102,9 +80,6 @@ static int avic_set_irq_fiq(unsigned int irq, unsigned int type)
 
 
 static struct mxc_extra_irq avic_extra_irq = {
-#ifdef CONFIG_MXC_IRQ_PRIOR
-       .set_priority = avic_irq_set_priority,
-#endif
 #ifdef CONFIG_FIQ
        .set_irq_fiq = avic_set_irq_fiq,
 #endif
index ce37af26ff8c6931b62e9459d7ffb7df1daf81ab..e349fd5aab9bbd9d18da630c591198be7da6f12d 100644 (file)
 #include <linux/io.h>
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
-#include <linux/of.h>
 #include <linux/err.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <dt-bindings/clock/imx5-clock.h>
 
 #include "crm-regs-imx5.h"
 #include "clk.h"
@@ -83,50 +83,7 @@ static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_
 static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", };
 static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", };
 
-
-enum imx5_clks {
-       dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
-       uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s,
-       emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred,
-       usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di_unused,
-       tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate,
-       uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate,
-       gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate,
-       gpt_hf_gate, fec_gate, usboh3_per_gate, esdhc1_ipg_gate, esdhc2_ipg_gate,
-       esdhc3_ipg_gate, esdhc4_ipg_gate, ssi1_ipg_gate, ssi2_ipg_gate,
-       ssi3_ipg_gate, ecspi1_ipg_gate, ecspi1_per_gate, ecspi2_ipg_gate,
-       ecspi2_per_gate, cspi_ipg_gate, sdma_gate, emi_slow_gate, ipu_s,
-       ipu_gate, nfc_gate, ipu_di1_gate, vpu_s, vpu_gate,
-       vpu_reference_gate, uart4_ipg_gate, uart4_per_gate, uart5_ipg_gate,
-       uart5_per_gate, tve_gate, tve_pred, esdhc1_per_gate, esdhc2_per_gate,
-       esdhc3_per_gate, esdhc4_per_gate, usb_phy_gate, hsi2c_gate,
-       mipi_hsc1_gate, mipi_hsc2_gate, mipi_esc_gate, mipi_hsp_gate,
-       ldb_di1_div_3_5, ldb_di1_div, ldb_di0_div_3_5, ldb_di0_div,
-       ldb_di1_gate, can2_serial_gate, can2_ipg_gate, i2c3_gate, lp_apm,
-       periph_apm, main_bus, ahb_max, aips_tz1, aips_tz2, tmax1, tmax2,
-       tmax3, spba, uart_sel, esdhc_a_sel, esdhc_b_sel, esdhc_a_podf,
-       esdhc_b_podf, ecspi_sel, usboh3_sel, usb_phy_sel, iim_gate,
-       usboh3_gate, emi_fast_gate, ipu_di0_gate,gpc_dvfs, pll1_sw, pll2_sw,
-       pll3_sw, ipu_di0_sel, ipu_di1_sel, tve_ext_sel, mx51_mipi, pll4_sw,
-       ldb_di1_sel, di_pll4_podf, ldb_di0_sel, ldb_di0_gate, usb_phy1_gate,
-       usb_phy2_gate, per_lp_apm, per_pred1, per_pred2, per_podf, per_root,
-       ssi_apm, ssi1_root_sel, ssi2_root_sel, ssi3_root_sel, ssi_ext1_sel,
-       ssi_ext2_sel, ssi_ext1_com_sel, ssi_ext2_com_sel, ssi1_root_pred,
-       ssi1_root_podf, ssi2_root_pred, ssi2_root_podf, ssi_ext1_pred,
-       ssi_ext1_podf, ssi_ext2_pred, ssi_ext2_podf, ssi1_root_gate,
-       ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate,
-       epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate,
-       can_sel, can1_serial_gate, can1_ipg_gate,
-       owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate,
-       cko1_sel, cko1_podf, cko1,
-       cko2_sel, cko2_podf, cko2,
-       srtc_gate, pata_gate, sata_gate, spdif_xtal_sel, spdif0_sel,
-       spdif1_sel, spdif0_pred, spdif0_podf, spdif1_pred, spdif1_podf,
-       spdif0_com_s, spdif1_com_sel, spdif0_gate, spdif1_gate, spdif_ipg_gate,
-       ocram, clk_max
-};
-
-static struct clk *clk[clk_max];
+static struct clk *clk[IMX5_CLK_END];
 static struct clk_onecell_data clk_data;
 
 static void __init mx5_clocks_common_init(unsigned long rate_ckil,
@@ -135,235 +92,295 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
 {
        int i;
 
-       clk[dummy] = imx_clk_fixed("dummy", 0);
-       clk[ckil] = imx_obtain_fixed_clock("ckil", rate_ckil);
-       clk[osc] = imx_obtain_fixed_clock("osc", rate_osc);
-       clk[ckih1] = imx_obtain_fixed_clock("ckih1", rate_ckih1);
-       clk[ckih2] = imx_obtain_fixed_clock("ckih2", rate_ckih2);
-
-       clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
-                               lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
-       clk[periph_apm] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2,
-                               periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
-       clk[main_bus] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1,
-                               main_bus_sel, ARRAY_SIZE(main_bus_sel));
-       clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1,
-                               per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
-       clk[per_pred1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2);
-       clk[per_pred2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3);
-       clk[per_podf] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3);
-       clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1,
-                               per_root_sel, ARRAY_SIZE(per_root_sel));
-       clk[ahb] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3);
-       clk[ahb_max] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28);
-       clk[aips_tz1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24);
-       clk[aips_tz2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26);
-       clk[tmax1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0);
-       clk[tmax2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2);
-       clk[tmax3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4);
-       clk[spba] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0);
-       clk[ipg] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2);
-       clk[axi_a] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3);
-       clk[axi_b] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3);
-       clk[uart_sel] = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2,
-                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-       clk[uart_pred] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3);
-       clk[uart_root] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3);
-
-       clk[esdhc_a_sel] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2,
-                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-       clk[esdhc_b_sel] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
-                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-       clk[esdhc_a_pred] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3);
-       clk[esdhc_a_podf] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3);
-       clk[esdhc_b_pred] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3);
-       clk[esdhc_b_podf] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3);
-       clk[esdhc_c_s] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
-       clk[esdhc_d_s] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
-
-       clk[emi_sel] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1,
-                               emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
-       clk[emi_slow_podf] = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3);
-       clk[nfc_podf] = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3);
-       clk[ecspi_sel] = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2,
-                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-       clk[ecspi_pred] = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3);
-       clk[ecspi_podf] = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6);
-       clk[usboh3_sel] = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2,
-                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
-       clk[usboh3_pred] = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3);
-       clk[usboh3_podf] = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2);
-       clk[usb_phy_pred] = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3);
-       clk[usb_phy_podf] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3);
-       clk[usb_phy_sel] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1,
-                               usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
-       clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3);
-       clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
-       clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
-       clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
-       clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
-       clk[uart2_ipg_gate] = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10);
-       clk[uart2_per_gate] = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12);
-       clk[uart3_ipg_gate] = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14);
-       clk[uart3_per_gate] = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16);
-       clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18);
-       clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20);
-       clk[pwm1_ipg_gate] = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10);
-       clk[pwm1_hf_gate] = imx_clk_gate2("pwm1_hf_gate", "per_root", MXC_CCM_CCGR2, 12);
-       clk[pwm2_ipg_gate] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14);
-       clk[pwm2_hf_gate] = imx_clk_gate2("pwm2_hf_gate", "per_root", MXC_CCM_CCGR2, 16);
-       clk[gpt_ipg_gate] = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 18);
-       clk[gpt_hf_gate] = imx_clk_gate2("gpt_hf_gate", "per_root", MXC_CCM_CCGR2, 20);
-       clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24);
-       clk[usboh3_gate] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26);
-       clk[usboh3_per_gate] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28);
-       clk[esdhc1_ipg_gate] = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0);
-       clk[esdhc2_ipg_gate] = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4);
-       clk[esdhc3_ipg_gate] = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8);
-       clk[esdhc4_ipg_gate] = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12);
-       clk[ssi1_ipg_gate] = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16);
-       clk[ssi2_ipg_gate] = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20);
-       clk[ssi3_ipg_gate] = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24);
-       clk[ecspi1_ipg_gate] = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18);
-       clk[ecspi1_per_gate] = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20);
-       clk[ecspi2_ipg_gate] = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22);
-       clk[ecspi2_per_gate] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24);
-       clk[cspi_ipg_gate] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26);
-       clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30);
-       clk[emi_fast_gate] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14);
-       clk[emi_slow_gate] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16);
-       clk[ipu_s] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
-       clk[ipu_gate] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10);
-       clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
-       clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
-       clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
-       clk[gpu3d_s] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel));
-       clk[gpu2d_s] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel));
-       clk[gpu3d_gate] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2);
-       clk[garb_gate] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4);
-       clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14);
-       clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
-       clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
-       clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
-       clk[uart4_ipg_gate] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
-       clk[uart4_per_gate] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
-       clk[uart5_ipg_gate] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
-       clk[uart5_per_gate] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
-       clk[gpc_dvfs] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24);
-
-       clk[ssi_apm] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels));
-       clk[ssi1_root_sel] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
-       clk[ssi2_root_sel] = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
-       clk[ssi3_root_sel] = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels));
-       clk[ssi_ext1_sel] = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
-       clk[ssi_ext2_sel] = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
-       clk[ssi_ext1_com_sel] = imx_clk_mux("ssi_ext1_com_sel", MXC_CCM_CSCMR1, 0, 1, ssi_ext1_com_sels, ARRAY_SIZE(ssi_ext1_com_sels));
-       clk[ssi_ext2_com_sel] = imx_clk_mux("ssi_ext2_com_sel", MXC_CCM_CSCMR1, 1, 1, ssi_ext2_com_sels, ARRAY_SIZE(ssi_ext2_com_sels));
-       clk[ssi1_root_pred] = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3);
-       clk[ssi1_root_podf] = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6);
-       clk[ssi2_root_pred] = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3);
-       clk[ssi2_root_podf] = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6);
-       clk[ssi_ext1_pred] = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3);
-       clk[ssi_ext1_podf] = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6);
-       clk[ssi_ext2_pred] = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3);
-       clk[ssi_ext2_podf] = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6);
-       clk[ssi1_root_gate] = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18);
-       clk[ssi2_root_gate] = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22);
-       clk[ssi3_root_gate] = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26);
-       clk[ssi_ext1_gate] = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28);
-       clk[ssi_ext2_gate] = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30);
-       clk[epit1_ipg_gate] = imx_clk_gate2("epit1_ipg_gate", "ipg", MXC_CCM_CCGR2, 2);
-       clk[epit1_hf_gate] = imx_clk_gate2("epit1_hf_gate", "per_root", MXC_CCM_CCGR2, 4);
-       clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6);
-       clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8);
-       clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
-       clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
-       clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
-       clk[spdif0_sel] = imx_clk_mux("spdif0_sel", MXC_CCM_CSCMR2, 0, 2, spdif_sel, ARRAY_SIZE(spdif_sel));
-       clk[spdif0_pred] = imx_clk_divider("spdif0_pred", "spdif0_sel", MXC_CCM_CDCDR, 25, 3);
-       clk[spdif0_podf] = imx_clk_divider("spdif0_podf", "spdif0_pred", MXC_CCM_CDCDR, 19, 6);
-       clk[spdif0_com_s] = imx_clk_mux_flags("spdif0_com_sel", MXC_CCM_CSCMR2, 4, 1,
-                               spdif0_com_sel, ARRAY_SIZE(spdif0_com_sel), CLK_SET_RATE_PARENT);
-       clk[spdif0_gate] = imx_clk_gate2("spdif0_gate", "spdif0_com_sel", MXC_CCM_CCGR5, 26);
-       clk[spdif_ipg_gate] = imx_clk_gate2("spdif_ipg_gate", "ipg", MXC_CCM_CCGR5, 30);
+       clk[IMX5_CLK_DUMMY]             = imx_clk_fixed("dummy", 0);
+       clk[IMX5_CLK_CKIL]              = imx_obtain_fixed_clock("ckil", rate_ckil);
+       clk[IMX5_CLK_OSC]               = imx_obtain_fixed_clock("osc", rate_osc);
+       clk[IMX5_CLK_CKIH1]             = imx_obtain_fixed_clock("ckih1", rate_ckih1);
+       clk[IMX5_CLK_CKIH2]             = imx_obtain_fixed_clock("ckih2", rate_ckih2);
+
+       clk[IMX5_CLK_PERIPH_APM]        = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2,
+                                               periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
+       clk[IMX5_CLK_MAIN_BUS]          = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1,
+                                               main_bus_sel, ARRAY_SIZE(main_bus_sel));
+       clk[IMX5_CLK_PER_LP_APM]        = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1,
+                                               per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
+       clk[IMX5_CLK_PER_PRED1]         = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2);
+       clk[IMX5_CLK_PER_PRED2]         = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3);
+       clk[IMX5_CLK_PER_PODF]          = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3);
+       clk[IMX5_CLK_PER_ROOT]          = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1,
+                                               per_root_sel, ARRAY_SIZE(per_root_sel));
+       clk[IMX5_CLK_AHB]               = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3);
+       clk[IMX5_CLK_AHB_MAX]           = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28);
+       clk[IMX5_CLK_AIPS_TZ1]          = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24);
+       clk[IMX5_CLK_AIPS_TZ2]          = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26);
+       clk[IMX5_CLK_TMAX1]             = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0);
+       clk[IMX5_CLK_TMAX2]             = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2);
+       clk[IMX5_CLK_TMAX3]             = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4);
+       clk[IMX5_CLK_SPBA]              = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0);
+       clk[IMX5_CLK_IPG]               = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2);
+       clk[IMX5_CLK_AXI_A]             = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3);
+       clk[IMX5_CLK_AXI_B]             = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3);
+       clk[IMX5_CLK_UART_SEL]          = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2,
+                                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+       clk[IMX5_CLK_UART_PRED]         = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3);
+       clk[IMX5_CLK_UART_ROOT]         = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3);
+
+       clk[IMX5_CLK_ESDHC_A_SEL]       = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2,
+                                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+       clk[IMX5_CLK_ESDHC_B_SEL]       = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
+                                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+       clk[IMX5_CLK_ESDHC_A_PRED]      = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3);
+       clk[IMX5_CLK_ESDHC_A_PODF]      = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3);
+       clk[IMX5_CLK_ESDHC_B_PRED]      = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3);
+       clk[IMX5_CLK_ESDHC_B_PODF]      = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3);
+       clk[IMX5_CLK_ESDHC_C_SEL]       = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
+       clk[IMX5_CLK_ESDHC_D_SEL]       = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
+
+       clk[IMX5_CLK_EMI_SEL]           = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1,
+                                               emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
+       clk[IMX5_CLK_EMI_SLOW_PODF]     = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3);
+       clk[IMX5_CLK_NFC_PODF]          = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3);
+       clk[IMX5_CLK_ECSPI_SEL]         = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2,
+                                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+       clk[IMX5_CLK_ECSPI_PRED]        = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3);
+       clk[IMX5_CLK_ECSPI_PODF]        = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6);
+       clk[IMX5_CLK_USBOH3_SEL]        = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2,
+                                               standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+       clk[IMX5_CLK_USBOH3_PRED]       = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3);
+       clk[IMX5_CLK_USBOH3_PODF]       = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2);
+       clk[IMX5_CLK_USB_PHY_PRED]      = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3);
+       clk[IMX5_CLK_USB_PHY_PODF]      = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3);
+       clk[IMX5_CLK_USB_PHY_SEL]       = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1,
+                                               usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
+       clk[IMX5_CLK_CPU_PODF]          = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3);
+       clk[IMX5_CLK_DI_PRED]           = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
+       clk[IMX5_CLK_IIM_GATE]          = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
+       clk[IMX5_CLK_UART1_IPG_GATE]    = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
+       clk[IMX5_CLK_UART1_PER_GATE]    = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
+       clk[IMX5_CLK_UART2_IPG_GATE]    = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10);
+       clk[IMX5_CLK_UART2_PER_GATE]    = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12);
+       clk[IMX5_CLK_UART3_IPG_GATE]    = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14);
+       clk[IMX5_CLK_UART3_PER_GATE]    = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16);
+       clk[IMX5_CLK_I2C1_GATE]         = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18);
+       clk[IMX5_CLK_I2C2_GATE]         = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20);
+       clk[IMX5_CLK_PWM1_IPG_GATE]     = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10);
+       clk[IMX5_CLK_PWM1_HF_GATE]      = imx_clk_gate2("pwm1_hf_gate", "per_root", MXC_CCM_CCGR2, 12);
+       clk[IMX5_CLK_PWM2_IPG_GATE]     = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14);
+       clk[IMX5_CLK_PWM2_HF_GATE]      = imx_clk_gate2("pwm2_hf_gate", "per_root", MXC_CCM_CCGR2, 16);
+       clk[IMX5_CLK_GPT_IPG_GATE]      = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 18);
+       clk[IMX5_CLK_GPT_HF_GATE]       = imx_clk_gate2("gpt_hf_gate", "per_root", MXC_CCM_CCGR2, 20);
+       clk[IMX5_CLK_FEC_GATE]          = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24);
+       clk[IMX5_CLK_USBOH3_GATE]       = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26);
+       clk[IMX5_CLK_USBOH3_PER_GATE]   = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28);
+       clk[IMX5_CLK_ESDHC1_IPG_GATE]   = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0);
+       clk[IMX5_CLK_ESDHC2_IPG_GATE]   = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4);
+       clk[IMX5_CLK_ESDHC3_IPG_GATE]   = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8);
+       clk[IMX5_CLK_ESDHC4_IPG_GATE]   = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12);
+       clk[IMX5_CLK_SSI1_IPG_GATE]     = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16);
+       clk[IMX5_CLK_SSI2_IPG_GATE]     = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20);
+       clk[IMX5_CLK_SSI3_IPG_GATE]     = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24);
+       clk[IMX5_CLK_ECSPI1_IPG_GATE]   = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18);
+       clk[IMX5_CLK_ECSPI1_PER_GATE]   = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20);
+       clk[IMX5_CLK_ECSPI2_IPG_GATE]   = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22);
+       clk[IMX5_CLK_ECSPI2_PER_GATE]   = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24);
+       clk[IMX5_CLK_CSPI_IPG_GATE]     = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26);
+       clk[IMX5_CLK_SDMA_GATE]         = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30);
+       clk[IMX5_CLK_EMI_FAST_GATE]     = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14);
+       clk[IMX5_CLK_EMI_SLOW_GATE]     = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16);
+       clk[IMX5_CLK_IPU_SEL]           = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
+       clk[IMX5_CLK_IPU_GATE]          = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10);
+       clk[IMX5_CLK_NFC_GATE]          = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
+       clk[IMX5_CLK_IPU_DI0_GATE]      = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
+       clk[IMX5_CLK_IPU_DI1_GATE]      = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
+       clk[IMX5_CLK_GPU3D_SEL]         = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel));
+       clk[IMX5_CLK_GPU2D_SEL]         = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel));
+       clk[IMX5_CLK_GPU3D_GATE]        = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2);
+       clk[IMX5_CLK_GARB_GATE]         = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4);
+       clk[IMX5_CLK_GPU2D_GATE]        = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14);
+       clk[IMX5_CLK_VPU_SEL]           = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
+       clk[IMX5_CLK_VPU_GATE]          = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
+       clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
+       clk[IMX5_CLK_UART4_IPG_GATE]    = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
+       clk[IMX5_CLK_UART4_PER_GATE]    = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
+       clk[IMX5_CLK_UART5_IPG_GATE]    = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
+       clk[IMX5_CLK_UART5_PER_GATE]    = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
+       clk[IMX5_CLK_GPC_DVFS]          = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24);
+
+       clk[IMX5_CLK_SSI_APM]           = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels));
+       clk[IMX5_CLK_SSI1_ROOT_SEL]     = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+       clk[IMX5_CLK_SSI2_ROOT_SEL]     = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+       clk[IMX5_CLK_SSI3_ROOT_SEL]     = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels));
+       clk[IMX5_CLK_SSI_EXT1_SEL]      = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+       clk[IMX5_CLK_SSI_EXT2_SEL]      = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+       clk[IMX5_CLK_SSI_EXT1_COM_SEL]  = imx_clk_mux("ssi_ext1_com_sel", MXC_CCM_CSCMR1, 0, 1, ssi_ext1_com_sels, ARRAY_SIZE(ssi_ext1_com_sels));
+       clk[IMX5_CLK_SSI_EXT2_COM_SEL]  = imx_clk_mux("ssi_ext2_com_sel", MXC_CCM_CSCMR1, 1, 1, ssi_ext2_com_sels, ARRAY_SIZE(ssi_ext2_com_sels));
+       clk[IMX5_CLK_SSI1_ROOT_PRED]    = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3);
+       clk[IMX5_CLK_SSI1_ROOT_PODF]    = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6);
+       clk[IMX5_CLK_SSI2_ROOT_PRED]    = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3);
+       clk[IMX5_CLK_SSI2_ROOT_PODF]    = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6);
+       clk[IMX5_CLK_SSI_EXT1_PRED]     = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3);
+       clk[IMX5_CLK_SSI_EXT1_PODF]     = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6);
+       clk[IMX5_CLK_SSI_EXT2_PRED]     = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3);
+       clk[IMX5_CLK_SSI_EXT2_PODF]     = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6);
+       clk[IMX5_CLK_SSI1_ROOT_GATE]    = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18);
+       clk[IMX5_CLK_SSI2_ROOT_GATE]    = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22);
+       clk[IMX5_CLK_SSI3_ROOT_GATE]    = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26);
+       clk[IMX5_CLK_SSI_EXT1_GATE]     = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28);
+       clk[IMX5_CLK_SSI_EXT2_GATE]     = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30);
+       clk[IMX5_CLK_EPIT1_IPG_GATE]    = imx_clk_gate2("epit1_ipg_gate", "ipg", MXC_CCM_CCGR2, 2);
+       clk[IMX5_CLK_EPIT1_HF_GATE]     = imx_clk_gate2("epit1_hf_gate", "per_root", MXC_CCM_CCGR2, 4);
+       clk[IMX5_CLK_EPIT2_IPG_GATE]    = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6);
+       clk[IMX5_CLK_EPIT2_HF_GATE]     = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8);
+       clk[IMX5_CLK_OWIRE_GATE]        = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
+       clk[IMX5_CLK_SRTC_GATE]         = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
+       clk[IMX5_CLK_PATA_GATE]         = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
+       clk[IMX5_CLK_SPDIF0_SEL]        = imx_clk_mux("spdif0_sel", MXC_CCM_CSCMR2, 0, 2, spdif_sel, ARRAY_SIZE(spdif_sel));
+       clk[IMX5_CLK_SPDIF0_PRED]       = imx_clk_divider("spdif0_pred", "spdif0_sel", MXC_CCM_CDCDR, 25, 3);
+       clk[IMX5_CLK_SPDIF0_PODF]       = imx_clk_divider("spdif0_podf", "spdif0_pred", MXC_CCM_CDCDR, 19, 6);
+       clk[IMX5_CLK_SPDIF0_COM_SEL]    = imx_clk_mux_flags("spdif0_com_sel", MXC_CCM_CSCMR2, 4, 1,
+                                               spdif0_com_sel, ARRAY_SIZE(spdif0_com_sel), CLK_SET_RATE_PARENT);
+       clk[IMX5_CLK_SPDIF0_GATE]       = imx_clk_gate2("spdif0_gate", "spdif0_com_sel", MXC_CCM_CCGR5, 26);
+       clk[IMX5_CLK_SPDIF_IPG_GATE]    = imx_clk_gate2("spdif_ipg_gate", "ipg", MXC_CCM_CCGR5, 30);
+       clk[IMX5_CLK_SAHARA_IPG_GATE]   = imx_clk_gate2("sahara_ipg_gate", "ipg", MXC_CCM_CCGR4, 14);
+       clk[IMX5_CLK_SATA_REF]          = imx_clk_fixed_factor("sata_ref", "usb_phy1_gate", 1, 1);
 
        for (i = 0; i < ARRAY_SIZE(clk); i++)
                if (IS_ERR(clk[i]))
                        pr_err("i.MX5 clk %d: register failed with %ld\n",
                                i, PTR_ERR(clk[i]));
 
-       clk_register_clkdev(clk[gpt_hf_gate], "per", "imx-gpt.0");
-       clk_register_clkdev(clk[gpt_ipg_gate], "ipg", "imx-gpt.0");
-       clk_register_clkdev(clk[uart1_per_gate], "per", "imx21-uart.0");
-       clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0");
-       clk_register_clkdev(clk[uart2_per_gate], "per", "imx21-uart.1");
-       clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1");
-       clk_register_clkdev(clk[uart3_per_gate], "per", "imx21-uart.2");
-       clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2");
-       clk_register_clkdev(clk[uart4_per_gate], "per", "imx21-uart.3");
-       clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3");
-       clk_register_clkdev(clk[uart5_per_gate], "per", "imx21-uart.4");
-       clk_register_clkdev(clk[uart5_ipg_gate], "ipg", "imx21-uart.4");
-       clk_register_clkdev(clk[ecspi1_per_gate], "per", "imx51-ecspi.0");
-       clk_register_clkdev(clk[ecspi1_ipg_gate], "ipg", "imx51-ecspi.0");
-       clk_register_clkdev(clk[ecspi2_per_gate], "per", "imx51-ecspi.1");
-       clk_register_clkdev(clk[ecspi2_ipg_gate], "ipg", "imx51-ecspi.1");
-       clk_register_clkdev(clk[cspi_ipg_gate], NULL, "imx35-cspi.2");
-       clk_register_clkdev(clk[pwm1_ipg_gate], "pwm", "mxc_pwm.0");
-       clk_register_clkdev(clk[pwm2_ipg_gate], "pwm", "mxc_pwm.1");
-       clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0");
-       clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1");
-       clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.0");
-       clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.0");
-       clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.0");
-       clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.1");
-       clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.1");
-       clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.1");
-       clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2");
-       clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2");
-       clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2");
-       clk_register_clkdev(clk[usboh3_per_gate], "per", "imx-udc-mx51");
-       clk_register_clkdev(clk[usboh3_gate], "ipg", "imx-udc-mx51");
-       clk_register_clkdev(clk[usboh3_gate], "ahb", "imx-udc-mx51");
-       clk_register_clkdev(clk[nfc_gate], NULL, "imx51-nand");
-       clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
-       clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
-       clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2");
-       clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
-       clk_register_clkdev(clk[cpu_podf], NULL, "cpu0");
-       clk_register_clkdev(clk[iim_gate], "iim", NULL);
-       clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
-       clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
-       clk_register_clkdev(clk[dummy], NULL, "imx-keypad");
-       clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0");
-       clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL);
-       clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0");
-       clk_register_clkdev(clk[epit1_hf_gate], "per", "imx-epit.0");
-       clk_register_clkdev(clk[epit2_ipg_gate], "ipg", "imx-epit.1");
-       clk_register_clkdev(clk[epit2_hf_gate], "per", "imx-epit.1");
+       clk_register_clkdev(clk[IMX5_CLK_GPT_HF_GATE], "per", "imx-gpt.0");
+       clk_register_clkdev(clk[IMX5_CLK_GPT_IPG_GATE], "ipg", "imx-gpt.0");
+       clk_register_clkdev(clk[IMX5_CLK_UART1_PER_GATE], "per", "imx21-uart.0");
+       clk_register_clkdev(clk[IMX5_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0");
+       clk_register_clkdev(clk[IMX5_CLK_UART2_PER_GATE], "per", "imx21-uart.1");
+       clk_register_clkdev(clk[IMX5_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1");
+       clk_register_clkdev(clk[IMX5_CLK_UART3_PER_GATE], "per", "imx21-uart.2");
+       clk_register_clkdev(clk[IMX5_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2");
+       clk_register_clkdev(clk[IMX5_CLK_UART4_PER_GATE], "per", "imx21-uart.3");
+       clk_register_clkdev(clk[IMX5_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3");
+       clk_register_clkdev(clk[IMX5_CLK_UART5_PER_GATE], "per", "imx21-uart.4");
+       clk_register_clkdev(clk[IMX5_CLK_UART5_IPG_GATE], "ipg", "imx21-uart.4");
+       clk_register_clkdev(clk[IMX5_CLK_ECSPI1_PER_GATE], "per", "imx51-ecspi.0");
+       clk_register_clkdev(clk[IMX5_CLK_ECSPI1_IPG_GATE], "ipg", "imx51-ecspi.0");
+       clk_register_clkdev(clk[IMX5_CLK_ECSPI2_PER_GATE], "per", "imx51-ecspi.1");
+       clk_register_clkdev(clk[IMX5_CLK_ECSPI2_IPG_GATE], "ipg", "imx51-ecspi.1");
+       clk_register_clkdev(clk[IMX5_CLK_CSPI_IPG_GATE], NULL, "imx35-cspi.2");
+       clk_register_clkdev(clk[IMX5_CLK_PWM1_IPG_GATE], "pwm", "mxc_pwm.0");
+       clk_register_clkdev(clk[IMX5_CLK_PWM2_IPG_GATE], "pwm", "mxc_pwm.1");
+       clk_register_clkdev(clk[IMX5_CLK_I2C1_GATE], NULL, "imx21-i2c.0");
+       clk_register_clkdev(clk[IMX5_CLK_I2C2_GATE], NULL, "imx21-i2c.1");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_PER_GATE], "per", "mxc-ehci.0");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ipg", "mxc-ehci.0");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ahb", "mxc-ehci.0");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_PER_GATE], "per", "mxc-ehci.1");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ipg", "mxc-ehci.1");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ahb", "mxc-ehci.1");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_PER_GATE], "per", "mxc-ehci.2");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ipg", "mxc-ehci.2");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ahb", "mxc-ehci.2");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_PER_GATE], "per", "imx-udc-mx51");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ipg", "imx-udc-mx51");
+       clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ahb", "imx-udc-mx51");
+       clk_register_clkdev(clk[IMX5_CLK_NFC_GATE], NULL, "imx51-nand");
+       clk_register_clkdev(clk[IMX5_CLK_SSI1_IPG_GATE], NULL, "imx-ssi.0");
+       clk_register_clkdev(clk[IMX5_CLK_SSI2_IPG_GATE], NULL, "imx-ssi.1");
+       clk_register_clkdev(clk[IMX5_CLK_SSI3_IPG_GATE], NULL, "imx-ssi.2");
+       clk_register_clkdev(clk[IMX5_CLK_SDMA_GATE], NULL, "imx35-sdma");
+       clk_register_clkdev(clk[IMX5_CLK_CPU_PODF], NULL, "cpu0");
+       clk_register_clkdev(clk[IMX5_CLK_IIM_GATE], "iim", NULL);
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], NULL, "imx2-wdt.0");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], NULL, "imx2-wdt.1");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], NULL, "imx-keypad");
+       clk_register_clkdev(clk[IMX5_CLK_IPU_DI1_GATE], "di1", "imx-tve.0");
+       clk_register_clkdev(clk[IMX5_CLK_GPC_DVFS], "gpc_dvfs", NULL);
+       clk_register_clkdev(clk[IMX5_CLK_EPIT1_IPG_GATE], "ipg", "imx-epit.0");
+       clk_register_clkdev(clk[IMX5_CLK_EPIT1_HF_GATE], "per", "imx-epit.0");
+       clk_register_clkdev(clk[IMX5_CLK_EPIT2_IPG_GATE], "ipg", "imx-epit.1");
+       clk_register_clkdev(clk[IMX5_CLK_EPIT2_HF_GATE], "per", "imx-epit.1");
 
        /* Set SDHC parents to be PLL2 */
-       clk_set_parent(clk[esdhc_a_sel], clk[pll2_sw]);
-       clk_set_parent(clk[esdhc_b_sel], clk[pll2_sw]);
+       clk_set_parent(clk[IMX5_CLK_ESDHC_A_SEL], clk[IMX5_CLK_PLL2_SW]);
+       clk_set_parent(clk[IMX5_CLK_ESDHC_B_SEL], clk[IMX5_CLK_PLL2_SW]);
 
        /* move usb phy clk to 24MHz */
-       clk_set_parent(clk[usb_phy_sel], clk[osc]);
-
-       clk_prepare_enable(clk[gpc_dvfs]);
-       clk_prepare_enable(clk[ahb_max]); /* esdhc3 */
-       clk_prepare_enable(clk[aips_tz1]);
-       clk_prepare_enable(clk[aips_tz2]); /* fec */
-       clk_prepare_enable(clk[spba]);
-       clk_prepare_enable(clk[emi_fast_gate]); /* fec */
-       clk_prepare_enable(clk[emi_slow_gate]); /* eim */
-       clk_prepare_enable(clk[mipi_hsc1_gate]);
-       clk_prepare_enable(clk[mipi_hsc2_gate]);
-       clk_prepare_enable(clk[mipi_esc_gate]);
-       clk_prepare_enable(clk[mipi_hsp_gate]);
-       clk_prepare_enable(clk[tmax1]);
-       clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */
-       clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */
+       clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]);
+
+       clk_prepare_enable(clk[IMX5_CLK_GPC_DVFS]);
+       clk_prepare_enable(clk[IMX5_CLK_AHB_MAX]); /* esdhc3 */
+       clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ1]);
+       clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ2]); /* fec */
+       clk_prepare_enable(clk[IMX5_CLK_SPBA]);
+       clk_prepare_enable(clk[IMX5_CLK_EMI_FAST_GATE]); /* fec */
+       clk_prepare_enable(clk[IMX5_CLK_EMI_SLOW_GATE]); /* eim */
+       clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC1_GATE]);
+       clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC2_GATE]);
+       clk_prepare_enable(clk[IMX5_CLK_MIPI_ESC_GATE]);
+       clk_prepare_enable(clk[IMX5_CLK_MIPI_HSP_GATE]);
+       clk_prepare_enable(clk[IMX5_CLK_TMAX1]);
+       clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */
+       clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */
+}
+
+static void __init mx50_clocks_init(struct device_node *np)
+{
+       void __iomem *base;
+       unsigned long r;
+       int i, irq;
+
+       clk[IMX5_CLK_PLL1_SW]           = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE);
+       clk[IMX5_CLK_PLL2_SW]           = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE);
+       clk[IMX5_CLK_PLL3_SW]           = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
+
+       clk[IMX5_CLK_LP_APM]            = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1,
+                                               lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+       clk[IMX5_CLK_ESDHC1_PER_GATE]   = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+       clk[IMX5_CLK_ESDHC2_PER_GATE]   = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
+       clk[IMX5_CLK_ESDHC3_PER_GATE]   = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
+       clk[IMX5_CLK_ESDHC4_PER_GATE]   = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+       clk[IMX5_CLK_USB_PHY1_GATE]     = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
+       clk[IMX5_CLK_USB_PHY2_GATE]     = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
+       clk[IMX5_CLK_I2C3_GATE]         = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
+
+       clk[IMX5_CLK_CKO1_SEL]          = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
+                                               mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
+       clk[IMX5_CLK_CKO1_PODF]         = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
+       clk[IMX5_CLK_CKO1]              = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
+
+       clk[IMX5_CLK_CKO2_SEL]          = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
+                                               mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
+       clk[IMX5_CLK_CKO2_PODF]         = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
+       clk[IMX5_CLK_CKO2]              = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
+
+       for (i = 0; i < ARRAY_SIZE(clk); i++)
+               if (IS_ERR(clk[i]))
+                       pr_err("i.MX50 clk %d: register failed with %ld\n",
+                               i, PTR_ERR(clk[i]));
+
+       clk_data.clks = clk;
+       clk_data.clk_num = ARRAY_SIZE(clk);
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+       mx5_clocks_common_init(0, 0, 0, 0);
+
+       /* set SDHC root clock to 200MHZ*/
+       clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000);
+       clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000);
+
+       clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
+       imx_print_silicon_rev("i.MX50", IMX_CHIP_REVISION_1_1);
+       clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
+
+       r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
+       clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx50-gpt");
+       base = of_iomap(np, 0);
+       WARN_ON(!base);
+       irq = irq_of_parse_and_map(np, 0);
+       mxc_timer_init(base, irq);
 }
+CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init);
 
 int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
                        unsigned long rate_ckih1, unsigned long rate_ckih2)
@@ -372,38 +389,40 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
        u32 val;
        struct device_node *np;
 
-       clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE);
-       clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX51_DPLL2_BASE);
-       clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX51_DPLL3_BASE);
-       clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
-                               mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
-       clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
-                               mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
-       clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
-                               mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
-       clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
-                               mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
-       clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
-       clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
-       clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
-       clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6);
-       clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10);
-       clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
-       clk[usb_phy_gate] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
-       clk[hsi2c_gate] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
-       clk[mipi_hsc1_gate] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6);
-       clk[mipi_hsc2_gate] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8);
-       clk[mipi_esc_gate] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10);
-       clk[mipi_hsp_gate] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12);
-       clk[spdif_xtal_sel] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
-                               mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel));
-       clk[spdif1_sel] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2,
-                               spdif_sel, ARRAY_SIZE(spdif_sel));
-       clk[spdif1_pred] = imx_clk_divider("spdif1_pred", "spdif1_sel", MXC_CCM_CDCDR, 16, 3);
-       clk[spdif1_podf] = imx_clk_divider("spdif1_podf", "spdif1_pred", MXC_CCM_CDCDR, 9, 6);
-       clk[spdif1_com_sel] = imx_clk_mux("spdif1_com_sel", MXC_CCM_CSCMR2, 5, 1,
-                               mx51_spdif1_com_sel, ARRAY_SIZE(mx51_spdif1_com_sel));
-       clk[spdif1_gate] = imx_clk_gate2("spdif1_gate", "spdif1_com_sel", MXC_CCM_CCGR5, 28);
+       clk[IMX5_CLK_PLL1_SW]           = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE);
+       clk[IMX5_CLK_PLL2_SW]           = imx_clk_pllv2("pll2_sw", "osc", MX51_DPLL2_BASE);
+       clk[IMX5_CLK_PLL3_SW]           = imx_clk_pllv2("pll3_sw", "osc", MX51_DPLL3_BASE);
+       clk[IMX5_CLK_LP_APM]            = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
+                                               lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+       clk[IMX5_CLK_IPU_DI0_SEL]       = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
+                                               mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
+       clk[IMX5_CLK_IPU_DI1_SEL]       = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
+                                               mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
+       clk[IMX5_CLK_TVE_EXT_SEL]       = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
+                                               mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
+       clk[IMX5_CLK_TVE_SEL]           = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
+                                               mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
+       clk[IMX5_CLK_TVE_GATE]          = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
+       clk[IMX5_CLK_TVE_PRED]          = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
+       clk[IMX5_CLK_ESDHC1_PER_GATE]   = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+       clk[IMX5_CLK_ESDHC2_PER_GATE]   = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6);
+       clk[IMX5_CLK_ESDHC3_PER_GATE]   = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10);
+       clk[IMX5_CLK_ESDHC4_PER_GATE]   = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+       clk[IMX5_CLK_USB_PHY_GATE]      = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
+       clk[IMX5_CLK_HSI2C_GATE]        = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
+       clk[IMX5_CLK_MIPI_HSC1_GATE]    = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6);
+       clk[IMX5_CLK_MIPI_HSC2_GATE]    = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8);
+       clk[IMX5_CLK_MIPI_ESC_GATE]     = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10);
+       clk[IMX5_CLK_MIPI_HSP_GATE]     = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12);
+       clk[IMX5_CLK_SPDIF_XTAL_SEL]    = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
+                                               mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel));
+       clk[IMX5_CLK_SPDIF1_SEL]        = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2,
+                                               spdif_sel, ARRAY_SIZE(spdif_sel));
+       clk[IMX5_CLK_SPDIF1_PRED]       = imx_clk_divider("spdif1_pred", "spdif1_sel", MXC_CCM_CDCDR, 16, 3);
+       clk[IMX5_CLK_SPDIF1_PODF]       = imx_clk_divider("spdif1_podf", "spdif1_pred", MXC_CCM_CDCDR, 9, 6);
+       clk[IMX5_CLK_SPDIF1_COM_SEL]    = imx_clk_mux("spdif1_com_sel", MXC_CCM_CSCMR2, 5, 1,
+                                               mx51_spdif1_com_sel, ARRAY_SIZE(mx51_spdif1_com_sel));
+       clk[IMX5_CLK_SPDIF1_GATE]       = imx_clk_gate2("spdif1_gate", "spdif1_com_sel", MXC_CCM_CCGR5, 28);
 
        for (i = 0; i < ARRAY_SIZE(clk); i++)
                if (IS_ERR(clk[i]))
@@ -417,37 +436,37 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
 
        mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
 
-       clk_register_clkdev(clk[hsi2c_gate], NULL, "imx21-i2c.2");
-       clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL);
-       clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0");
-       clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
-       clk_register_clkdev(clk[usb_phy_gate], "phy", "mxc-ehci.0");
-       clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx51.0");
-       clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.0");
-       clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx51.0");
-       clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx51.1");
-       clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.1");
-       clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx51.1");
-       clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx51.2");
-       clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.2");
-       clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx51.2");
-       clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx51.3");
-       clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.3");
-       clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx51.3");
+       clk_register_clkdev(clk[IMX5_CLK_HSI2C_GATE], NULL, "imx21-i2c.2");
+       clk_register_clkdev(clk[IMX5_CLK_MX51_MIPI], "mipi_hsp", NULL);
+       clk_register_clkdev(clk[IMX5_CLK_VPU_GATE], NULL, "imx51-vpu.0");
+       clk_register_clkdev(clk[IMX5_CLK_FEC_GATE], NULL, "imx27-fec.0");
+       clk_register_clkdev(clk[IMX5_CLK_USB_PHY_GATE], "phy", "mxc-ehci.0");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC1_IPG_GATE], "ipg", "sdhci-esdhc-imx51.0");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx51.0");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC1_PER_GATE], "per", "sdhci-esdhc-imx51.0");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC2_IPG_GATE], "ipg", "sdhci-esdhc-imx51.1");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx51.1");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC2_PER_GATE], "per", "sdhci-esdhc-imx51.1");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC3_IPG_GATE], "ipg", "sdhci-esdhc-imx51.2");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx51.2");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC3_PER_GATE], "per", "sdhci-esdhc-imx51.2");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC4_IPG_GATE], "ipg", "sdhci-esdhc-imx51.3");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx51.3");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC4_PER_GATE], "per", "sdhci-esdhc-imx51.3");
 
        /* set the usboh3 parent to pll2_sw */
-       clk_set_parent(clk[usboh3_sel], clk[pll2_sw]);
+       clk_set_parent(clk[IMX5_CLK_USBOH3_SEL], clk[IMX5_CLK_PLL2_SW]);
 
        /* set SDHC root clock to 166.25MHZ*/
-       clk_set_rate(clk[esdhc_a_podf], 166250000);
-       clk_set_rate(clk[esdhc_b_podf], 166250000);
+       clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 166250000);
+       clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 166250000);
 
        /* System timer */
        mxc_timer_init(MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), MX51_INT_GPT);
 
-       clk_prepare_enable(clk[iim_gate]);
+       clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
        imx_print_silicon_rev("i.MX51", mx51_revision());
-       clk_disable_unprepare(clk[iim_gate]);
+       clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
 
        /*
         * Reference Manual says: Functionality of CCDR[18] and CLPCR[23] is no
@@ -479,57 +498,59 @@ static void __init mx53_clocks_init(struct device_node *np)
        unsigned long r;
        void __iomem *base;
 
-       clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE);
-       clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE);
-       clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
-       clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE);
-
-       clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
-       clk[ldb_di1_div] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0);
-       clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
-                               mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT);
-       clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
-       clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
-       clk[ldb_di0_div] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0);
-       clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
-                               mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
-       clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
-       clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
-       clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
-                               mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
-       clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
-                               mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
-       clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
-                               mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
-       clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
-       clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
-       clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
-       clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
-       clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
-       clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
-       clk[usb_phy1_gate] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
-       clk[usb_phy2_gate] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
-       clk[can_sel] = imx_clk_mux("can_sel", MXC_CCM_CSCMR2, 6, 2,
-                               mx53_can_sel, ARRAY_SIZE(mx53_can_sel));
-       clk[can1_serial_gate] = imx_clk_gate2("can1_serial_gate", "can_sel", MXC_CCM_CCGR6, 22);
-       clk[can1_ipg_gate] = imx_clk_gate2("can1_ipg_gate", "ipg", MXC_CCM_CCGR6, 20);
-       clk[ocram] = imx_clk_gate2("ocram", "ahb", MXC_CCM_CCGR6, 2);
-       clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8);
-       clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
-       clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
-       clk[sata_gate] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2);
-
-       clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
-                               mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
-       clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
-       clk[cko1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
-
-       clk[cko2_sel] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
-                               mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
-       clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
-       clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
-       clk[spdif_xtal_sel] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
-                               mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel));
+       clk[IMX5_CLK_PLL1_SW]           = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE);
+       clk[IMX5_CLK_PLL2_SW]           = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE);
+       clk[IMX5_CLK_PLL3_SW]           = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
+       clk[IMX5_CLK_PLL4_SW]           = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE);
+
+       clk[IMX5_CLK_LP_APM]            = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1,
+                                               lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+       clk[IMX5_CLK_LDB_DI1_DIV_3_5]   = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+       clk[IMX5_CLK_LDB_DI1_DIV]       = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0);
+       clk[IMX5_CLK_LDB_DI1_SEL]       = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
+                                               mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT);
+       clk[IMX5_CLK_DI_PLL4_PODF]      = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
+       clk[IMX5_CLK_LDB_DI0_DIV_3_5]   = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+       clk[IMX5_CLK_LDB_DI0_DIV]       = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0);
+       clk[IMX5_CLK_LDB_DI0_SEL]       = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
+                                               mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
+       clk[IMX5_CLK_LDB_DI1_GATE]      = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
+       clk[IMX5_CLK_LDB_DI1_GATE]      = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
+       clk[IMX5_CLK_IPU_DI0_SEL]       = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
+                                               mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
+       clk[IMX5_CLK_IPU_DI1_SEL]       = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
+                                               mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
+       clk[IMX5_CLK_TVE_EXT_SEL]       = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
+                                               mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
+       clk[IMX5_CLK_TVE_GATE]          = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
+       clk[IMX5_CLK_TVE_PRED]          = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
+       clk[IMX5_CLK_ESDHC1_PER_GATE]   = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+       clk[IMX5_CLK_ESDHC2_PER_GATE]   = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
+       clk[IMX5_CLK_ESDHC3_PER_GATE]   = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
+       clk[IMX5_CLK_ESDHC4_PER_GATE]   = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+       clk[IMX5_CLK_USB_PHY1_GATE]     = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
+       clk[IMX5_CLK_USB_PHY2_GATE]     = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
+       clk[IMX5_CLK_CAN_SEL]           = imx_clk_mux("can_sel", MXC_CCM_CSCMR2, 6, 2,
+                                               mx53_can_sel, ARRAY_SIZE(mx53_can_sel));
+       clk[IMX5_CLK_CAN1_SERIAL_GATE]  = imx_clk_gate2("can1_serial_gate", "can_sel", MXC_CCM_CCGR6, 22);
+       clk[IMX5_CLK_CAN1_IPG_GATE]     = imx_clk_gate2("can1_ipg_gate", "ipg", MXC_CCM_CCGR6, 20);
+       clk[IMX5_CLK_OCRAM]             = imx_clk_gate2("ocram", "ahb", MXC_CCM_CCGR6, 2);
+       clk[IMX5_CLK_CAN2_SERIAL_GATE]  = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8);
+       clk[IMX5_CLK_CAN2_IPG_GATE]     = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
+       clk[IMX5_CLK_I2C3_GATE]         = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
+       clk[IMX5_CLK_SATA_GATE]         = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2);
+
+       clk[IMX5_CLK_CKO1_SEL]          = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
+                                               mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
+       clk[IMX5_CLK_CKO1_PODF]         = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
+       clk[IMX5_CLK_CKO1]              = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
+
+       clk[IMX5_CLK_CKO2_SEL]          = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
+                                               mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
+       clk[IMX5_CLK_CKO2_PODF]         = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
+       clk[IMX5_CLK_CKO2]              = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
+       clk[IMX5_CLK_SPDIF_XTAL_SEL]    = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
+                                               mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel));
 
        for (i = 0; i < ARRAY_SIZE(clk); i++)
                if (IS_ERR(clk[i]))
@@ -542,33 +563,33 @@ static void __init mx53_clocks_init(struct device_node *np)
 
        mx5_clocks_common_init(0, 0, 0, 0);
 
-       clk_register_clkdev(clk[vpu_gate], NULL, "imx53-vpu.0");
-       clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2");
-       clk_register_clkdev(clk[fec_gate], NULL, "imx25-fec.0");
-       clk_register_clkdev(clk[usb_phy1_gate], "usb_phy1", "mxc-ehci.0");
-       clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx53.0");
-       clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.0");
-       clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx53.0");
-       clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx53.1");
-       clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.1");
-       clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx53.1");
-       clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx53.2");
-       clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.2");
-       clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx53.2");
-       clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx53.3");
-       clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.3");
-       clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx53.3");
+       clk_register_clkdev(clk[IMX5_CLK_VPU_GATE], NULL, "imx53-vpu.0");
+       clk_register_clkdev(clk[IMX5_CLK_I2C3_GATE], NULL, "imx21-i2c.2");
+       clk_register_clkdev(clk[IMX5_CLK_FEC_GATE], NULL, "imx25-fec.0");
+       clk_register_clkdev(clk[IMX5_CLK_USB_PHY1_GATE], "usb_phy1", "mxc-ehci.0");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC1_IPG_GATE], "ipg", "sdhci-esdhc-imx53.0");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx53.0");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC1_PER_GATE], "per", "sdhci-esdhc-imx53.0");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC2_IPG_GATE], "ipg", "sdhci-esdhc-imx53.1");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx53.1");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC2_PER_GATE], "per", "sdhci-esdhc-imx53.1");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC3_IPG_GATE], "ipg", "sdhci-esdhc-imx53.2");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx53.2");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC3_PER_GATE], "per", "sdhci-esdhc-imx53.2");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC4_IPG_GATE], "ipg", "sdhci-esdhc-imx53.3");
+       clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx53.3");
+       clk_register_clkdev(clk[IMX5_CLK_ESDHC4_PER_GATE], "per", "sdhci-esdhc-imx53.3");
 
        /* set SDHC root clock to 200MHZ*/
-       clk_set_rate(clk[esdhc_a_podf], 200000000);
-       clk_set_rate(clk[esdhc_b_podf], 200000000);
+       clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000);
+       clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000);
 
-       clk_prepare_enable(clk[iim_gate]);
+       clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
        imx_print_silicon_rev("i.MX53", mx53_revision());
-       clk_disable_unprepare(clk[iim_gate]);
+       clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
 
-       r = clk_round_rate(clk[usboh3_per_gate], 54000000);
-       clk_set_rate(clk[usboh3_per_gate], r);
+       r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
+       clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
 
        np = of_find_compatible_node(NULL, NULL, "fsl,imx53-gpt");
        base = of_iomap(np, 0);
index 04cfd0fcb0e56db864d28f4240b2341ae20927b0..74ecceb4b5f46ba83d8a01972f985fff2b5c7581 100644 (file)
@@ -114,7 +114,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, arm,
 };
 
 static struct clk_div_table clk_enet_ref_table[] = {
index c0c4ef55e35bd7e522b4f83d038d50f752265db4..a747a7df175f08d3884c72d2138743befb4f3160 100644 (file)
@@ -63,7 +63,7 @@ static struct clk_div_table video_div_table[] = {
        { }
 };
 
-static struct clk *clks[IMX6SL_CLK_CLK_END];
+static struct clk *clks[IMX6SL_CLK_END];
 static struct clk_onecell_data clk_data;
 
 static void __init imx6sl_clocks_init(struct device_node *ccm_node)
index b169a396d93bfcf193c83d7329a6fdc290101425..ecd66d8e20b62b84419f0c0bcc4a54d0c5ef8a02 100644 (file)
@@ -298,6 +298,11 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
        clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(0));
        clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(4));
 
+       clk[VF610_CLK_DMAMUX0] = imx_clk_gate2("dmamux0", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(4));
+       clk[VF610_CLK_DMAMUX1] = imx_clk_gate2("dmamux1", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(5));
+       clk[VF610_CLK_DMAMUX2] = imx_clk_gate2("dmamux2", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(1));
+       clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2));
+
        clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]);
        clk_set_rate(clk[VF610_CLK_QSPI0_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_SEL]) / 2);
        clk_set_rate(clk[VF610_CLK_QSPI0_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X4_DIV]) / 2);
index 24a7899e36a8abed143d2bfdadcf854e0970a14c..59c3b9b26bb40bbabe40f471d6a420efee43a1c2 100644 (file)
@@ -108,6 +108,7 @@ void tzic_handle_irq(struct pt_regs *);
 #define imx27_handle_irq avic_handle_irq
 #define imx31_handle_irq avic_handle_irq
 #define imx35_handle_irq avic_handle_irq
+#define imx50_handle_irq tzic_handle_irq
 #define imx51_handle_irq tzic_handle_irq
 #define imx53_handle_irq tzic_handle_irq
 
index 5b2dabba330fd7ad69c534aa3714bc821d77342a..6e3175dc0c0aaed7dccca96b9767f4c0d4baf3ae 100644 (file)
@@ -24,7 +24,6 @@
 
 struct mxc_extra_irq
 {
-       int (*set_priority)(unsigned char irq, unsigned char prio);
        int (*set_irq_fiq)(unsigned int irq, unsigned int type);
 };
 
index 771362d1fbee712247242c3d7c5d9956b7f58e70..65e4c53e1554b134ff458ba3960f060bec130a1b 100644 (file)
@@ -53,7 +53,7 @@ static const struct imxi2c_platform_data
 };
 
 #define TSC2007_IRQGPIO                IMX_GPIO_NR(3, 2)
-static int tsc2007_get_pendown_state(void)
+static int tsc2007_get_pendown_state(struct device *dev)
 {
        return !gpio_get_value(TSC2007_IRQGPIO);
 }
index 9b5ddf5bbd339e4aff4012256762144c77332557..1fba2b8e983f7e9104ac506a8fccc951f361611b 100644 (file)
@@ -121,7 +121,7 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
        .flags = IMXUART_HAVE_RTSCTS,
 };
 
-static int tsc2007_get_pendown_state(void)
+static int tsc2007_get_pendown_state(struct device *dev)
 {
        if (mx51_revision() < IMX_CHIP_REVISION_3_0)
                return !gpio_get_value(TSC2007_IRQGPIO_REV2);
diff --git a/arch/arm/mach-imx/mach-imx50.c b/arch/arm/mach-imx/mach-imx50.c
new file mode 100644 (file)
index 0000000..2f74fad
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+static void __init imx50_dt_init(void)
+{
+       mxc_arch_reset_init_dt();
+
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *imx50_dt_board_compat[] __initdata = {
+       "fsl,imx50",
+       NULL
+};
+
+DT_MACHINE_START(IMX50_DT, "Freescale i.MX50 (Device Tree Support)")
+       .map_io         = mx53_map_io,
+       .init_irq       = mx53_init_irq,
+       .handle_irq     = imx50_handle_irq,
+       .init_machine   = imx50_dt_init,
+       .dt_compat      = imx50_dt_board_compat,
+       .restart        = mxc_restart,
+MACHINE_END
index d0cfb225ec9aa5e9e9599b6e3ee5c6c32870e0f7..7e5ec34894e2b66096fcbd7f18d9f211c2614a47 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/cpu.h>
+#include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -23,6 +24,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/pm_opp.h>
+#include <linux/pci.h>
 #include <linux/phy.h>
 #include <linux/reboot.h>
 #include <linux/regmap.h>
@@ -78,6 +80,34 @@ static int ksz9031rn_phy_fixup(struct phy_device *dev)
        return 0;
 }
 
+/*
+ * fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High
+ * as they are used for slots1-7 PERST#
+ */
+static void ventana_pciesw_early_fixup(struct pci_dev *dev)
+{
+       u32 dw;
+
+       if (!of_machine_is_compatible("gw,ventana"))
+               return;
+
+       if (dev->devfn != 0)
+               return;
+
+       pci_read_config_dword(dev, 0x62c, &dw);
+       dw |= 0xaaa8; // GPIO1-7 outputs
+       pci_write_config_dword(dev, 0x62c, dw);
+
+       pci_read_config_dword(dev, 0x644, &dw);
+       dw |= 0xfe;   // GPIO1-7 output high
+       pci_write_config_dword(dev, 0x644, dw);
+
+       msleep(100);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8609, ventana_pciesw_early_fixup);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8606, ventana_pciesw_early_fixup);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8604, ventana_pciesw_early_fixup);
+
 static int ar8031_phy_fixup(struct phy_device *dev)
 {
        u16 val;
index d1d52600f458c3604eb77c4bcfae51432b2a932c..4c112021aa4ef8511121a0237179a5b7a6ebcf4f 100644 (file)
@@ -89,15 +89,7 @@ void __init imx51_init_early(void)
 
 void __init imx53_init_early(void)
 {
-       struct device_node *np;
-       void __iomem *base;
-
        mxc_set_cpu_type(MXC_CPU_MX53);
-
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx53-iomuxc");
-       base = of_iomap(np, 0);
-       WARN_ON(!base);
-       mxc_iomux_v3_init(base);
        imx_src_init();
 }
 
index 9caa4fe95913c672a6b874c5b8b8d573294ae857..78188159484d79e760d8ec22a6303a81d100aeae 100644 (file)
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clk.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_net.h>
 #include <linux/of_platform.h>
-#include <linux/clk-provider.h>
 #include <linux/dma-mapping.h>
 #include <linux/irqchip.h>
 #include <linux/kexec.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
 #include <mach/bridge-regs.h>
-#include <linux/platform_data/usb-ehci-orion.h>
-#include <plat/irq.h>
 #include <plat/common.h>
 #include "common.h"
 
-/*
- * There are still devices that doesn't know about DT yet.  Get clock
- * gates here and add a clock lookup alias, so that old platform
- * devices still work.
-*/
-
-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;
-
-       /*
-        * 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);
-       clk_prepare_enable(clk);
-
-       clkspec.args[0] = CGC_BIT_GE1;
-       clk = of_clk_get_from_provider(&clkspec);
-       clk_prepare_enable(clk);
-}
-
 #define MV643XX_ETH_MAC_ADDR_LOW       0x0414
 #define MV643XX_ETH_MAC_ADDR_HIGH      0x0418
 
@@ -140,7 +106,7 @@ eth_fixup_skip:
 
 static void __init kirkwood_dt_init(void)
 {
-       pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk);
+       pr_info("Kirkwood: %s.\n", kirkwood_id());
 
        /*
         * Disable propagation of mbus errors to the CPU local bus,
@@ -156,8 +122,6 @@ static void __init kirkwood_dt_init(void)
 
        kirkwood_cpufreq_init();
        kirkwood_cpuidle_init();
-       /* Setup clocks for legacy devices */
-       kirkwood_legacy_clk_init();
 
        kirkwood_pm_init();
        kirkwood_dt_eth_fixup();
index 58adf2fd9cfc98ea03f6b1f8cfe037ceb01bd78b..4e9d58148ca7e3031cbbdaa5dba2bb5aa0607619 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/smp_plat.h>
 #include <asm/cacheflush.h>
 #include "armada-370-xp.h"
+#include "coherency.h"
 
 unsigned long coherency_phys_base;
 static void __iomem *coherency_base;
index df33ad8a6c08935b9fea023c570c8881b22ecb8b..760226c4135309b4ec79ddda47ba9fb18c31a3f4 100644 (file)
@@ -14,7 +14,9 @@
 #ifndef __MACH_370_XP_COHERENCY_H
 #define __MACH_370_XP_COHERENCY_H
 
-int set_cpu_coherent(int cpu_id, int smp_group_id);
+extern unsigned long coherency_phys_base;
+
+int set_cpu_coherent(unsigned int cpu_id, int smp_group_id);
 int coherency_init(void);
 
 #endif /* __MACH_370_XP_COHERENCY_H */
index e366010e1d91097432383f7c9c6cca7e220a6bc7..0e6016fadcc58a3ae249eba501d31c11b7e1062e 100644 (file)
@@ -26,7 +26,6 @@ void armada_370_xp_handle_irq(struct pt_regs *regs);
 
 void armada_xp_cpu_die(unsigned int cpu);
 int armada_370_xp_coherency_init(void);
-int armada_370_xp_pmsu_init(void);
 void armada_xp_secondary_startup(void);
 extern struct smp_operations armada_xp_smp_ops;
 #endif
index b228b6a80c85cc9693b3246de4272bd115c0e561..d95e910471684544d63e853308419d68036ec01c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/smp.h>
 #include <asm/proc-fns.h>
+#include "common.h"
 
 /*
  * platform-specific code to shutdown a CPU
index ff69c2df298b6b2ce69f742c7f5b6dbcf179f821..a6da03f5b24ec921090af5508a2b6d87a66c7197 100644 (file)
@@ -46,7 +46,7 @@ static struct clk *__init get_cpu_clk(int cpu)
        return cpu_clk;
 }
 
-void __init set_secondary_cpus_clock(void)
+static void __init set_secondary_cpus_clock(void)
 {
        int thiscpu, cpu;
        unsigned long rate;
@@ -94,7 +94,7 @@ static void __init armada_xp_smp_init_cpus(void)
        set_smp_cross_call(armada_mpic_send_doorbell);
 }
 
-void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
+static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
 {
        struct device_node *node;
        struct resource res;
index 27fc4f049474ed94b07cef00dfe3304b1165369c..d71ef53107c4e9a530a558458d31eecf92039bd2 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/smp.h>
 #include <asm/smp_plat.h>
+#include "pmsu.h"
 
 static void __iomem *pmsu_mp_base;
 static void __iomem *pmsu_reset_base;
@@ -58,7 +59,7 @@ int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
 }
 #endif
 
-int __init armada_370_xp_pmsu_init(void)
+static int __init armada_370_xp_pmsu_init(void)
 {
        struct device_node *np;
 
index 5175083cdb34650802288789c55a82aee8c20d08..a7fb89a5b5d9818db3174916d0e7e0589ed53456 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/of_address.h>
 #include <linux/io.h>
 #include <linux/reboot.h>
+#include "common.h"
 
 static void __iomem *system_controller_base;
 
@@ -39,14 +40,14 @@ struct mvebu_system_controller {
 };
 static struct mvebu_system_controller *mvebu_sc;
 
-const struct mvebu_system_controller armada_370_xp_system_controller = {
+static const struct mvebu_system_controller armada_370_xp_system_controller = {
        .rstoutn_mask_offset = 0x60,
        .system_soft_reset_offset = 0x64,
        .rstoutn_mask_reset_out_en = 0x1,
        .system_soft_reset = 0x1,
 };
 
-const struct mvebu_system_controller orion_system_controller = {
+static const struct mvebu_system_controller orion_system_controller = {
        .rstoutn_mask_offset = 0x108,
        .system_soft_reset_offset = 0x10c,
        .rstoutn_mask_reset_out_en = 0x4,
index 1dc5acd4fc99bb7f0001217214d53199dd89174d..3982e129c054da764d6035b0d2640b0f70a44760 100644 (file)
@@ -157,6 +157,7 @@ enum mac_oui {
        OUI_FSL,
        OUI_DENX,
        OUI_CRYSTALFONTZ,
+       OUI_I2SE,
 };
 
 static void __init update_fec_mac_prop(enum mac_oui oui)
@@ -211,6 +212,11 @@ static void __init update_fec_mac_prop(enum mac_oui oui)
                        macaddr[1] = 0xb9;
                        macaddr[2] = 0xe1;
                        break;
+               case OUI_I2SE:
+                       macaddr[0] = 0x00;
+                       macaddr[1] = 0x01;
+                       macaddr[2] = 0x87;
+                       break;
                }
                val = ocotp[i];
                macaddr[3] = (val >> 16) & 0xff;
@@ -330,6 +336,11 @@ static void __init crystalfontz_init(void)
        update_fec_mac_prop(OUI_CRYSTALFONTZ);
 }
 
+static void __init duckbill_init(void)
+{
+       update_fec_mac_prop(OUI_I2SE);
+}
+
 static void __init m28cu3_init(void)
 {
        update_fec_mac_prop(OUI_DENX);
@@ -462,6 +473,8 @@ static void __init mxs_machine_init(void)
                apx4devkit_init();
        else if (of_machine_is_compatible("crystalfontz,cfa10036"))
                crystalfontz_init();
+       else if (of_machine_is_compatible("i2se,duckbill"))
+               duckbill_init();
        else if (of_machine_is_compatible("msr,m28cu3"))
                m28cu3_init();
 
index 1f25f3e99c05481418dcb7aa1472df14cee7202f..adcef406ff0abdc5a1695cac7f9cb04dc6ac542e 100644 (file)
@@ -19,11 +19,11 @@ secure-common                               = omap-smc.o omap-secure.o
 
 obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
 obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
-obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common)
 obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common)
-obj-$(CONFIG_SOC_OMAP5)         += prm44xx.o $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_OMAP5)         += $(hwmod-common) $(secure-common)
 obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common)
-obj-$(CONFIG_SOC_DRA7XX) += prm44xx.o $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common)
 
 ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
 obj-y += mcbsp.o
index f7644febee81d7d41ae2cfc01e1fc362b972de02..e30ef6797c6311798cbb92b4521c56306b7fdc67 100644 (file)
@@ -299,7 +299,6 @@ struct omap_sdrc_params;
 extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
                                      struct omap_sdrc_params *sdrc_cs1);
 struct omap2_hsmmc_info;
-extern int omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers);
 extern void omap_reserve(void);
 
 struct omap_hwmod;
index a4e536b11ec9a997d8e640ff44745e6759c031fa..58347bb874a01dcd4d203f4f191712d473a338a3 100644 (file)
@@ -32,7 +32,6 @@
 
 #include "soc.h"
 #include "iomap.h"
-#include "mux.h"
 #include "control.h"
 #include "display.h"
 #include "prm.h"
@@ -102,90 +101,13 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = {
        { "dss_hdmi", "omapdss_hdmi", -1 },
 };
 
-static void __init omap4_tpd12s015_mux_pads(void)
-{
-       omap_mux_init_signal("hdmi_cec",
-                       OMAP_PIN_INPUT_PULLUP);
-       omap_mux_init_signal("hdmi_ddc_scl",
-                       OMAP_PIN_INPUT_PULLUP);
-       omap_mux_init_signal("hdmi_ddc_sda",
-                       OMAP_PIN_INPUT_PULLUP);
-}
-
-static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
-{
-       u32 reg;
-       u16 control_i2c_1;
-
-       /*
-        * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and
-        * HDMI_DDC_SCL_PULLUPRESX (bit 24) are set to disable
-        * internal pull up resistor.
-        */
-       if (flags & OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP) {
-               control_i2c_1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1;
-               reg = omap4_ctrl_pad_readl(control_i2c_1);
-               reg |= (OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK |
-                       OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK);
-                       omap4_ctrl_pad_writel(reg, control_i2c_1);
-       }
-}
-
-static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
-{
-       u32 enable_mask, enable_shift;
-       u32 pipd_mask, pipd_shift;
-       u32 reg;
-
-       if (dsi_id == 0) {
-               enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
-               enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
-               pipd_mask = OMAP4_DSI1_PIPD_MASK;
-               pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
-       } else if (dsi_id == 1) {
-               enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
-               enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
-               pipd_mask = OMAP4_DSI2_PIPD_MASK;
-               pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
-       } else {
-               return -ENODEV;
-       }
-
-       reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
-
-       reg &= ~enable_mask;
-       reg &= ~pipd_mask;
-
-       reg |= (lanes << enable_shift) & enable_mask;
-       reg |= (lanes << pipd_shift) & pipd_mask;
-
-       omap4_ctrl_pad_writel(reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
-
-       return 0;
-}
-
-int __init omap_hdmi_init(enum omap_hdmi_flags flags)
-{
-       if (cpu_is_omap44xx()) {
-               omap4_hdmi_mux_pads(flags);
-               omap4_tpd12s015_mux_pads();
-       }
-
-       return 0;
-}
-
 static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 {
-       if (cpu_is_omap44xx())
-               return omap4_dsi_mux_pads(dsi_id, lane_mask);
-
        return 0;
 }
 
 static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
-       if (cpu_is_omap44xx())
-               omap4_dsi_mux_pads(dsi_id, 0);
 }
 
 static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput)
index 365bfd3d9c68b8486f23049a71889484c60eb793..dadccc91488c64e94c06e9bf93b54bc5c294e26e 100644 (file)
@@ -223,7 +223,7 @@ void __init omap_4430sdp_display_init_of(void)
 static struct connector_dvi_platform_data omap3_igep2_dvi_connector_pdata = {
        .name                   = "dvi",
        .source                 = "tfp410.0",
-       .i2c_bus_num            = 3,
+       .i2c_bus_num            = 2,
 };
 
 static struct platform_device omap3_igep2_dvi_connector_device = {
index 81de56251955a7bf82b7f4ce3b03ffcd3333fd5e..d24926e6340fa714cf0aeacca14a6578e5b481a4 100644 (file)
@@ -1501,6 +1501,22 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
                return ret;
        }
 
+       /*
+        * For some GPMC devices we still need to rely on the bootloader
+        * timings because the devices can be connected via FPGA. So far
+        * the list is smc91x on the omap2 SDP boards, and 8250 on zooms.
+        * REVISIT: Add timing support from slls644g.pdf and from the
+        * lan91c96 manual.
+        */
+       if (of_device_is_compatible(child, "ns16550a") ||
+           of_device_is_compatible(child, "smsc,lan91c94") ||
+           of_device_is_compatible(child, "smsc,lan91c111")) {
+               dev_warn(&pdev->dev,
+                        "%s using bootloader timings on CS%d\n",
+                        child->name, cs);
+               goto no_timings;
+       }
+
        /*
         * FIXME: gpmc_cs_request() will map the CS to an arbitary
         * location in the gpmc address space. When booting with
@@ -1529,6 +1545,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
        gpmc_read_timings_dt(child, &gpmc_t);
        gpmc_cs_set_timings(cs, &gpmc_t);
 
+no_timings:
        if (of_platform_device_create(child, NULL, &pdev->dev))
                return 0;
 
@@ -1541,42 +1558,6 @@ err:
        return ret;
 }
 
-/*
- * REVISIT: Add timing support from slls644g.pdf
- */
-static int gpmc_probe_8250(struct platform_device *pdev,
-                               struct device_node *child)
-{
-       struct resource res;
-       unsigned long base;
-       int ret, cs;
-
-       if (of_property_read_u32(child, "reg", &cs) < 0) {
-               dev_err(&pdev->dev, "%s has no 'reg' property\n",
-                       child->full_name);
-               return -ENODEV;
-       }
-
-       if (of_address_to_resource(child, 0, &res) < 0) {
-               dev_err(&pdev->dev, "%s has malformed 'reg' property\n",
-                       child->full_name);
-               return -ENODEV;
-       }
-
-       ret = gpmc_cs_request(cs, resource_size(&res), &base);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
-               return ret;
-       }
-
-       if (of_platform_device_create(child, NULL, &pdev->dev))
-               return 0;
-
-       dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
-
-       return -ENODEV;
-}
-
 static int gpmc_probe_dt(struct platform_device *pdev)
 {
        int ret;
@@ -1618,10 +1599,9 @@ static int gpmc_probe_dt(struct platform_device *pdev)
                else if (of_node_cmp(child->name, "onenand") == 0)
                        ret = gpmc_probe_onenand_child(pdev, child);
                else if (of_node_cmp(child->name, "ethernet") == 0 ||
-                        of_node_cmp(child->name, "nor") == 0)
+                        of_node_cmp(child->name, "nor") == 0 ||
+                        of_node_cmp(child->name, "uart") == 0)
                        ret = gpmc_probe_generic_child(pdev, child);
-               else if (of_node_cmp(child->name, "8250") == 0)
-                       ret = gpmc_probe_8250(pdev, child);
 
                if (WARN(ret < 0, "%s: probing gpmc child %s failed\n",
                         __func__, child->full_name))
index cd22262a2cc09a1ad5b951254500a11afdfc8e30..07b68d5a7940e402705568114b7e0523cdda44f8 100644 (file)
@@ -244,7 +244,7 @@ static struct map_desc omap44xx_io_desc[] __initdata = {
                .virtual        = OMAP4_SRAM_VA,
                .pfn            = __phys_to_pfn(OMAP4_SRAM_PA),
                .length         = PAGE_SIZE,
-               .type           = MT_MEMORY_SO,
+               .type           = MT_MEMORY_RW_SO,
        },
 #endif
 
@@ -282,7 +282,7 @@ static struct map_desc omap54xx_io_desc[] __initdata = {
                .virtual        = OMAP4_SRAM_VA,
                .pfn            = __phys_to_pfn(OMAP4_SRAM_PA),
                .length         = PAGE_SIZE,
-               .type           = MT_MEMORY_SO,
+               .type           = MT_MEMORY_RW_SO,
        },
 #endif
 };
index 8cc7d331437d844a3b0ba5b3d2afb844b2de5d06..3e97c6c8ecf139781c7f0d03a68583d5ff81ea2b 100644 (file)
@@ -76,6 +76,13 @@ static inline void omap_barrier_reserve_memblock(void)
 { }
 #endif
 
+#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
 void set_cntfreq(void);
+#else
+static inline void set_cntfreq(void)
+{
+}
+#endif
+
 #endif /* __ASSEMBLER__ */
 #endif /* OMAP_ARCH_OMAP_SECURE_H */
index 57911430324e30cdfdfb1408d0272c8b6bf0dde4..b5110f19abc7b256484289336c7f28cb4bec913d 100644 (file)
@@ -35,7 +35,6 @@
 #include "iomap.h"
 #include "common.h"
 #include "mmc.h"
-#include "hsmmc.h"
 #include "prminst44xx.h"
 #include "prcm_mpu44xx.h"
 #include "omap4-sar-layout.h"
@@ -88,7 +87,7 @@ void __init omap_barriers_init(void)
        dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
        dram_io_desc[0].pfn = __phys_to_pfn(paddr);
        dram_io_desc[0].length = size;
-       dram_io_desc[0].type = MT_MEMORY_SO;
+       dram_io_desc[0].type = MT_MEMORY_RW_SO;
        iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
        dram_sync = (void __iomem *) dram_io_desc[0].virtual;
        sram_sync = (void __iomem *) OMAP4_SRAM_VA;
@@ -284,59 +283,3 @@ skip_errata_init:
        omap_wakeupgen_init();
        irqchip_init();
 }
-
-#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
-static int omap4_twl6030_hsmmc_late_init(struct device *dev)
-{
-       int irq = 0;
-       struct platform_device *pdev = container_of(dev,
-                               struct platform_device, dev);
-       struct omap_mmc_platform_data *pdata = dev->platform_data;
-
-       /* Setting MMC1 Card detect Irq */
-       if (pdev->id == 0) {
-               irq = twl6030_mmc_card_detect_config();
-               if (irq < 0) {
-                       dev_err(dev, "%s: Error card detect config(%d)\n",
-                               __func__, irq);
-                       return irq;
-               }
-               pdata->slots[0].card_detect_irq = irq;
-               pdata->slots[0].card_detect = twl6030_mmc_card_detect;
-       }
-       return 0;
-}
-
-static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
-{
-       struct omap_mmc_platform_data *pdata;
-
-       /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
-       if (!dev) {
-               pr_err("Failed %s\n", __func__);
-               return;
-       }
-       pdata = dev->platform_data;
-       pdata->init =   omap4_twl6030_hsmmc_late_init;
-}
-
-int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
-{
-       struct omap2_hsmmc_info *c;
-
-       omap_hsmmc_init(controllers);
-       for (c = controllers; c->mmc; c++) {
-               /* pdev can be null if CONFIG_MMC_OMAP_HS is not set */
-               if (!c->pdev)
-                       continue;
-               omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
-       }
-
-       return 0;
-}
-#else
-int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
-{
-       return 0;
-}
-#endif
index 10c71450cf632c2816c40ab22207ad65ef09dd0b..39f020c982e8b3a41d547d9d45b60c46cb08877b 100644 (file)
@@ -139,6 +139,7 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
 
 static struct pdata_init pdata_quirks[] __initdata = {
 #ifdef CONFIG_ARCH_OMAP3
+       { "nokia,omap3-n900", hsmmc2_internal_input_clk, },
        { "nokia,omap3-n9", hsmmc2_internal_input_clk, },
        { "nokia,omap3-n950", hsmmc2_internal_input_clk, },
        { "isee,omap3-igep0020", omap3_igep0020_legacy_init, },
index 93b80e5da8d4d5888982b30ffed5d5dc5f2cc470..1f3770a8a7286fd7650f76d46917408d0ff52b96 100644 (file)
@@ -120,7 +120,7 @@ static void omap3_save_secure_ram_context(void)
                 * will hang the system.
                 */
                pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
-               ret = _omap_save_secure_sram((u32 *)
+               ret = _omap_save_secure_sram((u32 *)(unsigned long)
                                __pa(omap3_secure_ram_storage));
                pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state);
                /* Following is for error tracking, it should not happen */
index 7a976065e1389cf8396c28e5da37ca6574e8cad4..8d95aa543ef562f65fe18e6ed0fd07ed23dbc505 100644 (file)
@@ -43,7 +43,7 @@ extern void omap4_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
-       defined(CONFIG_SOC_DRA7XX)
+       defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
 void omap44xx_prm_reconfigure_io_chain(void);
 #else
 static inline void omap44xx_prm_reconfigure_io_chain(void)
index b91002ca92f3b42b6a04f54683daa4f2504e5c2a..c134a826070a14ccadda4293181f27cf81278804 100644 (file)
@@ -21,7 +21,7 @@
 #include <plat/irq.h>
 #include "common.h"
 
-struct of_dev_auxdata orion5x_auxdata_lookup[] __initdata = {
+static struct of_dev_auxdata orion5x_auxdata_lookup[] __initdata = {
        OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
        OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
                       NULL),
index 91a5852b44f3a8fe09d0815009ff54329b23c582..3f1de1111e0f207e4a0dbd5d66208d2054f1a810 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/page.h>
 #include <asm/setup.h>
 #include <asm/system_misc.h>
-#include <asm/timex.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -135,7 +134,7 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
 /*****************************************************************************
  * SPI
  ****************************************************************************/
-void __init orion5x_spi_init()
+void __init orion5x_spi_init(void)
 {
        orion_spi_init(SPI_PHYS_BASE);
 }
@@ -185,7 +184,7 @@ static void __init orion5x_crypto_init(void)
 /*****************************************************************************
  * Watchdog
  ****************************************************************************/
-void __init orion5x_wdt_init(void)
+static void __init orion5x_wdt_init(void)
 {
        orion_wdt_init();
 }
@@ -246,7 +245,7 @@ void orion5x_setup_wins(void)
 
 int orion5x_tclk;
 
-int __init orion5x_find_tclk(void)
+static int __init orion5x_find_tclk(void)
 {
        u32 dev, rev;
 
index 4b2aefd1d96180e7a3e5962a72c907734a136539..dc01c4ffc9a8d090ad8d7691ffedf9588cdd2414 100644 (file)
@@ -202,7 +202,7 @@ __initcall(db88f5281_7seg_init);
  * PCI
  ****************************************************************************/
 
-void __init db88f5281_pci_preinit(void)
+static void __init db88f5281_pci_preinit(void)
 {
        int pin;
 
index 30a192b9c51730da9dfb94ccdf93128ceb8143de..9654b0cc58928741c13281eaf7c6b737411dd7ec 100644 (file)
@@ -16,6 +16,7 @@
 #include <mach/bridge-regs.h>
 #include <plat/orion-gpio.h>
 #include <plat/irq.h>
+#include "common.h"
 
 static int __initdata gpio0_irqs[4] = {
        IRQ_ORION5X_GPIO_0_7,
index 7fab6705303073ab9b6cdb1dbf6cae17a0840390..87a12d6930ffc4525a1a1335789162711968e4fe 100644 (file)
@@ -240,11 +240,11 @@ static int __init pcie_setup(struct pci_sys_data *sys)
 #define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \
                                 ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \
                                 ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \
-                                ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0)
+                                ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : NULL)
 #define PCI_BAR_REMAP_DDR_CS(n)        (((n) == 0) ? ORION5X_PCI_REG(0xc48) : \
                                 ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \
                                 ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \
-                                ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0)
+                                ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : NULL)
 #define PCI_BAR_ENABLE         ORION5X_PCI_REG(0xc3c)
 #define PCI_ADDR_DECODE_CTRL   ORION5X_PCI_REG(0xd3c)
 
index b1cf68493ffc35666b357d61242fafd01097b97d..b576ef5f18a16a777fd7948995d10d047a82eafe 100644 (file)
@@ -108,7 +108,7 @@ static struct platform_device rd88f5182_gpio_leds = {
  * PCI
  ****************************************************************************/
 
-void __init rd88f5182_pci_preinit(void)
+static void __init rd88f5182_pci_preinit(void)
 {
        int pin;
 
index 7e90648446980995bf00778342d1d2e57d546850..6208d125c1b946602ce12977ca45607a264685f6 100644 (file)
@@ -77,7 +77,7 @@ static struct platform_device tsp2_nor_flash = {
 #define TSP2_PCI_SLOT0_OFFS            7
 #define TSP2_PCI_SLOT0_IRQ_PIN         11
 
-void __init tsp2_pci_preinit(void)
+static void __init tsp2_pci_preinit(void)
 {
        int pin;
 
index e90c0618fdad5cb7cefe722639310811703b186d..9136797addb271816579c78505bd06630397d4d4 100644 (file)
@@ -106,7 +106,7 @@ static struct platform_device qnap_ts209_nor_flash = {
 #define QNAP_TS209_PCI_SLOT0_IRQ_PIN   6
 #define QNAP_TS209_PCI_SLOT1_IRQ_PIN   7
 
-void __init qnap_ts209_pci_preinit(void)
+static void __init qnap_ts209_pci_preinit(void)
 {
        int pin;
 
index e960855d32ac30b75e6a328181be3cbe8fed9535..db16dae441e252607bcb2d13f6e172b7410cc19d 100644 (file)
@@ -57,7 +57,7 @@ static struct map_desc ts78xx_io_desc[] __initdata = {
        },
 };
 
-void __init ts78xx_map_io(void)
+static void __init ts78xx_map_io(void)
 {
        orion5x_map_io();
        iotable_init(ts78xx_io_desc, ARRAY_SIZE(ts78xx_io_desc));
index a4a4b75109b218c53fc2cb8357f2465fb90b18d7..1b7df173db0ebaacef857684b622dff320a0ce92 100644 (file)
@@ -1,6 +1,10 @@
+config ARCH_SHMOBILE
+       bool
+
 config ARCH_SHMOBILE_MULTI
        bool "SH-Mobile Series" if ARCH_MULTI_V7
        depends on MMU
+       select ARCH_SHMOBILE
        select CPU_V7
        select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
@@ -30,7 +34,7 @@ config MACH_KZM9D
 comment "SH-Mobile System Configuration"
 endif
 
-if ARCH_SHMOBILE
+if ARCH_SHMOBILE_LEGACY
 
 comment "SH-Mobile System Type"
 
@@ -97,18 +101,22 @@ config ARCH_R8A7790
 
 config ARCH_R8A7791
        bool "R-Car M2 (R8A77910)"
+       select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
        select CPU_V7
        select SH_CLK_CPG
+       select RENESAS_IRQC
 
 config ARCH_EMEV2
        bool "Emma Mobile EV2"
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
        select CPU_V7
+       select USE_OF
 
 config ARCH_R7S72100
        bool "RZ/A1H (R7S72100)"
+       select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
        select CPU_V7
        select SH_CLK_CPG
@@ -231,12 +239,6 @@ config MACH_KOELSCH
        depends on ARCH_R8A7791
        select USE_OF
 
-config MACH_KZM9D
-       bool "KZM9D board"
-       depends on ARCH_EMEV2
-       select REGULATOR_FIXED_VOLTAGE if REGULATOR
-       select USE_OF
-
 config MACH_KZM9G
        bool "KZM-A9-GT board"
        depends on ARCH_SH73A0
@@ -274,7 +276,7 @@ source "drivers/sh/Kconfig"
 
 endif
 
-if ARCH_SHMOBILE || ARCH_SHMOBILE_MULTI
+if ARCH_SHMOBILE
 
 menu "Timer and clock configuration"
 
index 51db2bcafabf028f97cb4ffc5e32def8ef1aad77..c7e877499dc2d724708bbfa19a199231675eddc8 100644 (file)
@@ -71,7 +71,6 @@ obj-$(CONFIG_MACH_LAGER_REFERENCE)    += board-lager-reference.o
 obj-$(CONFIG_MACH_ARMADILLO800EVA)     += board-armadillo800eva.o
 obj-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE)   += board-armadillo800eva-reference.o
 obj-$(CONFIG_MACH_KOELSCH)     += board-koelsch.o
-obj-$(CONFIG_MACH_KZM9D)       += board-kzm9d.o
 obj-$(CONFIG_MACH_KZM9G)       += board-kzm9g.o
 obj-$(CONFIG_MACH_KZM9G_REFERENCE)     += board-kzm9g-reference.o
 endif
index 391d72a5536ceb473acee7eaf2f0312ef268b6ce..4f30e3dc0919150da0ec67ecca26caf0d07707e7 100644 (file)
@@ -8,7 +8,6 @@ loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000
 loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000
 loadaddr-$(CONFIG_MACH_GENMAI) += 0x8008000
 loadaddr-$(CONFIG_MACH_KOELSCH) += 0x40008000
-loadaddr-$(CONFIG_MACH_KZM9D) += 0x40008000
 loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000
 loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000
 loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000
index 0fa068e30a3001992952a41230cf9ca609793c72..fe071a9130b78d2986faecabfa7fb2f208166d4e 100644 (file)
@@ -168,7 +168,7 @@ static const struct sh_mmcif_plat_data mmcif0_pdata __initconst = {
 };
 
 static const struct resource mmcif0_resources[] __initconst = {
-       DEFINE_RES_MEM_NAMED(0xee200000, 0x100, "MMCIF0"),
+       DEFINE_RES_MEM(0xee200000, 0x100),
        DEFINE_RES_IRQ(gic_spi(169)),
 };
 
@@ -179,7 +179,7 @@ static const struct sh_mobile_sdhi_info sdhi0_pdata __initconst = {
 };
 
 static const struct resource sdhi0_resources[] __initconst = {
-       DEFINE_RES_MEM_NAMED(0xee100000, 0x100, "SDHI0"),
+       DEFINE_RES_MEM(0xee100000, 0x100),
        DEFINE_RES_IRQ(gic_spi(165)),
 };
 
@@ -191,7 +191,7 @@ static const struct sh_mobile_sdhi_info sdhi1_pdata __initconst = {
 };
 
 static const struct resource sdhi1_resources[] __initconst = {
-       DEFINE_RES_MEM_NAMED(0xee120000, 0x100, "SDHI1"),
+       DEFINE_RES_MEM(0xee120000, 0x100),
        DEFINE_RES_IRQ(gic_spi(166)),
 };
 
index ae88fdad4b3a9921ea02f9c1db001348753bb98a..875cf3f3f5035f572cb2665e323452a4a2023dca 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include <linux/of_platform.h>
-#include <linux/pinctrl/machine.h>
 #include <mach/common.h>
 #include <mach/r8a7778.h>
 #include <asm/mach/arch.h>
  *     see board-bock.c for checking detail of dip-switch
  */
 
-static const struct pinctrl_map bockw_pinctrl_map[] = {
-       /* SCIF0 */
-       PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778",
-                                 "scif0_data_a", "scif0"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778",
-                                 "scif0_ctrl", "scif0"),
-};
-
 #define FPGA   0x18200000
 #define IRQ0MR 0x30
 #define COMCTLR        0x101c
@@ -45,10 +36,6 @@ static void __init bockw_init(void)
 
        r8a7778_clock_init();
        r8a7778_init_irq_extpin_dt(1);
-
-       pinctrl_register_mappings(bockw_pinctrl_map,
-                                 ARRAY_SIZE(bockw_pinctrl_map));
-       r8a7778_pinmux_init();
        r8a7778_add_dt_devices();
 
        fpga = ioremap_nocache(FPGA, SZ_1M);
diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c
deleted file mode 100644 (file)
index 30c2cc6..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * kzm9d board support
- *
- * Copyright (C) 2012  Renesas Solutions Corp.
- * Copyright (C) 2012  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/machine.h>
-#include <linux/smsc911x.h>
-#include <mach/common.h>
-#include <mach/emev2.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-/* Dummy supplies, where voltage doesn't matter */
-static struct regulator_consumer_supply dummy_supplies[] = {
-       REGULATOR_SUPPLY("vddvario", "smsc911x"),
-       REGULATOR_SUPPLY("vdd33a", "smsc911x"),
-};
-
-/* Ether */
-static struct resource smsc911x_resources[] = {
-       [0] = {
-               .start  = 0x20000000,
-               .end    = 0x2000ffff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = EMEV2_GPIO_IRQ(1),
-               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
-       },
-};
-
-static struct smsc911x_platform_config smsc911x_platdata = {
-       .flags          = SMSC911X_USE_32BIT,
-       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
-       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
-};
-
-static struct platform_device smsc91x_device = {
-       .name   = "smsc911x",
-       .id     = -1,
-       .dev    = {
-                 .platform_data = &smsc911x_platdata,
-               },
-       .num_resources  = ARRAY_SIZE(smsc911x_resources),
-       .resource       = smsc911x_resources,
-};
-
-static struct platform_device *kzm9d_devices[] __initdata = {
-       &smsc91x_device,
-};
-
-void __init kzm9d_add_standard_devices(void)
-{
-       regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
-
-       emev2_add_standard_devices();
-
-       platform_add_devices(kzm9d_devices, ARRAY_SIZE(kzm9d_devices));
-}
-
-static const char *kzm9d_boards_compat_dt[] __initdata = {
-       "renesas,kzm9d",
-       NULL,
-};
-
-DT_MACHINE_START(KZM9D_DT, "kzm9d")
-       .smp            = smp_ops(emev2_smp_ops),
-       .map_io         = emev2_map_io,
-       .init_early     = emev2_init_delay,
-       .init_machine   = kzm9d_add_standard_devices,
-       .init_late      = shmobile_init_late,
-       .dt_compat      = kzm9d_boards_compat_dt,
-MACHINE_END
index 1a1a4a888632afb67fa47a532d3c251d3818fd65..7df9ea0839dbb76bc1ecfff15d1b9b5fadff09d9 100644 (file)
 
 #include <linux/init.h>
 #include <linux/of_platform.h>
+#include <mach/rcar-gen2.h>
 #include <mach/r8a7790.h>
 #include <asm/mach/arch.h>
 
 static void __init lager_add_standard_devices(void)
 {
-       /* clocks are setup late during boot in the case of DT */
        r8a7790_clock_init();
-
        r8a7790_add_dt_devices();
-        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static const char *lager_boards_compat_dt[] __initdata = {
index a8d3ce646fb900514fa983964bf8d70d0e88c278..d1a8dddecfc832cb38a736ddd1f2c8211a71fdba 100644 (file)
@@ -148,7 +148,7 @@ static const struct sh_mmcif_plat_data mmcif1_pdata __initconst = {
 };
 
 static const struct resource mmcif1_resources[] __initconst = {
-       DEFINE_RES_MEM_NAMED(0xee220000, 0x80, "MMCIF1"),
+       DEFINE_RES_MEM(0xee220000, 0x80),
        DEFINE_RES_IRQ(gic_spi(170)),
 };
 
@@ -245,7 +245,9 @@ static void __init lager_init(void)
 {
        lager_add_standard_devices();
 
-       phy_register_fixup_for_id("r8a7790-ether-ff:01", lager_ksz8041_fixup);
+       if (IS_ENABLED(CONFIG_PHYLIB))
+               phy_register_fixup_for_id("r8a7790-ether-ff:01",
+                                         lager_ksz8041_fixup);
 }
 
 static const char * const lager_boards_compat_dt[] __initconst = {
index da1352f5f71b6195969d17ef0de30ba9d4c8e7fe..d832a4477b4bdb8e46970c49ed1b45843405cf45 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/leds.h>
 #include <linux/dma-mapping.h>
 #include <linux/pinctrl/machine.h>
+#include <linux/platform_data/camera-rcar.h>
 #include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/rcar-du.h>
 #include <linux/platform_data/usb-rcar-phy.h>
@@ -259,10 +260,30 @@ static struct platform_device leds_device = {
        },
 };
 
+/* VIN */
 static struct rcar_vin_platform_data vin_platform_data __initdata = {
        .flags  = RCAR_VIN_BT656,
 };
 
+#define MARZEN_VIN(idx)                                                \
+static struct resource vin##idx##_resources[] __initdata = {   \
+       DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000),    \
+       DEFINE_RES_IRQ(gic_iid(0x5f + (idx))),                  \
+};                                                             \
+                                                               \
+static struct platform_device_info vin##idx##_info __initdata = { \
+       .parent         = &platform_bus,                        \
+       .name           = "r8a7779-vin",                        \
+       .id             = idx,                                  \
+       .res            = vin##idx##_resources,                 \
+       .num_res        = ARRAY_SIZE(vin##idx##_resources),     \
+       .dma_mask       = DMA_BIT_MASK(32),                     \
+       .data           = &vin_platform_data,                   \
+       .size_data      = sizeof(vin_platform_data),            \
+}
+MARZEN_VIN(1);
+MARZEN_VIN(3);
+
 #define MARZEN_CAMERA(idx)                                     \
 static struct i2c_board_info camera##idx##_info = {            \
        I2C_BOARD_INFO("adv7180", 0x20 + (idx)),                \
@@ -326,8 +347,6 @@ static const struct pinctrl_map marzen_pinctrl_map[] = {
                                  "sdhi0_ctrl", "sdhi0"),
        PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
                                  "sdhi0_cd", "sdhi0"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
-                                 "sdhi0_wp", "sdhi0"),
        /* SMSC */
        PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a7779",
                                  "intc_irq1_b", "intc"),
@@ -367,8 +386,8 @@ static void __init marzen_init(void)
        r8a7779_init_irq_extpin(1); /* IRQ1 as individual interrupt */
 
        r8a7779_add_standard_devices();
-       r8a7779_add_vin_device(1, &vin_platform_data);
-       r8a7779_add_vin_device(3, &vin_platform_data);
+       platform_device_register_full(&vin1_info);
+       platform_device_register_full(&vin3_info);
        platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
        marzen_add_du_device();
 }
index 4aba20ca127e1ef5f2cc214bfa946a28f216a6bf..7b457aed8253c96ce208de8d6575bca12af3012a 100644 (file)
@@ -170,6 +170,9 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
 
        /* MSTP clocks */
+       CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP33]),
+
+       /* ICK */
        CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]),
        CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]),
        CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]),
@@ -178,6 +181,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]),
        CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]),
        CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]),
+       CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP33]),
 };
 
 void __init r7s72100_clock_init(void)
index 571409b611d386b5067236248d129d2f0ca154a1..7348d58f500e9089bd46ef7a97cf4be79a8ec46b 100644 (file)
@@ -584,15 +584,15 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
        CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]),
        CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
-       CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]),
+       CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
-       CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]),
+       CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP312]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
-       CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]),
+       CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
-       CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]),
+       CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]),
        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
-       CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
+       CLKDEV_DEV_ID("ee200000.mmc", &mstp_clks[MSTP315]),
        CLKDEV_DEV_ID("e6550000.i2c", &mstp_clks[MSTP316]),
        CLKDEV_DEV_ID("e6560000.i2c", &mstp_clks[MSTP317]),
        CLKDEV_DEV_ID("e6500000.i2c", &mstp_clks[MSTP318]),
index c826bca4024e30bfc45a2cd07338f55cb5d97bac..6bfc8799708ec454eacd3193542f9f84c75baf2c 100644 (file)
@@ -589,18 +589,18 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("e6c20000.i2c",           &mstp_clks[MSTP323]),
        CLKDEV_DEV_ID("renesas_usbhs",          &mstp_clks[MSTP320]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.0",       &mstp_clks[MSTP314]),
-       CLKDEV_DEV_ID("e6850000.sdhi",          &mstp_clks[MSTP314]),
+       CLKDEV_DEV_ID("e6850000.sd",            &mstp_clks[MSTP314]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.1",       &mstp_clks[MSTP313]),
-       CLKDEV_DEV_ID("e6860000.sdhi",          &mstp_clks[MSTP313]),
+       CLKDEV_DEV_ID("e6860000.sd",            &mstp_clks[MSTP313]),
        CLKDEV_DEV_ID("sh_mmcif",               &mstp_clks[MSTP312]),
-       CLKDEV_DEV_ID("e6bd0000.mmcif",         &mstp_clks[MSTP312]),
+       CLKDEV_DEV_ID("e6bd0000.mmc",           &mstp_clks[MSTP312]),
        CLKDEV_DEV_ID("r8a7740-gether",         &mstp_clks[MSTP309]),
        CLKDEV_DEV_ID("e9a00000.sh-eth",        &mstp_clks[MSTP309]),
        CLKDEV_DEV_ID("renesas-tpu-pwm",        &mstp_clks[MSTP304]),
        CLKDEV_DEV_ID("e6600000.pwm",           &mstp_clks[MSTP304]),
 
        CLKDEV_DEV_ID("sh_mobile_sdhi.2",       &mstp_clks[MSTP415]),
-       CLKDEV_DEV_ID("e6870000.sdhi",          &mstp_clks[MSTP415]),
+       CLKDEV_DEV_ID("e6870000.sd",            &mstp_clks[MSTP415]),
 
        /* ICK */
        CLKDEV_ICK_ID("host",   "renesas_usbhs",        &mstp_clks[MSTP416]),
index fb6af83858e3f0210f9eeaae2c2794a5a618ca48..4b601bf4ede4de3d8395bc1515321f0e733c23fb 100644 (file)
@@ -173,9 +173,13 @@ static struct clk_lookup lookups[] = {
 
        /* MSTP32 clocks */
        CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP331]), /* MMC */
+       CLKDEV_DEV_ID("ffe4e000.mmc", &mstp_clks[MSTP331]), /* MMC */
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
+       CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
+       CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
+       CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
        CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
        CLKDEV_DEV_ID("r8a7778-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
        CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
@@ -183,9 +187,13 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
        CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP100]), /* USB FUNC */
        CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
+       CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
        CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
+       CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
        CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
+       CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
        CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
+       CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
        CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
        CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
        CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
@@ -195,8 +203,11 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
        CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP015]), /* TMU01 */
        CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
+       CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
        CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
+       CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
        CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
+       CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
        CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */
 
        CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]),
index 1f7080fab0a53556a4ce5efb3cbf3368dce71465..b7ce0e7d7d14acdeb310dd5bc834919c70e1c405 100644 (file)
@@ -184,9 +184,13 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
        CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP016]), /* TMU02 */
        CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
+       CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
        CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
+       CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
        CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
+       CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
        CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
+       CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
        CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
        CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
        CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
@@ -197,9 +201,13 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
        CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
+       CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
+       CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
+       CLKDEV_DEV_ID("ffe4e000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
+       CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP320]), /* SDHI3 */
        CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
 };
 
index a64f965c7da142b118ab42a52afadeb5038dff81..7960dc020e6a17c32863e0416c8b9a84dc4aac7a 100644 (file)
@@ -77,7 +77,7 @@ static struct sh_clk_ops followparent_clk_ops = {
 };
 
 static struct clk main_clk = {
-       /* .parent will be set r8a73a4_clock_init */
+       /* .parent will be set r8a7790_clock_init */
        .ops    = &followparent_clk_ops,
 };
 
@@ -183,9 +183,11 @@ static struct clk div6_clks[DIV6_NR] = {
 /* MSTP */
 enum {
        MSTP931, MSTP930, MSTP929, MSTP928,
+       MSTP917,
        MSTP813,
        MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720,
        MSTP717, MSTP716,
+       MSTP704,
        MSTP522,
        MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304,
        MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,
@@ -194,10 +196,11 @@ enum {
 };
 
 static struct clk mstp_clks[MSTP_NR] = {
-       [MSTP931] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 31, 0), /* I2C0 */
-       [MSTP930] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 30, 0), /* I2C1 */
-       [MSTP929] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 29, 0), /* I2C2 */
-       [MSTP928] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 28, 0), /* I2C3 */
+       [MSTP931] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 31, 0), /* I2C0 */
+       [MSTP930] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 30, 0), /* I2C1 */
+       [MSTP929] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 29, 0), /* I2C2 */
+       [MSTP928] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 28, 0), /* I2C3 */
+       [MSTP917] = SH_CLK_MSTP32(&qspi_clk, SMSTPCR9, 17, 0), /* QSPI */
        [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
        [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
        [MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */
@@ -208,6 +211,7 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
        [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */
        [MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */
+       [MSTP704] = SH_CLK_MSTP32(&mp_clk, SMSTPCR7, 4, 0), /* HSUSB */
        [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */
        [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, 0), /* MMC0 */
        [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_SD0], SMSTPCR3, 14, 0), /* SDHI0 */
@@ -262,11 +266,6 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("ssprs",          &div6_clks[DIV6_SSPRS]),
 
        /* MSTP */
-       CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]),
-       CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]),
-       CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]),
-       CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]),
-       CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]),
        CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
        CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
        CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),
@@ -282,20 +281,32 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]),
        CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]),
        CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]),
+       CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
        CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
-       CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
+       CLKDEV_DEV_ID("ee200000.mmc", &mstp_clks[MSTP315]),
        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
-       CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]),
+       CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
-       CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]),
+       CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
-       CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]),
+       CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP312]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
-       CLKDEV_DEV_ID("ee160000.sdhi", &mstp_clks[MSTP311]),
+       CLKDEV_DEV_ID("ee160000.sd", &mstp_clks[MSTP311]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
-       CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]),
+       CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]),
        CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
        CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+       CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
+       CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]),
+
+       /* ICK */
+       CLKDEV_ICK_ID("usbhs", "usb_phy_rcar_gen2", &mstp_clks[MSTP704]),
+       CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]),
+       CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]),
+       CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]),
+       CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]),
+       CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]),
+
 };
 
 #define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31)             \
@@ -321,10 +332,10 @@ void __init r8a7790_clock_init(void)
                R8A7790_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
                break;
        case MD(14):
-               R8A7790_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
+               R8A7790_CLOCK_ROOT(26 / 2, &extal_div2_clk, 200, 240, 122, 102);
                break;
        case MD(13) | MD(14):
-               R8A7790_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
+               R8A7790_CLOCK_ROOT(30 / 2, &extal_div2_clk, 172, 208, 106, 88);
                break;
        }
 
index c9a26f16ce5b68bb1fc01a9c036a8299262df0e7..ff2d60d55bd5310ed6e6e286a396392d176058f0 100644 (file)
@@ -103,6 +103,7 @@ SH_FIXED_RATIO_CLK_SET(hp_clk,                      pll1_clk,       1, 12);
 SH_FIXED_RATIO_CLK_SET(p_clk,                  pll1_clk,       1, 24);
 SH_FIXED_RATIO_CLK_SET(rclk_clk,               pll1_clk,       1, (48 * 1024));
 SH_FIXED_RATIO_CLK_SET(mp_clk,                 pll1_div2_clk,  1, 15);
+SH_FIXED_RATIO_CLK_SET(zx_clk,                 pll1_clk,       1, 3);
 
 static struct clk *main_clks[] = {
        &extal_clk,
@@ -116,12 +117,14 @@ static struct clk *main_clks[] = {
        &rclk_clk,
        &mp_clk,
        &cp_clk,
+       &zx_clk,
 };
 
 /* MSTP */
 enum {
-       MSTP721, MSTP720,
+       MSTP726, MSTP724, MSTP723, MSTP721, MSTP720,
        MSTP719, MSTP718, MSTP715, MSTP714,
+       MSTP522,
        MSTP216, MSTP207, MSTP206,
        MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107,
        MSTP124,
@@ -129,12 +132,16 @@ enum {
 };
 
 static struct clk mstp_clks[MSTP_NR] = {
+       [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
+       [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */
+       [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */
        [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
        [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
        [MSTP719] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 19, 0), /* SCIF2 */
        [MSTP718] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 18, 0), /* SCIF3 */
        [MSTP715] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 15, 0), /* SCIF4 */
        [MSTP714] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 14, 0), /* SCIF5 */
+       [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */
        [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
        [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
        [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
@@ -164,6 +171,9 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("peripheral_clk", &hp_clk),
 
        /* MSTP */
+       CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7791", &mstp_clks[MSTP726]),
+       CLKDEV_ICK_ID("du.0", "rcar-du-r8a7791", &mstp_clks[MSTP724]),
+       CLKDEV_ICK_ID("du.1", "rcar-du-r8a7791", &mstp_clks[MSTP723]),
        CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
        CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
        CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */
@@ -180,6 +190,8 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */
        CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */
        CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
+       CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
+       CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
 };
 
 #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31)             \
index 5390c6bbbc02dd389852ba519118ddaab2222a37..28489978b09ca949e7f6b1209a7f200c2373ae16 100644 (file)
@@ -504,10 +504,6 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
        CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
        CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
-       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
-       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
-       CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
-       CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
 
        /* MSTP32 clocks */
        CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
@@ -574,6 +570,11 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
        CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
 
+       /* ICK */
+       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
+       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
+       CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+       CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
        CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
                      &div6_reparent_clks[DIV6_HDMI]),
        CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
index c92c023f0d27c1de8778665e372d1abfba82db42..30d88689a9601af8eed53add75583db590c7342f 100644 (file)
@@ -625,12 +625,6 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
        CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
        CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
-       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
-       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
-       CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
-       CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
-       CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
-       CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
 
        /* MSTP32 clocks */
        CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
@@ -663,13 +657,13 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
        CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
-       CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
+       CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), /* SDHI0 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
-       CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
+       CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), /* SDHI1 */
        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
-       CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
+       CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), /* MMCIF0 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
-       CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP311]), /* SDHI2 */
+       CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP311]), /* SDHI2 */
        CLKDEV_DEV_ID("renesas-tpu-pwm.0", &mstp_clks[MSTP304]), /* TPU0 */
        CLKDEV_DEV_ID("renesas-tpu-pwm.1", &mstp_clks[MSTP303]), /* TPU1 */
        CLKDEV_DEV_ID("renesas-tpu-pwm.2", &mstp_clks[MSTP302]), /* TPU2 */
@@ -680,6 +674,14 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
        CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
        CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+
+       /* ICK */
+       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
+       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
+       CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+       CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+       CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
+       CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
 };
 
 void __init sh73a0_clock_init(void)
index c2eb7568d9bed4080b468efa9aba4a26e7d6d043..fcb142a14e0756b55eedec81a63fb0c78e51f302 100644 (file)
@@ -3,12 +3,7 @@
 
 extern void emev2_map_io(void);
 extern void emev2_init_delay(void);
-extern void emev2_add_standard_devices(void);
 extern void emev2_clock_init(void);
-
-#define EMEV2_GPIO_BASE 200
-#define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n))
-
 extern struct smp_operations emev2_smp_ops;
 
 #endif /* __ASM_EMEV2_H__ */
index 17af34ed89c801553b248f12f0d3c39336553854..5014145f272e22a1247c34f54b1039369ee4bc50 100644 (file)
@@ -3,8 +3,6 @@
 
 #include <linux/sh_clk.h>
 #include <linux/pm_domain.h>
-#include <linux/sh_eth.h>
-#include <linux/platform_data/camera-rcar.h>
 
 /* HPB-DMA slave IDs */
 enum {
@@ -40,9 +38,6 @@ extern void r8a7779_earlytimer_init(void);
 extern void r8a7779_add_early_devices(void);
 extern void r8a7779_add_standard_devices(void);
 extern void r8a7779_add_standard_devices_dt(void);
-extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata);
-extern void r8a7779_add_vin_device(int idx,
-                                  struct rcar_vin_platform_data *pdata);
 extern void r8a7779_init_late(void);
 extern void r8a7779_clock_init(void);
 extern void r8a7779_pinmux_init(void);
index 051ead3c286e7f4a7bc2015bb8e384e74972cc5c..200fa699f730e81fe8e02336ee69e07cc20e6898 100644 (file)
@@ -4,6 +4,7 @@
 void r8a7791_add_standard_devices(void);
 void r8a7791_add_dt_devices(void);
 void r8a7791_clock_init(void);
+void r8a7791_pinmux_init(void);
 void r8a7791_init_early(void);
 extern struct smp_operations r8a7791_smp_ops;
 
index 3ad531caf4f098a172d01824263546c5e2cc2c08..c8f2a1a69a5274bec8eab99f44549fb3bbbae955 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
+#include <linux/clk-provider.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/gpio-em.h>
 #include <linux/of_platform.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/irqchip/arm-gic.h>
 #include <mach/common.h>
 #include <mach/emev2.h>
-#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/mach/time.h>
 
 static struct map_desc emev2_io_desc[] __initdata = {
 #ifdef CONFIG_SMP
@@ -52,150 +43,20 @@ void __init emev2_map_io(void)
        iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc));
 }
 
-/* UART */
-static struct resource uart0_resources[] = {
-       DEFINE_RES_MEM(0xe1020000, 0x38),
-       DEFINE_RES_IRQ(40),
-};
-
-static struct resource uart1_resources[] = {
-       DEFINE_RES_MEM(0xe1030000, 0x38),
-       DEFINE_RES_IRQ(41),
-};
-
-static struct resource uart2_resources[] = {
-       DEFINE_RES_MEM(0xe1040000, 0x38),
-       DEFINE_RES_IRQ(42),
-};
-
-static struct resource uart3_resources[] = {
-       DEFINE_RES_MEM(0xe1050000, 0x38),
-       DEFINE_RES_IRQ(43),
-};
-
-#define emev2_register_uart(idx)                                       \
-       platform_device_register_simple("serial8250-em", idx,           \
-                                       uart##idx##_resources,          \
-                                       ARRAY_SIZE(uart##idx##_resources))
-
-/* STI */
-static struct resource sti_resources[] = {
-       DEFINE_RES_MEM(0xe0180000, 0x54),
-       DEFINE_RES_IRQ(157),
-};
-
-#define emev2_register_sti()                                   \
-       platform_device_register_simple("em_sti", 0,            \
-                                       sti_resources,          \
-                                       ARRAY_SIZE(sti_resources))
-
-/* GIO */
-static struct gpio_em_config gio0_config = {
-       .gpio_base = 0,
-       .irq_base = EMEV2_GPIO_IRQ(0),
-       .number_of_pins = 32,
-};
-
-static struct resource gio0_resources[] = {
-       DEFINE_RES_MEM(0xe0050000, 0x2c),
-       DEFINE_RES_MEM(0xe0050040, 0x20),
-       DEFINE_RES_IRQ(99),
-       DEFINE_RES_IRQ(100),
-};
-
-static struct gpio_em_config gio1_config = {
-       .gpio_base = 32,
-       .irq_base = EMEV2_GPIO_IRQ(32),
-       .number_of_pins = 32,
-};
-
-static struct resource gio1_resources[] = {
-       DEFINE_RES_MEM(0xe0050080, 0x2c),
-       DEFINE_RES_MEM(0xe00500c0, 0x20),
-       DEFINE_RES_IRQ(101),
-       DEFINE_RES_IRQ(102),
-};
-
-static struct gpio_em_config gio2_config = {
-       .gpio_base = 64,
-       .irq_base = EMEV2_GPIO_IRQ(64),
-       .number_of_pins = 32,
-};
-
-static struct resource gio2_resources[] = {
-       DEFINE_RES_MEM(0xe0050100, 0x2c),
-       DEFINE_RES_MEM(0xe0050140, 0x20),
-       DEFINE_RES_IRQ(103),
-       DEFINE_RES_IRQ(104),
-};
-
-static struct gpio_em_config gio3_config = {
-       .gpio_base = 96,
-       .irq_base = EMEV2_GPIO_IRQ(96),
-       .number_of_pins = 32,
-};
-
-static struct resource gio3_resources[] = {
-       DEFINE_RES_MEM(0xe0050180, 0x2c),
-       DEFINE_RES_MEM(0xe00501c0, 0x20),
-       DEFINE_RES_IRQ(105),
-       DEFINE_RES_IRQ(106),
-};
-
-static struct gpio_em_config gio4_config = {
-       .gpio_base = 128,
-       .irq_base = EMEV2_GPIO_IRQ(128),
-       .number_of_pins = 31,
-};
-
-static struct resource gio4_resources[] = {
-       DEFINE_RES_MEM(0xe0050200, 0x2c),
-       DEFINE_RES_MEM(0xe0050240, 0x20),
-       DEFINE_RES_IRQ(107),
-       DEFINE_RES_IRQ(108),
-};
-
-#define emev2_register_gio(idx)                                                \
-       platform_device_register_resndata(&platform_bus, "em_gio",      \
-                                         idx, gio##idx##_resources,    \
-                                         ARRAY_SIZE(gio##idx##_resources), \
-                                         &gio##idx##_config,           \
-                                         sizeof(struct gpio_em_config))
-
-static struct resource pmu_resources[] = {
-       DEFINE_RES_IRQ(152),
-       DEFINE_RES_IRQ(153),
-};
-
-#define emev2_register_pmu()                                   \
-       platform_device_register_simple("arm-pmu", -1,          \
-                                       pmu_resources,          \
-                                       ARRAY_SIZE(pmu_resources))
-
-void __init emev2_add_standard_devices(void)
-{
-       if (!IS_ENABLED(CONFIG_COMMON_CLK))
-               emev2_clock_init();
-
-       emev2_register_uart(0);
-       emev2_register_uart(1);
-       emev2_register_uart(2);
-       emev2_register_uart(3);
-       emev2_register_sti();
-       emev2_register_gio(0);
-       emev2_register_gio(1);
-       emev2_register_gio(2);
-       emev2_register_gio(3);
-       emev2_register_gio(4);
-       emev2_register_pmu();
-}
-
 void __init emev2_init_delay(void)
 {
        shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */
 }
 
-#ifdef CONFIG_USE_OF
+static void __init emev2_add_standard_devices_dt(void)
+{
+#ifdef CONFIG_COMMON_CLK
+       of_clk_init(NULL);
+#else
+       emev2_clock_init();
+#endif
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
 
 static const char *emev2_boards_compat_dt[] __initdata = {
        "renesas,emev2",
@@ -206,7 +67,7 @@ DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
        .smp            = smp_ops(emev2_smp_ops),
        .map_io         = emev2_map_io,
        .init_early     = emev2_init_delay,
+       .init_machine   = emev2_add_standard_devices_dt,
+       .init_late      = shmobile_init_late,
        .dt_compat      = emev2_boards_compat_dt,
 MACHINE_END
-
-#endif /* CONFIG_USE_OF */
index d4eb509a1c878b2add188c4760b30684773535ac..55f0b9c7c482c04c7b1631b6b3c482e0ffcb957d 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
 #include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
 #include <mach/common.h>
 #include <mach/irqs.h>
 #include <mach/r7s72100.h>
@@ -58,6 +59,26 @@ static inline void r7s72100_register_scif(int idx)
                                      sizeof(struct plat_sci_port));
 }
 
+
+static struct sh_timer_config mtu2_0_platform_data __initdata = {
+       .name = "MTU2_0",
+       .timer_bit = 0,
+       .channel_offset = -0x80,
+       .clockevent_rating = 200,
+};
+
+static struct resource mtu2_0_resources[] __initdata = {
+       DEFINE_RES_MEM(0xfcff0300, 0x27),
+       DEFINE_RES_IRQ(gic_iid(139)), /* MTU2 TGI0A */
+};
+
+#define r7s72100_register_mtu2(idx)                                    \
+       platform_device_register_resndata(&platform_bus, "sh_mtu2",     \
+                                         idx, mtu2_##idx##_resources,  \
+                                         ARRAY_SIZE(mtu2_##idx##_resources), \
+                                         &mtu2_##idx##_platform_data,  \
+                                         sizeof(struct sh_timer_config))
+
 void __init r7s72100_add_dt_devices(void)
 {
        r7s72100_register_scif(SCIF0);
@@ -68,6 +89,7 @@ void __init r7s72100_add_dt_devices(void)
        r7s72100_register_scif(SCIF5);
        r7s72100_register_scif(SCIF6);
        r7s72100_register_scif(SCIF7);
+       r7s72100_register_mtu2(0);
 }
 
 void __init r7s72100_init_early(void)
index b0f2749071bec3feee42e44a82c52449a8494e81..cc94b64c2ef50a0795ab7bb2a6435599d4320ea7 100644 (file)
@@ -275,7 +275,7 @@ static const struct sh_dmae_pdata dma_pdata = {
 
 static struct resource dma_resources[] = {
        DEFINE_RES_MEM(0xe6700020, 0x89e0),
-       DEFINE_RES_IRQ_NAMED(gic_spi(220), "error_irq"),
+       DEFINE_RES_IRQ(gic_spi(220)),
        {
                /* IRQ for channels 0-19 */
                .start  = gic_spi(200),
index 13049e9d691ca17d7be5d5d3dc9b8b565b42a3e3..8f9453152fb91f9760185466cf666c23c8eb1052 100644 (file)
@@ -598,45 +598,6 @@ static struct platform_device ohci1_device = {
        .resource       = ohci1_resources,
 };
 
-/* Ether */
-static struct resource ether_resources[] __initdata = {
-       {
-               .start  = 0xfde00000,
-               .end    = 0xfde003ff,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = gic_iid(0xb4),
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-#define R8A7779_VIN(idx) \
-static struct resource vin##idx##_resources[] __initdata = {           \
-       DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000),            \
-       DEFINE_RES_IRQ(gic_iid(0x5f + (idx))),                          \
-};                                                                     \
-                                                                       \
-static struct platform_device_info vin##idx##_info __initdata = {      \
-       .parent         = &platform_bus,                                \
-       .name           = "r8a7779-vin",                                \
-       .id             = idx,                                          \
-       .res            = vin##idx##_resources,                         \
-       .num_res        = ARRAY_SIZE(vin##idx##_resources),             \
-       .dma_mask       = DMA_BIT_MASK(32),                             \
-}
-
-R8A7779_VIN(0);
-R8A7779_VIN(1);
-R8A7779_VIN(2);
-R8A7779_VIN(3);
-
-static struct platform_device_info *vin_info_table[] __initdata = {
-       &vin0_info,
-       &vin1_info,
-       &vin2_info,
-       &vin3_info,
-};
-
 /* HPB-DMA */
 
 /* Asynchronous mode register bits */
@@ -825,24 +786,6 @@ void __init r8a7779_add_standard_devices(void)
        r8a7779_register_hpb_dmae();
 }
 
-void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata)
-{
-       platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1,
-                                         ether_resources,
-                                         ARRAY_SIZE(ether_resources),
-                                         pdata, sizeof(*pdata));
-}
-
-void __init r8a7779_add_vin_device(int id, struct rcar_vin_platform_data *pdata)
-{
-       BUG_ON(id < 0 || id > 3);
-
-       vin_info_table[id]->data = pdata;
-       vin_info_table[id]->size_data = sizeof(*pdata);
-
-       platform_device_register_full(vin_info_table[id]);
-}
-
 /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
 void __init __weak r8a7779_register_twd(void) { }
 
index c47bcebbcb00bbfa229d16c9d2fcad2430ef631e..3543c3bacb75d828cd9681f9e5b93740822a9467 100644 (file)
@@ -34,6 +34,10 @@ static const struct resource pfc_resources[] __initconst = {
        DEFINE_RES_MEM(0xe6060000, 0x250),
 };
 
+#define r8a7790_register_pfc()                                         \
+       platform_device_register_simple("pfc-r8a7790", -1, pfc_resources, \
+                                       ARRAY_SIZE(pfc_resources))
+
 #define R8A7790_GPIO(idx)                                              \
 static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \
        DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50),              \
@@ -65,8 +69,7 @@ R8A7790_GPIO(5);
 
 void __init r8a7790_pinmux_init(void)
 {
-       platform_device_register_simple("pfc-r8a7790", -1, pfc_resources,
-                                       ARRAY_SIZE(pfc_resources));
+       r8a7790_register_pfc();
        r8a7790_register_gpio(0);
        r8a7790_register_gpio(1);
        r8a7790_register_gpio(2);
index d9393d61ee27028fb59efe284cc7d9d69db132d6..cddca99b434f051ebdbf9e2ffe27d9a6482a2cc1 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/irq-renesas-irqc.h>
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
 #include <mach/rcar-gen2.h>
 #include <asm/mach/arch.h>
 
+static const struct resource pfc_resources[] __initconst = {
+       DEFINE_RES_MEM(0xe6060000, 0x250),
+};
+
+#define r8a7791_register_pfc()                                         \
+       platform_device_register_simple("pfc-r8a7791", -1, pfc_resources, \
+                                       ARRAY_SIZE(pfc_resources))
+
+#define R8A7791_GPIO(idx, base, nr)                                    \
+static const struct resource r8a7791_gpio##idx##_resources[] __initconst = { \
+       DEFINE_RES_MEM((base), 0x50),                                   \
+       DEFINE_RES_IRQ(gic_spi(4 + (idx))),                             \
+};                                                                     \
+                                                                       \
+static const struct gpio_rcar_config                                   \
+r8a7791_gpio##idx##_platform_data __initconst = {                      \
+       .gpio_base      = 32 * (idx),                                   \
+       .irq_base       = 0,                                            \
+       .number_of_pins = (nr),                                         \
+       .pctl_name      = "pfc-r8a7791",                                \
+       .has_both_edge_trigger = 1,                                     \
+};                                                                     \
+
+R8A7791_GPIO(0, 0xe6050000, 32);
+R8A7791_GPIO(1, 0xe6051000, 32);
+R8A7791_GPIO(2, 0xe6052000, 32);
+R8A7791_GPIO(3, 0xe6053000, 32);
+R8A7791_GPIO(4, 0xe6054000, 32);
+R8A7791_GPIO(5, 0xe6055000, 32);
+R8A7791_GPIO(6, 0xe6055400, 32);
+R8A7791_GPIO(7, 0xe6055800, 26);
+
+#define r8a7791_register_gpio(idx)                                     \
+       platform_device_register_resndata(&platform_bus, "gpio_rcar", idx, \
+               r8a7791_gpio##idx##_resources,                          \
+               ARRAY_SIZE(r8a7791_gpio##idx##_resources),              \
+               &r8a7791_gpio##idx##_platform_data,                     \
+               sizeof(r8a7791_gpio##idx##_platform_data))
+
+void __init r8a7791_pinmux_init(void)
+{
+       r8a7791_register_pfc();
+       r8a7791_register_gpio(0);
+       r8a7791_register_gpio(1);
+       r8a7791_register_gpio(2);
+       r8a7791_register_gpio(3);
+       r8a7791_register_gpio(4);
+       r8a7791_register_gpio(5);
+       r8a7791_register_gpio(6);
+       r8a7791_register_gpio(7);
+}
+
 #define SCIF_COMMON(scif_type, baseaddr, irq)                  \
        .type           = scif_type,                            \
        .mapbase        = baseaddr,                             \
@@ -136,6 +189,17 @@ static struct resource irqc0_resources[] = {
                                          &irqc##idx##_data,            \
                                          sizeof(struct renesas_irqc_config))
 
+static const struct resource thermal_resources[] __initconst = {
+       DEFINE_RES_MEM(0xe61f0000, 0x14),
+       DEFINE_RES_MEM(0xe61f0100, 0x38),
+       DEFINE_RES_IRQ(gic_spi(69)),
+};
+
+#define r8a7791_register_thermal()                                     \
+       platform_device_register_simple("rcar_thermal", -1,             \
+                                       thermal_resources,              \
+                                       ARRAY_SIZE(thermal_resources))
+
 void __init r8a7791_add_dt_devices(void)
 {
        r8a7791_register_scif(SCIFA0);
@@ -160,6 +224,7 @@ void __init r8a7791_add_standard_devices(void)
 {
        r8a7791_add_dt_devices();
        r8a7791_register_irqc(0);
+       r8a7791_register_thermal();
 }
 
 void __init r8a7791_init_early(void)
index 22de17417fd7c83a4ae4c9b66162cd3c16f1cb04..65151c48cbd4fdc1ee431abf4ce264358d4ad69b 100644 (file)
@@ -273,7 +273,7 @@ static struct sh_timer_config tmu00_platform_data = {
 };
 
 static struct resource tmu00_resources[] = {
-       [0] = DEFINE_RES_MEM_NAMED(0xfff60008, 0xc, "TMU00"),
+       [0] = DEFINE_RES_MEM(0xfff60008, 0xc),
        [1] = {
                .start  = intcs_evt2irq(0x0e80), /* TMU0_TUNI00 */
                .flags  = IORESOURCE_IRQ,
@@ -298,7 +298,7 @@ static struct sh_timer_config tmu01_platform_data = {
 };
 
 static struct resource tmu01_resources[] = {
-       [0] = DEFINE_RES_MEM_NAMED(0xfff60014, 0xc, "TMU00"),
+       [0] = DEFINE_RES_MEM(0xfff60014, 0xc),
        [1] = {
                .start  = intcs_evt2irq(0x0ea0), /* TMU0_TUNI01 */
                .flags  = IORESOURCE_IRQ,
@@ -316,7 +316,7 @@ static struct platform_device tmu01_device = {
 };
 
 static struct resource i2c0_resources[] = {
-       [0] = DEFINE_RES_MEM_NAMED(0xe6820000, 0x426, "IIC0"),
+       [0] = DEFINE_RES_MEM(0xe6820000, 0x426),
        [1] = {
                .start  = gic_spi(167),
                .end    = gic_spi(170),
@@ -325,7 +325,7 @@ static struct resource i2c0_resources[] = {
 };
 
 static struct resource i2c1_resources[] = {
-       [0] = DEFINE_RES_MEM_NAMED(0xe6822000, 0x426, "IIC1"),
+       [0] = DEFINE_RES_MEM(0xe6822000, 0x426),
        [1] = {
                .start  = gic_spi(51),
                .end    = gic_spi(54),
@@ -334,7 +334,7 @@ static struct resource i2c1_resources[] = {
 };
 
 static struct resource i2c2_resources[] = {
-       [0] = DEFINE_RES_MEM_NAMED(0xe6824000, 0x426, "IIC2"),
+       [0] = DEFINE_RES_MEM(0xe6824000, 0x426),
        [1] = {
                .start  = gic_spi(171),
                .end    = gic_spi(174),
@@ -343,7 +343,7 @@ static struct resource i2c2_resources[] = {
 };
 
 static struct resource i2c3_resources[] = {
-       [0] = DEFINE_RES_MEM_NAMED(0xe6826000, 0x426, "IIC3"),
+       [0] = DEFINE_RES_MEM(0xe6826000, 0x426),
        [1] = {
                .start  = gic_spi(183),
                .end    = gic_spi(186),
@@ -352,7 +352,7 @@ static struct resource i2c3_resources[] = {
 };
 
 static struct resource i2c4_resources[] = {
-       [0] = DEFINE_RES_MEM_NAMED(0xe6828000, 0x426, "IIC4"),
+       [0] = DEFINE_RES_MEM(0xe6828000, 0x426),
        [1] = {
                .start  = gic_spi(187),
                .end    = gic_spi(190),
@@ -722,7 +722,7 @@ static struct platform_device pmu_device = {
 
 /* an IPMMU module for ICB */
 static struct resource ipmmu_resources[] = {
-       DEFINE_RES_MEM_NAMED(0xfe951000, 0x100, "IPMMU"),
+       DEFINE_RES_MEM(0xfe951000, 0x100),
 };
 
 static const char * const ipmmu_dev_names[] = {
index d4639c5066222ea785f3dab068f46874fd52513c..9a4e910c3796154c8fa6c167851a8f6b112265f3 100644 (file)
@@ -209,13 +209,3 @@ void __init tegra_init_fuse(void)
                tegra_sku_id, tegra_cpu_process_id,
                tegra_core_process_id);
 }
-
-unsigned long long tegra_chip_uid(void)
-{
-       unsigned long long lo, hi;
-
-       lo = tegra_fuse_readl(FUSE_UID_LOW);
-       hi = tegra_fuse_readl(FUSE_UID_HIGH);
-       return (hi << 32ull) | lo;
-}
-EXPORT_SYMBOL(tegra_chip_uid);
index 2e85c1e72535138a1b90c543ec3e95e2b36a6fa6..12c7e5c03ea488336eac954daab98f4b6a22c649 100644 (file)
@@ -140,6 +140,10 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
        /* Requires call-back bindings. */
        OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
        /* Requires DMA bindings. */
+       OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0",  &mop500_sdi0_data),
+       OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1",  &mop500_sdi1_data),
+       OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2",  &mop500_sdi2_data),
+       OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4",  &mop500_sdi4_data),
        OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
                       "ux500-msp-i2s.0", &msp0_platform_data),
        OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000,
index bdb356498a748563091d7563525db015500dbfc1..b1dd8584bed48d13efa4bde9c6b57074598009fa 100644 (file)
@@ -43,7 +43,7 @@ extern void ux500_timer_init(void);
        .virtual        = IO_ADDRESS(x),        \
        .pfn            = __phys_to_pfn(x),     \
        .length         = sz,                   \
-       .type           = MT_MEMORY,            \
+       .type           = MT_MEMORY_RWX,                \
 }
 
 extern struct smp_operations ux500_smp_ops;
index 033d34dcbd3fb8a8e1325900ddecdeb64090e874..c26ef5b92ca78587ce35b0f597a9cea66f9d592a 100644 (file)
 #define A15_BX_ADDR0           0x68
 #define A7_BX_ADDR0            0x78
 
+/* SPC CPU/cluster reset statue */
+#define STANDBYWFI_STAT                0x3c
+#define STANDBYWFI_STAT_A15_CPU_MASK(cpu)      (1 << (cpu))
+#define STANDBYWFI_STAT_A7_CPU_MASK(cpu)       (1 << (3 + (cpu)))
+
 /* SPC system config interface registers */
 #define SYSCFG_WDATA           0x70
 #define SYSCFG_RDATA           0x74
@@ -213,6 +218,41 @@ void ve_spc_powerdown(u32 cluster, bool enable)
        writel_relaxed(enable, info->baseaddr + pwdrn_reg);
 }
 
+static u32 standbywfi_cpu_mask(u32 cpu, u32 cluster)
+{
+       return cluster_is_a15(cluster) ?
+                 STANDBYWFI_STAT_A15_CPU_MASK(cpu)
+               : STANDBYWFI_STAT_A7_CPU_MASK(cpu);
+}
+
+/**
+ * ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
+ *
+ * @cpu: mpidr[7:0] bitfield describing CPU affinity level within cluster
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ *
+ * @return: non-zero if and only if the specified CPU is in WFI
+ *
+ * Take care when interpreting the result of this function: a CPU might
+ * be in WFI temporarily due to idle, and is not necessarily safely
+ * parked.
+ */
+int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
+{
+       int ret;
+       u32 mask = standbywfi_cpu_mask(cpu, cluster);
+
+       if (cluster >= MAX_CLUSTERS)
+               return 1;
+
+       ret = readl_relaxed(info->baseaddr + STANDBYWFI_STAT);
+
+       pr_debug("%s: PCFGREG[0x%X] = 0x%08X, mask = 0x%X\n",
+                __func__, STANDBYWFI_STAT, ret, mask);
+
+       return ret & mask;
+}
+
 static int ve_spc_get_performance(int cluster, u32 *freq)
 {
        struct ve_spc_opp *opps = info->opps[cluster];
index dbd44c3720f98e711e5cabf28e6734847d8c7ea8..793d065243b9e469300be86a3325f777d7a37b4c 100644 (file)
@@ -20,5 +20,6 @@ void ve_spc_global_wakeup_irq(bool set);
 void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set);
 void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr);
 void ve_spc_powerdown(u32 cluster, bool enable);
+int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster);
 
 #endif
index 05a364c5077a7a40f4c3a348bced3a70e22ea280..29e7785a54bcbbb3e4e7fa3f2f46180e430ad91c 100644 (file)
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include "spc.h"
 
 /* SCC conf registers */
+#define RESET_CTRL             0x018
+#define RESET_A15_NCORERESET(cpu)      (1 << (2 + (cpu)))
+#define RESET_A7_NCORERESET(cpu)       (1 << (16 + (cpu)))
+
 #define A15_CONF               0x400
 #define A7_CONF                        0x500
 #define SYS_INFO               0x700
 #define SPC_BASE               0xb00
 
+static void __iomem *scc;
+
 /*
  * We can't use regular spinlocks. In the switcher case, it is possible
  * for an outbound CPU to call power_down() after its inbound counterpart
@@ -190,6 +197,55 @@ static void tc2_pm_power_down(void)
        tc2_pm_down(0);
 }
 
+static int tc2_core_in_reset(unsigned int cpu, unsigned int cluster)
+{
+       u32 mask = cluster ?
+                 RESET_A7_NCORERESET(cpu)
+               : RESET_A15_NCORERESET(cpu);
+
+       return !(readl_relaxed(scc + RESET_CTRL) & mask);
+}
+
+#define POLL_MSEC 10
+#define TIMEOUT_MSEC 1000
+
+static int tc2_pm_power_down_finish(unsigned int cpu, unsigned int cluster)
+{
+       unsigned tries;
+
+       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+       BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
+
+       for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; ++tries) {
+               /*
+                * Only examine the hardware state if the target CPU has
+                * caught up at least as far as tc2_pm_down():
+                */
+               if (ACCESS_ONCE(tc2_pm_use_count[cpu][cluster]) == 0) {
+                       pr_debug("%s(cpu=%u, cluster=%u): RESET_CTRL = 0x%08X\n",
+                                __func__, cpu, cluster,
+                                readl_relaxed(scc + RESET_CTRL));
+
+                       /*
+                        * We need the CPU to reach WFI, but the power
+                        * controller may put the cluster in reset and
+                        * power it off as soon as that happens, before
+                        * we have a chance to see STANDBYWFI.
+                        *
+                        * So we need to check for both conditions:
+                        */
+                       if (tc2_core_in_reset(cpu, cluster) ||
+                           ve_spc_cpu_in_wfi(cpu, cluster))
+                               return 0; /* success: the CPU is halted */
+               }
+
+               /* Otherwise, wait and retry: */
+               msleep(POLL_MSEC);
+       }
+
+       return -ETIMEDOUT; /* timeout */
+}
+
 static void tc2_pm_suspend(u64 residency)
 {
        unsigned int mpidr, cpu, cluster;
@@ -232,10 +288,11 @@ static void tc2_pm_powered_up(void)
 }
 
 static const struct mcpm_platform_ops tc2_pm_power_ops = {
-       .power_up       = tc2_pm_power_up,
-       .power_down     = tc2_pm_power_down,
-       .suspend        = tc2_pm_suspend,
-       .powered_up     = tc2_pm_powered_up,
+       .power_up               = tc2_pm_power_up,
+       .power_down             = tc2_pm_power_down,
+       .power_down_finish      = tc2_pm_power_down_finish,
+       .suspend                = tc2_pm_suspend,
+       .powered_up             = tc2_pm_powered_up,
 };
 
 static bool __init tc2_pm_usage_count_init(void)
@@ -269,7 +326,6 @@ static void __naked tc2_pm_power_up_setup(unsigned int affinity_level)
 static int __init tc2_pm_init(void)
 {
        int ret, irq;
-       void __iomem *scc;
        u32 a15_cluster_id, a7_cluster_id, sys_info;
        struct device_node *np;
 
index ecfe6e53f6e03ffe7a12bf0776b784106f7efe19..7f39ce2f841fb1f9056269c1a8ce415b89a21191 100644 (file)
@@ -12,6 +12,7 @@ ifneq ($(CONFIG_MMU),y)
 obj-y                          += nommu.o
 endif
 
+obj-$(CONFIG_ARM_PTDUMP)       += dump.o
 obj-$(CONFIG_MODULES)          += proc-syms.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)   += alignment.o
index b5c467a65c271a8c8538defc2880b0689067d046..778bcf88ee798b4104f35fef3ed1d6fc933f3392 100644 (file)
@@ -146,18 +146,18 @@ flush_levels:
        ldr     r7, =0x7fff
        ands    r7, r7, r1, lsr #13             @ extract max number of the index size
 loop1:
-       mov     r9, r4                          @ create working copy of max way size
+       mov     r9, r7                          @ create working copy of max index
 loop2:
- ARM(  orr     r11, r10, r9, lsl r5    )       @ factor way and cache number into r11
- THUMB(        lsl     r6, r9, r5              )
+ ARM(  orr     r11, r10, r4, lsl r5    )       @ factor way and cache number into r11
+ THUMB(        lsl     r6, r4, r5              )
  THUMB(        orr     r11, r10, r6            )       @ factor way and cache number into r11
- ARM(  orr     r11, r11, r7, lsl r2    )       @ factor index number into r11
- THUMB(        lsl     r6, r7, r2              )
+ ARM(  orr     r11, r11, r9, lsl r2    )       @ factor index number into r11
+ THUMB(        lsl     r6, r9, r2              )
  THUMB(        orr     r11, r11, r6            )       @ factor index number into r11
        mcr     p15, 0, r11, c7, c14, 2         @ clean & invalidate by set/way
-       subs    r9, r9, #1                      @ decrement the way
+       subs    r9, r9, #1                      @ decrement the index
        bge     loop2
-       subs    r7, r7, #1                      @ decrement the index
+       subs    r4, r4, #1                      @ decrement the way
        bge     loop1
 skip:
        add     r10, r10, #2                    @ increment cache number
index 79f8b39801a8e570bd86ea80e566ee939bbb600b..a18cfc53f445e9183d7a0aee4fc20815d0e27f07 100644 (file)
@@ -9,6 +9,7 @@
  *
  *  DMA uncached mapping support.
  */
+#include <linux/bootmem.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/gfp.h>
@@ -162,6 +163,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
        u64 mask = (u64)DMA_BIT_MASK(32);
 
        if (dev) {
+               unsigned long max_dma_pfn;
+
                mask = dev->coherent_dma_mask;
 
                /*
@@ -173,6 +176,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
                        return 0;
                }
 
+               max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
+
                /*
                 * If the mask allows for more memory than we can address,
                 * and we actually have that much memory, then fail the
@@ -180,7 +185,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
                 */
                if (sizeof(mask) != sizeof(dma_addr_t) &&
                    mask > (dma_addr_t)~0 &&
-                   dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) {
+                   dma_to_pfn(dev, ~0) > max_dma_pfn) {
                        dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
                                 mask);
                        dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
@@ -192,7 +197,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
                 * fits within the allowable addresses which we can
                 * allocate.
                 */
-               if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit) {
+               if (dma_to_pfn(dev, mask) < max_dma_pfn) {
                        dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
                                 mask,
                                 dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
@@ -361,7 +366,7 @@ void __init init_dma_coherent_pool_size(unsigned long size)
 static int __init atomic_pool_init(void)
 {
        struct dma_pool *pool = &atomic_pool;
-       pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
+       pgprot_t prot = pgprot_dmacoherent(PAGE_KERNEL);
        gfp_t gfp = GFP_KERNEL | GFP_DMA;
        unsigned long nr_pages = pool->size >> PAGE_SHIFT;
        unsigned long *bitmap;
@@ -609,7 +614,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
        if (PageHighMem(page))
                __dma_free_remap(cpu_addr, size);
        else
-               __dma_remap(page, size, pgprot_kernel);
+               __dma_remap(page, size, PAGE_KERNEL);
        dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
 }
 
@@ -1357,7 +1362,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
 static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
            dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
 {
-       pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
+       pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
        struct page **pages;
        void *addr = NULL;
 
diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c
new file mode 100644 (file)
index 0000000..c11d3f3
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * Debug helper to dump the current kernel pagetables of the system
+ * so that we can see what the various memory ranges are set to.
+ *
+ * Derived from x86 implementation:
+ * (C) Copyright 2008 Intel Corporation
+ *
+ * Author: Arjan van de Ven <arjan@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/seq_file.h>
+
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+
+struct addr_marker {
+       unsigned long start_address;
+       const char *name;
+};
+
+static struct addr_marker address_markers[] = {
+       { MODULES_VADDR,        "Modules" },
+       { PAGE_OFFSET,          "Kernel Mapping" },
+       { 0,                    "vmalloc() Area" },
+       { VMALLOC_END,          "vmalloc() End" },
+       { FIXADDR_START,        "Fixmap Area" },
+       { CONFIG_VECTORS_BASE,  "Vectors" },
+       { CONFIG_VECTORS_BASE + PAGE_SIZE * 2, "Vectors End" },
+       { -1,                   NULL },
+};
+
+struct pg_state {
+       struct seq_file *seq;
+       const struct addr_marker *marker;
+       unsigned long start_address;
+       unsigned level;
+       u64 current_prot;
+};
+
+struct prot_bits {
+       u64             mask;
+       u64             val;
+       const char      *set;
+       const char      *clear;
+};
+
+static const struct prot_bits pte_bits[] = {
+       {
+               .mask   = L_PTE_USER,
+               .val    = L_PTE_USER,
+               .set    = "USR",
+               .clear  = "   ",
+       }, {
+               .mask   = L_PTE_RDONLY,
+               .val    = L_PTE_RDONLY,
+               .set    = "ro",
+               .clear  = "RW",
+       }, {
+               .mask   = L_PTE_XN,
+               .val    = L_PTE_XN,
+               .set    = "NX",
+               .clear  = "x ",
+       }, {
+               .mask   = L_PTE_SHARED,
+               .val    = L_PTE_SHARED,
+               .set    = "SHD",
+               .clear  = "   ",
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_UNCACHED,
+               .set    = "SO/UNCACHED",
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_BUFFERABLE,
+               .set    = "MEM/BUFFERABLE/WC",
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_WRITETHROUGH,
+               .set    = "MEM/CACHED/WT",
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_WRITEBACK,
+               .set    = "MEM/CACHED/WBRA",
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_MINICACHE,
+               .set    = "MEM/MINICACHE",
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_WRITEALLOC,
+               .set    = "MEM/CACHED/WBWA",
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_DEV_SHARED,
+               .set    = "DEV/SHARED",
+#ifndef CONFIG_LPAE
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_DEV_NONSHARED,
+               .set    = "DEV/NONSHARED",
+#endif
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_DEV_WC,
+               .set    = "DEV/WC",
+       }, {
+               .mask   = L_PTE_MT_MASK,
+               .val    = L_PTE_MT_DEV_CACHED,
+               .set    = "DEV/CACHED",
+       },
+};
+
+static const struct prot_bits section_bits[] = {
+#ifndef CONFIG_LPAE
+       /* These are approximate */
+       {
+               .mask   = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+               .val    = 0,
+               .set    = "    ro",
+       }, {
+               .mask   = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+               .val    = PMD_SECT_AP_WRITE,
+               .set    = "    RW",
+       }, {
+               .mask   = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+               .val    = PMD_SECT_AP_READ,
+               .set    = "USR ro",
+       }, {
+               .mask   = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+               .val    = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
+               .set    = "USR RW",
+#else
+       {
+               .mask   = PMD_SECT_USER,
+               .val    = PMD_SECT_USER,
+               .set    = "USR",
+       }, {
+               .mask   = PMD_SECT_RDONLY,
+               .val    = PMD_SECT_RDONLY,
+               .set    = "ro",
+               .clear  = "RW",
+#endif
+       }, {
+               .mask   = PMD_SECT_XN,
+               .val    = PMD_SECT_XN,
+               .set    = "NX",
+               .clear  = "x ",
+       }, {
+               .mask   = PMD_SECT_S,
+               .val    = PMD_SECT_S,
+               .set    = "SHD",
+               .clear  = "   ",
+       },
+};
+
+struct pg_level {
+       const struct prot_bits *bits;
+       size_t num;
+       u64 mask;
+};
+
+static struct pg_level pg_level[] = {
+       {
+       }, { /* pgd */
+       }, { /* pud */
+       }, { /* pmd */
+               .bits   = section_bits,
+               .num    = ARRAY_SIZE(section_bits),
+       }, { /* pte */
+               .bits   = pte_bits,
+               .num    = ARRAY_SIZE(pte_bits),
+       },
+};
+
+static void dump_prot(struct pg_state *st, const struct prot_bits *bits, size_t num)
+{
+       unsigned i;
+
+       for (i = 0; i < num; i++, bits++) {
+               const char *s;
+
+               if ((st->current_prot & bits->mask) == bits->val)
+                       s = bits->set;
+               else
+                       s = bits->clear;
+
+               if (s)
+                       seq_printf(st->seq, " %s", s);
+       }
+}
+
+static void note_page(struct pg_state *st, unsigned long addr, unsigned level, u64 val)
+{
+       static const char units[] = "KMGTPE";
+       u64 prot = val & pg_level[level].mask;
+
+       if (addr < USER_PGTABLES_CEILING)
+               return;
+
+       if (!st->level) {
+               st->level = level;
+               st->current_prot = prot;
+               seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
+       } else if (prot != st->current_prot || level != st->level ||
+                  addr >= st->marker[1].start_address) {
+               const char *unit = units;
+               unsigned long delta;
+
+               if (st->current_prot) {
+                       seq_printf(st->seq, "0x%08lx-0x%08lx   ",
+                                  st->start_address, addr);
+
+                       delta = (addr - st->start_address) >> 10;
+                       while (!(delta & 1023) && unit[1]) {
+                               delta >>= 10;
+                               unit++;
+                       }
+                       seq_printf(st->seq, "%9lu%c", delta, *unit);
+                       if (pg_level[st->level].bits)
+                               dump_prot(st, pg_level[st->level].bits, pg_level[st->level].num);
+                       seq_printf(st->seq, "\n");
+               }
+
+               if (addr >= st->marker[1].start_address) {
+                       st->marker++;
+                       seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
+               }
+               st->start_address = addr;
+               st->current_prot = prot;
+               st->level = level;
+       }
+}
+
+static void walk_pte(struct pg_state *st, pmd_t *pmd, unsigned long start)
+{
+       pte_t *pte = pte_offset_kernel(pmd, 0);
+       unsigned long addr;
+       unsigned i;
+
+       for (i = 0; i < PTRS_PER_PTE; i++, pte++) {
+               addr = start + i * PAGE_SIZE;
+               note_page(st, addr, 4, pte_val(*pte));
+       }
+}
+
+static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
+{
+       pmd_t *pmd = pmd_offset(pud, 0);
+       unsigned long addr;
+       unsigned i;
+
+       for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
+               addr = start + i * PMD_SIZE;
+               if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd))
+                       note_page(st, addr, 3, pmd_val(*pmd));
+               else
+                       walk_pte(st, pmd, addr);
+       }
+}
+
+static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
+{
+       pud_t *pud = pud_offset(pgd, 0);
+       unsigned long addr;
+       unsigned i;
+
+       for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
+               addr = start + i * PUD_SIZE;
+               if (!pud_none(*pud)) {
+                       walk_pmd(st, pud, addr);
+               } else {
+                       note_page(st, addr, 2, pud_val(*pud));
+               }
+       }
+}
+
+static void walk_pgd(struct seq_file *m)
+{
+       pgd_t *pgd = swapper_pg_dir;
+       struct pg_state st;
+       unsigned long addr;
+       unsigned i, pgdoff = USER_PGTABLES_CEILING / PGDIR_SIZE;
+
+       memset(&st, 0, sizeof(st));
+       st.seq = m;
+       st.marker = address_markers;
+
+       pgd += pgdoff;
+
+       for (i = pgdoff; i < PTRS_PER_PGD; i++, pgd++) {
+               addr = i * PGDIR_SIZE;
+               if (!pgd_none(*pgd)) {
+                       walk_pud(&st, pgd, addr);
+               } else {
+                       note_page(&st, addr, 1, pgd_val(*pgd));
+               }
+       }
+
+       note_page(&st, 0, 0, 0);
+}
+
+static int ptdump_show(struct seq_file *m, void *v)
+{
+       walk_pgd(m);
+       return 0;
+}
+
+static int ptdump_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ptdump_show, NULL);
+}
+
+static const struct file_operations ptdump_fops = {
+       .open           = ptdump_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int ptdump_init(void)
+{
+       struct dentry *pe;
+       unsigned i, j;
+
+       for (i = 0; i < ARRAY_SIZE(pg_level); i++)
+               if (pg_level[i].bits)
+                       for (j = 0; j < pg_level[i].num; j++)
+                               pg_level[i].mask |= pg_level[i].bits[j].mask;
+
+       address_markers[2].start_address = VMALLOC_START;
+
+       pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL,
+                                &ptdump_fops);
+       return pe ? 0 : -ENOMEM;
+}
+__initcall(ptdump_init);
index f123d6eb074b056586dd840ba2465d3fba2b36a2..f9c32ba73544d64551e8ff2d4f890b74432eec15 100644 (file)
@@ -392,9 +392,9 @@ __arm_ioremap_exec(phys_addr_t phys_addr, size_t size, bool cached)
        unsigned int mtype;
 
        if (cached)
-               mtype = MT_MEMORY;
+               mtype = MT_MEMORY_RWX;
        else
-               mtype = MT_MEMORY_NONCACHED;
+               mtype = MT_MEMORY_RWX_NONCACHED;
 
        return __arm_ioremap_caller(phys_addr, size, mtype,
                        __builtin_return_address(0));
index d27158c38eb0b190b869e028b93d8265fb90969e..5e85ed371364c17657be7d7155139a5e3f536437 100644 (file)
@@ -146,7 +146,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 
        info.flags = VM_UNMAPPED_AREA_TOPDOWN;
        info.length = len;
-       info.low_limit = PAGE_SIZE;
+       info.low_limit = FIRST_USER_ADDRESS;
        info.high_limit = mm->mmap_base;
        info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
        info.align_offset = pgoff << PAGE_SHIFT;
index 580ef2de82d728f8ecfde5f5f3b208a2e5525b06..4f08c133cc255e2e2c2b93a0f28b79caaf3fc795 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/cputype.h>
 #include <asm/sections.h>
 #include <asm/cachetype.h>
+#include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp_plat.h>
 #include <asm/tlb.h>
@@ -287,36 +288,43 @@ static struct mem_type mem_types[] = {
                .prot_l1   = PMD_TYPE_TABLE,
                .domain    = DOMAIN_USER,
        },
-       [MT_MEMORY] = {
+       [MT_MEMORY_RWX] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
                .prot_l1   = PMD_TYPE_TABLE,
                .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
                .domain    = DOMAIN_KERNEL,
        },
+       [MT_MEMORY_RW] = {
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                            L_PTE_XN,
+               .prot_l1   = PMD_TYPE_TABLE,
+               .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+               .domain    = DOMAIN_KERNEL,
+       },
        [MT_ROM] = {
                .prot_sect = PMD_TYPE_SECT,
                .domain    = DOMAIN_KERNEL,
        },
-       [MT_MEMORY_NONCACHED] = {
+       [MT_MEMORY_RWX_NONCACHED] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                                L_PTE_MT_BUFFERABLE,
                .prot_l1   = PMD_TYPE_TABLE,
                .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
                .domain    = DOMAIN_KERNEL,
        },
-       [MT_MEMORY_DTCM] = {
+       [MT_MEMORY_RW_DTCM] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                                L_PTE_XN,
                .prot_l1   = PMD_TYPE_TABLE,
                .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
                .domain    = DOMAIN_KERNEL,
        },
-       [MT_MEMORY_ITCM] = {
+       [MT_MEMORY_RWX_ITCM] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
                .prot_l1   = PMD_TYPE_TABLE,
                .domain    = DOMAIN_KERNEL,
        },
-       [MT_MEMORY_SO] = {
+       [MT_MEMORY_RW_SO] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                                L_PTE_MT_UNCACHED | L_PTE_XN,
                .prot_l1   = PMD_TYPE_TABLE,
@@ -325,7 +333,8 @@ static struct mem_type mem_types[] = {
                .domain    = DOMAIN_KERNEL,
        },
        [MT_MEMORY_DMA_READY] = {
-               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_XN,
                .prot_l1   = PMD_TYPE_TABLE,
                .domain    = DOMAIN_KERNEL,
        },
@@ -337,6 +346,44 @@ const struct mem_type *get_mem_type(unsigned int type)
 }
 EXPORT_SYMBOL(get_mem_type);
 
+#define PTE_SET_FN(_name, pteop) \
+static int pte_set_##_name(pte_t *ptep, pgtable_t token, unsigned long addr, \
+                       void *data) \
+{ \
+       pte_t pte = pteop(*ptep); \
+\
+       set_pte_ext(ptep, pte, 0); \
+       return 0; \
+} \
+
+#define SET_MEMORY_FN(_name, callback) \
+int set_memory_##_name(unsigned long addr, int numpages) \
+{ \
+       unsigned long start = addr; \
+       unsigned long size = PAGE_SIZE*numpages; \
+       unsigned end = start + size; \
+\
+       if (start < MODULES_VADDR || start >= MODULES_END) \
+               return -EINVAL;\
+\
+       if (end < MODULES_VADDR || end >= MODULES_END) \
+               return -EINVAL; \
+\
+       apply_to_page_range(&init_mm, start, size, callback, NULL); \
+       flush_tlb_kernel_range(start, end); \
+       return 0;\
+}
+
+PTE_SET_FN(ro, pte_wrprotect)
+PTE_SET_FN(rw, pte_mkwrite)
+PTE_SET_FN(x, pte_mkexec)
+PTE_SET_FN(nx, pte_mknexec)
+
+SET_MEMORY_FN(ro, pte_set_ro)
+SET_MEMORY_FN(rw, pte_set_rw)
+SET_MEMORY_FN(x, pte_set_x)
+SET_MEMORY_FN(nx, pte_set_nx)
+
 /*
  * Adjust the PMD section entries according to the CPU in use.
  */
@@ -410,6 +457,9 @@ static void __init build_mem_type_table(void)
                        mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_XN;
                        mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_XN;
                        mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_XN;
+
+                       /* Also setup NX memory mapping */
+                       mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_XN;
                }
                if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
                        /*
@@ -487,11 +537,13 @@ static void __init build_mem_type_table(void)
                        mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
                        mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
                        mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
-                       mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
-                       mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
+                       mem_types[MT_MEMORY_RWX].prot_sect |= PMD_SECT_S;
+                       mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
+                       mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S;
+                       mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED;
                        mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
-                       mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
-                       mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
+                       mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S;
+                       mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED;
                }
        }
 
@@ -502,15 +554,15 @@ static void __init build_mem_type_table(void)
        if (cpu_arch >= CPU_ARCH_ARMv6) {
                if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
                        /* Non-cacheable Normal is XCB = 001 */
-                       mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+                       mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |=
                                PMD_SECT_BUFFERED;
                } else {
                        /* For both ARMv6 and non-TEX-remapping ARMv7 */
-                       mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+                       mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |=
                                PMD_SECT_TEX(1);
                }
        } else {
-               mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
+               mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
        }
 
 #ifdef CONFIG_ARM_LPAE
@@ -543,10 +595,12 @@ static void __init build_mem_type_table(void)
 
        mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
        mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
-       mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
-       mem_types[MT_MEMORY].prot_pte |= kern_pgprot;
+       mem_types[MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd;
+       mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
+       mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
+       mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
        mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
-       mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask;
+       mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
        mem_types[MT_ROM].prot_sect |= cp->pmd;
 
        switch (cp->pmd) {
@@ -1296,6 +1350,8 @@ static void __init kmap_init(void)
 static void __init map_lowmem(void)
 {
        struct memblock_region *reg;
+       unsigned long kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
+       unsigned long kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
 
        /* Map all the lowmem memory banks. */
        for_each_memblock(memory, reg) {
@@ -1308,12 +1364,40 @@ static void __init map_lowmem(void)
                if (start >= end)
                        break;
 
-               map.pfn = __phys_to_pfn(start);
-               map.virtual = __phys_to_virt(start);
-               map.length = end - start;
-               map.type = MT_MEMORY;
+               if (end < kernel_x_start || start >= kernel_x_end) {
+                       map.pfn = __phys_to_pfn(start);
+                       map.virtual = __phys_to_virt(start);
+                       map.length = end - start;
+                       map.type = MT_MEMORY_RWX;
 
-               create_mapping(&map);
+                       create_mapping(&map);
+               } else {
+                       /* This better cover the entire kernel */
+                       if (start < kernel_x_start) {
+                               map.pfn = __phys_to_pfn(start);
+                               map.virtual = __phys_to_virt(start);
+                               map.length = kernel_x_start - start;
+                               map.type = MT_MEMORY_RW;
+
+                               create_mapping(&map);
+                       }
+
+                       map.pfn = __phys_to_pfn(kernel_x_start);
+                       map.virtual = __phys_to_virt(kernel_x_start);
+                       map.length = kernel_x_end - kernel_x_start;
+                       map.type = MT_MEMORY_RWX;
+
+                       create_mapping(&map);
+
+                       if (kernel_x_end < end) {
+                               map.pfn = __phys_to_pfn(kernel_x_end);
+                               map.virtual = __phys_to_virt(kernel_x_end);
+                               map.length = end - kernel_x_end;
+                               map.type = MT_MEMORY_RW;
+
+                               create_mapping(&map);
+                       }
+               }
        }
 }
 
index 0acb089d0f70db818ce487fa67b0fb90b1b0b69d..1046b373d1aedb2823e3bb62f106681f9b63fc2a 100644 (file)
@@ -87,7 +87,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
                init_pud = pud_offset(init_pgd, 0);
                init_pmd = pmd_offset(init_pud, 0);
                init_pte = pte_offset_map(init_pmd, 0);
-               set_pte_ext(new_pte, *init_pte, 0);
+               set_pte_ext(new_pte + 0, init_pte[0], 0);
+               set_pte_ext(new_pte + 1, init_pte[1], 0);
                pte_unmap(init_pte);
                pte_unmap(new_pte);
        }
index fb92abb91628a2e06f6aebc54f03a724a79c23ee..2861b155485aefa0adeb1029d6657b4081179af6 100644 (file)
@@ -336,8 +336,11 @@ static inline void __omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
        if (timer->posted)
                return;
 
-       if (timer->errata & OMAP_TIMER_ERRATA_I103_I767)
+       if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) {
+               timer->posted = OMAP_TIMER_NONPOSTED;
+               __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, 0, 0);
                return;
+       }
 
        __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
                              OMAP_TIMER_CTRL_POSTED, 0);
index c66d163d7a2a25084179e71e6a2d57f8e04263ff..830ff07f33856dfa886a3224fe352dab2bd336f5 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_data/dma-mv_xor.h>
 #include <linux/platform_data/usb-ehci-orion.h>
 #include <mach/bridge-regs.h>
+#include <plat/common.h>
 
 /* Create a clkdev entry for a given device/clk */
 void __init orion_clkdev_add(const char *con_id, const char *dev_id,
@@ -256,7 +257,7 @@ static __init void ge_complete(
 /*****************************************************************************
  * GE00
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
+static struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
 
 static struct resource orion_ge00_shared_resources[] = {
        {
@@ -322,7 +323,7 @@ void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
 /*****************************************************************************
  * GE01
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge01_shared_data;
+static struct mv643xx_eth_shared_platform_data orion_ge01_shared_data;
 
 static struct resource orion_ge01_shared_resources[] = {
        {
@@ -373,7 +374,7 @@ void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
 /*****************************************************************************
  * GE10
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge10_shared_data;
+static struct mv643xx_eth_shared_platform_data orion_ge10_shared_data;
 
 static struct resource orion_ge10_shared_resources[] = {
        {
@@ -422,7 +423,7 @@ void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
 /*****************************************************************************
  * GE11
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion_ge11_shared_data;
+static struct mv643xx_eth_shared_platform_data orion_ge11_shared_data;
 
 static struct resource orion_ge11_shared_resources[] = {
        {
index 9d2b2ac74938da9b52f2ee1f629fdb6ca3b602b7..15921a1839d75dc482a8ed4b29d5b08d421f31f6 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/sched_clock.h>
+#include <plat/time.h>
 
 /*
  * MBus bridge block registers.
@@ -174,7 +175,7 @@ static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction orion_timer_irq = {
        .name           = "orion_tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .flags          = IRQF_TIMER,
        .handler        = orion_timer_interrupt
 };
 
index faa651602780b6570b1af0d079d08a9b409e651e..ebee4dc11a946686a1c558c82f3f027b7c0f173b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/gpio.h>
 #include <linux/irqchip/arm-vic.h>
+#include <linux/of.h>
 
 #include <plat/regs-irqtype.h>
 
@@ -202,6 +203,9 @@ static int __init s5p_init_irq_eint(void)
 {
        int irq;
 
+       if (of_have_populated_dt())
+               return -ENODEV;
+
        for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++)
                irq_set_chip(irq, &s5p_irq_vic_eint);
 
index 23732cdff5511ff3c20bf1cbd403034797faf296..b31ee1b275b011d7010dbcac1eea3ab206290908 100644 (file)
@@ -25,8 +25,9 @@ struct xen_p2m_entry {
        struct rb_node rbnode_phys;
 };
 
-rwlock_t p2m_lock;
+static rwlock_t p2m_lock;
 struct rb_root phys_to_mach = RB_ROOT;
+EXPORT_SYMBOL_GPL(phys_to_mach);
 static struct rb_root mach_to_phys = RB_ROOT;
 
 static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new)
@@ -200,7 +201,7 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 }
 EXPORT_SYMBOL_GPL(__set_phys_to_machine);
 
-int p2m_init(void)
+static int p2m_init(void)
 {
        rwlock_init(&p2m_lock);
        return 0;
index 84fcc5018284b6cee3dca436dd4ec7634e3b00cc..519c4b2c06873dc82f7ed2ebff9ccb698691e24f 100644 (file)
@@ -6,6 +6,8 @@
 
 /dts-v1/;
 
+/memreserve/ 0x80000000 0x00010000;
+
 / {
        model = "Foundation-v8A";
        compatible = "arm,foundation-aarch64", "arm,vexpress";
index aa11943b850213c77a32f87c1ce22c8aac87bf83..b2fcfbc51ecc4b0eaef6e4b20efd0f7afd2a9efd 100644 (file)
@@ -56,6 +56,9 @@ static inline void arch_local_irq_disable(void)
 #define local_fiq_enable()     asm("msr        daifclr, #1" : : : "memory")
 #define local_fiq_disable()    asm("msr        daifset, #1" : : : "memory")
 
+#define local_async_enable()   asm("msr        daifclr, #4" : : : "memory")
+#define local_async_disable()  asm("msr        daifset, #4" : : : "memory")
+
 /*
  * Save the current interrupt enable state.
  */
index 17bd3af0a1177d094f27a9a4294dd6eae5103098..7f2b60affbb49509f290a5a56e5842fd1f29f4eb 100644 (file)
  * Software defined PTE bits definition.
  */
 #define PTE_VALID              (_AT(pteval_t, 1) << 0)
-#define PTE_PROT_NONE          (_AT(pteval_t, 1) << 2) /* only when !PTE_VALID */
-#define PTE_FILE               (_AT(pteval_t, 1) << 3) /* only when !pte_present() */
+#define PTE_FILE               (_AT(pteval_t, 1) << 2) /* only when !pte_present() */
 #define PTE_DIRTY              (_AT(pteval_t, 1) << 55)
 #define PTE_SPECIAL            (_AT(pteval_t, 1) << 56)
+                               /* bit 57 for PMD_SECT_SPLITTING */
+#define PTE_PROT_NONE          (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
 
 /*
  * VMALLOC and SPARSEMEM_VMEMMAP ranges.
@@ -254,7 +255,7 @@ static inline int has_transparent_hugepage(void)
 #define pgprot_noncached(prot) \
        __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
 #define pgprot_writecombine(prot) \
-       __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_GRE))
+       __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
 #define pgprot_dmacoherent(prot) \
        __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
 #define __HAVE_PHYS_MEM_ACCESS_PROT
@@ -357,18 +358,20 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
 
 /*
  * Encode and decode a swap entry:
- *     bits 0, 2:      present (must both be zero)
- *     bit  3:         PTE_FILE
- *     bits 4-8:       swap type
- *     bits 9-63:      swap offset
+ *     bits 0-1:       present (must be zero)
+ *     bit  2:         PTE_FILE
+ *     bits 3-8:       swap type
+ *     bits 9-57:      swap offset
  */
-#define __SWP_TYPE_SHIFT       4
+#define __SWP_TYPE_SHIFT       3
 #define __SWP_TYPE_BITS                6
+#define __SWP_OFFSET_BITS      49
 #define __SWP_TYPE_MASK                ((1 << __SWP_TYPE_BITS) - 1)
 #define __SWP_OFFSET_SHIFT     (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
+#define __SWP_OFFSET_MASK      ((1UL << __SWP_OFFSET_BITS) - 1)
 
 #define __swp_type(x)          (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
-#define __swp_offset(x)                ((x).val >> __SWP_OFFSET_SHIFT)
+#define __swp_offset(x)                (((x).val >> __SWP_OFFSET_SHIFT) & __SWP_OFFSET_MASK)
 #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
 
 #define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) })
@@ -382,15 +385,15 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
 
 /*
  * Encode and decode a file entry:
- *     bits 0, 2:      present (must both be zero)
- *     bit  3:         PTE_FILE
- *     bits 4-63:      file offset / PAGE_SIZE
+ *     bits 0-1:       present (must be zero)
+ *     bit  2:         PTE_FILE
+ *     bits 3-57:      file offset / PAGE_SIZE
  */
 #define pte_file(pte)          (pte_val(pte) & PTE_FILE)
-#define pte_to_pgoff(x)                (pte_val(x) >> 4)
-#define pgoff_to_pte(x)                __pte(((x) << 4) | PTE_FILE)
+#define pte_to_pgoff(x)                (pte_val(x) >> 3)
+#define pgoff_to_pte(x)                __pte(((x) << 3) | PTE_FILE)
 
-#define PTE_FILE_MAX_BITS      60
+#define PTE_FILE_MAX_BITS      55
 
 extern int kern_addr_valid(unsigned long addr);
 
index 6a0a9b132d7af11714348f3950990a9854d56ba6..4ae68579031db9fb1e8e5a04689499fde2fcbc4c 100644 (file)
@@ -248,7 +248,8 @@ static int brk_handler(unsigned long addr, unsigned int esr,
 int aarch32_break_handler(struct pt_regs *regs)
 {
        siginfo_t info;
-       unsigned int instr;
+       u32 arm_instr;
+       u16 thumb_instr;
        bool bp = false;
        void __user *pc = (void __user *)instruction_pointer(regs);
 
@@ -257,18 +258,21 @@ int aarch32_break_handler(struct pt_regs *regs)
 
        if (compat_thumb_mode(regs)) {
                /* get 16-bit Thumb instruction */
-               get_user(instr, (u16 __user *)pc);
-               if (instr == AARCH32_BREAK_THUMB2_LO) {
+               get_user(thumb_instr, (u16 __user *)pc);
+               thumb_instr = le16_to_cpu(thumb_instr);
+               if (thumb_instr == AARCH32_BREAK_THUMB2_LO) {
                        /* get second half of 32-bit Thumb-2 instruction */
-                       get_user(instr, (u16 __user *)(pc + 2));
-                       bp = instr == AARCH32_BREAK_THUMB2_HI;
+                       get_user(thumb_instr, (u16 __user *)(pc + 2));
+                       thumb_instr = le16_to_cpu(thumb_instr);
+                       bp = thumb_instr == AARCH32_BREAK_THUMB2_HI;
                } else {
-                       bp = instr == AARCH32_BREAK_THUMB;
+                       bp = thumb_instr == AARCH32_BREAK_THUMB;
                }
        } else {
                /* 32-bit ARM instruction */
-               get_user(instr, (u32 __user *)pc);
-               bp = (instr & ~0xf0000000) == AARCH32_BREAK_ARM;
+               get_user(arm_instr, (u32 __user *)pc);
+               arm_instr = le32_to_cpu(arm_instr);
+               bp = (arm_instr & ~0xf0000000) == AARCH32_BREAK_ARM;
        }
 
        if (!bp)
index e1166145ca29b59801c84420e1f98225650f4580..4d2c6f3f0c4186da25fb1d6932d2671040941df2 100644 (file)
@@ -309,15 +309,12 @@ el1_irq:
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
 #endif
-#ifdef CONFIG_PREEMPT
-       get_thread_info tsk
-       ldr     w24, [tsk, #TI_PREEMPT]         // get preempt count
-       add     w0, w24, #1                     // increment it
-       str     w0, [tsk, #TI_PREEMPT]
-#endif
+
        irq_handler
+
 #ifdef CONFIG_PREEMPT
-       str     w24, [tsk, #TI_PREEMPT]         // restore preempt count
+       get_thread_info tsk
+       ldr     w24, [tsk, #TI_PREEMPT]         // restore preempt count
        cbnz    w24, 1f                         // preempt count != 0
        ldr     x0, [tsk, #TI_FLAGS]            // get flags
        tbz     x0, #TIF_NEED_RESCHED, 1f       // needs rescheduling?
@@ -507,22 +504,10 @@ el0_irq_naked:
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
 #endif
-       get_thread_info tsk
-#ifdef CONFIG_PREEMPT
-       ldr     w24, [tsk, #TI_PREEMPT]         // get preempt count
-       add     w23, w24, #1                    // increment it
-       str     w23, [tsk, #TI_PREEMPT]
-#endif
+
        irq_handler
-#ifdef CONFIG_PREEMPT
-       ldr     w0, [tsk, #TI_PREEMPT]
-       str     w24, [tsk, #TI_PREEMPT]
-       cmp     w0, w23
-       b.eq    1f
-       mov     x1, #0
-       str     x1, [x1]                        // BUG
-1:
-#endif
+       get_thread_info tsk
+
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_on
 #endif
index fecdbf7de82e9a94d6f467f5999428cfcf623145..6777a2192b83846f1065f442f5777d4092e9bc0c 100644 (file)
@@ -636,28 +636,27 @@ static int compat_gpr_get(struct task_struct *target,
 
        for (i = 0; i < num_regs; ++i) {
                unsigned int idx = start + i;
-               void *reg;
+               compat_ulong_t reg;
 
                switch (idx) {
                case 15:
-                       reg = (void *)&task_pt_regs(target)->pc;
+                       reg = task_pt_regs(target)->pc;
                        break;
                case 16:
-                       reg = (void *)&task_pt_regs(target)->pstate;
+                       reg = task_pt_regs(target)->pstate;
                        break;
                case 17:
-                       reg = (void *)&task_pt_regs(target)->orig_x0;
+                       reg = task_pt_regs(target)->orig_x0;
                        break;
                default:
-                       reg = (void *)&task_pt_regs(target)->regs[idx];
+                       reg = task_pt_regs(target)->regs[idx];
                }
 
-               ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t));
-
+               ret = copy_to_user(ubuf, &reg, sizeof(reg));
                if (ret)
                        break;
-               else
-                       ubuf += sizeof(compat_ulong_t);
+
+               ubuf += sizeof(reg);
        }
 
        return ret;
@@ -685,28 +684,28 @@ static int compat_gpr_set(struct task_struct *target,
 
        for (i = 0; i < num_regs; ++i) {
                unsigned int idx = start + i;
-               void *reg;
+               compat_ulong_t reg;
+
+               ret = copy_from_user(&reg, ubuf, sizeof(reg));
+               if (ret)
+                       return ret;
+
+               ubuf += sizeof(reg);
 
                switch (idx) {
                case 15:
-                       reg = (void *)&newregs.pc;
+                       newregs.pc = reg;
                        break;
                case 16:
-                       reg = (void *)&newregs.pstate;
+                       newregs.pstate = reg;
                        break;
                case 17:
-                       reg = (void *)&newregs.orig_x0;
+                       newregs.orig_x0 = reg;
                        break;
                default:
-                       reg = (void *)&newregs.regs[idx];
+                       newregs.regs[idx] = reg;
                }
 
-               ret = copy_from_user(reg, ubuf, sizeof(compat_ulong_t));
-
-               if (ret)
-                       goto out;
-               else
-                       ubuf += sizeof(compat_ulong_t);
        }
 
        if (valid_user_regs(&newregs.user_regs))
@@ -714,7 +713,6 @@ static int compat_gpr_set(struct task_struct *target,
        else
                ret = -EINVAL;
 
-out:
        return ret;
 }
 
index 0bc5e4cbc017674db8785f434fa3cff0b30d4c56..bd9bbd0e44edf176c262cfad0e32b9f62599d4b7 100644 (file)
@@ -205,6 +205,11 @@ u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
 
 void __init setup_arch(char **cmdline_p)
 {
+       /*
+        * Unmask asynchronous aborts early to catch possible system errors.
+        */
+       local_async_enable();
+
        setup_processor();
 
        setup_machine_fdt(__fdt_pointer);
index a5aeefab03c3e9cd2c0a241d4f4632bb0933b31f..a0c2ca602cf85bebc6e7996454adb9e47fe9456d 100644 (file)
@@ -160,6 +160,7 @@ asmlinkage void secondary_start_kernel(void)
 
        local_irq_enable();
        local_fiq_enable();
+       local_async_enable();
 
        /*
         * OK, it's off to the idle thread for us
index 09c5a0f5f4d1778156a5ee83715e6a2aec7f0441..86648c083bb4b1297275dc2bc4ceb3ecd949aa5b 100644 (file)
@@ -12,6 +12,7 @@
 #define _ASM_C6X_CACHE_H
 
 #include <linux/irqflags.h>
+#include <linux/init.h>
 
 /*
  * Cache line size
index 916ffe770bcf5691c0e2b6744a40f0d45c81d487..84715fcbba0875ed7e689ec761c2e4a2184477bd 100644 (file)
@@ -23,8 +23,7 @@
  */
 
 #include <linux/module.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <asm/sal.h>
 
 MODULE_AUTHOR("Bjorn Helgaas <bjorn.helgaas@hp.com>");
index 99449fbf9a726834ec2b2c268956a13f0ab0b99d..ba03cec3f711e024422fe916a407b4cf56556f76 100644 (file)
@@ -87,7 +87,7 @@ void *amiga_chip_alloc_res(unsigned long size, struct resource *res)
 
        atomic_sub(size, &chipavail);
        pr_debug("amiga_chip_alloc_res: returning %pR\n", res);
-       return (void *)ZTWO_VADDR(res->start);
+       return ZTWO_VADDR(res->start);
 }
 
 void amiga_chip_free(void *ptr)
index b819390e29cdb7e901e926a9190b30ebadb8916c..c425fa6c2795181802984b0328453f166a27e3bc 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/keyboard.h>
 
 #include <asm/bootinfo.h>
+#include <asm/bootinfo-amiga.h>
+#include <asm/byteorder.h>
 #include <asm/setup.h>
 #include <asm/pgtable.h>
 #include <asm/amigahw.h>
@@ -140,46 +142,46 @@ static struct resource ram_resource[NUM_MEMINFO];
      *  Parse an Amiga-specific record in the bootinfo
      */
 
-int amiga_parse_bootinfo(const struct bi_record *record)
+int __init amiga_parse_bootinfo(const struct bi_record *record)
 {
        int unknown = 0;
-       const unsigned long *data = record->data;
+       const void *data = record->data;
 
-       switch (record->tag) {
+       switch (be16_to_cpu(record->tag)) {
        case BI_AMIGA_MODEL:
-               amiga_model = *data;
+               amiga_model = be32_to_cpup(data);
                break;
 
        case BI_AMIGA_ECLOCK:
-               amiga_eclock = *data;
+               amiga_eclock = be32_to_cpup(data);
                break;
 
        case BI_AMIGA_CHIPSET:
-               amiga_chipset = *data;
+               amiga_chipset = be32_to_cpup(data);
                break;
 
        case BI_AMIGA_CHIP_SIZE:
-               amiga_chip_size = *(const int *)data;
+               amiga_chip_size = be32_to_cpup(data);
                break;
 
        case BI_AMIGA_VBLANK:
-               amiga_vblank = *(const unsigned char *)data;
+               amiga_vblank = *(const __u8 *)data;
                break;
 
        case BI_AMIGA_PSFREQ:
-               amiga_psfreq = *(const unsigned char *)data;
+               amiga_psfreq = *(const __u8 *)data;
                break;
 
        case BI_AMIGA_AUTOCON:
 #ifdef CONFIG_ZORRO
                if (zorro_num_autocon < ZORRO_NUM_AUTO) {
-                       const struct ConfigDev *cd = (struct ConfigDev *)data;
-                       struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++];
+                       const struct ConfigDev *cd = data;
+                       struct zorro_dev_init *dev = &zorro_autocon_init[zorro_num_autocon++];
                        dev->rom = cd->cd_Rom;
-                       dev->slotaddr = cd->cd_SlotAddr;
-                       dev->slotsize = cd->cd_SlotSize;
-                       dev->resource.start = (unsigned long)cd->cd_BoardAddr;
-                       dev->resource.end = dev->resource.start + cd->cd_BoardSize - 1;
+                       dev->slotaddr = be16_to_cpu(cd->cd_SlotAddr);
+                       dev->slotsize = be16_to_cpu(cd->cd_SlotSize);
+                       dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr);
+                       dev->boardsize = be32_to_cpu(cd->cd_BoardSize);
                } else
                        printk("amiga_parse_bootinfo: too many AutoConfig devices\n");
 #endif /* CONFIG_ZORRO */
@@ -358,6 +360,14 @@ static void __init amiga_identify(void)
 #undef AMIGAHW_ANNOUNCE
 }
 
+
+static unsigned long amiga_random_get_entropy(void)
+{
+       /* VPOSR/VHPOSR provide at least 17 bits of data changing at 1.79 MHz */
+       return *(unsigned long *)&amiga_custom.vposr;
+}
+
+
     /*
      *  Setup the Amiga configuration info
      */
@@ -395,6 +405,8 @@ void __init config_amiga(void)
        mach_heartbeat = amiga_heartbeat;
 #endif
 
+       mach_random_get_entropy = amiga_random_get_entropy;
+
        /* Fill in the clock value (based on the 700 kHz E-Clock) */
        amiga_colorclock = 5*amiga_eclock;      /* 3.5 MHz */
 
@@ -618,7 +630,7 @@ static int __init amiga_savekmsg_setup(char *arg)
 
        /* Just steal the block, the chipram allocator isn't functional yet */
        amiga_chip_size -= SAVEKMSG_MAXMEM;
-       savekmsg = (void *)ZTWO_VADDR(CHIP_PHYSADDR + amiga_chip_size);
+       savekmsg = ZTWO_VADDR(CHIP_PHYSADDR + amiga_chip_size);
        savekmsg->magic1 = SAVEKMSG_MAGIC1;
        savekmsg->magic2 = SAVEKMSG_MAGIC2;
        savekmsg->magicptr = ZTWO_PADDR(savekmsg);
index dacd9f911f7171f847fc0087faf20a34092f0e1c..d34029d7b05892a5c0d2e646129a89407402b368 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <asm/amigahw.h>
 #include <asm/amigayle.h>
+#include <asm/byteorder.h>
 
 
 #ifdef CONFIG_ZORRO
@@ -66,10 +67,12 @@ static int __init z_dev_present(zorro_id id)
 {
        unsigned int i;
 
-       for (i = 0; i < zorro_num_autocon; i++)
-               if (zorro_autocon[i].rom.er_Manufacturer == ZORRO_MANUF(id) &&
-                   zorro_autocon[i].rom.er_Product == ZORRO_PROD(id))
+       for (i = 0; i < zorro_num_autocon; i++) {
+               const struct ExpansionRom *rom = &zorro_autocon_init[i].rom;
+               if (be16_to_cpu(rom->er_Manufacturer) == ZORRO_MANUF(id) &&
+                   rom->er_Product == ZORRO_PROD(id))
                        return 1;
+       }
 
        return 0;
 }
index 3ea56b90e7188df2c758bce798fc46c2d96df461..9268c0f96376b30eee39caba6d023d3fd0488cab 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/init.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -9,6 +10,8 @@
 
 #include <asm/setup.h>
 #include <asm/bootinfo.h>
+#include <asm/bootinfo-apollo.h>
+#include <asm/byteorder.h>
 #include <asm/pgtable.h>
 #include <asm/apollohw.h>
 #include <asm/irq.h>
@@ -43,26 +46,25 @@ static const char *apollo_models[] = {
        [APOLLO_DN4500-APOLLO_DN3000] = "DN4500 (Roadrunner)"
 };
 
-int apollo_parse_bootinfo(const struct bi_record *record) {
-
+int __init apollo_parse_bootinfo(const struct bi_record *record)
+{
        int unknown = 0;
-       const unsigned long *data = record->data;
+       const void *data = record->data;
 
-       switch(record->tag) {
-               case BI_APOLLO_MODEL:
-                       apollo_model=*data;
-                       break;
+       switch (be16_to_cpu(record->tag)) {
+       case BI_APOLLO_MODEL:
+               apollo_model = be32_to_cpup(data);
+               break;
 
-               default:
-                        unknown=1;
+       default:
+                unknown=1;
        }
 
        return unknown;
 }
 
-void dn_setup_model(void) {
-
-
+static void __init dn_setup_model(void)
+{
        printk("Apollo hardware found: ");
        printk("[%s]\n", apollo_models[apollo_model - APOLLO_DN3000]);
 
index fb2d0bd9b3adab5304dc160a3bcf192aa0568a53..01a62161b08a1a69a74635de7004e4e65c73bf20 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/module.h>
 
 #include <asm/bootinfo.h>
+#include <asm/bootinfo-atari.h>
+#include <asm/byteorder.h>
 #include <asm/setup.h>
 #include <asm/atarihw.h>
 #include <asm/atariints.h>
@@ -129,14 +131,14 @@ static int __init scc_test(volatile char *ctla)
 int __init atari_parse_bootinfo(const struct bi_record *record)
 {
        int unknown = 0;
-       const u_long *data = record->data;
+       const void *data = record->data;
 
-       switch (record->tag) {
+       switch (be16_to_cpu(record->tag)) {
        case BI_ATARI_MCH_COOKIE:
-               atari_mch_cookie = *data;
+               atari_mch_cookie = be32_to_cpup(data);
                break;
        case BI_ATARI_MCH_TYPE:
-               atari_mch_type = *data;
+               atari_mch_type = be32_to_cpup(data);
                break;
        default:
                unknown = 1;
index 8943aa4c18e63cd3b0719b3a8d9f50e6bec40671..478623dbb2092b357a1f355d382ad3cc272f8e95 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/bcd.h>
 
 #include <asm/bootinfo.h>
+#include <asm/bootinfo-vme.h>
+#include <asm/byteorder.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -50,9 +52,9 @@ void bvme6000_set_vectors (void);
 static irq_handler_t tick_handler;
 
 
-int bvme6000_parse_bootinfo(const struct bi_record *bi)
+int __init bvme6000_parse_bootinfo(const struct bi_record *bi)
 {
-       if (bi->tag == BI_VME_TYPE)
+       if (be16_to_cpu(bi->tag) == BI_VME_TYPE)
                return 0;
        else
                return 1;
index 19325e117eeaaec7b844e1e50d328719077e3261..04432b7ce1576af9687be0d8d7642ced03bbcbce 100644 (file)
@@ -385,7 +385,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index 14dc6ccda7f45349c82c0dd1f0d113831b3ac07b..a018fd7ed7bc24b6bdfa7b20a42facb22035ce9a 100644 (file)
@@ -342,7 +342,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index 6d5370c914b265123b6963df409ca3b82d17f8cf..fa33639b41070e0bed1d76f1c5618e7cdd76cbea 100644 (file)
@@ -360,7 +360,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index c015ddb6fd80635c81affec06369ced3f62185f8..ca310d58668971bc728a18c44ddd5c210e895a4a 100644 (file)
@@ -334,7 +334,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index ec7382d8afff5390a4210a45ba348637605c4f59..aa98958c230e6798247e450b4e80b4b122aacd51 100644 (file)
@@ -344,7 +344,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index c1616824e201f0e8e53605226dae70cf4feb692a..e7292f460af45665ac7cdbef46c02a56f4b07921 100644 (file)
@@ -40,7 +40,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index a6599e42facfb8cefb1062f7be679366a4ef5210..0cd4b39f325b6c609a385f31de4cf4c76db2a957 100644 (file)
@@ -38,7 +38,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index 3fa60a57a0f9a19eab0872db442251c87f65f606..a60cb35091352d20399c39fbfe1cd863b072a5b8 100644 (file)
@@ -36,7 +36,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index a1230e82bb1e5226c3d61968b1c625bbf40c6a17..e6502ab7cb2fee0ac7b2bd7a1089e41450f05780 100644 (file)
@@ -39,7 +39,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index 43795f41f7c7b1da1267c8c5bef183cde4e97257..023812abd2e6c6d701015dd99f70693dd1eb7251 100644 (file)
@@ -38,7 +38,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index 72746c57a571312b47b4b2989bd05d08ffa9180c..557b39f3be9094e223fb8715cae927c0c5ba1cd3 100644 (file)
@@ -38,7 +38,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index 7d46fbec70424dc84fbe07a9ab1e77c7d1f2bec2..ac2c153f8a4c0330226ce7f4381250c4bea013a6 100644 (file)
@@ -367,7 +367,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index b17a8837f0e1016b273e5f74c6f75803a1e372b8..61cdb096ca434089c38c0a3da7024d70a3253f41 100644 (file)
@@ -445,7 +445,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index 5586c6529fce367fb22061b87c708b9ba10a1f61..f89613f9c82bc3ae7d6016c430554009dba2e3fa 100644 (file)
@@ -334,7 +334,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index e5e8262bbacdd0a94c4f0b1e0e89c06166ddd8ec..d086acd6aa26c020437b62839707986b392315d6 100644 (file)
@@ -334,7 +334,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index be1496ed9b66028655205c48a36b69a365ed203b..3662899c0f88fa6911c4f0afb20ebe36111a77ec 100644 (file)
@@ -358,7 +358,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index 54674d61e00141069e1fb5113e22e19784fc5c01..bb87f17ef477171990078b369a3e2a09cf8220ac 100644 (file)
@@ -336,7 +336,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index 832d9539f44194faff9d4e6940223f1d938850fc..b75a0b177b24cb38cb7f5e5652e762911999235f 100644 (file)
@@ -336,7 +336,7 @@ CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
 CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
index 121a6660ad4e5c40db157c25385507f4f51a674f..71b78ecee75c64773921bb9aed81aefbf24dae73 100644 (file)
@@ -9,6 +9,7 @@
  * the GNU General Public License (GPL), incorporated herein by reference.
  */
 
+#include <linux/init.h>
 #include <linux/types.h>
 #include <linux/console.h>
 #include <linux/string.h>
@@ -70,7 +71,7 @@ static void nf_poweroff(void)
                nf_call(id);
 }
 
-void nf_init(void)
+void __init nf_init(void)
 {
        unsigned long id, version;
        char buf[256];
index 0721858fbd1ef6618b288bcbea33369995e35653..2d75ae246167a37f07d71a9bb743702fff686092 100644 (file)
@@ -62,17 +62,18 @@ struct nfhd_device {
 static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
 {
        struct nfhd_device *dev = queue->queuedata;
-       struct bio_vec *bvec;
-       int i, dir, len, shift;
-       sector_t sec = bio->bi_sector;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
+       int dir, len, shift;
+       sector_t sec = bio->bi_iter.bi_sector;
 
        dir = bio_data_dir(bio);
        shift = dev->bshift;
-       bio_for_each_segment(bvec, bio, i) {
-               len = bvec->bv_len;
+       bio_for_each_segment(bvec, bio, iter) {
+               len = bvec.bv_len;
                len >>= 9;
                nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
-                               bvec_to_phys(bvec));
+                               bvec_to_phys(&bvec));
                sec += len;
        }
        bio_endio(bio, 0);
index b7609f791522a45f12170799cdae4f89bc8ab80f..2e5a787ea11b8f987ef3994292c7d57832bfc266 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/console.h>
 
 #include <asm/bootinfo.h>
+#include <asm/bootinfo-hp300.h>
+#include <asm/byteorder.h>
 #include <asm/machdep.h>
 #include <asm/blinken.h>
 #include <asm/io.h>                               /* readb() and writeb() */
@@ -70,15 +72,15 @@ extern int hp300_setup_serial_console(void) __init;
 int __init hp300_parse_bootinfo(const struct bi_record *record)
 {
        int unknown = 0;
-       const unsigned long *data = record->data;
+       const void *data = record->data;
 
-       switch (record->tag) {
+       switch (be16_to_cpu(record->tag)) {
        case BI_HP300_MODEL:
-               hp300_model = *data;
+               hp300_model = be32_to_cpup(data);
                break;
 
        case BI_HP300_UART_SCODE:
-               hp300_uart_scode = *data;
+               hp300_uart_scode = be32_to_cpup(data);
                break;
 
        case BI_HP300_UART_ADDR:
index 7a19b5686a4a69255f94c96aab86c382d461e482..5ad568110f1728701bab85c80c783910740cb069 100644 (file)
 
 #include <linux/ioport.h>
 
-    /*
-     *  Different Amiga models
-     */
-
-#define AMI_UNKNOWN    (0)
-#define AMI_500                (1)
-#define AMI_500PLUS    (2)
-#define AMI_600                (3)
-#define AMI_1000       (4)
-#define AMI_1200       (5)
-#define AMI_2000       (6)
-#define AMI_2500       (7)
-#define AMI_3000       (8)
-#define AMI_3000T      (9)
-#define AMI_3000PLUS   (10)
-#define AMI_4000       (11)
-#define AMI_4000T      (12)
-#define AMI_CDTV       (13)
-#define AMI_CD32       (14)
-#define AMI_DRACO      (15)
+#include <asm/bootinfo-amiga.h>
 
 
     /*
 
 extern unsigned long amiga_chipset;
 
-#define CS_STONEAGE    (0)
-#define CS_OCS         (1)
-#define CS_ECS         (2)
-#define CS_AGA         (3)
-
 
     /*
      *  Miscellaneous
@@ -266,7 +242,7 @@ struct CIA {
 
 #define zTwoBase (0x80000000)
 #define ZTWO_PADDR(x) (((unsigned long)(x))-zTwoBase)
-#define ZTWO_VADDR(x) (((unsigned long)(x))+zTwoBase)
+#define ZTWO_VADDR(x) ((void __iomem *)(((unsigned long)(x))+zTwoBase))
 
 #define CUSTOM_PHYSADDR     (0xdff000)
 #define amiga_custom ((*(volatile struct CUSTOM *)(zTwoBase+CUSTOM_PHYSADDR)))
index 6c19e0c22411a2bd4f7b76c2daf228e462f1eb27..87fc899d32eeba4fa057d52ce172e25fa8bb0664 100644 (file)
@@ -5,18 +5,11 @@
 
 #include <linux/types.h>
 
-/*
-   apollo models
-*/
+#include <asm/bootinfo-apollo.h>
+
 
 extern u_long apollo_model;
 
-#define APOLLO_UNKNOWN (0)
-#define APOLLO_DN3000 (1)
-#define APOLLO_DN3010 (2)
-#define APOLLO_DN3500 (3)
-#define APOLLO_DN4000 (4)
-#define APOLLO_DN4500 (5)
 
 /*
    see scn2681 data sheet for more info.
index d887050e6da6438516f0884c78ed9eb9889e2eda..972c8f33f05532c5bb6576471ca0ff4466f8b81d 100644 (file)
@@ -21,7 +21,7 @@
 #define _LINUX_ATARIHW_H_
 
 #include <linux/types.h>
-#include <asm/bootinfo.h>
+#include <asm/bootinfo-atari.h>
 #include <asm/raw_io.h>
 
 extern u_long atari_mch_cookie;
index 67e7a78ad96be0c0a6c069fc2dbb399729f20eba..9edc31893fb8ca982bc05628b8992c34bdc7bea3 100644 (file)
 ** This file is subject to the terms and conditions of the GNU General Public
 ** License.  See the file COPYING in the main directory of this archive
 ** for more details.
-**
-** Created 09/29/92 by Greg Harp
-**
-** 5/2/94 Roman Hodek:
-**   Added bi_atari part of the machine dependent union bi_un; for now it
-**   contains just a model field to distinguish between TT and Falcon.
-** 26/7/96 Roman Zippel:
-**   Renamed to setup.h; added some useful macros to allow gcc some
-**   optimizations if possible.
-** 5/10/96 Geert Uytterhoeven:
-**   Redesign of the boot information structure; renamed to bootinfo.h again
-** 27/11/96 Geert Uytterhoeven:
-**   Backwards compatibility with bootinfo interface version 1.0
 */
 
 #ifndef _M68K_BOOTINFO_H
 #define _M68K_BOOTINFO_H
 
-
-    /*
-     *  Bootinfo definitions
-     *
-     *  This is an easily parsable and extendable structure containing all
-     *  information to be passed from the bootstrap to the kernel.
-     *
-     *  This way I hope to keep all future changes back/forewards compatible.
-     *  Thus, keep your fingers crossed...
-     *
-     *  This structure is copied right after the kernel bss by the bootstrap
-     *  routine.
-     */
-
-#ifndef __ASSEMBLY__
-
-struct bi_record {
-    unsigned short tag;                        /* tag ID */
-    unsigned short size;               /* size of record (in bytes) */
-    unsigned long data[0];             /* data */
-};
-
-#endif /* __ASSEMBLY__ */
-
-
-    /*
-     *  Tag Definitions
-     *
-     *  Machine independent tags start counting from 0x0000
-     *  Machine dependent tags start counting from 0x8000
-     */
-
-#define BI_LAST                        0x0000  /* last record (sentinel) */
-#define BI_MACHTYPE            0x0001  /* machine type (u_long) */
-#define BI_CPUTYPE             0x0002  /* cpu type (u_long) */
-#define BI_FPUTYPE             0x0003  /* fpu type (u_long) */
-#define BI_MMUTYPE             0x0004  /* mmu type (u_long) */
-#define BI_MEMCHUNK            0x0005  /* memory chunk address and size */
-                                       /* (struct mem_info) */
-#define BI_RAMDISK             0x0006  /* ramdisk address and size */
-                                       /* (struct mem_info) */
-#define BI_COMMAND_LINE                0x0007  /* kernel command line parameters */
-                                       /* (string) */
-
-    /*
-     *  Amiga-specific tags
-     */
-
-#define BI_AMIGA_MODEL         0x8000  /* model (u_long) */
-#define BI_AMIGA_AUTOCON       0x8001  /* AutoConfig device */
-                                       /* (struct ConfigDev) */
-#define BI_AMIGA_CHIP_SIZE     0x8002  /* size of Chip RAM (u_long) */
-#define BI_AMIGA_VBLANK                0x8003  /* VBLANK frequency (u_char) */
-#define BI_AMIGA_PSFREQ                0x8004  /* power supply frequency (u_char) */
-#define BI_AMIGA_ECLOCK                0x8005  /* EClock frequency (u_long) */
-#define BI_AMIGA_CHIPSET       0x8006  /* native chipset present (u_long) */
-#define BI_AMIGA_SERPER                0x8007  /* serial port period (u_short) */
-
-    /*
-     *  Atari-specific tags
-     */
-
-#define BI_ATARI_MCH_COOKIE    0x8000  /* _MCH cookie from TOS (u_long) */
-#define BI_ATARI_MCH_TYPE      0x8001  /* special machine type (u_long) */
-                                       /* (values are ATARI_MACH_* defines */
-
-/* mch_cookie values (upper word) */
-#define ATARI_MCH_ST           0
-#define ATARI_MCH_STE          1
-#define ATARI_MCH_TT           2
-#define ATARI_MCH_FALCON       3
-
-/* mch_type values */
-#define ATARI_MACH_NORMAL      0       /* no special machine type */
-#define ATARI_MACH_MEDUSA      1       /* Medusa 040 */
-#define ATARI_MACH_HADES       2       /* Hades 040 or 060 */
-#define ATARI_MACH_AB40                3       /* Afterburner040 on Falcon */
-
-    /*
-     *  VME-specific tags
-     */
-
-#define BI_VME_TYPE            0x8000  /* VME sub-architecture (u_long) */
-#define BI_VME_BRDINFO         0x8001  /* VME board information (struct) */
-
-/* BI_VME_TYPE codes */
-#define        VME_TYPE_TP34V          0x0034  /* Tadpole TP34V */
-#define VME_TYPE_MVME147       0x0147  /* Motorola MVME147 */
-#define VME_TYPE_MVME162       0x0162  /* Motorola MVME162 */
-#define VME_TYPE_MVME166       0x0166  /* Motorola MVME166 */
-#define VME_TYPE_MVME167       0x0167  /* Motorola MVME167 */
-#define VME_TYPE_MVME172       0x0172  /* Motorola MVME172 */
-#define VME_TYPE_MVME177       0x0177  /* Motorola MVME177 */
-#define VME_TYPE_BVME4000      0x4000  /* BVM Ltd. BVME4000 */
-#define VME_TYPE_BVME6000      0x6000  /* BVM Ltd. BVME6000 */
-
-/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
- * Motorola VME boards.  Contains board number, Bug version, board
- * configuration options, etc.  See include/asm/mvme16xhw.h for details.
- */
-
-
-    /*
-     *  Macintosh-specific tags (all u_long)
-     */
-
-#define BI_MAC_MODEL           0x8000  /* Mac Gestalt ID (model type) */
-#define BI_MAC_VADDR           0x8001  /* Mac video base address */
-#define BI_MAC_VDEPTH          0x8002  /* Mac video depth */
-#define BI_MAC_VROW            0x8003  /* Mac video rowbytes */
-#define BI_MAC_VDIM            0x8004  /* Mac video dimensions */
-#define BI_MAC_VLOGICAL                0x8005  /* Mac video logical base */
-#define BI_MAC_SCCBASE         0x8006  /* Mac SCC base address */
-#define BI_MAC_BTIME           0x8007  /* Mac boot time */
-#define BI_MAC_GMTBIAS         0x8008  /* Mac GMT timezone offset */
-#define BI_MAC_MEMSIZE         0x8009  /* Mac RAM size (sanity check) */
-#define BI_MAC_CPUID           0x800a  /* Mac CPU type (sanity check) */
-#define BI_MAC_ROMBASE         0x800b  /* Mac system ROM base address */
-
-    /*
-     *  Macintosh hardware profile data - unused, see macintosh.h for
-     *  reasonable type values
-     */
-
-#define BI_MAC_VIA1BASE                0x8010  /* Mac VIA1 base address (always present) */
-#define BI_MAC_VIA2BASE                0x8011  /* Mac VIA2 base address (type varies) */
-#define BI_MAC_VIA2TYPE                0x8012  /* Mac VIA2 type (VIA, RBV, OSS) */
-#define BI_MAC_ADBTYPE         0x8013  /* Mac ADB interface type */
-#define BI_MAC_ASCBASE         0x8014  /* Mac Apple Sound Chip base address */
-#define BI_MAC_SCSI5380                0x8015  /* Mac NCR 5380 SCSI (base address, multi) */
-#define BI_MAC_SCSIDMA         0x8016  /* Mac SCSI DMA (base address) */
-#define BI_MAC_SCSI5396                0x8017  /* Mac NCR 53C96 SCSI (base address, multi) */
-#define BI_MAC_IDETYPE         0x8018  /* Mac IDE interface type */
-#define BI_MAC_IDEBASE         0x8019  /* Mac IDE interface base address */
-#define BI_MAC_NUBUS           0x801a  /* Mac Nubus type (none, regular, pseudo) */
-#define BI_MAC_SLOTMASK                0x801b  /* Mac Nubus slots present */
-#define BI_MAC_SCCTYPE         0x801c  /* Mac SCC serial type (normal, IOP) */
-#define BI_MAC_ETHTYPE         0x801d  /* Mac builtin ethernet type (Sonic, MACE */
-#define BI_MAC_ETHBASE         0x801e  /* Mac builtin ethernet base address */
-#define BI_MAC_PMU             0x801f  /* Mac power management / poweroff hardware */
-#define BI_MAC_IOP_SWIM                0x8020  /* Mac SWIM floppy IOP */
-#define BI_MAC_IOP_ADB         0x8021  /* Mac ADB IOP */
-
-    /*
-     * Mac: compatibility with old booter data format (temporarily)
-     * Fields unused with the new bootinfo can be deleted now; instead of
-     * adding new fields the struct might be splitted into a hardware address
-     * part and a hardware type part
-     */
-
-#ifndef __ASSEMBLY__
-
-struct mac_booter_data
-{
-       unsigned long videoaddr;
-       unsigned long videorow;
-       unsigned long videodepth;
-       unsigned long dimensions;
-       unsigned long args;
-       unsigned long boottime;
-       unsigned long gmtbias;
-       unsigned long bootver;
-       unsigned long videological;
-       unsigned long sccbase;
-       unsigned long id;
-       unsigned long memsize;
-       unsigned long serialmf;
-       unsigned long serialhsk;
-       unsigned long serialgpi;
-       unsigned long printmf;
-       unsigned long printhsk;
-       unsigned long printgpi;
-       unsigned long cpuid;
-       unsigned long rombase;
-       unsigned long adbdelay;
-       unsigned long timedbra;
-};
-
-extern struct mac_booter_data
-       mac_bi_data;
-
-#endif
-
-    /*
-     *  Apollo-specific tags
-     */
-
-#define BI_APOLLO_MODEL         0x8000  /* model (u_long) */
-
-    /*
-     *  HP300-specific tags
-     */
-
-#define BI_HP300_MODEL         0x8000  /* model (u_long) */
-#define BI_HP300_UART_SCODE    0x8001  /* UART select code (u_long) */
-#define BI_HP300_UART_ADDR     0x8002  /* phys. addr of UART (u_long) */
-
-    /*
-     * Stuff for bootinfo interface versioning
-     *
-     * At the start of kernel code, a 'struct bootversion' is located.
-     * bootstrap checks for a matching version of the interface before booting
-     * a kernel, to avoid user confusion if kernel and bootstrap don't work
-     * together :-)
-     *
-     * If incompatible changes are made to the bootinfo interface, the major
-     * number below should be stepped (and the minor reset to 0) for the
-     * appropriate machine. If a change is backward-compatible, the minor
-     * should be stepped. "Backwards-compatible" means that booting will work,
-     * but certain features may not.
-     */
-
-#define BOOTINFOV_MAGIC                        0x4249561A      /* 'BIV^Z' */
-#define MK_BI_VERSION(major,minor)     (((major)<<16)+(minor))
-#define BI_VERSION_MAJOR(v)            (((v) >> 16) & 0xffff)
-#define BI_VERSION_MINOR(v)            ((v) & 0xffff)
-
-#ifndef __ASSEMBLY__
-
-struct bootversion {
-    unsigned short branch;
-    unsigned long magic;
-    struct {
-       unsigned long machtype;
-       unsigned long version;
-    } machversions[0];
-};
-
-#endif /* __ASSEMBLY__ */
-
-#define AMIGA_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
-#define ATARI_BOOTI_VERSION    MK_BI_VERSION( 2, 1 )
-#define MAC_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
-#define MVME147_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
-#define MVME16x_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
-#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define Q40_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
-#define HP300_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
-
-#ifdef BOOTINFO_COMPAT_1_0
-
-    /*
-     *  Backwards compatibility with bootinfo interface version 1.0
-     */
-
-#define COMPAT_AMIGA_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
-#define COMPAT_ATARI_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
-#define COMPAT_MAC_BOOTI_VERSION      MK_BI_VERSION( 1, 0 )
-
-#include <linux/zorro.h>
-
-#define COMPAT_NUM_AUTO    16
-
-struct compat_bi_Amiga {
-    int model;
-    int num_autocon;
-    struct ConfigDev autocon[COMPAT_NUM_AUTO];
-    unsigned long chip_size;
-    unsigned char vblank;
-    unsigned char psfreq;
-    unsigned long eclock;
-    unsigned long chipset;
-    unsigned long hw_present;
-};
-
-struct compat_bi_Atari {
-    unsigned long hw_present;
-    unsigned long mch_cookie;
-};
-
-#ifndef __ASSEMBLY__
-
-struct compat_bi_Macintosh
-{
-       unsigned long videoaddr;
-       unsigned long videorow;
-       unsigned long videodepth;
-       unsigned long dimensions;
-       unsigned long args;
-       unsigned long boottime;
-       unsigned long gmtbias;
-       unsigned long bootver;
-       unsigned long videological;
-       unsigned long sccbase;
-       unsigned long id;
-       unsigned long memsize;
-       unsigned long serialmf;
-       unsigned long serialhsk;
-       unsigned long serialgpi;
-       unsigned long printmf;
-       unsigned long printhsk;
-       unsigned long printgpi;
-       unsigned long cpuid;
-       unsigned long rombase;
-       unsigned long adbdelay;
-       unsigned long timedbra;
-};
-
-#endif
-
-struct compat_mem_info {
-    unsigned long addr;
-    unsigned long size;
-};
-
-#define COMPAT_NUM_MEMINFO  4
-
-#define COMPAT_CPUB_68020 0
-#define COMPAT_CPUB_68030 1
-#define COMPAT_CPUB_68040 2
-#define COMPAT_CPUB_68060 3
-#define COMPAT_FPUB_68881 5
-#define COMPAT_FPUB_68882 6
-#define COMPAT_FPUB_68040 7
-#define COMPAT_FPUB_68060 8
-
-#define COMPAT_CPU_68020    (1<<COMPAT_CPUB_68020)
-#define COMPAT_CPU_68030    (1<<COMPAT_CPUB_68030)
-#define COMPAT_CPU_68040    (1<<COMPAT_CPUB_68040)
-#define COMPAT_CPU_68060    (1<<COMPAT_CPUB_68060)
-#define COMPAT_CPU_MASK     (31)
-#define COMPAT_FPU_68881    (1<<COMPAT_FPUB_68881)
-#define COMPAT_FPU_68882    (1<<COMPAT_FPUB_68882)
-#define COMPAT_FPU_68040    (1<<COMPAT_FPUB_68040)
-#define COMPAT_FPU_68060    (1<<COMPAT_FPUB_68060)
-#define COMPAT_FPU_MASK     (0xfe0)
-
-#define COMPAT_CL_SIZE      (256)
-
-struct compat_bootinfo {
-    unsigned long machtype;
-    unsigned long cputype;
-    struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
-    int num_memory;
-    unsigned long ramdisk_size;
-    unsigned long ramdisk_addr;
-    char command_line[COMPAT_CL_SIZE];
-    union {
-       struct compat_bi_Amiga     bi_ami;
-       struct compat_bi_Atari     bi_ata;
-       struct compat_bi_Macintosh bi_mac;
-    } bi_un;
-};
-
-#define bi_amiga       bi_un.bi_ami
-#define bi_atari       bi_un.bi_ata
-#define bi_mac         bi_un.bi_mac
-
-#endif /* BOOTINFO_COMPAT_1_0 */
-
+#include <uapi/asm/bootinfo.h>
 
 #endif /* _M68K_BOOTINFO_H */
index d998ea67c19c34d8fd1c005629bffecb9771d7cb..64f5271dd7be2ec70f4503af410a7af48362dfad 100644 (file)
@@ -1,25 +1,9 @@
 #ifndef _M68K_HP300HW_H
 #define _M68K_HP300HW_H
 
-extern unsigned long hp300_model;
+#include <asm/bootinfo-hp300.h>
 
-/* This information was taken from NetBSD */
-#define        HP_320          (0)     /* 16MHz 68020+HP MMU+16K external cache */
-#define        HP_330          (1)     /* 16MHz 68020+68851 MMU */
-#define        HP_340          (2)     /* 16MHz 68030 */
-#define        HP_345          (3)     /* 50MHz 68030+32K external cache */
-#define        HP_350          (4)     /* 25MHz 68020+HP MMU+32K external cache */
-#define        HP_360          (5)     /* 25MHz 68030 */
-#define        HP_370          (6)     /* 33MHz 68030+64K external cache */
-#define        HP_375          (7)     /* 50MHz 68030+32K external cache */
-#define        HP_380          (8)     /* 25MHz 68040 */
-#define        HP_385          (9)     /* 33MHz 68040 */
 
-#define        HP_400          (10)    /* 50MHz 68030+32K external cache */
-#define        HP_425T         (11)    /* 25MHz 68040 - model 425t */
-#define        HP_425S         (12)    /* 25MHz 68040 - model 425s */
-#define HP_425E                (13)    /* 25MHz 68040 - model 425e */
-#define HP_433T                (14)    /* 33MHz 68040 - model 433t */
-#define HP_433S                (15)    /* 33MHz 68040 - model 433s */
+extern unsigned long hp300_model;
 
 #endif /* _M68K_HP300HW_H */
index 682a1a2ff55f931ceeeac2f812d5254a75d1810b..d323b2c2d07d4e9a574da7e7f97d7a21bca08b6f 100644 (file)
@@ -4,6 +4,9 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 
+#include <asm/bootinfo-mac.h>
+
+
 /*
  *     Apple Macintoshisms
  */
@@ -74,65 +77,29 @@ struct mac_model
 #define MAC_FLOPPY_SWIM_IOP    3
 #define MAC_FLOPPY_AV          4
 
-/*
- *     Gestalt numbers
- */
+extern struct mac_model *macintosh_config;
 
-#define MAC_MODEL_II           6
-#define MAC_MODEL_IIX          7
-#define MAC_MODEL_IICX         8
-#define MAC_MODEL_SE30         9
-#define MAC_MODEL_IICI         11
-#define MAC_MODEL_IIFX         13      /* And well numbered it is too */
-#define MAC_MODEL_IISI         18
-#define MAC_MODEL_LC           19
-#define MAC_MODEL_Q900         20
-#define MAC_MODEL_PB170                21
-#define MAC_MODEL_Q700         22
-#define MAC_MODEL_CLII         23      /* aka: P200 */
-#define MAC_MODEL_PB140                25
-#define MAC_MODEL_Q950         26      /* aka: WGS95 */
-#define MAC_MODEL_LCIII                27      /* aka: P450 */
-#define MAC_MODEL_PB210                29
-#define MAC_MODEL_C650         30
-#define MAC_MODEL_PB230                32
-#define MAC_MODEL_PB180                33
-#define MAC_MODEL_PB160                34
-#define MAC_MODEL_Q800         35      /* aka: WGS80 */
-#define MAC_MODEL_Q650         36
-#define MAC_MODEL_LCII         37      /* aka: P400/405/410/430 */
-#define MAC_MODEL_PB250                38
-#define MAC_MODEL_IIVI         44
-#define MAC_MODEL_P600         45      /* aka: P600CD */
-#define MAC_MODEL_IIVX         48
-#define MAC_MODEL_CCL          49      /* aka: P250 */
-#define MAC_MODEL_PB165C       50
-#define MAC_MODEL_C610         52      /* aka: WGS60 */
-#define MAC_MODEL_Q610         53
-#define MAC_MODEL_PB145                54      /* aka: PB145B */
-#define MAC_MODEL_P520         56      /* aka: LC520 */
-#define MAC_MODEL_C660         60
-#define MAC_MODEL_P460         62      /* aka: LCIII+, P466/P467 */
-#define MAC_MODEL_PB180C       71
-#define MAC_MODEL_PB520                72      /* aka: PB520C, PB540, PB540C, PB550C */
-#define MAC_MODEL_PB270C       77
-#define MAC_MODEL_Q840         78
-#define MAC_MODEL_P550         80      /* aka: LC550, P560 */
-#define MAC_MODEL_CCLII                83      /* aka: P275 */
-#define MAC_MODEL_PB165                84
-#define MAC_MODEL_PB190                85      /* aka: PB190CS */
-#define MAC_MODEL_TV           88
-#define MAC_MODEL_P475         89      /* aka: LC475, P476 */
-#define MAC_MODEL_P475F                90      /* aka: P475 w/ FPU (no LC040) */
-#define MAC_MODEL_P575         92      /* aka: LC575, P577/P578 */
-#define MAC_MODEL_Q605         94
-#define MAC_MODEL_Q605_ACC     95      /* Q605 accelerated to 33 MHz */
-#define MAC_MODEL_Q630         98      /* aka: LC630, P630/631/635/636/637/638/640 */
-#define MAC_MODEL_P588         99      /* aka: LC580, P580 */
-#define MAC_MODEL_PB280                102
-#define MAC_MODEL_PB280C       103
-#define MAC_MODEL_PB150                115
 
-extern struct mac_model *macintosh_config;
+    /*
+     * Internal representation of the Mac hardware, filled in from bootinfo
+     */
+
+struct mac_booter_data
+{
+       unsigned long videoaddr;
+       unsigned long videorow;
+       unsigned long videodepth;
+       unsigned long dimensions;
+       unsigned long boottime;
+       unsigned long gmtbias;
+       unsigned long videological;
+       unsigned long sccbase;
+       unsigned long id;
+       unsigned long memsize;
+       unsigned long cpuid;
+       unsigned long rombase;
+};
+
+extern struct mac_booter_data mac_bi_data;
 
 #endif
index 6117f56653d28d3c14bcbee597a552b18cf6cecd..1eb89de631e5c09d1be76d0c043d2e467906b9a6 100644 (file)
@@ -3,23 +3,6 @@
 
 #include <asm/irq.h>
 
-/* Board ID data structure - pointer to this retrieved from Bug by head.S */
-
-/* Note, bytes 12 and 13 are board no in BCD (0162,0166,0167,0177,etc) */
-
-extern long mvme_bdid_ptr;
-
-typedef struct {
-       char    bdid[4];
-       u_char  rev, mth, day, yr;
-       u_short size, reserved;
-       u_short brdno;
-       char brdsuffix[2];
-       u_long  options;
-       u_short clun, dlun, ctype, dnum;
-       u_long  option2;
-} t_bdid, *p_bdid;
-
 
 typedef struct {
        u_char  ack_icr,
index 65e78a2dad64a9840fdb96bdc898e8b848f52331..8f2023f8c1c45727a6904d0567fb070e9f8b7364 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef _M68K_SETUP_H
 #define _M68K_SETUP_H
 
+#include <uapi/asm/bootinfo.h>
 #include <uapi/asm/setup.h>
 
 
@@ -297,14 +298,14 @@ extern int m68k_is040or060;
 #define NUM_MEMINFO    4
 
 #ifndef __ASSEMBLY__
-struct mem_info {
+struct m68k_mem_info {
        unsigned long addr;             /* physical address of memory chunk */
        unsigned long size;             /* length of memory chunk (in bytes) */
 };
 
 extern int m68k_num_memory;            /* # of memory blocks found (and used) */
 extern int m68k_realnum_memory;                /* real # of memory blocks found */
-extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */
+extern struct m68k_mem_info m68k_memory[NUM_MEMINFO];/* memory description */
 #endif
 
 #endif /* _M68K_SETUP_H */
index 6759dad954f61d9a3d40800f63cf95179c8129aa..efc1f48923573d4731806326b1e72395775fde3d 100644 (file)
@@ -28,4 +28,14 @@ static inline cycles_t get_cycles(void)
        return 0;
 }
 
+extern unsigned long (*mach_random_get_entropy)(void);
+
+static inline unsigned long random_get_entropy(void)
+{
+       if (mach_random_get_entropy)
+               return mach_random_get_entropy();
+       return 0;
+}
+#define random_get_entropy     random_get_entropy
+
 #endif
index 1fef45ada0973c7d83494f42c0c780ebc18f5ca3..6a2d257bdfb2224492f8f901575d17cc9b4f82d7 100644 (file)
@@ -11,6 +11,14 @@ generic-y += termbits.h
 generic-y += termios.h
 
 header-y += a.out.h
+header-y += bootinfo.h
+header-y += bootinfo-amiga.h
+header-y += bootinfo-apollo.h
+header-y += bootinfo-atari.h
+header-y += bootinfo-hp300.h
+header-y += bootinfo-mac.h
+header-y += bootinfo-q40.h
+header-y += bootinfo-vme.h
 header-y += byteorder.h
 header-y += cachectl.h
 header-y += fcntl.h
diff --git a/arch/m68k/include/uapi/asm/bootinfo-amiga.h b/arch/m68k/include/uapi/asm/bootinfo-amiga.h
new file mode 100644 (file)
index 0000000..daad3c5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+** asm/bootinfo-amiga.h -- Amiga-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_AMIGA_H
+#define _UAPI_ASM_M68K_BOOTINFO_AMIGA_H
+
+
+    /*
+     *  Amiga-specific tags
+     */
+
+#define BI_AMIGA_MODEL         0x8000  /* model (__be32) */
+#define BI_AMIGA_AUTOCON       0x8001  /* AutoConfig device */
+                                       /* (AmigaOS struct ConfigDev) */
+#define BI_AMIGA_CHIP_SIZE     0x8002  /* size of Chip RAM (__be32) */
+#define BI_AMIGA_VBLANK                0x8003  /* VBLANK frequency (__u8) */
+#define BI_AMIGA_PSFREQ                0x8004  /* power supply frequency (__u8) */
+#define BI_AMIGA_ECLOCK                0x8005  /* EClock frequency (__be32) */
+#define BI_AMIGA_CHIPSET       0x8006  /* native chipset present (__be32) */
+#define BI_AMIGA_SERPER                0x8007  /* serial port period (__be16) */
+
+
+    /*
+     *  Amiga models (BI_AMIGA_MODEL)
+     */
+
+#define AMI_UNKNOWN            0
+#define AMI_500                        1
+#define AMI_500PLUS            2
+#define AMI_600                        3
+#define AMI_1000               4
+#define AMI_1200               5
+#define AMI_2000               6
+#define AMI_2500               7
+#define AMI_3000               8
+#define AMI_3000T              9
+#define AMI_3000PLUS           10
+#define AMI_4000               11
+#define AMI_4000T              12
+#define AMI_CDTV               13
+#define AMI_CD32               14
+#define AMI_DRACO              15
+
+
+    /*
+     *  Amiga chipsets (BI_AMIGA_CHIPSET)
+     */
+
+#define CS_STONEAGE            0
+#define CS_OCS                 1
+#define CS_ECS                 2
+#define CS_AGA                 3
+
+
+    /*
+     *  Latest Amiga bootinfo version
+     */
+
+#define AMIGA_BOOTI_VERSION    MK_BI_VERSION(2, 0)
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_AMIGA_H */
diff --git a/arch/m68k/include/uapi/asm/bootinfo-apollo.h b/arch/m68k/include/uapi/asm/bootinfo-apollo.h
new file mode 100644 (file)
index 0000000..a93e0af
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+** asm/bootinfo-apollo.h -- Apollo-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_APOLLO_H
+#define _UAPI_ASM_M68K_BOOTINFO_APOLLO_H
+
+
+    /*
+     *  Apollo-specific tags
+     */
+
+#define BI_APOLLO_MODEL                0x8000  /* model (__be32) */
+
+
+    /*
+     *  Apollo models (BI_APOLLO_MODEL)
+     */
+
+#define APOLLO_UNKNOWN         0
+#define APOLLO_DN3000          1
+#define APOLLO_DN3010          2
+#define APOLLO_DN3500          3
+#define APOLLO_DN4000          4
+#define APOLLO_DN4500          5
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_APOLLO_H */
diff --git a/arch/m68k/include/uapi/asm/bootinfo-atari.h b/arch/m68k/include/uapi/asm/bootinfo-atari.h
new file mode 100644 (file)
index 0000000..a817854
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+** asm/bootinfo-atari.h -- Atari-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_ATARI_H
+#define _UAPI_ASM_M68K_BOOTINFO_ATARI_H
+
+
+    /*
+     *  Atari-specific tags
+     */
+
+#define BI_ATARI_MCH_COOKIE    0x8000  /* _MCH cookie from TOS (__be32) */
+#define BI_ATARI_MCH_TYPE      0x8001  /* special machine type (__be32) */
+
+
+    /*
+     *  mch_cookie values (upper word of BI_ATARI_MCH_COOKIE)
+     */
+
+#define ATARI_MCH_ST           0
+#define ATARI_MCH_STE          1
+#define ATARI_MCH_TT           2
+#define ATARI_MCH_FALCON       3
+
+
+    /*
+     *  Atari machine types (BI_ATARI_MCH_TYPE)
+     */
+
+#define ATARI_MACH_NORMAL      0       /* no special machine type */
+#define ATARI_MACH_MEDUSA      1       /* Medusa 040 */
+#define ATARI_MACH_HADES       2       /* Hades 040 or 060 */
+#define ATARI_MACH_AB40                3       /* Afterburner040 on Falcon */
+
+
+    /*
+     *  Latest Atari bootinfo version
+     */
+
+#define ATARI_BOOTI_VERSION    MK_BI_VERSION(2, 1)
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_ATARI_H */
diff --git a/arch/m68k/include/uapi/asm/bootinfo-hp300.h b/arch/m68k/include/uapi/asm/bootinfo-hp300.h
new file mode 100644 (file)
index 0000000..c90cb71
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+** asm/bootinfo-hp300.h -- HP9000/300-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_HP300_H
+#define _UAPI_ASM_M68K_BOOTINFO_HP300_H
+
+
+    /*
+     *  HP9000/300-specific tags
+     */
+
+#define BI_HP300_MODEL         0x8000  /* model (__be32) */
+#define BI_HP300_UART_SCODE    0x8001  /* UART select code (__be32) */
+#define BI_HP300_UART_ADDR     0x8002  /* phys. addr of UART (__be32) */
+
+
+    /*
+     *  HP9000/300 and /400 models (BI_HP300_MODEL)
+     *
+     * This information was taken from NetBSD
+     */
+
+#define HP_320         0       /* 16MHz 68020+HP MMU+16K external cache */
+#define HP_330         1       /* 16MHz 68020+68851 MMU */
+#define HP_340         2       /* 16MHz 68030 */
+#define HP_345         3       /* 50MHz 68030+32K external cache */
+#define HP_350         4       /* 25MHz 68020+HP MMU+32K external cache */
+#define HP_360         5       /* 25MHz 68030 */
+#define HP_370         6       /* 33MHz 68030+64K external cache */
+#define HP_375         7       /* 50MHz 68030+32K external cache */
+#define HP_380         8       /* 25MHz 68040 */
+#define HP_385         9       /* 33MHz 68040 */
+
+#define HP_400         10      /* 50MHz 68030+32K external cache */
+#define HP_425T                11      /* 25MHz 68040 - model 425t */
+#define HP_425S                12      /* 25MHz 68040 - model 425s */
+#define HP_425E                13      /* 25MHz 68040 - model 425e */
+#define HP_433T                14      /* 33MHz 68040 - model 433t */
+#define HP_433S                15      /* 33MHz 68040 - model 433s */
+
+
+    /*
+     *  Latest HP9000/300 bootinfo version
+     */
+
+#define HP300_BOOTI_VERSION    MK_BI_VERSION(2, 0)
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_HP300_H */
diff --git a/arch/m68k/include/uapi/asm/bootinfo-mac.h b/arch/m68k/include/uapi/asm/bootinfo-mac.h
new file mode 100644 (file)
index 0000000..b44ff73
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+** asm/bootinfo-mac.h -- Macintosh-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_MAC_H
+#define _UAPI_ASM_M68K_BOOTINFO_MAC_H
+
+
+    /*
+     *  Macintosh-specific tags (all __be32)
+     */
+
+#define BI_MAC_MODEL           0x8000  /* Mac Gestalt ID (model type) */
+#define BI_MAC_VADDR           0x8001  /* Mac video base address */
+#define BI_MAC_VDEPTH          0x8002  /* Mac video depth */
+#define BI_MAC_VROW            0x8003  /* Mac video rowbytes */
+#define BI_MAC_VDIM            0x8004  /* Mac video dimensions */
+#define BI_MAC_VLOGICAL                0x8005  /* Mac video logical base */
+#define BI_MAC_SCCBASE         0x8006  /* Mac SCC base address */
+#define BI_MAC_BTIME           0x8007  /* Mac boot time */
+#define BI_MAC_GMTBIAS         0x8008  /* Mac GMT timezone offset */
+#define BI_MAC_MEMSIZE         0x8009  /* Mac RAM size (sanity check) */
+#define BI_MAC_CPUID           0x800a  /* Mac CPU type (sanity check) */
+#define BI_MAC_ROMBASE         0x800b  /* Mac system ROM base address */
+
+
+    /*
+     *  Macintosh hardware profile data - unused, see macintosh.h for
+     *  reasonable type values
+     */
+
+#define BI_MAC_VIA1BASE                0x8010  /* Mac VIA1 base address (always present) */
+#define BI_MAC_VIA2BASE                0x8011  /* Mac VIA2 base address (type varies) */
+#define BI_MAC_VIA2TYPE                0x8012  /* Mac VIA2 type (VIA, RBV, OSS) */
+#define BI_MAC_ADBTYPE         0x8013  /* Mac ADB interface type */
+#define BI_MAC_ASCBASE         0x8014  /* Mac Apple Sound Chip base address */
+#define BI_MAC_SCSI5380                0x8015  /* Mac NCR 5380 SCSI (base address, multi) */
+#define BI_MAC_SCSIDMA         0x8016  /* Mac SCSI DMA (base address) */
+#define BI_MAC_SCSI5396                0x8017  /* Mac NCR 53C96 SCSI (base address, multi) */
+#define BI_MAC_IDETYPE         0x8018  /* Mac IDE interface type */
+#define BI_MAC_IDEBASE         0x8019  /* Mac IDE interface base address */
+#define BI_MAC_NUBUS           0x801a  /* Mac Nubus type (none, regular, pseudo) */
+#define BI_MAC_SLOTMASK                0x801b  /* Mac Nubus slots present */
+#define BI_MAC_SCCTYPE         0x801c  /* Mac SCC serial type (normal, IOP) */
+#define BI_MAC_ETHTYPE         0x801d  /* Mac builtin ethernet type (Sonic, MACE */
+#define BI_MAC_ETHBASE         0x801e  /* Mac builtin ethernet base address */
+#define BI_MAC_PMU             0x801f  /* Mac power management / poweroff hardware */
+#define BI_MAC_IOP_SWIM                0x8020  /* Mac SWIM floppy IOP */
+#define BI_MAC_IOP_ADB         0x8021  /* Mac ADB IOP */
+
+
+    /*
+     * Macintosh Gestalt numbers (BI_MAC_MODEL)
+     */
+
+#define MAC_MODEL_II           6
+#define MAC_MODEL_IIX          7
+#define MAC_MODEL_IICX         8
+#define MAC_MODEL_SE30         9
+#define MAC_MODEL_IICI         11
+#define MAC_MODEL_IIFX         13      /* And well numbered it is too */
+#define MAC_MODEL_IISI         18
+#define MAC_MODEL_LC           19
+#define MAC_MODEL_Q900         20
+#define MAC_MODEL_PB170                21
+#define MAC_MODEL_Q700         22
+#define MAC_MODEL_CLII         23      /* aka: P200 */
+#define MAC_MODEL_PB140                25
+#define MAC_MODEL_Q950         26      /* aka: WGS95 */
+#define MAC_MODEL_LCIII                27      /* aka: P450 */
+#define MAC_MODEL_PB210                29
+#define MAC_MODEL_C650         30
+#define MAC_MODEL_PB230                32
+#define MAC_MODEL_PB180                33
+#define MAC_MODEL_PB160                34
+#define MAC_MODEL_Q800         35      /* aka: WGS80 */
+#define MAC_MODEL_Q650         36
+#define MAC_MODEL_LCII         37      /* aka: P400/405/410/430 */
+#define MAC_MODEL_PB250                38
+#define MAC_MODEL_IIVI         44
+#define MAC_MODEL_P600         45      /* aka: P600CD */
+#define MAC_MODEL_IIVX         48
+#define MAC_MODEL_CCL          49      /* aka: P250 */
+#define MAC_MODEL_PB165C       50
+#define MAC_MODEL_C610         52      /* aka: WGS60 */
+#define MAC_MODEL_Q610         53
+#define MAC_MODEL_PB145                54      /* aka: PB145B */
+#define MAC_MODEL_P520         56      /* aka: LC520 */
+#define MAC_MODEL_C660         60
+#define MAC_MODEL_P460         62      /* aka: LCIII+, P466/P467 */
+#define MAC_MODEL_PB180C       71
+#define MAC_MODEL_PB520                72      /* aka: PB520C, PB540, PB540C, PB550C */
+#define MAC_MODEL_PB270C       77
+#define MAC_MODEL_Q840         78
+#define MAC_MODEL_P550         80      /* aka: LC550, P560 */
+#define MAC_MODEL_CCLII                83      /* aka: P275 */
+#define MAC_MODEL_PB165                84
+#define MAC_MODEL_PB190                85      /* aka: PB190CS */
+#define MAC_MODEL_TV           88
+#define MAC_MODEL_P475         89      /* aka: LC475, P476 */
+#define MAC_MODEL_P475F                90      /* aka: P475 w/ FPU (no LC040) */
+#define MAC_MODEL_P575         92      /* aka: LC575, P577/P578 */
+#define MAC_MODEL_Q605         94
+#define MAC_MODEL_Q605_ACC     95      /* Q605 accelerated to 33 MHz */
+#define MAC_MODEL_Q630         98      /* aka: LC630, P630/631/635/636/637/638/640 */
+#define MAC_MODEL_P588         99      /* aka: LC580, P580 */
+#define MAC_MODEL_PB280                102
+#define MAC_MODEL_PB280C       103
+#define MAC_MODEL_PB150                115
+
+
+    /*
+     *  Latest Macintosh bootinfo version
+     */
+
+#define MAC_BOOTI_VERSION      MK_BI_VERSION(2, 0)
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_MAC_H */
diff --git a/arch/m68k/include/uapi/asm/bootinfo-q40.h b/arch/m68k/include/uapi/asm/bootinfo-q40.h
new file mode 100644 (file)
index 0000000..c79fea7
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+** asm/bootinfo-q40.h -- Q40-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_Q40_H
+#define _UAPI_ASM_M68K_BOOTINFO_Q40_H
+
+
+    /*
+     *  Latest Q40 bootinfo version
+     */
+
+#define Q40_BOOTI_VERSION      MK_BI_VERSION(2, 0)
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_Q40_H */
diff --git a/arch/m68k/include/uapi/asm/bootinfo-vme.h b/arch/m68k/include/uapi/asm/bootinfo-vme.h
new file mode 100644 (file)
index 0000000..a135eb4
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+** asm/bootinfo-vme.h -- VME-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_VME_H
+#define _UAPI_ASM_M68K_BOOTINFO_VME_H
+
+
+#include <linux/types.h>
+
+
+    /*
+     *  VME-specific tags
+     */
+
+#define BI_VME_TYPE            0x8000  /* VME sub-architecture (__be32) */
+#define BI_VME_BRDINFO         0x8001  /* VME board information (struct) */
+
+
+    /*
+     *  VME models (BI_VME_TYPE)
+     */
+
+#define VME_TYPE_TP34V         0x0034  /* Tadpole TP34V */
+#define VME_TYPE_MVME147       0x0147  /* Motorola MVME147 */
+#define VME_TYPE_MVME162       0x0162  /* Motorola MVME162 */
+#define VME_TYPE_MVME166       0x0166  /* Motorola MVME166 */
+#define VME_TYPE_MVME167       0x0167  /* Motorola MVME167 */
+#define VME_TYPE_MVME172       0x0172  /* Motorola MVME172 */
+#define VME_TYPE_MVME177       0x0177  /* Motorola MVME177 */
+#define VME_TYPE_BVME4000      0x4000  /* BVM Ltd. BVME4000 */
+#define VME_TYPE_BVME6000      0x6000  /* BVM Ltd. BVME6000 */
+
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Board ID data structure - pointer to this retrieved from Bug by head.S
+ *
+ * BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
+ * Motorola VME boards.  Contains board number, Bug version, board
+ * configuration options, etc.
+ *
+ * Note, bytes 12 and 13 are board no in BCD (0162,0166,0167,0177,etc)
+ */
+
+typedef struct {
+       char    bdid[4];
+       __u8    rev, mth, day, yr;
+       __be16  size, reserved;
+       __be16  brdno;
+       char    brdsuffix[2];
+       __be32  options;
+       __be16  clun, dlun, ctype, dnum;
+       __be32  option2;
+} t_bdid, *p_bdid;
+
+#endif /* __ASSEMBLY__ */
+
+
+    /*
+     *  Latest VME bootinfo versions
+     */
+
+#define MVME147_BOOTI_VERSION  MK_BI_VERSION(2, 0)
+#define MVME16x_BOOTI_VERSION  MK_BI_VERSION(2, 0)
+#define BVME6000_BOOTI_VERSION MK_BI_VERSION(2, 0)
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_VME_H */
diff --git a/arch/m68k/include/uapi/asm/bootinfo.h b/arch/m68k/include/uapi/asm/bootinfo.h
new file mode 100644 (file)
index 0000000..cdeb26a
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
+ *
+ * Copyright 1992 by Greg Harp
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_H
+#define _UAPI_ASM_M68K_BOOTINFO_H
+
+
+#include <linux/types.h>
+
+
+#ifndef __ASSEMBLY__
+
+    /*
+     *  Bootinfo definitions
+     *
+     *  This is an easily parsable and extendable structure containing all
+     *  information to be passed from the bootstrap to the kernel.
+     *
+     *  This way I hope to keep all future changes back/forewards compatible.
+     *  Thus, keep your fingers crossed...
+     *
+     *  This structure is copied right after the kernel by the bootstrap
+     *  routine.
+     */
+
+struct bi_record {
+       __be16 tag;                     /* tag ID */
+       __be16 size;                    /* size of record (in bytes) */
+       __be32 data[0];                 /* data */
+};
+
+
+struct mem_info {
+       __be32 addr;                    /* physical address of memory chunk */
+       __be32 size;                    /* length of memory chunk (in bytes) */
+};
+
+#endif /* __ASSEMBLY__ */
+
+
+    /*
+     *  Tag Definitions
+     *
+     *  Machine independent tags start counting from 0x0000
+     *  Machine dependent tags start counting from 0x8000
+     */
+
+#define BI_LAST                        0x0000  /* last record (sentinel) */
+#define BI_MACHTYPE            0x0001  /* machine type (__be32) */
+#define BI_CPUTYPE             0x0002  /* cpu type (__be32) */
+#define BI_FPUTYPE             0x0003  /* fpu type (__be32) */
+#define BI_MMUTYPE             0x0004  /* mmu type (__be32) */
+#define BI_MEMCHUNK            0x0005  /* memory chunk address and size */
+                                       /* (struct mem_info) */
+#define BI_RAMDISK             0x0006  /* ramdisk address and size */
+                                       /* (struct mem_info) */
+#define BI_COMMAND_LINE                0x0007  /* kernel command line parameters */
+                                       /* (string) */
+
+
+    /*
+     *  Linux/m68k Architectures (BI_MACHTYPE)
+     */
+
+#define MACH_AMIGA             1
+#define MACH_ATARI             2
+#define MACH_MAC               3
+#define MACH_APOLLO            4
+#define MACH_SUN3              5
+#define MACH_MVME147           6
+#define MACH_MVME16x           7
+#define MACH_BVME6000          8
+#define MACH_HP300             9
+#define MACH_Q40               10
+#define MACH_SUN3X             11
+#define MACH_M54XX             12
+
+
+    /*
+     *  CPU, FPU and MMU types (BI_CPUTYPE, BI_FPUTYPE, BI_MMUTYPE)
+     *
+     *  Note: we may rely on the following equalities:
+     *
+     *      CPU_68020 == MMU_68851
+     *      CPU_68030 == MMU_68030
+     *      CPU_68040 == FPU_68040 == MMU_68040
+     *      CPU_68060 == FPU_68060 == MMU_68060
+     */
+
+#define CPUB_68020             0
+#define CPUB_68030             1
+#define CPUB_68040             2
+#define CPUB_68060             3
+#define CPUB_COLDFIRE          4
+
+#define CPU_68020              (1 << CPUB_68020)
+#define CPU_68030              (1 << CPUB_68030)
+#define CPU_68040              (1 << CPUB_68040)
+#define CPU_68060              (1 << CPUB_68060)
+#define CPU_COLDFIRE           (1 << CPUB_COLDFIRE)
+
+#define FPUB_68881             0
+#define FPUB_68882             1
+#define FPUB_68040             2       /* Internal FPU */
+#define FPUB_68060             3       /* Internal FPU */
+#define FPUB_SUNFPA            4       /* Sun-3 FPA */
+#define FPUB_COLDFIRE          5       /* ColdFire FPU */
+
+#define FPU_68881              (1 << FPUB_68881)
+#define FPU_68882              (1 << FPUB_68882)
+#define FPU_68040              (1 << FPUB_68040)
+#define FPU_68060              (1 << FPUB_68060)
+#define FPU_SUNFPA             (1 << FPUB_SUNFPA)
+#define FPU_COLDFIRE           (1 << FPUB_COLDFIRE)
+
+#define MMUB_68851             0
+#define MMUB_68030             1       /* Internal MMU */
+#define MMUB_68040             2       /* Internal MMU */
+#define MMUB_68060             3       /* Internal MMU */
+#define MMUB_APOLLO            4       /* Custom Apollo */
+#define MMUB_SUN3              5       /* Custom Sun-3 */
+#define MMUB_COLDFIRE          6       /* Internal MMU */
+
+#define MMU_68851              (1 << MMUB_68851)
+#define MMU_68030              (1 << MMUB_68030)
+#define MMU_68040              (1 << MMUB_68040)
+#define MMU_68060              (1 << MMUB_68060)
+#define MMU_SUN3               (1 << MMUB_SUN3)
+#define MMU_APOLLO             (1 << MMUB_APOLLO)
+#define MMU_COLDFIRE           (1 << MMUB_COLDFIRE)
+
+
+    /*
+     * Stuff for bootinfo interface versioning
+     *
+     * At the start of kernel code, a 'struct bootversion' is located.
+     * bootstrap checks for a matching version of the interface before booting
+     * a kernel, to avoid user confusion if kernel and bootstrap don't work
+     * together :-)
+     *
+     * If incompatible changes are made to the bootinfo interface, the major
+     * number below should be stepped (and the minor reset to 0) for the
+     * appropriate machine. If a change is backward-compatible, the minor
+     * should be stepped. "Backwards-compatible" means that booting will work,
+     * but certain features may not.
+     */
+
+#define BOOTINFOV_MAGIC                        0x4249561A      /* 'BIV^Z' */
+#define MK_BI_VERSION(major, minor)    (((major) << 16) + (minor))
+#define BI_VERSION_MAJOR(v)            (((v) >> 16) & 0xffff)
+#define BI_VERSION_MINOR(v)            ((v) & 0xffff)
+
+#ifndef __ASSEMBLY__
+
+struct bootversion {
+       __be16 branch;
+       __be32 magic;
+       struct {
+               __be32 machtype;
+               __be32 version;
+       } machversions[0];
+} __packed;
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_H */
index 85579bff455ccb32fc7f9e805d0f78383c053245..6a6dc636761eaa210844f10614ad1633cff41bc3 100644 (file)
@@ -6,98 +6,11 @@
 ** This file is subject to the terms and conditions of the GNU General Public
 ** License.  See the file COPYING in the main directory of this archive
 ** for more details.
-**
-** Created 09/29/92 by Greg Harp
-**
-** 5/2/94 Roman Hodek:
-**   Added bi_atari part of the machine dependent union bi_un; for now it
-**   contains just a model field to distinguish between TT and Falcon.
-** 26/7/96 Roman Zippel:
-**   Renamed to setup.h; added some useful macros to allow gcc some
-**   optimizations if possible.
-** 5/10/96 Geert Uytterhoeven:
-**   Redesign of the boot information structure; moved boot information
-**   structure to bootinfo.h
 */
 
 #ifndef _UAPI_M68K_SETUP_H
 #define _UAPI_M68K_SETUP_H
 
-
-
-    /*
-     *  Linux/m68k Architectures
-     */
-
-#define MACH_AMIGA    1
-#define MACH_ATARI    2
-#define MACH_MAC      3
-#define MACH_APOLLO   4
-#define MACH_SUN3     5
-#define MACH_MVME147  6
-#define MACH_MVME16x  7
-#define MACH_BVME6000 8
-#define MACH_HP300    9
-#define MACH_Q40     10
-#define MACH_SUN3X   11
-#define MACH_M54XX   12
-
 #define COMMAND_LINE_SIZE 256
 
-
-
-    /*
-     *  CPU, FPU and MMU types
-     *
-     *  Note: we may rely on the following equalities:
-     *
-     *      CPU_68020 == MMU_68851
-     *      CPU_68030 == MMU_68030
-     *      CPU_68040 == FPU_68040 == MMU_68040
-     *      CPU_68060 == FPU_68060 == MMU_68060
-     */
-
-#define CPUB_68020     0
-#define CPUB_68030     1
-#define CPUB_68040     2
-#define CPUB_68060     3
-#define CPUB_COLDFIRE  4
-
-#define CPU_68020      (1<<CPUB_68020)
-#define CPU_68030      (1<<CPUB_68030)
-#define CPU_68040      (1<<CPUB_68040)
-#define CPU_68060      (1<<CPUB_68060)
-#define CPU_COLDFIRE   (1<<CPUB_COLDFIRE)
-
-#define FPUB_68881     0
-#define FPUB_68882     1
-#define FPUB_68040     2                       /* Internal FPU */
-#define FPUB_68060     3                       /* Internal FPU */
-#define FPUB_SUNFPA    4                       /* Sun-3 FPA */
-#define FPUB_COLDFIRE  5                       /* ColdFire FPU */
-
-#define FPU_68881      (1<<FPUB_68881)
-#define FPU_68882      (1<<FPUB_68882)
-#define FPU_68040      (1<<FPUB_68040)
-#define FPU_68060      (1<<FPUB_68060)
-#define FPU_SUNFPA     (1<<FPUB_SUNFPA)
-#define FPU_COLDFIRE   (1<<FPUB_COLDFIRE)
-
-#define MMUB_68851     0
-#define MMUB_68030     1                       /* Internal MMU */
-#define MMUB_68040     2                       /* Internal MMU */
-#define MMUB_68060     3                       /* Internal MMU */
-#define MMUB_APOLLO    4                       /* Custom Apollo */
-#define MMUB_SUN3      5                       /* Custom Sun-3 */
-#define MMUB_COLDFIRE  6                       /* Internal MMU */
-
-#define MMU_68851      (1<<MMUB_68851)
-#define MMU_68030      (1<<MMUB_68030)
-#define MMU_68040      (1<<MMUB_68040)
-#define MMU_68060      (1<<MMUB_68060)
-#define MMU_SUN3       (1<<MMUB_SUN3)
-#define MMU_APOLLO     (1<<MMUB_APOLLO)
-#define MMU_COLDFIRE   (1<<MMUB_COLDFIRE)
-
-
 #endif /* _UAPI_M68K_SETUP_H */
index ac85f16534af929c33d0f1daf1f3a565488b6af4..7d7913f5dce3beabd14ecac0afdc66109ee30e55 100644 (file)
@@ -23,7 +23,7 @@
 ** 98/04/25 Phil Blundell: added HP300 support
 ** 1998/08/30 David Kilzer: Added support for font_desc structures
 **            for linux-2.1.115
-** 9/02/11  Richard Zidlicky: added Q40 support (initial vesion 99/01/01)
+** 1999/02/11  Richard Zidlicky: added Q40 support (initial version 99/01/01)
 ** 2004/05/13 Kars de Jong: Finalised HP300 support
 **
 ** This file is subject to the terms and conditions of the GNU General Public
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/bootinfo.h>
+#include <asm/bootinfo-amiga.h>
+#include <asm/bootinfo-atari.h>
+#include <asm/bootinfo-hp300.h>
+#include <asm/bootinfo-mac.h>
+#include <asm/bootinfo-q40.h>
+#include <asm/bootinfo-vme.h>
 #include <asm/setup.h>
 #include <asm/entry.h>
 #include <asm/pgtable.h>
@@ -1532,7 +1538,7 @@ L(cache_done):
 
 /*
  * Find a tag record in the bootinfo structure
- * The bootinfo structure is located right after the kernel bss
+ * The bootinfo structure is located right after the kernel
  * Returns: d0: size (-1 if not found)
  *          a0: data pointer (end-of-records if not found)
  */
@@ -3896,8 +3902,6 @@ BVME_SCC_DATA_A   = 0xffb0000f
 #endif
 
 #if defined(CONFIG_MAC)
-L(mac_booter_data):
-       .long   0
 L(mac_videobase):
        .long   0
 L(mac_videodepth):
index e67e53159573a81d0db7da0d93464766e47ab264..28abca421974f4a240e203b84afa332b17acd041 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/initrd.h>
 
 #include <asm/bootinfo.h>
+#include <asm/byteorder.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/fpu.h>
@@ -71,12 +72,12 @@ EXPORT_SYMBOL(m68k_num_memory);
 int m68k_realnum_memory;
 EXPORT_SYMBOL(m68k_realnum_memory);
 unsigned long m68k_memoffset;
-struct mem_info m68k_memory[NUM_MEMINFO];
+struct m68k_mem_info m68k_memory[NUM_MEMINFO];
 EXPORT_SYMBOL(m68k_memory);
 
-struct mem_info m68k_ramdisk;
+static struct m68k_mem_info m68k_ramdisk __initdata;
 
-static char m68k_command_line[CL_SIZE];
+static char m68k_command_line[CL_SIZE] __initdata;
 
 void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL;
 /* machine dependent irq functions */
@@ -143,11 +144,14 @@ extern void paging_init(void);
 
 static void __init m68k_parse_bootinfo(const struct bi_record *record)
 {
-       while (record->tag != BI_LAST) {
+       uint16_t tag;
+
+       while ((tag = be16_to_cpu(record->tag)) != BI_LAST) {
                int unknown = 0;
-               const unsigned long *data = record->data;
+               const void *data = record->data;
+               uint16_t size = be16_to_cpu(record->size);
 
-               switch (record->tag) {
+               switch (tag) {
                case BI_MACHTYPE:
                case BI_CPUTYPE:
                case BI_FPUTYPE:
@@ -157,20 +161,27 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
 
                case BI_MEMCHUNK:
                        if (m68k_num_memory < NUM_MEMINFO) {
-                               m68k_memory[m68k_num_memory].addr = data[0];
-                               m68k_memory[m68k_num_memory].size = data[1];
+                               const struct mem_info *m = data;
+                               m68k_memory[m68k_num_memory].addr =
+                                       be32_to_cpu(m->addr);
+                               m68k_memory[m68k_num_memory].size =
+                                       be32_to_cpu(m->size);
                                m68k_num_memory++;
                        } else
-                               printk("m68k_parse_bootinfo: too many memory chunks\n");
+                               pr_warn("%s: too many memory chunks\n",
+                                       __func__);
                        break;
 
                case BI_RAMDISK:
-                       m68k_ramdisk.addr = data[0];
-                       m68k_ramdisk.size = data[1];
+                       {
+                               const struct mem_info *m = data;
+                               m68k_ramdisk.addr = be32_to_cpu(m->addr);
+                               m68k_ramdisk.size = be32_to_cpu(m->size);
+                       }
                        break;
 
                case BI_COMMAND_LINE:
-                       strlcpy(m68k_command_line, (const char *)data,
+                       strlcpy(m68k_command_line, data,
                                sizeof(m68k_command_line));
                        break;
 
@@ -197,17 +208,16 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
                                unknown = 1;
                }
                if (unknown)
-                       printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n",
-                              record->tag);
-               record = (struct bi_record *)((unsigned long)record +
-                                             record->size);
+                       pr_warn("%s: unknown tag 0x%04x ignored\n", __func__,
+                               tag);
+               record = (struct bi_record *)((unsigned long)record + size);
        }
 
        m68k_realnum_memory = m68k_num_memory;
 #ifdef CONFIG_SINGLE_MEMORY_CHUNK
        if (m68k_num_memory > 1) {
-               printk("Ignoring last %i chunks of physical memory\n",
-                      (m68k_num_memory - 1));
+               pr_warn("%s: ignoring last %i chunks of physical memory\n",
+                       __func__, (m68k_num_memory - 1));
                m68k_num_memory = 1;
        }
 #endif
@@ -219,7 +229,7 @@ void __init setup_arch(char **cmdline_p)
        int i;
 #endif
 
-       /* The bootinfo is located right after the kernel bss */
+       /* The bootinfo is located right after the kernel */
        if (!CPU_IS_COLDFIRE)
                m68k_parse_bootinfo((const struct bi_record *)_end);
 
@@ -247,7 +257,7 @@ void __init setup_arch(char **cmdline_p)
                asm (".chip 68060; movec %%pcr,%0; .chip 68k"
                     : "=d" (pcr));
                if (((pcr >> 8) & 0xff) <= 5) {
-                       printk("Enabling workaround for errata I14\n");
+                       pr_warn("Enabling workaround for errata I14\n");
                        asm (".chip 68060; movec %0,%%pcr; .chip 68k"
                             : : "d" (pcr | 0x20));
                }
@@ -336,12 +346,12 @@ void __init setup_arch(char **cmdline_p)
                panic("No configuration setup");
        }
 
+       paging_init();
+
 #ifdef CONFIG_NATFEAT
        nf_init();
 #endif
 
-       paging_init();
-
 #ifndef CONFIG_SUN3
        for (i = 1; i < m68k_num_memory; i++)
                free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
@@ -353,7 +363,7 @@ void __init setup_arch(char **cmdline_p)
                                     BOOTMEM_DEFAULT);
                initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
                initrd_end = initrd_start + m68k_ramdisk.size;
-               printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
+               pr_info("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
        }
 #endif
 
@@ -538,9 +548,9 @@ void check_bugs(void)
 {
 #ifndef CONFIG_M68KFPU_EMU
        if (m68k_fputype == 0) {
-               printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
+               pr_emerg("*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
                        "WHICH IS REQUIRED BY LINUX/M68K ***\n");
-               printk(KERN_EMERG "Upgrade your hardware or join the FPU "
+               pr_emerg("Upgrade your hardware or join the FPU "
                        "emulation project\n");
                panic("no FPU");
        }
index 7eb9792009f8994d4bddd0566b6da18649318cb1..958f1adb9d0c421eeec89d1cdbdf62361a866326 100644 (file)
 #include <linux/timex.h>
 #include <linux/profile.h>
 
+
+unsigned long (*mach_random_get_entropy)(void);
+
+
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "xtime_update()" routine every clocktick
index afb95d5fb26b3b29b172d730d8b5bacc4c3c664a..982c3fe73c4a45b45eeeff08e8d8446a47151c16 100644 (file)
 #include <linux/adb.h>
 #include <linux/cuda.h>
 
-#define BOOTINFO_COMPAT_1_0
 #include <asm/setup.h>
 #include <asm/bootinfo.h>
+#include <asm/bootinfo-mac.h>
+#include <asm/byteorder.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -107,45 +108,46 @@ static void __init mac_sched_init(irq_handler_t vector)
 int __init mac_parse_bootinfo(const struct bi_record *record)
 {
        int unknown = 0;
-       const u_long *data = record->data;
+       const void *data = record->data;
 
-       switch (record->tag) {
+       switch (be16_to_cpu(record->tag)) {
        case BI_MAC_MODEL:
-               mac_bi_data.id = *data;
+               mac_bi_data.id = be32_to_cpup(data);
                break;
        case BI_MAC_VADDR:
-               mac_bi_data.videoaddr = *data;
+               mac_bi_data.videoaddr = be32_to_cpup(data);
                break;
        case BI_MAC_VDEPTH:
-               mac_bi_data.videodepth = *data;
+               mac_bi_data.videodepth = be32_to_cpup(data);
                break;
        case BI_MAC_VROW:
-               mac_bi_data.videorow = *data;
+               mac_bi_data.videorow = be32_to_cpup(data);
                break;
        case BI_MAC_VDIM:
-               mac_bi_data.dimensions = *data;
+               mac_bi_data.dimensions = be32_to_cpup(data);
                break;
        case BI_MAC_VLOGICAL:
-               mac_bi_data.videological = VIDEOMEMBASE + (*data & ~VIDEOMEMMASK);
-               mac_orig_videoaddr = *data;
+               mac_orig_videoaddr = be32_to_cpup(data);
+               mac_bi_data.videological =
+                       VIDEOMEMBASE + (mac_orig_videoaddr & ~VIDEOMEMMASK);
                break;
        case BI_MAC_SCCBASE:
-               mac_bi_data.sccbase = *data;
+               mac_bi_data.sccbase = be32_to_cpup(data);
                break;
        case BI_MAC_BTIME:
-               mac_bi_data.boottime = *data;
+               mac_bi_data.boottime = be32_to_cpup(data);
                break;
        case BI_MAC_GMTBIAS:
-               mac_bi_data.gmtbias = *data;
+               mac_bi_data.gmtbias = be32_to_cpup(data);
                break;
        case BI_MAC_MEMSIZE:
-               mac_bi_data.memsize = *data;
+               mac_bi_data.memsize = be32_to_cpup(data);
                break;
        case BI_MAC_CPUID:
-               mac_bi_data.cpuid = *data;
+               mac_bi_data.cpuid = be32_to_cpup(data);
                break;
        case BI_MAC_ROMBASE:
-               mac_bi_data.rombase = *data;
+               mac_bi_data.rombase = be32_to_cpup(data);
                break;
        default:
                unknown = 1;
index 7d8d46127ad9fc91717dcb660ac9647d0b9708e4..4d2adfb32a2ab4f61951357114a8d053bf74de82 100644 (file)
 #include <linux/init.h>
 #include <linux/interrupt.h>
 
-#include <asm/bootinfo.h>
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_iop.h>
 
 /*#define DEBUG_IOP*/
 
-/* Set to non-zero if the IOPs are present. Set by iop_init() */
+/* Non-zero if the IOPs are present */
 
-int iop_scc_present,iop_ism_present;
+int iop_scc_present, iop_ism_present;
 
 /* structure for tracking channel listeners */
 
index 5e085554ac7f2bb9f0c3a964a30f001049804f8a..707b61aea2030c8f7de9058a2546a8eb85ce1639 100644 (file)
@@ -25,8 +25,6 @@
 #include <asm/mac_via.h>
 #include <asm/mac_oss.h>
 
-#define BOOTINFO_COMPAT_1_0
-#include <asm/bootinfo.h>
 #include <asm/machdep.h>
 
 /* Offset between Unix time (1970-based) and Mac time (1904-based) */
index 6c4c882c126e826e2d1b114f39acaf3e8b9ddc15..54037125ebf8c0e05c82cb937cb2560a7575244d 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 
-#include <asm/bootinfo.h>
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_via.h>
index 6f026fc302fab3ca70f6e05386a732ac52e1d985..835fa04511c85ad0d6e71ba8ee1f3a2dc26fcc1b 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/irq.h>
 
 #include <asm/traps.h>
-#include <asm/bootinfo.h>
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_psc.h>
@@ -54,7 +53,7 @@ static void psc_debug_dump(void)
  * expanded to cover what I think are the other 7 channels.
  */
 
-static void psc_dma_die_die_die(void)
+static __init void psc_dma_die_die_die(void)
 {
        int i;
 
index 5d1458bb871b8bd5e55eb25c5501067adef4810b..e198dec868e472e802768c5a9459e498e7623b00 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/module.h>
 #include <linux/irq.h>
 
-#include <asm/bootinfo.h>
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_via.h>
index 6b4baa6e4d31d8f24e09950d581f6ae9ab1cc6dd..acaff6a49e357e89154651f6ec57db9ab53f0459 100644 (file)
@@ -59,7 +59,7 @@ EXPORT_SYMBOL(pg_data_table);
 void __init m68k_setup_node(int node)
 {
 #ifndef CONFIG_SINGLE_MEMORY_CHUNK
-       struct mem_info *info = m68k_memory + node;
+       struct m68k_mem_info *info = m68k_memory + node;
        int i, end;
 
        i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift();
index 251c5437787be6054086b4d5586adfc0887e0472..7d4024432163ffa534665582fcf522ed4e9ea51f 100644 (file)
@@ -233,7 +233,7 @@ void __init paging_init(void)
                        printk("Fix your bootloader or use a memfile to make use of this area!\n");
                        m68k_num_memory--;
                        memmove(m68k_memory + i, m68k_memory + i + 1,
-                               (m68k_num_memory - i) * sizeof(struct mem_info));
+                               (m68k_num_memory - i) * sizeof(struct m68k_mem_info));
                        continue;
                }
                addr = m68k_memory[i].addr + m68k_memory[i].size;
index 1c6262803b9455d46fbde9b05587fc910b1687f5..1bb3ce6634d36630d4ad82e34e91cc45de83da97 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/interrupt.h>
 
 #include <asm/bootinfo.h>
+#include <asm/bootinfo-vme.h>
+#include <asm/byteorder.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -51,9 +53,10 @@ static int bcd2int (unsigned char b);
 irq_handler_t tick_handler;
 
 
-int mvme147_parse_bootinfo(const struct bi_record *bi)
+int __init mvme147_parse_bootinfo(const struct bi_record *bi)
 {
-       if (bi->tag == BI_VME_TYPE || bi->tag == BI_VME_BRDINFO)
+       uint16_t tag = be16_to_cpu(bi->tag);
+       if (tag == BI_VME_TYPE || tag == BI_VME_BRDINFO)
                return 0;
        else
                return 1;
index 080a342458a1934162aa61f44d72d59dfc1afbd9..eab7d342757ef6abdf01e13ff1a199209381c81d 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/module.h>
 
 #include <asm/bootinfo.h>
+#include <asm/bootinfo-vme.h>
+#include <asm/byteorder.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -60,9 +62,10 @@ unsigned short mvme16x_config;
 EXPORT_SYMBOL(mvme16x_config);
 
 
-int mvme16x_parse_bootinfo(const struct bi_record *bi)
+int __init mvme16x_parse_bootinfo(const struct bi_record *bi)
 {
-       if (bi->tag == BI_VME_TYPE || bi->tag == BI_VME_BRDINFO)
+       uint16_t tag = be16_to_cpu(bi->tag);
+       if (tag == BI_VME_TYPE || tag == BI_VME_BRDINFO)
                return 0;
        else
                return 1;
@@ -87,15 +90,15 @@ static void mvme16x_get_model(char *model)
     suf[3] = '\0';
     suf[0] = suf[1] ? '-' : '\0';
 
-    sprintf(model, "Motorola MVME%x%s", p->brdno, suf);
+    sprintf(model, "Motorola MVME%x%s", be16_to_cpu(p->brdno), suf);
 }
 
 
 static void mvme16x_get_hardware_list(struct seq_file *m)
 {
-    p_bdid p = &mvme_bdid;
+    uint16_t brdno = be16_to_cpu(mvme_bdid.brdno);
 
-    if (p->brdno == 0x0162 || p->brdno == 0x0172)
+    if (brdno == 0x0162 || brdno == 0x0172)
     {
        unsigned char rev = *(unsigned char *)MVME162_VERSION_REG;
 
@@ -285,6 +288,7 @@ void __init config_mvme16x(void)
 {
     p_bdid p = &mvme_bdid;
     char id[40];
+    uint16_t brdno = be16_to_cpu(p->brdno);
 
     mach_max_dma_address = 0xffffffff;
     mach_sched_init      = mvme16x_sched_init;
@@ -306,18 +310,18 @@ void __init config_mvme16x(void)
     }
     /* Board type is only set by newer versions of vmelilo/tftplilo */
     if (vme_brdtype == 0)
-       vme_brdtype = p->brdno;
+       vme_brdtype = brdno;
 
     mvme16x_get_model(id);
     printk ("\nBRD_ID: %s   BUG %x.%x %02x/%02x/%02x\n", id, p->rev>>4,
                                        p->rev&0xf, p->yr, p->mth, p->day);
-    if (p->brdno == 0x0162 || p->brdno == 0x172)
+    if (brdno == 0x0162 || brdno == 0x172)
     {
        unsigned char rev = *(unsigned char *)MVME162_VERSION_REG;
 
        mvme16x_config = rev | MVME16x_CONFIG_GOT_SCCA;
 
-       printk ("MVME%x Hardware status:\n", p->brdno);
+       printk ("MVME%x Hardware status:\n", brdno);
        printk ("    CPU Type           68%s040\n",
                        rev & MVME16x_CONFIG_GOT_FPU ? "" : "LC");
        printk ("    CPU clock          %dMHz\n",
@@ -347,12 +351,12 @@ void __init config_mvme16x(void)
 
 static irqreturn_t mvme16x_abort_int (int irq, void *dev_id)
 {
-       p_bdid p = &mvme_bdid;
        unsigned long *new = (unsigned long *)vectors;
        unsigned long *old = (unsigned long *)0xffe00000;
        volatile unsigned char uc, *ucp;
+       uint16_t brdno = be16_to_cpu(mvme_bdid.brdno);
 
-       if (p->brdno == 0x0162 || p->brdno == 0x172)
+       if (brdno == 0x0162 || brdno == 0x172)
        {
                ucp = (volatile unsigned char *)0xfff42043;
                uc = *ucp | 8;
@@ -366,7 +370,7 @@ static irqreturn_t mvme16x_abort_int (int irq, void *dev_id)
        *(new+9) = *(old+9);            /* Trace */
        *(new+47) = *(old+47);          /* Trap #15 */
 
-       if (p->brdno == 0x0162 || p->brdno == 0x172)
+       if (brdno == 0x0162 || brdno == 0x172)
                *(new+0x5e) = *(old+0x5e);      /* ABORT switch */
        else
                *(new+0x6e) = *(old+0x6e);      /* ABORT switch */
@@ -381,7 +385,7 @@ static irqreturn_t mvme16x_timer_int (int irq, void *dev_id)
 
 void mvme16x_sched_init (irq_handler_t timer_routine)
 {
-    p_bdid p = &mvme_bdid;
+    uint16_t brdno = be16_to_cpu(mvme_bdid.brdno);
     int irq;
 
     tick_handler = timer_routine;
@@ -394,7 +398,7 @@ void mvme16x_sched_init (irq_handler_t timer_routine)
                                "timer", mvme16x_timer_int))
        panic ("Couldn't register timer int");
 
-    if (p->brdno == 0x0162 || p->brdno == 0x172)
+    if (brdno == 0x0162 || brdno == 0x172)
        irq = MVME162_IRQ_ABORT;
     else
         irq = MVME167_IRQ_ABORT;
index 078bb744b5fe1193232a96999eb85c92b798c04a..e90fe903613ead8ad480797d138f7d566f738f48 100644 (file)
@@ -154,7 +154,7 @@ static unsigned int serports[] =
        0x3f8,0x2f8,0x3e8,0x2e8,0
 };
 
-static void q40_disable_irqs(void)
+static void __init q40_disable_irqs(void)
 {
        unsigned i, j;
 
@@ -198,7 +198,7 @@ void __init config_q40(void)
 }
 
 
-int q40_parse_bootinfo(const struct bi_record *rec)
+int __init q40_parse_bootinfo(const struct bi_record *rec)
 {
        return 1;
 }
index d522eaab45510aacd13b7cdf6e11ff14f88659a0..d95506e06c2ac42b67f9ce634413da8efc50082f 100644 (file)
@@ -7,6 +7,7 @@
  *
  */
 
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
@@ -62,10 +63,7 @@ int dvma_map_iommu(unsigned long kaddr, unsigned long baddr,
 
 }
 
-void sun3_dvma_init(void)
+void __init sun3_dvma_init(void)
 {
-
        memset(ptelist, 0, sizeof(ptelist));
-
-
 }
index 8edc510a21be663122fc285df8f624cf818d6b7b..3f258e230ba5d0c95806848ef96c64ce1160d479 100644 (file)
@@ -6,6 +6,7 @@
 ** Started 1/16/98 @ 2:22 am
 */
 
+#include <linux/init.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/kernel.h>
@@ -122,7 +123,7 @@ void print_pte_vaddr (unsigned long vaddr)
 /*
  * Initialise the MMU emulator.
  */
-void mmu_emu_init(unsigned long bootmem_end)
+void __init mmu_emu_init(unsigned long bootmem_end)
 {
        unsigned long seg, num;
        int i,j;
index cab54482ca34b97fa4412eaaaa4a0ee31d173833..b37521a5259ddb7a040d6606fdd24f324f657e8f 100644 (file)
@@ -6,6 +6,8 @@
  * Contains common routines for sun3/sun3x DVMA management.
  */
 
+#include <linux/bootmem.h>
+#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/gfp.h>
@@ -30,7 +32,7 @@ static inline void dvma_unmap_iommu(unsigned long a, int b)
 extern void sun3_dvma_init(void);
 #endif
 
-static unsigned long iommu_use[IOMMU_TOTAL_ENTRIES];
+static unsigned long *iommu_use;
 
 #define dvma_index(baddr) ((baddr - DVMA_START) >> DVMA_PAGE_SHIFT)
 
@@ -245,7 +247,7 @@ static inline int free_baddr(unsigned long baddr)
 
 }
 
-void dvma_init(void)
+void __init dvma_init(void)
 {
 
        struct hole *hole;
@@ -265,7 +267,7 @@ void dvma_init(void)
 
        list_add(&(hole->list), &hole_list);
 
-       memset(iommu_use, 0, sizeof(iommu_use));
+       iommu_use = alloc_bootmem(IOMMU_TOTAL_ENTRIES * sizeof(unsigned long));
 
        dvma_unmap_iommu(DVMA_START, DVMA_SIZE);
 
index a7b7e818d6279450119f4a8da5e76cf1c6746466..0898c3f8150851a34e8c4f54fe8c3d7760497cd4 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/bootinfo.h>
 #include <asm/setup.h>
 #include <asm/traps.h>
 #include <asm/sun3xprom.h>
index db589ad5dbc41e5bb1cb0bc52dfc4faefc9c1820..c700d625067a96cb725064e0c19ceadad078cd6a 100644 (file)
@@ -399,11 +399,6 @@ static int __init dma_alloc_init(void)
                pgd = pgd_offset(&init_mm, CONSISTENT_START);
                pud = pud_alloc(&init_mm, pgd, CONSISTENT_START);
                pmd = pmd_alloc(&init_mm, pud, CONSISTENT_START);
-               if (!pmd) {
-                       pr_err("%s: no pmd tables\n", __func__);
-                       ret = -ENOMEM;
-                       break;
-               }
                WARN_ON(!pmd_none(*pmd));
 
                pte = pte_alloc_kernel(pmd, CONSISTENT_START);
index 7c01131429817ab58ce63490cc97e5dba4f4b4c9..177ffb408c5a0d075b2c46a6a9b32e60a83d6013 100644 (file)
@@ -517,11 +517,10 @@ static DEFINE_SPINLOCK(stop_lock);
  *
  *  Bit 0 - Inter-processor function call
  */
-static int do_IPI(struct pt_regs *regs)
+static int do_IPI(void)
 {
        unsigned int cpu = smp_processor_id();
        struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
-       struct pt_regs *old_regs = set_irq_regs(regs);
        unsigned long msgs, nextmsg;
        int handled = 0;
 
@@ -557,8 +556,6 @@ static int do_IPI(struct pt_regs *regs)
                }
        }
 
-       set_irq_regs(old_regs);
-
        return handled;
 }
 
@@ -624,7 +621,7 @@ static void kick_raise_softirq(cpumask_t callmap, unsigned int irq)
 static TBIRES ipi_handler(TBIRES State, int SigNum, int Triggers,
                   int Inst, PTBI pTBI, int *handled)
 {
-       *handled = do_IPI((struct pt_regs *)State.Sig.pCtx);
+       *handled = do_IPI();
 
        return State;
 }
index 40350a3c24e907f01f3c193018abb6a34ee35541..a69eaf2ab1301466c662e27f37837c86d8193d61 100644 (file)
@@ -1,3 +1,5 @@
+KBUILD_DEFCONFIG := mmu_defconfig
+
 ifeq ($(CONFIG_MMU),y)
 UTS_SYSNAME = -DUTS_SYSNAME=\"Linux\"
 else
index c07ed5d2a82034f11cbadc6e836d4e31761d380f..1b281d3ea734418a0f39d12625e8ac1a749a6b1c 100644 (file)
@@ -16,7 +16,6 @@
 # ifndef __ASSEMBLY__
 extern char _ssbss[], _esbss[];
 extern unsigned long __ivt_start[], __ivt_end[];
-extern char _etext[], _stext[];
 
 extern u32 _fdt_start[], _fdt_end[];
 
index 8de8ebc309f15b0ca080cdf6f7c93e54fd168d74..603e22fec6d5b888d3f164cd08afa0d17ed3b037 100644 (file)
@@ -136,7 +136,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
        lockdep_init();
 
 /* initialize device tree for usage in early_printk */
-       early_init_devtree((void *)_fdt_start);
+       early_init_devtree(_fdt_start);
 
 #ifdef CONFIG_EARLY_PRINTK
        setup_early_printk(NULL);
@@ -152,8 +152,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
        if (fdt)
                pr_info("FDT at 0x%08x\n", fdt);
        else
-               pr_info("Compiled-in FDT at 0x%08x\n",
-                                       (unsigned int)_fdt_start);
+               pr_info("Compiled-in FDT at %p\n", _fdt_start);
 
 #ifdef CONFIG_MTD_UCLINUX
        pr_info("Found romfs @ 0x%08x (0x%08x)\n",
index 9a357fffcfbe0a0c6767e5b12d70d22f23e5b1b7..820b7a313d9bfd593cdaa63e6374f0cf4bd15d6a 100644 (file)
@@ -92,7 +92,6 @@ void __init plat_mem_setup(void)
        _machine_restart = ar7_machine_restart;
        _machine_halt = ar7_machine_halt;
        pm_power_off = ar7_machine_power_off;
-       panic_timeout = 3;
 
        io_base = (unsigned long)ioremap(AR7_REGS_BASE, 0x10000);
        if (!io_base)
index d71005835c007aeb8df0f8b288fbfb1f3045457d..9100122e5cef891c18767fee89c98858df661f11 100644 (file)
@@ -111,9 +111,6 @@ void __init plat_mem_setup(void)
        iomem_resource.start = EMMA2RH_IO_BASE;
        iomem_resource.end = EMMA2RH_ROM_BASE - 1;
 
-       /* Reboot on panic */
-       panic_timeout = 180;
-
        markeins_sio_setup();
 }
 
index 638c5db122c924dca997725d58ee0fd34b36fe1b..8c55de42693d2bcd73420654f45bb050c3e2c696 100644 (file)
@@ -44,7 +44,7 @@ static int pvc_line_proc_show(struct seq_file *m, void *v)
 {
        int lineno = *(int *)m->private;
 
-       if (lineno < 0 || lineno > PVC_NLINES) {
+       if (lineno < 0 || lineno >= PVC_NLINES) {
                printk(KERN_WARNING "proc_read_line: invalid lineno %d\n", lineno);
                return 0;
        }
@@ -68,7 +68,7 @@ static ssize_t pvc_line_proc_write(struct file *file, const char __user *buf,
        char kbuf[PVC_LINELEN];
        size_t len;
 
-       BUG_ON(lineno < 0 || lineno > PVC_NLINES);
+       BUG_ON(lineno < 0 || lineno >= PVC_NLINES);
 
        len = min(count, sizeof(kbuf) - 1);
        if (copy_from_user(kbuf, buf, len))
index 6d981bb337ecd8abf96324d1e0f2a006caa942de..54e75c77184b883fdbec601e1b2e97e49b1aa8c9 100644 (file)
@@ -92,7 +92,6 @@ static void __init xlp_init_mem_from_bars(void)
 
 void __init plat_mem_setup(void)
 {
-       panic_timeout   = 5;
        _machine_restart = (void (*)(char *))nlm_linux_exit;
        _machine_halt   = nlm_linux_exit;
        pm_power_off    = nlm_linux_exit;
index 214d123b79faf7f6659ae4127ffe938257fb26ae..921be5f77797706279d61c1c79f897a206546d07 100644 (file)
@@ -92,7 +92,6 @@ static void nlm_linux_exit(void)
 
 void __init plat_mem_setup(void)
 {
-       panic_timeout   = 5;
        _machine_restart = (void (*)(char *))nlm_linux_exit;
        _machine_halt   = nlm_linux_exit;
        pm_power_off    = nlm_linux_exit;
index 41707a245dea61c1cabd467f2bc3d2ec2ca28cd8..3462c831d0ea5f1b307fcd002645d7b328bc816f 100644 (file)
@@ -134,8 +134,6 @@ void __init plat_mem_setup(void)
 #error invalid SiByte board configuration
 #endif
 
-       panic_timeout = 5;  /* For debug.  */
-
        board_be_handler = swarm_be_handler;
 
        if (xicor_probe())
index d8a455ede5a751c8dc31604526e425fb50167ee0..fec8bf97d806422ce76a578c83576733633a9bf6 100644 (file)
@@ -853,37 +853,44 @@ UNHANDLED_EXCEPTION(_vector_0x1f00,0x1f00)
 
 /* ========================================================[ return ] === */
 
+_resume_userspace:
+       DISABLE_INTERRUPTS(r3,r4)
+       l.lwz   r4,TI_FLAGS(r10)
+       l.andi  r13,r4,_TIF_WORK_MASK
+       l.sfeqi r13,0
+       l.bf    _restore_all
+        l.nop
+
 _work_pending:
-       /*
-        * if (current_thread_info->flags & _TIF_NEED_RESCHED)
-        *     schedule();
-        */
-       l.lwz   r5,TI_FLAGS(r10)
-       l.andi  r3,r5,_TIF_NEED_RESCHED
-       l.sfnei r3,0
-       l.bnf   _work_notifysig
+       l.lwz   r5,PT_ORIG_GPR11(r1)
+       l.sfltsi r5,0
+       l.bnf   1f
         l.nop
-       l.jal   schedule
+       l.andi  r5,r5,0
+1:
+       l.jal   do_work_pending
+        l.ori  r3,r1,0                 /* pt_regs */
+
+       l.sfeqi r11,0
+       l.bf    _restore_all
         l.nop
-       l.j     _resume_userspace
+       l.sfltsi r11,0
+       l.bnf   1f
         l.nop
-
-/* Handle pending signals and notify-resume requests.
- * do_notify_resume must be passed the latest pushed pt_regs, not
- * necessarily the "userspace" ones.  Also, pt_regs->syscallno
- * must be set so that the syscall restart functionality works.
- */
-_work_notifysig:
-       l.jal   do_notify_resume
-        l.ori  r3,r1,0           /* pt_regs */
-
-_resume_userspace:
-       DISABLE_INTERRUPTS(r3,r4)
-       l.lwz   r3,TI_FLAGS(r10)
-       l.andi  r3,r3,_TIF_WORK_MASK
-       l.sfnei r3,0
-       l.bf    _work_pending
+       l.and   r11,r11,r0
+       l.ori   r11,r11,__NR_restart_syscall
+       l.j     _syscall_check_trace_enter
         l.nop
+1:
+       l.lwz   r11,PT_ORIG_GPR11(r1)
+       /* Restore arg registers */
+       l.lwz   r3,PT_GPR3(r1)
+       l.lwz   r4,PT_GPR4(r1)
+       l.lwz   r5,PT_GPR5(r1)
+       l.lwz   r6,PT_GPR6(r1)
+       l.lwz   r7,PT_GPR7(r1)
+       l.j     _syscall_check_trace_enter
+        l.lwz  r8,PT_GPR8(r1)
 
 _restore_all:
        RESTORE_ALL
index ae167f7e081aa0368cb571093df8f16a9dcf71d9..66775bc07a8eeb780e65a290247b3156f0a44ccd 100644 (file)
 #include <linux/tracehook.h>
 
 #include <asm/processor.h>
+#include <asm/syscall.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 
 #define DEBUG_SIG 0
 
 struct rt_sigframe {
-       struct siginfo *pinfo;
-       void *puc;
        struct siginfo info;
        struct ucontext uc;
        unsigned char retcode[16];      /* trampoline code */
 };
 
-static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+static int restore_sigcontext(struct pt_regs *regs,
+                             struct sigcontext __user *sc)
 {
-       unsigned int err = 0;
+       int err = 0;
 
-       /* Alwys make any pending restarted system call return -EINTR */
+       /* Always make any pending restarted system calls return -EINTR */
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
        /*
@@ -53,25 +53,21 @@ static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
         * (sc is already checked for VERIFY_READ since the sigframe was
         *  checked in sys_sigreturn previously)
         */
-       if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long)))
-               goto badframe;
-       if (__copy_from_user(&regs->pc, &sc->regs.pc, sizeof(unsigned long)))
-               goto badframe;
-       if (__copy_from_user(&regs->sr, &sc->regs.sr, sizeof(unsigned long)))
-               goto badframe;
+       err |= __copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long));
+       err |= __copy_from_user(&regs->pc, &sc->regs.pc, sizeof(unsigned long));
+       err |= __copy_from_user(&regs->sr, &sc->regs.sr, sizeof(unsigned long));
 
        /* make sure the SM-bit is cleared so user-mode cannot fool us */
        regs->sr &= ~SPR_SR_SM;
 
+       regs->orig_gpr11 = -1;  /* Avoid syscall restart checks */
+
        /* TODO: the other ports use regs->orig_XX to disable syscall checks
         * after this completes, but we don't use that mechanism. maybe we can
         * use it now ?
         */
 
        return err;
-
-badframe:
-       return 1;
 }
 
 asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
@@ -111,21 +107,18 @@ badframe:
  * Set up a signal frame.
  */
 
-static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
-                           unsigned long mask)
+static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 {
        int err = 0;
 
        /* copy the regs */
-
+       /* There should be no need to save callee-saved registers here...
+        * ...but we save them anyway.  Revisit this
+        */
        err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long));
        err |= __copy_to_user(&sc->regs.pc, &regs->pc, sizeof(unsigned long));
        err |= __copy_to_user(&sc->regs.sr, &regs->sr, sizeof(unsigned long));
 
-       /* then some other stuff */
-
-       err |= __put_user(mask, &sc->oldmask);
-
        return err;
 }
 
@@ -173,55 +166,53 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
  * trampoline which performs the syscall sigreturn, or a provided
  * user-mode trampoline.
  */
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                         sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe *frame;
        unsigned long return_ip;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
-       err |= __put_user(&frame->info, &frame->pinfo);
-       err |= __put_user(&frame->uc, &frame->puc);
+       /* Create siginfo.  */
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               err |= copy_siginfo_to_user(&frame->info, info);
-       if (err)
-               goto give_sigsegv;
-
-       /* Clear all the bits of the ucontext we don't use.  */
-       err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
+       /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
        err |= __put_user(NULL, &frame->uc.uc_link);
        err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
-       err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
+       err |= setup_sigcontext(regs, &frame->uc.uc_mcontext);
 
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* trampoline - the desired return ip is the retcode itself */
        return_ip = (unsigned long)&frame->retcode;
-       /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
-       err |= __put_user(0xa960, (short *)(frame->retcode + 0));
-       err |= __put_user(__NR_rt_sigreturn, (short *)(frame->retcode + 2));
+       /* This is:
+               l.ori r11,r0,__NR_sigreturn
+               l.sys 1
+        */
+       err |= __put_user(0xa960,             (short *)(frame->retcode + 0));
+       err |= __put_user(__NR_rt_sigreturn,  (short *)(frame->retcode + 2));
        err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
        err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* TODO what is the current->exec_domain stuff and invmap ? */
 
        /* Set up registers for signal handler */
-       regs->pc = (unsigned long)ka->sa.sa_handler; /* what we enter NOW */
+       regs->pc = (unsigned long)ksig->ka.sa.sa_handler; /* what we enter NOW */
        regs->gpr[9] = (unsigned long)return_ip;     /* what we enter LATER */
-       regs->gpr[3] = (unsigned long)sig;           /* arg 1: signo */
+       regs->gpr[3] = (unsigned long)ksig->sig;           /* arg 1: signo */
        regs->gpr[4] = (unsigned long)&frame->info;  /* arg 2: (siginfo_t*) */
        regs->gpr[5] = (unsigned long)&frame->uc;    /* arg 3: ucontext */
 
@@ -229,25 +220,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->sp = (unsigned long)frame;
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 static inline void
-handle_signal(unsigned long sig,
-             siginfo_t *info, struct k_sigaction *ka,
-             struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        int ret;
 
-       ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs);
-       if (ret)
-               return;
+       ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
 
-       signal_delivered(sig, info, ka, regs,
-                                test_thread_flag(TIF_SINGLESTEP));
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
@@ -262,82 +244,99 @@ handle_signal(unsigned long sig,
  * mode below.
  */
 
-void do_signal(struct pt_regs *regs)
+int do_signal(struct pt_regs *regs, int syscall)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
-
-       /*
-        * We want the common case to go fast, which
-        * is why we may in certain cases get here from
-        * kernel mode. Just return without doing anything
-        * if so.
-        */
-       if (!user_mode(regs))
-               return;
-
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
-       /* If we are coming out of a syscall then we need
-        * to check if the syscall was interrupted and wants to be
-        * restarted after handling the signal.  If so, the original
-        * syscall number is put back into r11 and the PC rewound to
-        * point at the l.sys instruction that resulted in the
-        * original syscall.  Syscall results other than the four
-        * below mean that the syscall executed to completion and no
-        * restart is necessary.
-        */
-       if (regs->orig_gpr11) {
-               int restart = 0;
-
-               switch (regs->gpr[11]) {
+       struct ksignal ksig;
+       unsigned long continue_addr = 0;
+       unsigned long restart_addr = 0;
+       unsigned long retval = 0;
+       int restart = 0;
+
+       if (syscall) {
+               continue_addr = regs->pc;
+               restart_addr = continue_addr - 4;
+               retval = regs->gpr[11];
+
+               /*
+                * Setup syscall restart here so that a debugger will
+                * see the already changed PC.
+                */
+               switch (retval) {
                case -ERESTART_RESTARTBLOCK:
+                       restart = -2;
+                       /* Fall through */
                case -ERESTARTNOHAND:
-                       /* Restart if there is no signal handler */
-                       restart = (signr <= 0);
-                       break;
                case -ERESTARTSYS:
-                       /* Restart if there no signal handler or
-                        * SA_RESTART flag is set */
-                       restart = (signr <= 0 || (ka.sa.sa_flags & SA_RESTART));
-                       break;
                case -ERESTARTNOINTR:
-                       /* Always restart */
-                       restart = 1;
+                       restart++;
+                       regs->gpr[11] = regs->orig_gpr11;
+                       regs->pc = restart_addr;
                        break;
                }
-
-               if (restart) {
-                       if (regs->gpr[11] == -ERESTART_RESTARTBLOCK)
-                               regs->gpr[11] = __NR_restart_syscall;
-                       else
-                               regs->gpr[11] = regs->orig_gpr11;
-                       regs->pc -= 4;
-               } else {
-                       regs->gpr[11] = -EINTR;
-               }
        }
 
-       if (signr <= 0) {
-               /* no signal to deliver so we just put the saved sigmask
-                * back */
+       /*
+        * Get the signal to deliver.  During the call to get_signal the
+        * debugger may change all our registers so we may need to revert
+        * the decision to restart the syscall; specifically, if the PC is
+        * changed, don't restart the syscall.
+        */
+       if (get_signal(&ksig)) {
+               if (unlikely(restart) && regs->pc == restart_addr) {
+                       if (retval == -ERESTARTNOHAND ||
+                           retval == -ERESTART_RESTARTBLOCK
+                           || (retval == -ERESTARTSYS
+                               && !(ksig.ka.sa.sa_flags & SA_RESTART))) {
+                               /* No automatic restart */
+                               regs->gpr[11] = -EINTR;
+                               regs->pc = continue_addr;
+                       }
+               }
+               handle_signal(&ksig, regs);
+       } else {
+               /* no handler */
                restore_saved_sigmask();
-       } else {                /* signr > 0 */
-               /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, &info, &ka, regs);
+               /*
+                * Restore pt_regs PC as syscall restart will be handled by
+                * kernel without return to userspace
+                */
+               if (unlikely(restart) && regs->pc == restart_addr) {
+                       regs->pc = continue_addr;
+                       return restart;
+               }
        }
 
-       return;
+       return 0;
 }
 
-asmlinkage void do_notify_resume(struct pt_regs *regs)
+asmlinkage int
+do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 {
-       if (current_thread_info()->flags & _TIF_SIGPENDING)
-               do_signal(regs);
-
-       if (current_thread_info()->flags & _TIF_NOTIFY_RESUME) {
-               clear_thread_flag(TIF_NOTIFY_RESUME);
-               tracehook_notify_resume(regs);
-       }
+       do {
+               if (likely(thread_flags & _TIF_NEED_RESCHED)) {
+                       schedule();
+               } else {
+                       if (unlikely(!user_mode(regs)))
+                               return 0;
+                       local_irq_enable();
+                       if (thread_flags & _TIF_SIGPENDING) {
+                               int restart = do_signal(regs, syscall);
+                               if (unlikely(restart)) {
+                                       /*
+                                        * Restart without handlers.
+                                        * Deal with it without leaving
+                                        * the kernel space.
+                                        */
+                                       return restart;
+                               }
+                               syscall = 0;
+                       } else {
+                               clear_thread_flag(TIF_NOTIFY_RESUME);
+                               tracehook_notify_resume(regs);
+                       }
+               }
+               local_irq_disable();
+               thread_flags = current_thread_info()->flags;
+       } while (thread_flags & _TIF_WORK_MASK);
+       return 0;
 }
index e1c8d2015c8938ac0a3440d38af427b4ac8eec7a..bb81d026b7b39f61eca2720c6dee4d9aff2488ca 100644 (file)
@@ -20,7 +20,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_BLK_DEV_INTEGRITY=y
 CONFIG_PA8X00=y
-CONFIG_MLONGCALLS=y
 CONFIG_64BIT=y
 CONFIG_SMP=y
 CONFIG_PREEMPT=y
index 5874cebee07701725f3ab9939acb6cd11f1e46f2..1413b8d7f5d3a37ec1ba96d99f2f72b6c3a16ac9 100644 (file)
@@ -24,7 +24,6 @@ CONFIG_MODVERSIONS=y
 CONFIG_BLK_DEV_INTEGRITY=y
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_PA8X00=y
-CONFIG_MLONGCALLS=y
 CONFIG_64BIT=y
 CONFIG_SMP=y
 # CONFIG_COMPACTION is not set
index d7e3cc60dbc3693a3b8ce475fbd128bb9563a284..77e9b67c87ee1ed382670ec604b067f5b3a99b25 100644 (file)
@@ -6,5 +6,3 @@
  * This is used for 16550-compatible UARTs
  */
 #define BASE_BAUD ( 1843200 / 16 )
-
-#define SERIAL_PORT_DFNS
index 06cb3992907e67e9847b84259e5a61f3e42c2b71..608716f8496bf8dfe0acc08a71a15807ce20c557 100644 (file)
@@ -36,6 +36,9 @@
  *     HP PARISC Hardware Database
  *     Access to this database is only possible during bootup
  *     so don't reference this table after starting the init process
+ *
+ *     NOTE: Product names which are listed here and ends with a '?'
+ *     are guessed. If you know the correct name, please let us know.
  */
  
 static struct hp_hardware hp_hardware_list[] = {
@@ -222,7 +225,7 @@ static struct hp_hardware hp_hardware_list[] = {
        {HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
        {HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
        {HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
-       {HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"},
+       {HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+ (rp5470)?"},
        {HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
        {HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
        {HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
@@ -276,9 +279,11 @@ static struct hp_hardware hp_hardware_list[] = {
        {HPHW_NPROC,0x888,0x4,0x91,"Storm Peak Fast DC-"},
        {HPHW_NPROC,0x889,0x4,0x91,"Storm Peak Fast"},
        {HPHW_NPROC,0x88A,0x4,0x91,"Crestone Peak Slow"},
+       {HPHW_NPROC,0x88B,0x4,0x91,"Crestone Peak Fast?"},
        {HPHW_NPROC,0x88C,0x4,0x91,"Orca Mako+"},
        {HPHW_NPROC,0x88D,0x4,0x91,"Rainier/Medel Mako+ Slow"},
        {HPHW_NPROC,0x88E,0x4,0x91,"Rainier/Medel Mako+ Fast"},
+       {HPHW_NPROC,0x892,0x4,0x91,"Mt. Hamilton Slow Mako+?"},
        {HPHW_NPROC,0x894,0x4,0x91,"Mt. Hamilton Fast Mako+"},
        {HPHW_NPROC,0x895,0x4,0x91,"Storm Peak Slow Mako+"},
        {HPHW_NPROC,0x896,0x4,0x91,"Storm Peak Fast Mako+"},
index d2d58258aea68084c4f09cc6012a741b838b22d5..d4dc588c0dc1f6963f99e6545de14031192d4543 100644 (file)
@@ -41,9 +41,7 @@ END(boot_args)
         .import fault_vector_11,code    /* IVA parisc 1.1 32 bit */
        .import $global$                /* forward declaration */
 #endif /*!CONFIG_64BIT*/
-       .export _stext,data             /* Kernel want it this way! */
-_stext:
-ENTRY(stext)
+ENTRY(parisc_kernel_start)
        .proc
        .callinfo
 
@@ -347,7 +345,7 @@ smp_slave_stext:
        .procend
 #endif /* CONFIG_SMP */
 
-ENDPROC(stext)
+ENDPROC(parisc_kernel_start)
 
 #ifndef CONFIG_64BIT
        .section .data..read_mostly
index 5dfd248e3f1a84fd6dbd961bf278002338cba4b0..0d3a9d4927b58009bfe0c4dc4114585409ddd2f5 100644 (file)
@@ -61,8 +61,15 @@ static int get_offset(struct address_space *mapping)
        return (unsigned long) mapping >> 8;
 }
 
-static unsigned long get_shared_area(struct address_space *mapping,
-               unsigned long addr, unsigned long len, unsigned long pgoff)
+static unsigned long shared_align_offset(struct file *filp, unsigned long pgoff)
+{
+       struct address_space *mapping = filp ? filp->f_mapping : NULL;
+
+       return (get_offset(mapping) + pgoff) << PAGE_SHIFT;
+}
+
+static unsigned long get_shared_area(struct file *filp, unsigned long addr,
+               unsigned long len, unsigned long pgoff)
 {
        struct vm_unmapped_area_info info;
 
@@ -71,7 +78,7 @@ static unsigned long get_shared_area(struct address_space *mapping,
        info.low_limit = PAGE_ALIGN(addr);
        info.high_limit = TASK_SIZE;
        info.align_mask = PAGE_MASK & (SHMLBA - 1);
-       info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT;
+       info.align_offset = shared_align_offset(filp, pgoff);
        return vm_unmapped_area(&info);
 }
 
@@ -82,20 +89,18 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
                return -ENOMEM;
        if (flags & MAP_FIXED) {
                if ((flags & MAP_SHARED) &&
-                   (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
+                   (addr - shared_align_offset(filp, pgoff)) & (SHMLBA - 1))
                        return -EINVAL;
                return addr;
        }
        if (!addr)
                addr = TASK_UNMAPPED_BASE;
 
-       if (filp) {
-               addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
-       } else if(flags & MAP_SHARED) {
-               addr = get_shared_area(NULL, addr, len, pgoff);
-       } else {
+       if (filp || (flags & MAP_SHARED))
+               addr = get_shared_area(filp, addr, len, pgoff);
+       else
                addr = get_unshared_area(addr, len);
-       }
+
        return addr;
 }
 
index 76ed62ed785b6f4be9c1a6e663101ff3daeb6aa7..ddd988b267a9ddde0e9d2433f87e036f41e9d2a1 100644 (file)
@@ -168,7 +168,7 @@ void unwind_table_remove(struct unwind_table *table)
 }
 
 /* Called from setup_arch to import the kernel unwind info */
-int unwind_init(void)
+int __init unwind_init(void)
 {
        long start, stop;
        register unsigned long gp __asm__ ("r27");
@@ -233,7 +233,6 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
        e = find_unwind_entry(info->ip);
        if (e == NULL) {
                unsigned long sp;
-               extern char _stext[], _etext[];
 
                dbg("Cannot find unwind entry for 0x%lx; forced unwinding\n", info->ip);
 
@@ -281,8 +280,7 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
                                break;
                        info->prev_ip = tmp;
                        sp = info->prev_sp;
-               } while (info->prev_ip < (unsigned long)_stext ||
-                        info->prev_ip > (unsigned long)_etext);
+               } while (!kernel_text_address(info->prev_ip));
 
                info->rp = 0;
 
@@ -435,9 +433,8 @@ unsigned long return_address(unsigned int level)
        do {
                if (unwind_once(&info) < 0 || info.ip == 0)
                        return 0;
-               if (!__kernel_text_address(info.ip)) {
+               if (!kernel_text_address(info.ip))
                        return 0;
-               }
        } while (info.ip && level--);
 
        return info.ip;
index 4bb095a2f6fc2266388723cbb2634518a9570e44..0dacc5ca555afe7643da970bf9f3ae75ebc88790 100644 (file)
@@ -6,24 +6,19 @@
  *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
  *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
  *    Copyright (C) 2003 James Bottomley <jejb with parisc-linux.org>
- *    Copyright (C) 2006 Helge Deller <deller@gmx.de>
- *
- *
- *    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
+ *    Copyright (C) 2006-2013 Helge Deller <deller@gmx.de>
+ */
+
+/*
+ * Put page table entries (swapper_pg_dir) as the first thing in .bss. This
+ * will ensure that it has .bss alignment (PAGE_SIZE).
  */
+#define BSS_FIRST_SECTIONS     *(.data..vm0.pmd) \
+                               *(.data..vm0.pgd) \
+                               *(.data..vm0.pte)
+
 #include <asm-generic/vmlinux.lds.h>
+
 /* needed for the processor specific cache alignment size */   
 #include <asm/cache.h>
 #include <asm/page.h>
@@ -39,7 +34,7 @@ OUTPUT_FORMAT("elf64-hppa-linux")
 OUTPUT_ARCH(hppa:hppa2.0w)
 #endif
 
-ENTRY(_stext)
+ENTRY(parisc_kernel_start)
 #ifndef CONFIG_64BIT
 jiffies = jiffies_64 + 4;
 #else
@@ -49,11 +44,29 @@ SECTIONS
 {
        . = KERNEL_BINARY_TEXT_START;
 
+       __init_begin = .;
+       HEAD_TEXT_SECTION
+       INIT_TEXT_SECTION(8)
+
+       . = ALIGN(PAGE_SIZE);
+       INIT_DATA_SECTION(PAGE_SIZE)
+       /* we have to discard exit text and such at runtime, not link time */
+       .exit.text :
+       {
+               EXIT_TEXT
+       }
+       .exit.data :
+       {
+               EXIT_DATA
+       }
+       PERCPU_SECTION(8)
+       . = ALIGN(PAGE_SIZE);
+       __init_end = .;
+       /* freed after init ends here */
+
        _text = .;              /* Text and read-only data */
-       .head ALIGN(16) : {
-               HEAD_TEXT
-       } = 0
-       .text ALIGN(16) : {
+       _stext = .;
+       .text ALIGN(PAGE_SIZE) : {
                TEXT_TEXT
                SCHED_TEXT
                LOCK_TEXT
@@ -68,21 +81,28 @@ SECTIONS
                *(.lock.text)           /* out-of-line lock text */
                *(.gnu.warning)
        }
-       /* End of text section */
+       . = ALIGN(PAGE_SIZE);
        _etext = .;
+       /* End of text section */
 
        /* Start of data section */
        _sdata = .;
 
-       RODATA
+       RO_DATA_SECTION(8)
 
-       /* writeable */
-       /* Make sure this is page aligned so
-        * that we can properly leave these
-        * as writable
-        */
-       . = ALIGN(PAGE_SIZE);
-       data_start = .;
+#ifdef CONFIG_64BIT
+       . = ALIGN(16);
+       /* Linkage tables */
+       .opd : {
+               *(.opd)
+       } PROVIDE (__gp = .);
+       .plt : {
+               *(.plt)
+       }
+       .dlt : {
+               *(.dlt)
+       }
+#endif
 
        /* unwind info */
        .PARISC.unwind : {
@@ -91,7 +111,15 @@ SECTIONS
                __stop___unwind = .;
        }
 
-       EXCEPTION_TABLE(16)
+       /* writeable */
+       /* Make sure this is page aligned so
+        * that we can properly leave these
+        * as writable
+        */
+       . = ALIGN(PAGE_SIZE);
+       data_start = .;
+
+       EXCEPTION_TABLE(8)
        NOTES
 
        /* Data */
@@ -107,54 +135,8 @@ SECTIONS
        _edata = .;
 
        /* BSS */
-       __bss_start = .;
-       /* page table entries need to be PAGE_SIZE aligned */
-       . = ALIGN(PAGE_SIZE);
-       .data..vmpages : {
-               *(.data..vm0.pmd)
-               *(.data..vm0.pgd)
-               *(.data..vm0.pte)
-       }
-       .bss : {
-               *(.bss)
-               *(COMMON)
-       }
-       __bss_stop = .;
-
-#ifdef CONFIG_64BIT
-       . = ALIGN(16);
-       /* Linkage tables */
-       .opd : {
-               *(.opd)
-       } PROVIDE (__gp = .); 
-       .plt : {
-               *(.plt)
-       } 
-       .dlt : {
-               *(.dlt)
-       }
-#endif
+       BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 8)
 
-       /* reserve space for interrupt stack by aligning __init* to 16k */
-       . = ALIGN(16384);
-       __init_begin = .;
-       INIT_TEXT_SECTION(16384)
-       . = ALIGN(PAGE_SIZE);
-       INIT_DATA_SECTION(16)
-       /* we have to discard exit text and such at runtime, not link time */
-       .exit.text :
-       {
-               EXIT_TEXT
-       }
-       .exit.data :
-       {
-               EXIT_DATA
-       }
-
-       PERCPU_SECTION(L1_CACHE_BYTES)
-       . = ALIGN(PAGE_SIZE);
-       __init_end = .;
-       /* freed after init ends here */
        _end = . ;
 
        STABS_DEBUG
index b0f96c0e6316f15531afb2a5a2a0e4684d1892a8..96f8168cf4ec1d9d50aad70ae17f54110a2c1527 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/sections.h>
 
 extern int  data_start;
+extern void parisc_kernel_start(void); /* Kernel entry point in head.S */
 
 #if PT_NLEVELS == 3
 /* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout
@@ -324,8 +325,9 @@ static void __init setup_bootmem(void)
        reserve_bootmem_node(NODE_DATA(0), 0UL,
                        (unsigned long)(PAGE0->mem_free +
                                PDC_CONSOLE_IO_IODC_SIZE), BOOTMEM_DEFAULT);
-       reserve_bootmem_node(NODE_DATA(0), __pa((unsigned long)_text),
-                       (unsigned long)(_end - _text), BOOTMEM_DEFAULT);
+       reserve_bootmem_node(NODE_DATA(0), __pa(KERNEL_BINARY_TEXT_START),
+                       (unsigned long)(_end - KERNEL_BINARY_TEXT_START),
+                       BOOTMEM_DEFAULT);
        reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT),
                        ((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT),
                        BOOTMEM_DEFAULT);
@@ -378,6 +380,17 @@ static void __init setup_bootmem(void)
        request_resource(&sysram_resources[0], &pdcdata_resource);
 }
 
+static int __init parisc_text_address(unsigned long vaddr)
+{
+       static unsigned long head_ptr __initdata;
+
+       if (!head_ptr)
+               head_ptr = PAGE_MASK & (unsigned long)
+                       dereference_function_descriptor(&parisc_kernel_start);
+
+       return core_kernel_text(vaddr) || vaddr == head_ptr;
+}
+
 static void __init map_pages(unsigned long start_vaddr,
                             unsigned long start_paddr, unsigned long size,
                             pgprot_t pgprot, int force)
@@ -466,7 +479,7 @@ static void __init map_pages(unsigned long start_vaddr,
                                 */
                                if (force)
                                        pte =  __mk_pte(address, pgprot);
-                               else if (core_kernel_text(vaddr) &&
+                               else if (parisc_text_address(vaddr) &&
                                         address != fv_addr)
                                        pte = __mk_pte(address, PAGE_KERNEL_EXEC);
                                else
index b44b52c0a8f07d2854d5a21ca6fb2ecf409409c1..b2be8e8cb5c71471864e9fafebf6a475cab67bec 100644 (file)
@@ -147,6 +147,10 @@ config EARLY_PRINTK
        bool
        default y
 
+config PANIC_TIMEOUT
+       int
+       default 180
+
 config COMPAT
        bool
        default y if PPC64
index 8a2463670a5b8107243f313c7e272339570ce301..0f4344e6fbca99f621daf6776811d1538e1e69af 100644 (file)
@@ -75,8 +75,10 @@ LDEMULATION  := lppc
 GNUTARGET      := powerpcle
 MULTIPLEWORD   := -mno-multiple
 else
+ifeq ($(call cc-option-yn,-mbig-endian),y)
 override CC    += -mbig-endian
 override AS    += -mbig-endian
+endif
 override LD    += -EB
 LDEMULATION    := ppc
 GNUTARGET      := powerpc
@@ -128,7 +130,12 @@ CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5)
 CFLAGS-$(CONFIG_POWER6_CPU) += $(call cc-option,-mcpu=power6)
 CFLAGS-$(CONFIG_POWER7_CPU) += $(call cc-option,-mcpu=power7)
 
+# Altivec option not allowed with e500mc64 in GCC.
+ifeq ($(CONFIG_ALTIVEC),y)
+E5500_CPU := -mcpu=powerpc64
+else
 E5500_CPU := $(call cc-option,-mcpu=e500mc64,-mcpu=powerpc64)
+endif
 CFLAGS-$(CONFIG_E5500_CPU) += $(E5500_CPU)
 CFLAGS-$(CONFIG_E6500_CPU) += $(call cc-option,-mcpu=e6500,$(E5500_CPU))
 
index cc00f4ddd9a7c1e1d5d3d8b2f869050b85204fa6..c409cbafb12678b0782edce46af71f5040f933f5 100644 (file)
                tlu@2f000 {
                        compatible = "fsl,mpc8572-tlu", "fsl_tlu";
                        reg = <0x2f000 0x1000>;
-                       interupts = <61 2 >;
+                       interrupts = <61 2>;
                        interrupt-parent = <&mpic>;
                };
 
                tlu@15000 {
                        compatible = "fsl,mpc8572-tlu", "fsl_tlu";
                        reg = <0x15000 0x1000>;
-                       interupts = <75 2>;
+                       interrupts = <75 2>;
                        interrupt-parent = <&mpic>;
                };
        };
index 53c1c6a9752f953a543b3d44ac134f0dfe321cc2..04cb410da48b78337b04fcfdc6b8940471917bda 100644 (file)
                tlu@2f000 {
                        compatible = "fsl,mpc8572-tlu", "fsl_tlu";
                        reg = <0x2f000 0x1000>;
-                       interupts = <61 2 >;
+                       interrupts = <61 2>;
                        interrupt-parent = <&mpic>;
                };
 
                tlu@15000 {
                        compatible = "fsl,mpc8572-tlu", "fsl_tlu";
                        reg = <0x15000 0x1000>;
-                       interupts = <75 2>;
+                       interrupts = <75 2>;
                        interrupt-parent = <&mpic>;
                };
        };
index 2152259831509ea89b1e64e2676c6e580de59c0f..73f8620f1ce7eeb714d6691b01d588a0c935f055 100644 (file)
                tlu@2f000 {
                        compatible = "fsl,mpc8572-tlu", "fsl_tlu";
                        reg = <0x2f000 0x1000>;
-                       interupts = <61 2 >;
+                       interrupts = <61 2>;
                        interrupt-parent = <&mpic>;
                };
 
                tlu@15000 {
                        compatible = "fsl,mpc8572-tlu", "fsl_tlu";
                        reg = <0x15000 0x1000>;
-                       interupts = <75 2>;
+                       interrupts = <75 2>;
                        interrupt-parent = <&mpic>;
                };
        };
index 11dbda10d7563dbe574e2cb60e13b09cb0927f01..cd0ea2b993622a8fc389b24a3387b2be72932948 100644 (file)
                tlu@2f000 {
                        compatible = "fsl,mpc8572-tlu", "fsl_tlu";
                        reg = <0x2f000 0x1000>;
-                       interupts = <61 2 >;
+                       interrupts = <61 2>;
                        interrupt-parent = <&mpic>;
                };
 
                tlu@15000 {
                        compatible = "fsl,mpc8572-tlu", "fsl_tlu";
                        reg = <0x15000 0x1000>;
-                       interupts = <75 2>;
+                       interrupts = <75 2>;
                        interrupt-parent = <&mpic>;
                };
        };
index 5143228e3e5fe975a1d19eacbd2393b210622497..6636b1d7821b6e5d5bcd8126674a8f3d8499601f 100644 (file)
@@ -71,18 +71,32 @@ udelay:
        add     r4,r4,r5
        addi    r4,r4,-1
        divw    r4,r4,r5        /* BUS ticks */
+#ifdef CONFIG_8xx
+1:     mftbu   r5
+       mftb    r6
+       mftbu   r7
+#else
 1:     mfspr   r5, SPRN_TBRU
        mfspr   r6, SPRN_TBRL
        mfspr   r7, SPRN_TBRU
+#endif
        cmpw    0,r5,r7
        bne     1b              /* Get [synced] base time */
        addc    r9,r6,r4        /* Compute end time */
        addze   r8,r5
+#ifdef CONFIG_8xx
+2:     mftbu   r5
+#else
 2:     mfspr   r5, SPRN_TBRU
+#endif
        cmpw    0,r5,r8
        blt     2b
        bgt     3f
+#ifdef CONFIG_8xx
+       mftb    r6
+#else
        mfspr   r6, SPRN_TBRL
+#endif
        cmpw    0,r6,r9
        blt     2b
 3:     blr
index 16cb92d215d27850f3ba15a0b7417cc0d1719f13..694012877bf7f1cfd1e1ea067b448f7e7c449e87 100644 (file)
@@ -16,6 +16,7 @@ struct vmemmap_backing {
        unsigned long phys;
        unsigned long virt_addr;
 };
+extern struct vmemmap_backing *vmemmap_list;
 
 /*
  * Functions that deal with pagetables that could be at any level of
index 3c1acc31a09280bdc8c706813879571587f3d75e..f595b98079ee1ec75064640001998a407524ad59 100644 (file)
@@ -366,6 +366,8 @@ BEGIN_FTR_SECTION_NESTED(96);               \
        cmpwi dest,0;                   \
        beq-  90b;                      \
 END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
+#elif defined(CONFIG_8xx)
+#define MFTB(dest)                     mftb dest
 #else
 #define MFTB(dest)                     mfspr dest, SPRN_TBRL
 #endif
index 5c45787d551e80c45c5d776bd972c868c19d9a14..fa8388ed94c52e6086110bc382c7196ea32f1ad0 100644 (file)
 
 #else /* __powerpc64__ */
 
+#if defined(CONFIG_8xx)
+#define mftbl()                ({unsigned long rval;   \
+                       asm volatile("mftbl %0" : "=r" (rval)); rval;})
+#define mftbu()                ({unsigned long rval;   \
+                       asm volatile("mftbu %0" : "=r" (rval)); rval;})
+#else
 #define mftbl()                ({unsigned long rval;   \
                        asm volatile("mfspr %0, %1" : "=r" (rval) : \
                                "i" (SPRN_TBRL)); rval;})
 #define mftbu()                ({unsigned long rval;   \
                        asm volatile("mfspr %0, %1" : "=r" (rval) : \
                                "i" (SPRN_TBRU)); rval;})
+#endif
 #endif /* !__powerpc64__ */
 
 #define mttbl(v)       asm volatile("mttbl %0":: "r"(v))
index 703a8412dac28e2a567b4d1b4da5586ae890c34a..11ba86e176315e4ef260c8eb740ba52ca347c192 100644 (file)
@@ -26,6 +26,7 @@ extern void reloc_got2(unsigned long);
 void check_for_initrd(void);
 void do_init_bootmem(void);
 void setup_panic(void);
+#define ARCH_PANIC_TIMEOUT 180
 
 #endif /* !__ASSEMBLY__ */
 
index 18908caa1f3b3c0209e8324474f4ce2b6473da63..2cf846edb3fcc4e941e44a8fc032eecd789b22d7 100644 (file)
@@ -29,7 +29,11 @@ static inline cycles_t get_cycles(void)
        ret = 0;
 
        __asm__ __volatile__(
+#ifdef CONFIG_8xx
+               "97:    mftb %0\n"
+#else
                "97:    mfspr %0, %2\n"
+#endif
                "99:\n"
                ".section __ftr_fixup,\"a\"\n"
                ".align 2\n"
@@ -41,7 +45,11 @@ static inline cycles_t get_cycles(void)
                "       .long 0\n"
                "       .long 0\n"
                ".previous"
+#ifdef CONFIG_8xx
+               : "=r" (ret) : "i" (CPU_FTR_601));
+#else
                : "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL));
+#endif
        return ret;
 #endif
 }
index 75c6ecdb8f3728a175bd61808cad34a9689fd47e..7422a999a39a5bfd8edbd674905417951a792a25 100644 (file)
@@ -36,9 +36,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
 
 struct arch_uprobe {
        union {
-               u8      insn[MAX_UINSN_BYTES];
-               u8      ixol[MAX_UINSN_BYTES];
-               u32     ainsn;
+               u32     insn;
+               u32     ixol;
        };
 };
 
index e1ec57e87b3b435b88ef55c4598d32c37c8e2e07..88a7fb458dfd50f0201d269d8177007cc382c62d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ftrace.h>
 
 #include <asm/machdep.h>
+#include <asm/pgalloc.h>
 #include <asm/prom.h>
 #include <asm/sections.h>
 
@@ -75,6 +76,17 @@ void arch_crash_save_vmcoreinfo(void)
 #ifndef CONFIG_NEED_MULTIPLE_NODES
        VMCOREINFO_SYMBOL(contig_page_data);
 #endif
+#if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP)
+       VMCOREINFO_SYMBOL(vmemmap_list);
+       VMCOREINFO_SYMBOL(mmu_vmemmap_psize);
+       VMCOREINFO_SYMBOL(mmu_psize_defs);
+       VMCOREINFO_STRUCT_SIZE(vmemmap_backing);
+       VMCOREINFO_OFFSET(vmemmap_backing, list);
+       VMCOREINFO_OFFSET(vmemmap_backing, phys);
+       VMCOREINFO_OFFSET(vmemmap_backing, virt_addr);
+       VMCOREINFO_STRUCT_SIZE(mmu_psize_def);
+       VMCOREINFO_OFFSET(mmu_psize_def, shift);
+#endif
 }
 
 /*
index fd82c289ab1c1c76c52c9fe147503d277870874c..28b898e681850ab22996a2043d46c867e96232be 100644 (file)
@@ -210,7 +210,7 @@ static void __init nvram_print_partitions(char * label)
        printk(KERN_WARNING "--------%s---------\n", label);
        printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n");
        list_for_each_entry(tmp_part, &nvram_partitions, partition) {
-               printk(KERN_WARNING "%4d    \t%02x\t%02x\t%d\t%12s\n",
+               printk(KERN_WARNING "%4d    \t%02x\t%02x\t%d\t%12.12s\n",
                       tmp_part->index, tmp_part->header.signature,
                       tmp_part->header.checksum, tmp_part->header.length,
                       tmp_part->header.name);
index b903dc5cf944aee99fc36629fdb974f3e26b6888..2b0da27eaee4242f156d37bfbb4efa06bad334df 100644 (file)
@@ -296,9 +296,6 @@ void __init setup_arch(char **cmdline_p)
        if (cpu_has_feature(CPU_FTR_UNIFIED_ID_CACHE))
                ucache_bsize = icache_bsize = dcache_bsize;
 
-       /* reboot on panic */
-       panic_timeout = 180;
-
        if (ppc_md.panic)
                setup_panic();
 
index 4085aaa9478fd90eff1f1ce149d661bc7488284f..856dd4e99bfe459cdb430f5cba6fbc0b3229be89 100644 (file)
@@ -588,9 +588,6 @@ void __init setup_arch(char **cmdline_p)
        dcache_bsize = ppc64_caches.dline_size;
        icache_bsize = ppc64_caches.iline_size;
 
-       /* reboot on panic */
-       panic_timeout = 180;
-
        if (ppc_md.panic)
                setup_panic();
 
index 1844298f5ea49ea913111c761fb324398c5ed530..68027bfa5f8e3c4a958deeb13db1b6a9fcf89325 100644 (file)
@@ -445,6 +445,12 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
 #endif /* CONFIG_ALTIVEC */
        if (copy_fpr_to_user(&frame->mc_fregs, current))
                return 1;
+
+       /*
+        * Clear the MSR VSX bit to indicate there is no valid state attached
+        * to this context, except in the specific case below where we set it.
+        */
+       msr &= ~MSR_VSX;
 #ifdef CONFIG_VSX
        /*
         * Copy VSR 0-31 upper half from thread_struct to local
@@ -457,15 +463,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
                if (copy_vsx_to_user(&frame->mc_vsregs, current))
                        return 1;
                msr |= MSR_VSX;
-       } else if (!ctx_has_vsx_region)
-               /*
-                * With a small context structure we can't hold the VSX
-                * registers, hence clear the MSR value to indicate the state
-                * was not saved.
-                */
-               msr &= ~MSR_VSX;
-
-
+       }
 #endif /* CONFIG_VSX */
 #ifdef CONFIG_SPE
        /* save spe registers */
index e66f67b8b9e67c1ca4bddbfaa6fb9e32e86c24a9..42991045349f815e124e18dba78c9a914c8b8b84 100644 (file)
@@ -122,6 +122,12 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
        flush_fp_to_thread(current);
        /* copy fpr regs and fpscr */
        err |= copy_fpr_to_user(&sc->fp_regs, current);
+
+       /*
+        * Clear the MSR VSX bit to indicate there is no valid state attached
+        * to this context, except in the specific case below where we set it.
+        */
+       msr &= ~MSR_VSX;
 #ifdef CONFIG_VSX
        /*
         * Copy VSX low doubleword to local buffer for formatting,
index 59f419b935f2501653379fd099b2b1b731a4e7d9..003b20964ea0dfa435af8e1aac8fadde534f1fc2 100644 (file)
@@ -186,7 +186,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
         * emulate_step() returns 1 if the insn was successfully emulated.
         * For all other cases, we need to single-step in hardware.
         */
-       ret = emulate_step(regs, auprobe->ainsn);
+       ret = emulate_step(regs, auprobe->insn);
        if (ret > 0)
                return true;
 
index 6b1f2a6d55178c445a4d1a657dc72b0a53ae7a4a..6b2b69616e7762507f3375300513834f328bb503 100644 (file)
@@ -232,9 +232,15 @@ __do_get_tspec:
        lwz     r6,(CFG_TB_ORIG_STAMP+4)(r9)
 
        /* Get a stable TB value */
+#ifdef CONFIG_8xx
+2:     mftbu   r3
+       mftbl   r4
+       mftbu   r0
+#else
 2:     mfspr   r3, SPRN_TBRU
        mfspr   r4, SPRN_TBRL
        mfspr   r0, SPRN_TBRU
+#endif
        cmplw   cr0,r3,r0
        bne-    2b
 
index 072287f1c3bc7347b6ff4f959843c97053fa4aa1..93203bbe571441bbf05c312470ec728fa969cc70 100644 (file)
@@ -669,12 +669,10 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu,
                /* hcall - punt to userspace */
                int i;
 
-               if (vcpu->arch.shregs.msr & MSR_PR) {
-                       /* sc 1 from userspace - reflect to guest syscall */
-                       kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_SYSCALL);
-                       r = RESUME_GUEST;
-                       break;
-               }
+               /* hypercall with MSR_PR has already been handled in rmode,
+                * and never reaches here.
+                */
+
                run->papr_hcall.nr = kvmppc_get_gpr(vcpu, 3);
                for (i = 0; i < 9; ++i)
                        run->papr_hcall.args[i] = kvmppc_get_gpr(vcpu, 4 + i);
index bc8de75b1925cd34ad1d11379fee8c09f1d275e5..d5ddc2d10748443d4237f03de10987bae6bff070 100644 (file)
@@ -686,6 +686,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
 5:     mtspr   SPRN_SRR0, r6
        mtspr   SPRN_SRR1, r7
 
+/*
+ * Required state:
+ * R4 = vcpu
+ * R10: value for HSRR0
+ * R11: value for HSRR1
+ * R13 = PACA
+ */
 fast_guest_return:
        li      r0,0
        stb     r0,VCPU_CEDED(r4)       /* cancel cede */
@@ -1471,7 +1478,8 @@ kvmppc_hisi:
 hcall_try_real_mode:
        ld      r3,VCPU_GPR(R3)(r9)
        andi.   r0,r11,MSR_PR
-       bne     guest_exit_cont
+       /* sc 1 from userspace - reflect to guest syscall */
+       bne     sc_1_fast_return
        clrrdi  r3,r3,2
        cmpldi  r3,hcall_real_table_end - hcall_real_table
        bge     guest_exit_cont
@@ -1492,6 +1500,15 @@ hcall_try_real_mode:
        ld      r11,VCPU_MSR(r4)
        b       fast_guest_return
 
+sc_1_fast_return:
+       mtspr   SPRN_SRR0,r10
+       mtspr   SPRN_SRR1,r11
+       li      r10, BOOK3S_INTERRUPT_SYSCALL
+       li      r11, (MSR_ME << 1) | 1  /* synthesize MSR_SF | MSR_ME */
+       rotldi  r11, r11, 63
+       mr      r4,r9
+       b       fast_guest_return
+
        /* We've attempted a real mode hcall, but it's punted it back
         * to userspace.  We need to restore some clobbered volatiles
         * before resuming the pass-it-to-qemu path */
index 3bc700655fc88255ae39fe854341e467cd9910a5..74551b5e41e5156b0720c65ec9cdd1adf988260a 100644 (file)
@@ -117,6 +117,5 @@ void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
        struct hstate *hstate = hstate_file(vma->vm_file);
        unsigned long tsize = huge_page_shift(hstate) - 10;
 
-       __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, tsize, 0);
-
+       __flush_tlb_page(vma->vm_mm, vmaddr, tsize, 0);
 }
index 41cd68dee68164c38f3436ee7a40e60326ecc8cb..358d743031385ae7a269ba65200483227126d372 100644 (file)
@@ -305,7 +305,7 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
 {
 #ifdef CONFIG_HUGETLB_PAGE
-       if (is_vm_hugetlb_page(vma))
+       if (vma && is_vm_hugetlb_page(vma))
                flush_hugetlb_page(vma, vmaddr);
 #endif
 
index 132f8726a257c4ed7608534a8f61496d89b69d80..bca2465a9c347ad65f3617a7a51f2e4f2a73034a 100644 (file)
@@ -404,13 +404,27 @@ config PPC_DOORBELL
 
 endmenu
 
-config CPU_LITTLE_ENDIAN
-       bool "Build little endian kernel"
-       default n
+choice
+       prompt "Endianness selection"
+       default CPU_BIG_ENDIAN
        help
          This option selects whether a big endian or little endian kernel will
          be built.
 
+config CPU_BIG_ENDIAN
+       bool "Build big endian kernel"
+       help
+         Build a big endian kernel.
+
+         If unsure, select this option.
+
+config CPU_LITTLE_ENDIAN
+       bool "Build little endian kernel"
+       help
+         Build a little endian kernel.
+
          Note that if cross compiling a little endian kernel,
          CROSS_COMPILE must point to a toolchain capable of targeting
          little endian powerpc.
+
+endchoice
index c1f1908587011d6d131dd56bdf2e1cb283c41128..6f76ae417f47e561bbf7e8b01c588a8e73f6374d 100644 (file)
@@ -470,7 +470,7 @@ static long pseries_little_endian_exceptions(void)
 
 static void __init pSeries_setup_arch(void)
 {
-       panic_timeout = 10;
+       set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
 
        /* Discover PIC type and setup ppc_md accordingly */
        pseries_discover_pic();
index 1c16141c031c9e2d2512b0d308a8456c15fd1ae1..47b6b9f81d4305537b7d0e6290e178efb4253f4c 100644 (file)
@@ -109,27 +109,28 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
        struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data;
        unsigned long phys_mem, phys_end;
        void *user_mem;
-       struct bio_vec *vec;
+       struct bio_vec vec;
        unsigned int transfered;
-       unsigned short idx;
+       struct bvec_iter iter;
 
-       phys_mem = bank->io_addr + (bio->bi_sector << AXON_RAM_SECTOR_SHIFT);
+       phys_mem = bank->io_addr + (bio->bi_iter.bi_sector <<
+                                   AXON_RAM_SECTOR_SHIFT);
        phys_end = bank->io_addr + bank->size;
        transfered = 0;
-       bio_for_each_segment(vec, bio, idx) {
-               if (unlikely(phys_mem + vec->bv_len > phys_end)) {
+       bio_for_each_segment(vec, bio, iter) {
+               if (unlikely(phys_mem + vec.bv_len > phys_end)) {
                        bio_io_error(bio);
                        return;
                }
 
-               user_mem = page_address(vec->bv_page) + vec->bv_offset;
+               user_mem = page_address(vec.bv_page) + vec.bv_offset;
                if (bio_data_dir(bio) == READ)
-                       memcpy(user_mem, (void *) phys_mem, vec->bv_len);
+                       memcpy(user_mem, (void *) phys_mem, vec.bv_len);
                else
-                       memcpy((void *) phys_mem, user_mem, vec->bv_len);
+                       memcpy((void *) phys_mem, user_mem, vec.bv_len);
 
-               phys_mem += vec->bv_len;
-               transfered += vec->bv_len;
+               phys_mem += vec.bv_len;
+               transfered += vec.bv_len;
        }
        bio_endio(bio, 0);
 }
index 314fced4fc14a50f2785d273c87fd590d241e9da..5877e71901b345ef191a911f9ad0ba537abd9c8c 100644 (file)
@@ -101,7 +101,7 @@ config S390
        select GENERIC_CPU_DEVICES if !SMP
        select GENERIC_FIND_FIRST_BIT
        select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_TIME_VSYSCALL_OLD
+       select GENERIC_TIME_VSYSCALL
        select HAVE_ALIGNED_STRUCT_PAGE if SLUB
        select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
        select HAVE_ARCH_SECCOMP_FILTER
index 46cae138ece2efa3617447d1fccf82fa504d4e7d..b3feabd39f31f8eead0a69f4340a8abc0ea17da6 100644 (file)
@@ -35,7 +35,6 @@ static u8 *ctrblk;
 static char keylen_flag;
 
 struct s390_aes_ctx {
-       u8 iv[AES_BLOCK_SIZE];
        u8 key[AES_MAX_KEY_SIZE];
        long enc;
        long dec;
@@ -56,8 +55,7 @@ struct pcc_param {
 
 struct s390_xts_ctx {
        u8 key[32];
-       u8 xts_param[16];
-       struct pcc_param pcc;
+       u8 pcc_key[32];
        long enc;
        long dec;
        int key_len;
@@ -441,30 +439,36 @@ static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
        return aes_set_key(tfm, in_key, key_len);
 }
 
-static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
+static int cbc_aes_crypt(struct blkcipher_desc *desc, long func,
                         struct blkcipher_walk *walk)
 {
+       struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
        int ret = blkcipher_walk_virt(desc, walk);
        unsigned int nbytes = walk->nbytes;
+       struct {
+               u8 iv[AES_BLOCK_SIZE];
+               u8 key[AES_MAX_KEY_SIZE];
+       } param;
 
        if (!nbytes)
                goto out;
 
-       memcpy(param, walk->iv, AES_BLOCK_SIZE);
+       memcpy(param.iv, walk->iv, AES_BLOCK_SIZE);
+       memcpy(param.key, sctx->key, sctx->key_len);
        do {
                /* only use complete blocks */
                unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
                u8 *out = walk->dst.virt.addr;
                u8 *in = walk->src.virt.addr;
 
-               ret = crypt_s390_kmc(func, param, out, in, n);
+               ret = crypt_s390_kmc(func, &param, out, in, n);
                if (ret < 0 || ret != n)
                        return -EIO;
 
                nbytes &= AES_BLOCK_SIZE - 1;
                ret = blkcipher_walk_done(desc, walk, nbytes);
        } while ((nbytes = walk->nbytes));
-       memcpy(walk->iv, param, AES_BLOCK_SIZE);
+       memcpy(walk->iv, param.iv, AES_BLOCK_SIZE);
 
 out:
        return ret;
@@ -481,7 +485,7 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
                return fallback_blk_enc(desc, dst, src, nbytes);
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
-       return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
+       return cbc_aes_crypt(desc, sctx->enc, &walk);
 }
 
 static int cbc_aes_decrypt(struct blkcipher_desc *desc,
@@ -495,7 +499,7 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
                return fallback_blk_dec(desc, dst, src, nbytes);
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
-       return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
+       return cbc_aes_crypt(desc, sctx->dec, &walk);
 }
 
 static struct crypto_alg cbc_aes_alg = {
@@ -586,7 +590,7 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
                xts_ctx->enc = KM_XTS_128_ENCRYPT;
                xts_ctx->dec = KM_XTS_128_DECRYPT;
                memcpy(xts_ctx->key + 16, in_key, 16);
-               memcpy(xts_ctx->pcc.key + 16, in_key + 16, 16);
+               memcpy(xts_ctx->pcc_key + 16, in_key + 16, 16);
                break;
        case 48:
                xts_ctx->enc = 0;
@@ -597,7 +601,7 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
                xts_ctx->enc = KM_XTS_256_ENCRYPT;
                xts_ctx->dec = KM_XTS_256_DECRYPT;
                memcpy(xts_ctx->key, in_key, 32);
-               memcpy(xts_ctx->pcc.key, in_key + 32, 32);
+               memcpy(xts_ctx->pcc_key, in_key + 32, 32);
                break;
        default:
                *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
@@ -616,29 +620,33 @@ static int xts_aes_crypt(struct blkcipher_desc *desc, long func,
        unsigned int nbytes = walk->nbytes;
        unsigned int n;
        u8 *in, *out;
-       void *param;
+       struct pcc_param pcc_param;
+       struct {
+               u8 key[32];
+               u8 init[16];
+       } xts_param;
 
        if (!nbytes)
                goto out;
 
-       memset(xts_ctx->pcc.block, 0, sizeof(xts_ctx->pcc.block));
-       memset(xts_ctx->pcc.bit, 0, sizeof(xts_ctx->pcc.bit));
-       memset(xts_ctx->pcc.xts, 0, sizeof(xts_ctx->pcc.xts));
-       memcpy(xts_ctx->pcc.tweak, walk->iv, sizeof(xts_ctx->pcc.tweak));
-       param = xts_ctx->pcc.key + offset;
-       ret = crypt_s390_pcc(func, param);
+       memset(pcc_param.block, 0, sizeof(pcc_param.block));
+       memset(pcc_param.bit, 0, sizeof(pcc_param.bit));
+       memset(pcc_param.xts, 0, sizeof(pcc_param.xts));
+       memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak));
+       memcpy(pcc_param.key, xts_ctx->pcc_key, 32);
+       ret = crypt_s390_pcc(func, &pcc_param.key[offset]);
        if (ret < 0)
                return -EIO;
 
-       memcpy(xts_ctx->xts_param, xts_ctx->pcc.xts, 16);
-       param = xts_ctx->key + offset;
+       memcpy(xts_param.key, xts_ctx->key, 32);
+       memcpy(xts_param.init, pcc_param.xts, 16);
        do {
                /* only use complete blocks */
                n = nbytes & ~(AES_BLOCK_SIZE - 1);
                out = walk->dst.virt.addr;
                in = walk->src.virt.addr;
 
-               ret = crypt_s390_km(func, param, out, in, n);
+               ret = crypt_s390_km(func, &xts_param.key[offset], out, in, n);
                if (ret < 0 || ret != n)
                        return -EIO;
 
index 316c8503a3b4fda3824ca071065f145038b34a0c..114258eeaacdbbd796a07605e74c53d9610ba3be 100644 (file)
@@ -48,33 +48,21 @@ static inline void clear_page(void *page)
                : "memory", "cc");
 }
 
+/*
+ * copy_page uses the mvcl instruction with 0xb0 padding byte in order to
+ * bypass caches when copying a page. Especially when copying huge pages
+ * this keeps L1 and L2 data caches alive.
+ */
 static inline void copy_page(void *to, void *from)
 {
-       if (MACHINE_HAS_MVPG) {
-               register unsigned long reg0 asm ("0") = 0;
-               asm volatile(
-                       "       mvpg    %0,%1"
-                       : : "a" (to), "a" (from), "d" (reg0)
-                       : "memory", "cc");
-       } else
-               asm volatile(
-                       "       mvc     0(256,%0),0(%1)\n"
-                       "       mvc     256(256,%0),256(%1)\n"
-                       "       mvc     512(256,%0),512(%1)\n"
-                       "       mvc     768(256,%0),768(%1)\n"
-                       "       mvc     1024(256,%0),1024(%1)\n"
-                       "       mvc     1280(256,%0),1280(%1)\n"
-                       "       mvc     1536(256,%0),1536(%1)\n"
-                       "       mvc     1792(256,%0),1792(%1)\n"
-                       "       mvc     2048(256,%0),2048(%1)\n"
-                       "       mvc     2304(256,%0),2304(%1)\n"
-                       "       mvc     2560(256,%0),2560(%1)\n"
-                       "       mvc     2816(256,%0),2816(%1)\n"
-                       "       mvc     3072(256,%0),3072(%1)\n"
-                       "       mvc     3328(256,%0),3328(%1)\n"
-                       "       mvc     3584(256,%0),3584(%1)\n"
-                       "       mvc     3840(256,%0),3840(%1)\n"
-                       : : "a" (to), "a" (from) : "memory");
+       register void *reg2 asm ("2") = to;
+       register unsigned long reg3 asm ("3") = 0x1000;
+       register void *reg4 asm ("4") = from;
+       register unsigned long reg5 asm ("5") = 0xb0001000;
+       asm volatile(
+               "       mvcl    2,4"
+               : "+d" (reg2), "+d" (reg3), "+d" (reg4), "+d" (reg5)
+               : : "memory", "cc");
 }
 
 #define clear_user_page(page, vaddr, pg)       clear_page(page)
index a73eb2e1e918351356005b99940629235ef6ee98..bc9746a7d47c53edf219c4b4b1f500bc0728a284 100644 (file)
@@ -26,8 +26,9 @@ struct vdso_data {
        __u64 wtom_clock_nsec;          /*                              0x28 */
        __u32 tz_minuteswest;           /* Minutes west of Greenwich    0x30 */
        __u32 tz_dsttime;               /* Type of dst correction       0x34 */
-       __u32 ectg_available;
-       __u32 ntp_mult;                 /* NTP adjusted multiplier      0x3C */
+       __u32 ectg_available;           /* ECTG instruction present     0x38 */
+       __u32 tk_mult;                  /* Mult. used for xtime_nsec    0x3c */
+       __u32 tk_shift;                 /* Shift used for xtime_nsec    0x40 */
 };
 
 struct vdso_per_cpu_data {
index e83fc116f5bf2c24ceb4f4b9aa663d7d1c291b8f..fe94ea7c9fa0b554ac757fed5272de835ec158b1 100644 (file)
@@ -154,6 +154,46 @@ struct ica_xcRB {
        unsigned short  priority_window;
        unsigned int    status;
 } __attribute__((packed));
+
+/**
+ * EP11 CPRB
+ */
+struct ep11_cprb {
+       unsigned short  cprb_len;       /* CPRB header length     0x0020    */
+       unsigned char   cprb_ver_id;    /* CPRB version id.       0x04      */
+       unsigned char   pad_000[2];     /* Alignment pad bytes              */
+       unsigned char   flags;          /* Admin cmd 0x80 / func. cmd 0x00  */
+       unsigned char   func_id[2];     /* Function id / subtype  0x5434    */
+       unsigned int    source_id;      /* Source id [originator id]        */
+       unsigned int    target_id;      /* Target id [usage/ctrl domain id] */
+       unsigned int    ret_code;       /* Return code                      */
+       unsigned int    reserved1;      /* Reserved                         */
+       unsigned int    reserved2;      /* Reserved                         */
+       unsigned int    payload_len;    /* Payload length                   */
+} __attribute__((packed));
+
+/**
+ * EP11 target device
+ */
+struct ep11_target_dev {
+       short ap_id;    /* AP device id    */
+       short dom_id;   /* Usage domain id */
+};
+
+/**
+ * EP11 user request block
+ */
+struct ep11_urb {
+       short                   targets_num;    /* Number of target adapters */
+       struct target_list      *targets;       /* Target adapter list       */
+       unsigned long           weight;         /* Level of request priority */
+       unsigned long           req_no;         /* Request id/number         */
+       unsigned long           req_len;        /* Request length            */
+       char __user             *req;           /* Pointer to request block  */
+       unsigned long           resp_len;       /* Response length           */
+       char  __user            *resp;          /* Pointer to response block */
+} __attribute__((packed));
+
 #define AUTOSELECT ((unsigned int)0xFFFFFFFF)
 
 #define ZCRYPT_IOCTL_MAGIC 'z'
@@ -183,6 +223,9 @@ struct ica_xcRB {
  *   ZSECSENDCPRB
  *     Send an arbitrary CPRB to a crypto card.
  *
+ *   ZSENDEP11CPRB
+ *     Send an arbitrary EP11 CPRB to an EP11 coprocessor crypto card.
+ *
  *   Z90STAT_STATUS_MASK
  *     Return an 64 element array of unsigned chars for the status of
  *     all devices.
@@ -256,6 +299,7 @@ struct ica_xcRB {
 #define ICARSAMODEXPO  _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0)
 #define ICARSACRT      _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0)
 #define ZSECSENDCPRB   _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0)
+#define ZSENDEP11CPRB  _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x04, 0)
 
 /* New status calls */
 #define Z90STAT_TOTALCOUNT     _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int)
index 2416138ebd3e5fa5584d897737e27ab7e0978383..496116cd65ec8ef3a1b566ac8c1c0641dfcad5f4 100644 (file)
@@ -65,7 +65,8 @@ int main(void)
        DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
        DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
        DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
-       DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
+       DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult));
+       DEFINE(__VDSO_TK_SHIFT, offsetof(struct vdso_data, tk_shift));
        DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
        DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
        /* constants used by the vdso */
index 6e24429784097c034d41072929e446a5ef49cab4..95e7ba0fbb7eb1323b45300c4f6afcae04103dc8 100644 (file)
@@ -194,7 +194,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
                return -EINVAL;
 
        /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
-       regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
+       regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
                (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
                (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 |
                (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);
index 4a460c44e17ec15763da0cf24207ed048fa929f9..813ec7260878662d097ba90ef04d90b6f183367d 100644 (file)
@@ -78,7 +78,7 @@ PGM_CHECK_DEFAULT                     /* 34 */
 PGM_CHECK_DEFAULT                      /* 35 */
 PGM_CHECK_DEFAULT                      /* 36 */
 PGM_CHECK_DEFAULT                      /* 37 */
-PGM_CHECK_DEFAULT                      /* 38 */
+PGM_CHECK_64BIT(do_dat_exception)      /* 38 */
 PGM_CHECK_64BIT(do_dat_exception)      /* 39 */
 PGM_CHECK_64BIT(do_dat_exception)      /* 3a */
 PGM_CHECK_64BIT(do_dat_exception)      /* 3b */
index fb535874a2464853168c9a9182620acf10e37c74..d8fd508ccd1e180b7679d24939b253d31a56bc26 100644 (file)
@@ -94,7 +94,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
                return -EINVAL;
 
        /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
-       regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
+       regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
                (user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
        /* Check for invalid user address space control. */
        if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
index 064c3082ab33604c4d360d7267ecd5e0f6ac1ac1..dd95f1631621722ca9d35a5d67269b152cb630d2 100644 (file)
@@ -108,20 +108,10 @@ static void fixup_clock_comparator(unsigned long long delta)
        set_clock_comparator(S390_lowcore.clock_comparator);
 }
 
-static int s390_next_ktime(ktime_t expires,
+static int s390_next_event(unsigned long delta,
                           struct clock_event_device *evt)
 {
-       struct timespec ts;
-       u64 nsecs;
-
-       ts.tv_sec = ts.tv_nsec = 0;
-       monotonic_to_bootbased(&ts);
-       nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
-       do_div(nsecs, 125);
-       S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
-       /* Program the maximum value if we have an overflow (== year 2042) */
-       if (unlikely(S390_lowcore.clock_comparator < sched_clock_base_cc))
-               S390_lowcore.clock_comparator = -1ULL;
+       S390_lowcore.clock_comparator = get_tod_clock() + delta;
        set_clock_comparator(S390_lowcore.clock_comparator);
        return 0;
 }
@@ -146,15 +136,14 @@ void init_cpu_timer(void)
        cpu = smp_processor_id();
        cd = &per_cpu(comparators, cpu);
        cd->name                = "comparator";
-       cd->features            = CLOCK_EVT_FEAT_ONESHOT |
-                                 CLOCK_EVT_FEAT_KTIME;
+       cd->features            = CLOCK_EVT_FEAT_ONESHOT;
        cd->mult                = 16777;
        cd->shift               = 12;
        cd->min_delta_ns        = 1;
        cd->max_delta_ns        = LONG_MAX;
        cd->rating              = 400;
        cd->cpumask             = cpumask_of(cpu);
-       cd->set_next_ktime      = s390_next_ktime;
+       cd->set_next_event      = s390_next_event;
        cd->set_mode            = s390_set_mode;
 
        clockevents_register_device(cd);
@@ -221,21 +210,30 @@ struct clocksource * __init clocksource_default_clock(void)
        return &clocksource_tod;
 }
 
-void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm,
-                       struct clocksource *clock, u32 mult)
+void update_vsyscall(struct timekeeper *tk)
 {
-       if (clock != &clocksource_tod)
+       u64 nsecps;
+
+       if (tk->clock != &clocksource_tod)
                return;
 
        /* Make userspace gettimeofday spin until we're done. */
        ++vdso_data->tb_update_count;
        smp_wmb();
-       vdso_data->xtime_tod_stamp = clock->cycle_last;
-       vdso_data->xtime_clock_sec = wall_time->tv_sec;
-       vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
-       vdso_data->wtom_clock_sec = wtm->tv_sec;
-       vdso_data->wtom_clock_nsec = wtm->tv_nsec;
-       vdso_data->ntp_mult = mult;
+       vdso_data->xtime_tod_stamp = tk->clock->cycle_last;
+       vdso_data->xtime_clock_sec = tk->xtime_sec;
+       vdso_data->xtime_clock_nsec = tk->xtime_nsec;
+       vdso_data->wtom_clock_sec =
+               tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
+       vdso_data->wtom_clock_nsec = tk->xtime_nsec +
+               + (tk->wall_to_monotonic.tv_nsec << tk->shift);
+       nsecps = (u64) NSEC_PER_SEC << tk->shift;
+       while (vdso_data->wtom_clock_nsec >= nsecps) {
+               vdso_data->wtom_clock_nsec -= nsecps;
+               vdso_data->wtom_clock_sec++;
+       }
+       vdso_data->tk_mult = tk->mult;
+       vdso_data->tk_shift = tk->shift;
        smp_wmb();
        ++vdso_data->tb_update_count;
 }
index b2224e0b974ce5beff26c4d1e7838d48e0232ae9..5be8e472f57d1d0debe31c849b4177492380d957 100644 (file)
@@ -38,25 +38,26 @@ __kernel_clock_gettime:
        sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
        brc     3,2f
        ahi     %r0,-1
-2:     ms      %r0,__VDSO_NTP_MULT(%r5)        /* cyc2ns(clock,cycle_delta) */
+2:     ms      %r0,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
        lr      %r2,%r0
-       l       %r0,__VDSO_NTP_MULT(%r5)
+       l       %r0,__VDSO_TK_MULT(%r5)
        ltr     %r1,%r1
        mr      %r0,%r0
        jnm     3f
-       a       %r0,__VDSO_NTP_MULT(%r5)
+       a       %r0,__VDSO_TK_MULT(%r5)
 3:     alr     %r0,%r2
-       srdl    %r0,12
-       al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
+       al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
        al      %r1,__VDSO_XTIME_NSEC+4(%r5)
        brc     12,4f
        ahi     %r0,1
-4:     l       %r2,__VDSO_XTIME_SEC+4(%r5)
-       al      %r0,__VDSO_WTOM_NSEC(%r5)       /*  + wall_to_monotonic */
+4:     al      %r0,__VDSO_WTOM_NSEC(%r5)       /*  + wall_to_monotonic.nsec */
        al      %r1,__VDSO_WTOM_NSEC+4(%r5)
        brc     12,5f
        ahi     %r0,1
-5:     al      %r2,__VDSO_WTOM_SEC+4(%r5)
+5:     l       %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
+       srdl    %r0,0(%r2)                      /*  >> tk->shift */
+       l       %r2,__VDSO_XTIME_SEC+4(%r5)
+       al      %r2,__VDSO_WTOM_SEC+4(%r5)
        cl      %r4,__VDSO_UPD_COUNT+4(%r5)     /* check update counter */
        jne     1b
        basr    %r5,0
@@ -86,20 +87,21 @@ __kernel_clock_gettime:
        sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
        brc     3,12f
        ahi     %r0,-1
-12:    ms      %r0,__VDSO_NTP_MULT(%r5)        /* cyc2ns(clock,cycle_delta) */
+12:    ms      %r0,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
        lr      %r2,%r0
-       l       %r0,__VDSO_NTP_MULT(%r5)
+       l       %r0,__VDSO_TK_MULT(%r5)
        ltr     %r1,%r1
        mr      %r0,%r0
        jnm     13f
-       a       %r0,__VDSO_NTP_MULT(%r5)
+       a       %r0,__VDSO_TK_MULT(%r5)
 13:    alr     %r0,%r2
-       srdl    %r0,12
-       al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
+       al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
        al      %r1,__VDSO_XTIME_NSEC+4(%r5)
        brc     12,14f
        ahi     %r0,1
-14:    l       %r2,__VDSO_XTIME_SEC+4(%r5)
+14:    l       %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
+       srdl    %r0,0(%r2)                      /*  >> tk->shift */
+       l       %r2,__VDSO_XTIME_SEC+4(%r5)
        cl      %r4,__VDSO_UPD_COUNT+4(%r5)     /* check update counter */
        jne     11b
        basr    %r5,0
index 2d3633175e3be520850ad6b48b30e94c88058072..fd621a950f7c70e917ea6ca44bb4a5fd5b9869ab 100644 (file)
@@ -35,15 +35,14 @@ __kernel_gettimeofday:
        sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
        brc     3,3f
        ahi     %r0,-1
-3:     ms      %r0,__VDSO_NTP_MULT(%r5)        /* cyc2ns(clock,cycle_delta) */
+3:     ms      %r0,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
        st      %r0,24(%r15)
-       l       %r0,__VDSO_NTP_MULT(%r5)
+       l       %r0,__VDSO_TK_MULT(%r5)
        ltr     %r1,%r1
        mr      %r0,%r0
        jnm     4f
-       a       %r0,__VDSO_NTP_MULT(%r5)
+       a       %r0,__VDSO_TK_MULT(%r5)
 4:     al      %r0,24(%r15)
-       srdl    %r0,12
        al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
        al      %r1,__VDSO_XTIME_NSEC+4(%r5)
        brc     12,5f
@@ -51,6 +50,8 @@ __kernel_gettimeofday:
 5:     mvc     24(4,%r15),__VDSO_XTIME_SEC+4(%r5)
        cl      %r4,__VDSO_UPD_COUNT+4(%r5)     /* check update counter */
        jne     1b
+       l       %r4,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
+       srdl    %r0,0(%r4)                      /*  >> tk->shift */
        l       %r4,24(%r15)                    /* get tv_sec from stack */
        basr    %r5,0
 6:     ltr     %r0,%r0
index d46c95ed5f19ae8c25f9255b32338e8cc3197906..0add1072ba306623665148816155f951f0baeeda 100644 (file)
@@ -34,14 +34,15 @@ __kernel_clock_gettime:
        tmll    %r4,0x0001                      /* pending update ? loop */
        jnz     0b
        stck    48(%r15)                        /* Store TOD clock */
+       lgf     %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
+       lg      %r0,__VDSO_XTIME_SEC(%r5)       /* tk->xtime_sec */
+       alg     %r0,__VDSO_WTOM_SEC(%r5)        /*  + wall_to_monotonic.sec */
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
-       msgf    %r1,__VDSO_NTP_MULT(%r5)        /*  * NTP adjustment */
-       srlg    %r1,%r1,12                      /* cyc2ns(clock,cycle_delta) */
-       alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
-       lg      %r0,__VDSO_XTIME_SEC(%r5)
-       alg     %r1,__VDSO_WTOM_NSEC(%r5)       /*  + wall_to_monotonic */
-       alg     %r0,__VDSO_WTOM_SEC(%r5)
+       msgf    %r1,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
+       alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
+       alg     %r1,__VDSO_WTOM_NSEC(%r5)       /*  + wall_to_monotonic.nsec */
+       srlg    %r1,%r1,0(%r2)                  /*  >> tk->shift */
        clg     %r4,__VDSO_UPD_COUNT(%r5)       /* check update counter */
        jne     0b
        larl    %r5,13f
@@ -62,12 +63,13 @@ __kernel_clock_gettime:
        tmll    %r4,0x0001                      /* pending update ? loop */
        jnz     5b
        stck    48(%r15)                        /* Store TOD clock */
+       lgf     %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
-       msgf    %r1,__VDSO_NTP_MULT(%r5)        /*  * NTP adjustment */
-       srlg    %r1,%r1,12                      /* cyc2ns(clock,cycle_delta) */
-       alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
-       lg      %r0,__VDSO_XTIME_SEC(%r5)
+       msgf    %r1,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
+       alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
+       srlg    %r1,%r1,0(%r2)                  /*  >> tk->shift */
+       lg      %r0,__VDSO_XTIME_SEC(%r5)       /* tk->xtime_sec */
        clg     %r4,__VDSO_UPD_COUNT(%r5)       /* check update counter */
        jne     5b
        larl    %r5,13f
index 36ee674722ec3a76b3439fe78752f024ba5ba434..d0860d1d0cccfafe86320a07380ea14ddff1a284 100644 (file)
@@ -31,12 +31,13 @@ __kernel_gettimeofday:
        stck    48(%r15)                        /* Store TOD clock */
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
-       msgf    %r1,__VDSO_NTP_MULT(%r5)        /*  * NTP adjustment */
-       srlg    %r1,%r1,12                      /* cyc2ns(clock,cycle_delta) */
-       alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + xtime.tv_nsec */
-       lg      %r0,__VDSO_XTIME_SEC(%r5)       /* xtime.tv_sec */
+       msgf    %r1,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
+       alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
+       lg      %r0,__VDSO_XTIME_SEC(%r5)       /* tk->xtime_sec */
        clg     %r4,__VDSO_UPD_COUNT(%r5)       /* check update counter */
        jne     0b
+       lgf     %r5,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
+       srlg    %r1,%r1,0(%r5)                  /*  >> tk->shift */
        larl    %r5,5f
 2:     clg     %r1,0(%r5)
        jl      3f
index 97e03caf782598a20857ab276ff03df701c4c3f9..dbdab3e7a1a6266ca3b96cd692d298896bc9902f 100644 (file)
@@ -78,11 +78,14 @@ static size_t copy_in_kernel(size_t count, void __user *to,
  * contains the (negative) exception code.
  */
 #ifdef CONFIG_64BIT
+
 static unsigned long follow_table(struct mm_struct *mm,
                                  unsigned long address, int write)
 {
        unsigned long *table = (unsigned long *)__pa(mm->pgd);
 
+       if (unlikely(address > mm->context.asce_limit - 1))
+               return -0x38UL;
        switch (mm->context.asce_bits & _ASCE_TYPE_MASK) {
        case _ASCE_TYPE_REGION1:
                table = table + ((address >> 53) & 0x7ff);
index 122f737a901fbad4e22de06652e6eb9b04abdfc8..5bc3a15465c71a53906ed0f99a848298c30b2831 100644 (file)
@@ -502,7 +502,7 @@ static struct platform_device keysc_device = {
 /* TouchScreen */
 #define IRQ0 evt2irq(0x600)
 
-static int ts_get_pendown_state(void)
+static int ts_get_pendown_state(struct device *dev)
 {
        int val = 0;
        gpio_free(GPIO_FN_INTC_IRQ0);
index ec9ad593c3da743bacbd5875a577709a94e3333b..01a38696137e9952c9e07f91669685b3b349b50d 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/kdebug.h>
 #include <linux/types.h>
+#include <cpu/ubc.h>
 
 struct arch_hw_breakpoint {
        char            *name; /* Contains name of the symbol to set bkpt */
@@ -15,17 +16,6 @@ struct arch_hw_breakpoint {
        u16             type;
 };
 
-enum {
-       SH_BREAKPOINT_READ      = (1 << 1),
-       SH_BREAKPOINT_WRITE     = (1 << 2),
-       SH_BREAKPOINT_RW        = SH_BREAKPOINT_READ | SH_BREAKPOINT_WRITE,
-
-       SH_BREAKPOINT_LEN_1     = (1 << 12),
-       SH_BREAKPOINT_LEN_2     = (1 << 13),
-       SH_BREAKPOINT_LEN_4     = SH_BREAKPOINT_LEN_1 | SH_BREAKPOINT_LEN_2,
-       SH_BREAKPOINT_LEN_8     = (1 << 14),
-};
-
 struct sh_ubc {
        const char      *name;
        unsigned int    num_events;
diff --git a/arch/sh/include/cpu-common/cpu/ubc.h b/arch/sh/include/cpu-common/cpu/ubc.h
new file mode 100644 (file)
index 0000000..b604619
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __ARCH_SH_CPU_UBC_H__
+#define __ARCH_SH_CPU_UBC_H__
+
+enum {
+       SH_BREAKPOINT_READ      = (1 << 1),
+       SH_BREAKPOINT_WRITE     = (1 << 2),
+       SH_BREAKPOINT_RW        = SH_BREAKPOINT_READ | SH_BREAKPOINT_WRITE,
+
+       SH_BREAKPOINT_LEN_1     = (1 << 12),
+       SH_BREAKPOINT_LEN_2     = (1 << 13),
+       SH_BREAKPOINT_LEN_4     = SH_BREAKPOINT_LEN_1 | SH_BREAKPOINT_LEN_2,
+       SH_BREAKPOINT_LEN_8     = (1 << 14),
+};
+
+#define UBC_64BIT      1
+
+#endif /* __ARCH_SH_CPU_UBC_H__ */
diff --git a/arch/sh/include/cpu-sh2a/cpu/ubc.h b/arch/sh/include/cpu-sh2a/cpu/ubc.h
new file mode 100644 (file)
index 0000000..3371f90
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __ARCH_SH_CPU_UBC_H__
+#define __ARCH_SH_CPU_UBC_H__
+
+enum {
+       SH_BREAKPOINT_READ      = (1 << 2),
+       SH_BREAKPOINT_WRITE     = (1 << 3),
+       SH_BREAKPOINT_RW        = SH_BREAKPOINT_READ | SH_BREAKPOINT_WRITE,
+
+       SH_BREAKPOINT_LEN_1     = (1 << 0),
+       SH_BREAKPOINT_LEN_2     = (1 << 1),
+       SH_BREAKPOINT_LEN_4     = SH_BREAKPOINT_LEN_1 | SH_BREAKPOINT_LEN_2,
+};
+
+#endif /* __ARCH_SH_CPU_UBC_H__ */
index 990195d9845607bfcca4a8b3cfcd05c41df582bc..92f0da4c86a7533e18269e6f5d439130e1a71815 100644 (file)
@@ -22,3 +22,4 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7264)   := pinmux-sh7264.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7269)    := pinmux-sh7269.o
 
 obj-$(CONFIG_GPIOLIB)                  += $(pinmux-y)
+obj-$(CONFIG_HAVE_HW_BREAKPOINT)       += ubc.o
diff --git a/arch/sh/kernel/cpu/sh2a/ubc.c b/arch/sh/kernel/cpu/sh2a/ubc.c
new file mode 100644 (file)
index 0000000..ef95a9b
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * arch/sh/kernel/cpu/sh2a/ubc.c
+ *
+ * On-chip UBC support for SH-2A CPUs.
+ *
+ * Copyright (C) 2009 - 2010  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <asm/hw_breakpoint.h>
+
+#define UBC_BAR(idx)   (0xfffc0400 + (0x10 * idx))
+#define UBC_BAMR(idx)  (0xfffc0404 + (0x10 * idx))
+#define UBC_BBR(idx)   (0xfffc04A0 + (0x10 * idx))
+#define UBC_BDR(idx)   (0xfffc0408 + (0x10 * idx))
+#define UBC_BDMR(idx)  (0xfffc040C + (0x10 * idx))
+
+#define UBC_BRCR       0xfffc04C0
+
+/* BBR */
+#define UBC_BBR_UBID   (1 << 13)     /* User Break Interrupt Disable */
+#define UBC_BBR_DBE    (1 << 12)     /* Data Break Enable */
+#define UBC_BBR_CD_C   (1 << 6)      /* C Bus Cycle */
+#define UBC_BBR_CD_I   (2 << 6)      /* I Bus Cycle */
+#define UBC_BBR_ID_I   (1 << 4)      /* Break Condition is instruction fetch cycle */
+#define UBC_BBR_ID_D   (2 << 4)      /* Break Condition is data access cycle */
+#define UBC_BBR_ID_ID  (3 << 4)      /* Break Condition is instruction fetch or data access cycle */
+
+#define UBC_CRR_BIE    (1 << 0)
+
+/* CBR */
+#define UBC_CBR_CE     (1 << 0)
+
+static struct sh_ubc sh2a_ubc;
+
+static void sh2a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
+{
+       __raw_writel(UBC_BBR_DBE | UBC_BBR_CD_C | UBC_BBR_ID_ID |
+                    info->len | info->type, UBC_BBR(idx));
+       __raw_writel(info->address, UBC_BAR(idx));
+}
+
+static void sh2a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
+{
+       __raw_writel(UBC_BBR_UBID, UBC_BBR(idx));
+       __raw_writel(0, UBC_BAR(idx));
+}
+
+static void sh2a_ubc_enable_all(unsigned long mask)
+{
+       int i;
+
+       for (i = 0; i < sh2a_ubc.num_events; i++)
+               if (mask & (1 << i))
+                       __raw_writel(__raw_readl(UBC_BBR(i)) & ~UBC_BBR_UBID,
+                                    UBC_BBR(i));
+}
+
+static void sh2a_ubc_disable_all(void)
+{
+       int i;
+       
+       for (i = 0; i < sh2a_ubc.num_events; i++)
+               __raw_writel(__raw_readl(UBC_BBR(i)) | UBC_BBR_UBID,
+                            UBC_BBR(i));
+}
+
+static unsigned long sh2a_ubc_active_mask(void)
+{
+       unsigned long active = 0;
+       int i;
+
+       for (i = 0; i < sh2a_ubc.num_events; i++)
+               if (!(__raw_readl(UBC_BBR(i)) & UBC_BBR_UBID))
+                       active |= (1 << i);
+
+       return active;
+}
+
+static unsigned long sh2a_ubc_triggered_mask(void)
+{
+       unsigned int ret, mask;
+       
+       mask = 0;
+       ret = __raw_readl(UBC_BRCR);
+       if ((ret & (1 << 15)) || (ret & (1 << 13))) {
+               mask |= (1 << 0); /* Match condition for channel 0 */
+       } else 
+               mask &= ~(1 << 0);
+       
+       if ((ret & (1 << 14)) || (ret & (1 << 12))) {
+               mask |= (1 << 1); /* Match condition for channel 1 */
+       } else 
+               mask &= ~(1 << 1);
+
+       return mask;
+}
+
+static void sh2a_ubc_clear_triggered_mask(unsigned long mask)
+{
+       if (mask & (1 << 0)) /* Channel 0 statisfied break condition */
+               __raw_writel(__raw_readl(UBC_BRCR) &
+                            ~((1 << 15) | (1 << 13)), UBC_BRCR);
+       
+       if (mask & (1 << 1)) /* Channel 1 statisfied break condition */
+               __raw_writel(__raw_readl(UBC_BRCR) &
+                            ~((1 << 14) | (1 << 12)), UBC_BRCR);
+}
+
+static struct sh_ubc sh2a_ubc = {
+       .name                   = "SH-2A",
+       .num_events             = 2,
+       .trap_nr                = 0x1e0,
+       .enable                 = sh2a_ubc_enable,
+       .disable                = sh2a_ubc_disable,
+       .enable_all             = sh2a_ubc_enable_all,
+       .disable_all            = sh2a_ubc_disable_all,
+       .active_mask            = sh2a_ubc_active_mask,
+       .triggered_mask         = sh2a_ubc_triggered_mask,
+       .clear_triggered_mask   = sh2a_ubc_clear_triggered_mask,
+};
+
+static int __init sh2a_ubc_init(void)
+{
+       struct clk *ubc_iclk = clk_get(NULL, "ubc0");
+       int i;
+
+       /*
+        * The UBC MSTP bit is optional, as not all platforms will have
+        * it. Just ignore it if we can't find it.
+        */
+       if (IS_ERR(ubc_iclk))
+               ubc_iclk = NULL;
+
+       clk_enable(ubc_iclk);
+
+       for (i = 0; i < sh2a_ubc.num_events; i++) {
+               __raw_writel(0, UBC_BAMR(i));
+               __raw_writel(0, UBC_BBR(i));
+       }
+
+       clk_disable(ubc_iclk);
+
+       sh2a_ubc.clk = ubc_iclk;
+
+       return register_sh_ubc(&sh2a_ubc);
+}
+arch_initcall(sh2a_ubc_init);
index f9173766ec4be2393e4207efe7092741f35fc271..ac4922ad3c148d3fc0883afe9ccb8a50d078fc76 100644 (file)
@@ -113,9 +113,11 @@ static int get_hbp_len(u16 hbp_len)
        case SH_BREAKPOINT_LEN_4:
                len_in_bytes = 4;
                break;
+#ifdef UBC_64BIT
        case SH_BREAKPOINT_LEN_8:
                len_in_bytes = 8;
                break;
+#endif
        }
        return len_in_bytes;
 }
@@ -149,9 +151,11 @@ int arch_bp_generic_fields(int sh_len, int sh_type,
        case SH_BREAKPOINT_LEN_4:
                *gen_len = HW_BREAKPOINT_LEN_4;
                break;
+#ifdef UBC_64BIT
        case SH_BREAKPOINT_LEN_8:
                *gen_len = HW_BREAKPOINT_LEN_8;
                break;
+#endif
        default:
                return -EINVAL;
        }
@@ -190,9 +194,11 @@ static int arch_build_bp_info(struct perf_event *bp)
        case HW_BREAKPOINT_LEN_4:
                info->len = SH_BREAKPOINT_LEN_4;
                break;
+#ifdef UBC_64BIT
        case HW_BREAKPOINT_LEN_8:
                info->len = SH_BREAKPOINT_LEN_8;
                break;
+#endif
        default:
                return -EINVAL;
        }
@@ -240,9 +246,11 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
        case SH_BREAKPOINT_LEN_4:
                align = 3;
                break;
+#ifdef UBC_64BIT
        case SH_BREAKPOINT_LEN_8:
                align = 7;
                break;
+#endif
        default:
                return ret;
        }
index 5d5d3b739a6b2964669012d46d5e144a077b8c62..86a746243dc83500803de2f6fa2a79b0898e1442 100644 (file)
@@ -19,9 +19,6 @@
 
 #include <asm-generic/sections.h>
 
-/* Text and data are at different areas in the kernel VA space. */
-extern char _sinitdata[], _einitdata[];
-
 /* Write-once data is writable only till the end of initialization. */
 extern char __w1data_begin[], __w1data_end[];
 
index f1819423ffc9f7b006098729605506d85f617acb..0e059a0101ea3097527968bd2632a2b91436bb0d 100644 (file)
@@ -66,11 +66,9 @@ SECTIONS
 
   . = ALIGN(PAGE_SIZE);
   __init_begin = .;
-  VMLINUX_SYMBOL(_sinitdata) = .;
   INIT_DATA_SECTION(16) :data =0
   PERCPU_SECTION(L2_CACHE_BYTES)
   . = ALIGN(PAGE_SIZE);
-  VMLINUX_SYMBOL(_einitdata) = .;
   __init_end = .;
 
   _sdata = .;                   /* Start of data section */
index 0fa1acfac79ad2a25ba82aed6607e36f868ade7c..2bd245b5a42a271f861270f64a88f0fd0fe10470 100644 (file)
@@ -254,8 +254,8 @@ static pgprot_t __init init_pgprot(ulong address)
         * Everything else that isn't data or bss is heap, so mark it
         * with the initial heap home (hash-for-home, or this cpu).  This
         * includes any addresses after the loaded image and any address before
-        * _einitdata, since we already captured the case of text before
-        * _sinittext, and __pa(einittext) is approximately __pa(sinitdata).
+        * __init_end, since we already captured the case of text before
+        * _sinittext, and __pa(einittext) is approximately __pa(__init_begin).
         *
         * All the LOWMEM pages that we mark this way will get their
         * struct page homecache properly marked later, in set_page_homes().
@@ -263,7 +263,7 @@ static pgprot_t __init init_pgprot(ulong address)
         * homes, but with a zero free_time we don't have to actually
         * do a flush action the first time we use them, either.
         */
-       if (address >= (ulong) _end || address < (ulong) _einitdata)
+       if (address >= (ulong) _end || address < (ulong) __init_end)
                return construct_pgprot(PAGE_KERNEL, initial_heap_home());
 
        /* Use hash-for-home if requested for data/bss. */
@@ -632,7 +632,7 @@ int devmem_is_allowed(unsigned long pagenr)
 {
        return pagenr < kaddr_to_pfn(_end) &&
                !(pagenr >= kaddr_to_pfn(&init_thread_union) ||
-                 pagenr < kaddr_to_pfn(_einitdata)) &&
+                 pagenr < kaddr_to_pfn(__init_end)) &&
                !(pagenr >= kaddr_to_pfn(_sinittext) ||
                  pagenr <= kaddr_to_pfn(_einittext-1));
 }
@@ -975,8 +975,8 @@ void free_initmem(void)
 
        /* Free the data pages that we won't use again after init. */
        free_init_pages("unused kernel data",
-                       (unsigned long)_sinitdata,
-                       (unsigned long)_einitdata);
+                       (unsigned long)__init_begin,
+                       (unsigned long)__init_end);
 
        /*
         * Free the pages mapped from 0xc0000000 that correspond to code
index e903c71f7e69822d2ce5240b957399dbab783037..a5c83b9dad45953d0ee11abd9869b5245a41aa0b 100644 (file)
@@ -1727,16 +1727,60 @@ config RELOCATABLE
 
          Note: If CONFIG_RELOCATABLE=y, then the kernel runs from the address
          it has been loaded at and the compile time physical address
-         (CONFIG_PHYSICAL_START) is ignored.
+         (CONFIG_PHYSICAL_START) is used as the minimum location.
 
-# Relocation on x86-32 needs some additional build support
+config RANDOMIZE_BASE
+       bool "Randomize the address of the kernel image"
+       depends on RELOCATABLE
+       depends on !HIBERNATION
+       default n
+       ---help---
+          Randomizes the physical and virtual address at which the
+          kernel image is decompressed, as a security feature that
+          deters exploit attempts relying on knowledge of the location
+          of kernel internals.
+
+          Entropy is generated using the RDRAND instruction if it is
+          supported. If RDTSC is supported, it is used as well. If
+          neither RDRAND nor RDTSC are supported, then randomness is
+          read from the i8254 timer.
+
+          The kernel will be offset by up to RANDOMIZE_BASE_MAX_OFFSET,
+          and aligned according to PHYSICAL_ALIGN. Since the kernel is
+          built using 2GiB addressing, and PHYSICAL_ALGIN must be at a
+          minimum of 2MiB, only 10 bits of entropy is theoretically
+          possible. At best, due to page table layouts, 64-bit can use
+          9 bits of entropy and 32-bit uses 8 bits.
+
+config RANDOMIZE_BASE_MAX_OFFSET
+       hex "Maximum ASLR offset allowed"
+       depends on RANDOMIZE_BASE
+       range 0x0 0x20000000 if X86_32
+       default "0x20000000" if X86_32
+       range 0x0 0x40000000 if X86_64
+       default "0x40000000" if X86_64
+       ---help---
+        Determines the maximal offset in bytes that will be applied to the
+        kernel when Address Space Layout Randomization (ASLR) is active.
+        Must be less than or equal to the actual physical memory on the
+        system. This must be a multiple of CONFIG_PHYSICAL_ALIGN.
+
+        On 32-bit this is limited to 512MiB.
+
+        On 64-bit this is limited by how the kernel fixmap page table is
+        positioned, so this cannot be larger that 1GiB currently. Normally
+        there is a 512MiB to 1.5GiB split between kernel and modules. When
+        this is raised above the 512MiB default, the modules area will
+        shrink to compensate, up to the current maximum 1GiB to 1GiB split.
+
+# Relocation on x86 needs some additional build support
 config X86_NEED_RELOCS
        def_bool y
-       depends on X86_32 && RELOCATABLE
+       depends on RANDOMIZE_BASE || (X86_32 && RELOCATABLE)
 
 config PHYSICAL_ALIGN
        hex "Alignment value to which kernel should be aligned"
-       default "0x1000000"
+       default "0x200000"
        range 0x2000 0x1000000 if X86_32
        range 0x200000 0x1000000 if X86_64
        ---help---
index dce69a2568963bf97efa8a3598be4645cc93834b..28f7db7993f5015f27b724bbad43c89c2ec0bb73 100644 (file)
@@ -20,7 +20,7 @@ targets               := vmlinux.bin setup.bin setup.elf bzImage
 targets                += fdimage fdimage144 fdimage288 image.iso mtools.conf
 subdir-                := compressed
 
-setup-y                += a20.o bioscall.o cmdline.o copy.o cpu.o cpucheck.o
+setup-y                += a20.o bioscall.o cmdline.o copy.o cpu.o cpuflags.o cpucheck.o
 setup-y                += early_serial_console.o edd.o header.o main.o mca.o memory.o
 setup-y                += pm.o pmjump.o printf.o regs.o string.o tty.o video.o
 setup-y                += video-mode.o version.o
index ef72baeff48475cd1ce9583880c33b9970b1b556..50f8c5e0f37e1d2dd7030da9d72c5be21e2ee282 100644 (file)
@@ -26,9 +26,8 @@
 #include <asm/boot.h>
 #include <asm/setup.h>
 #include "bitops.h"
-#include <asm/cpufeature.h>
-#include <asm/processor-flags.h>
 #include "ctype.h"
+#include "cpuflags.h"
 
 /* Useful macros */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
@@ -307,14 +306,7 @@ static inline int cmdline_find_option_bool(const char *option)
        return __cmdline_find_option_bool(cmd_line_ptr, option);
 }
 
-
 /* cpu.c, cpucheck.c */
-struct cpu_features {
-       int level;              /* Family, or 64 for x86-64 */
-       int model;
-       u32 flags[NCAPINTS];
-};
-extern struct cpu_features cpu;
 int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
 int validate_cpu(void);
 
index dcd90df10ab4e271dd6ee0e3ed737015326efa18..ae8b5dbbd8c5c401ff63e6a188aac29e0b197ca1 100644 (file)
@@ -27,7 +27,7 @@ HOST_EXTRACFLAGS += -I$(srctree)/tools/include
 
 VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \
        $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \
-       $(obj)/piggy.o
+       $(obj)/piggy.o $(obj)/cpuflags.o $(obj)/aslr.o
 
 $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone
 
diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c
new file mode 100644 (file)
index 0000000..84be175
--- /dev/null
@@ -0,0 +1,317 @@
+#include "misc.h"
+
+#ifdef CONFIG_RANDOMIZE_BASE
+#include <asm/msr.h>
+#include <asm/archrandom.h>
+#include <asm/e820.h>
+
+#include <generated/compile.h>
+#include <linux/module.h>
+#include <linux/uts.h>
+#include <linux/utsname.h>
+#include <generated/utsrelease.h>
+#include <linux/version.h>
+
+/* Simplified build-specific string for starting entropy. */
+static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@"
+               LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION;
+
+#define I8254_PORT_CONTROL     0x43
+#define I8254_PORT_COUNTER0    0x40
+#define I8254_CMD_READBACK     0xC0
+#define I8254_SELECT_COUNTER0  0x02
+#define I8254_STATUS_NOTREADY  0x40
+static inline u16 i8254(void)
+{
+       u16 status, timer;
+
+       do {
+               outb(I8254_PORT_CONTROL,
+                    I8254_CMD_READBACK | I8254_SELECT_COUNTER0);
+               status = inb(I8254_PORT_COUNTER0);
+               timer  = inb(I8254_PORT_COUNTER0);
+               timer |= inb(I8254_PORT_COUNTER0) << 8;
+       } while (status & I8254_STATUS_NOTREADY);
+
+       return timer;
+}
+
+static unsigned long rotate_xor(unsigned long hash, const void *area,
+                               size_t size)
+{
+       size_t i;
+       unsigned long *ptr = (unsigned long *)area;
+
+       for (i = 0; i < size / sizeof(hash); i++) {
+               /* Rotate by odd number of bits and XOR. */
+               hash = (hash << ((sizeof(hash) * 8) - 7)) | (hash >> 7);
+               hash ^= ptr[i];
+       }
+
+       return hash;
+}
+
+/* Attempt to create a simple but unpredictable starting entropy. */
+static unsigned long get_random_boot(void)
+{
+       unsigned long hash = 0;
+
+       hash = rotate_xor(hash, build_str, sizeof(build_str));
+       hash = rotate_xor(hash, real_mode, sizeof(*real_mode));
+
+       return hash;
+}
+
+static unsigned long get_random_long(void)
+{
+#ifdef CONFIG_X86_64
+       const unsigned long mix_const = 0x5d6008cbf3848dd3UL;
+#else
+       const unsigned long mix_const = 0x3f39e593UL;
+#endif
+       unsigned long raw, random = get_random_boot();
+       bool use_i8254 = true;
+
+       debug_putstr("KASLR using");
+
+       if (has_cpuflag(X86_FEATURE_RDRAND)) {
+               debug_putstr(" RDRAND");
+               if (rdrand_long(&raw)) {
+                       random ^= raw;
+                       use_i8254 = false;
+               }
+       }
+
+       if (has_cpuflag(X86_FEATURE_TSC)) {
+               debug_putstr(" RDTSC");
+               rdtscll(raw);
+
+               random ^= raw;
+               use_i8254 = false;
+       }
+
+       if (use_i8254) {
+               debug_putstr(" i8254");
+               random ^= i8254();
+       }
+
+       /* Circular multiply for better bit diffusion */
+       asm("mul %3"
+           : "=a" (random), "=d" (raw)
+           : "a" (random), "rm" (mix_const));
+       random += raw;
+
+       debug_putstr("...\n");
+
+       return random;
+}
+
+struct mem_vector {
+       unsigned long start;
+       unsigned long size;
+};
+
+#define MEM_AVOID_MAX 5
+struct mem_vector mem_avoid[MEM_AVOID_MAX];
+
+static bool mem_contains(struct mem_vector *region, struct mem_vector *item)
+{
+       /* Item at least partially before region. */
+       if (item->start < region->start)
+               return false;
+       /* Item at least partially after region. */
+       if (item->start + item->size > region->start + region->size)
+               return false;
+       return true;
+}
+
+static bool mem_overlaps(struct mem_vector *one, struct mem_vector *two)
+{
+       /* Item one is entirely before item two. */
+       if (one->start + one->size <= two->start)
+               return false;
+       /* Item one is entirely after item two. */
+       if (one->start >= two->start + two->size)
+               return false;
+       return true;
+}
+
+static void mem_avoid_init(unsigned long input, unsigned long input_size,
+                          unsigned long output, unsigned long output_size)
+{
+       u64 initrd_start, initrd_size;
+       u64 cmd_line, cmd_line_size;
+       unsigned long unsafe, unsafe_len;
+       char *ptr;
+
+       /*
+        * Avoid the region that is unsafe to overlap during
+        * decompression (see calculations at top of misc.c).
+        */
+       unsafe_len = (output_size >> 12) + 32768 + 18;
+       unsafe = (unsigned long)input + input_size - unsafe_len;
+       mem_avoid[0].start = unsafe;
+       mem_avoid[0].size = unsafe_len;
+
+       /* Avoid initrd. */
+       initrd_start  = (u64)real_mode->ext_ramdisk_image << 32;
+       initrd_start |= real_mode->hdr.ramdisk_image;
+       initrd_size  = (u64)real_mode->ext_ramdisk_size << 32;
+       initrd_size |= real_mode->hdr.ramdisk_size;
+       mem_avoid[1].start = initrd_start;
+       mem_avoid[1].size = initrd_size;
+
+       /* Avoid kernel command line. */
+       cmd_line  = (u64)real_mode->ext_cmd_line_ptr << 32;
+       cmd_line |= real_mode->hdr.cmd_line_ptr;
+       /* Calculate size of cmd_line. */
+       ptr = (char *)(unsigned long)cmd_line;
+       for (cmd_line_size = 0; ptr[cmd_line_size++]; )
+               ;
+       mem_avoid[2].start = cmd_line;
+       mem_avoid[2].size = cmd_line_size;
+
+       /* Avoid heap memory. */
+       mem_avoid[3].start = (unsigned long)free_mem_ptr;
+       mem_avoid[3].size = BOOT_HEAP_SIZE;
+
+       /* Avoid stack memory. */
+       mem_avoid[4].start = (unsigned long)free_mem_end_ptr;
+       mem_avoid[4].size = BOOT_STACK_SIZE;
+}
+
+/* Does this memory vector overlap a known avoided area? */
+bool mem_avoid_overlap(struct mem_vector *img)
+{
+       int i;
+
+       for (i = 0; i < MEM_AVOID_MAX; i++) {
+               if (mem_overlaps(img, &mem_avoid[i]))
+                       return true;
+       }
+
+       return false;
+}
+
+unsigned long slots[CONFIG_RANDOMIZE_BASE_MAX_OFFSET / CONFIG_PHYSICAL_ALIGN];
+unsigned long slot_max = 0;
+
+static void slots_append(unsigned long addr)
+{
+       /* Overflowing the slots list should be impossible. */
+       if (slot_max >= CONFIG_RANDOMIZE_BASE_MAX_OFFSET /
+                       CONFIG_PHYSICAL_ALIGN)
+               return;
+
+       slots[slot_max++] = addr;
+}
+
+static unsigned long slots_fetch_random(void)
+{
+       /* Handle case of no slots stored. */
+       if (slot_max == 0)
+               return 0;
+
+       return slots[get_random_long() % slot_max];
+}
+
+static void process_e820_entry(struct e820entry *entry,
+                              unsigned long minimum,
+                              unsigned long image_size)
+{
+       struct mem_vector region, img;
+
+       /* Skip non-RAM entries. */
+       if (entry->type != E820_RAM)
+               return;
+
+       /* Ignore entries entirely above our maximum. */
+       if (entry->addr >= CONFIG_RANDOMIZE_BASE_MAX_OFFSET)
+               return;
+
+       /* Ignore entries entirely below our minimum. */
+       if (entry->addr + entry->size < minimum)
+               return;
+
+       region.start = entry->addr;
+       region.size = entry->size;
+
+       /* Potentially raise address to minimum location. */
+       if (region.start < minimum)
+               region.start = minimum;
+
+       /* Potentially raise address to meet alignment requirements. */
+       region.start = ALIGN(region.start, CONFIG_PHYSICAL_ALIGN);
+
+       /* Did we raise the address above the bounds of this e820 region? */
+       if (region.start > entry->addr + entry->size)
+               return;
+
+       /* Reduce size by any delta from the original address. */
+       region.size -= region.start - entry->addr;
+
+       /* Reduce maximum size to fit end of image within maximum limit. */
+       if (region.start + region.size > CONFIG_RANDOMIZE_BASE_MAX_OFFSET)
+               region.size = CONFIG_RANDOMIZE_BASE_MAX_OFFSET - region.start;
+
+       /* Walk each aligned slot and check for avoided areas. */
+       for (img.start = region.start, img.size = image_size ;
+            mem_contains(&region, &img) ;
+            img.start += CONFIG_PHYSICAL_ALIGN) {
+               if (mem_avoid_overlap(&img))
+                       continue;
+               slots_append(img.start);
+       }
+}
+
+static unsigned long find_random_addr(unsigned long minimum,
+                                     unsigned long size)
+{
+       int i;
+       unsigned long addr;
+
+       /* Make sure minimum is aligned. */
+       minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN);
+
+       /* Verify potential e820 positions, appending to slots list. */
+       for (i = 0; i < real_mode->e820_entries; i++) {
+               process_e820_entry(&real_mode->e820_map[i], minimum, size);
+       }
+
+       return slots_fetch_random();
+}
+
+unsigned char *choose_kernel_location(unsigned char *input,
+                                     unsigned long input_size,
+                                     unsigned char *output,
+                                     unsigned long output_size)
+{
+       unsigned long choice = (unsigned long)output;
+       unsigned long random;
+
+       if (cmdline_find_option_bool("nokaslr")) {
+               debug_putstr("KASLR disabled...\n");
+               goto out;
+       }
+
+       /* Record the various known unsafe memory ranges. */
+       mem_avoid_init((unsigned long)input, input_size,
+                      (unsigned long)output, output_size);
+
+       /* Walk e820 and find a random address. */
+       random = find_random_addr(choice, output_size);
+       if (!random) {
+               debug_putstr("KASLR could not find suitable E820 region...\n");
+               goto out;
+       }
+
+       /* Always enforce the minimum. */
+       if (random < choice)
+               goto out;
+
+       choice = random;
+out:
+       return (unsigned char *)choice;
+}
+
+#endif /* CONFIG_RANDOMIZE_BASE */
index bffd73b45b1f27a4dc6cdd2ab6ee5451cd1bbd0d..b68e3033e6b9bd6fa76f89e3fbaa034823790ad7 100644 (file)
@@ -1,6 +1,6 @@
 #include "misc.h"
 
-#ifdef CONFIG_EARLY_PRINTK
+#if CONFIG_EARLY_PRINTK || CONFIG_RANDOMIZE_BASE
 
 static unsigned long fs;
 static inline void set_fs(unsigned long seg)
diff --git a/arch/x86/boot/compressed/cpuflags.c b/arch/x86/boot/compressed/cpuflags.c
new file mode 100644 (file)
index 0000000..aa31346
--- /dev/null
@@ -0,0 +1,12 @@
+#ifdef CONFIG_RANDOMIZE_BASE
+
+#include "../cpuflags.c"
+
+bool has_cpuflag(int flag)
+{
+       get_cpuflags();
+
+       return test_bit(flag, cpu.flags);
+}
+
+#endif
index 5d6f6891b1881ee812c060bc730915d73d4d7f65..9116aac232c746ae4f5262508fba437db9fbb431 100644 (file)
@@ -117,9 +117,11 @@ preferred_addr:
        addl    %eax, %ebx
        notl    %eax
        andl    %eax, %ebx
-#else
-       movl    $LOAD_PHYSICAL_ADDR, %ebx
+       cmpl    $LOAD_PHYSICAL_ADDR, %ebx
+       jge     1f
 #endif
+       movl    $LOAD_PHYSICAL_ADDR, %ebx
+1:
 
        /* Target address to relocate to for decompression */
        addl    $z_extract_offset, %ebx
@@ -191,14 +193,14 @@ relocated:
        leal    boot_heap(%ebx), %eax
        pushl   %eax            /* heap area */
        pushl   %esi            /* real mode pointer */
-       call    decompress_kernel
+       call    decompress_kernel /* returns kernel location in %eax */
        addl    $24, %esp
 
 /*
  * Jump to the decompressed kernel.
  */
        xorl    %ebx, %ebx
-       jmp     *%ebp
+       jmp     *%eax
 
 /*
  * Stack and heap for uncompression
index c337422b575de190280334ef5cd61214441644f9..c5c1ae0997e7b223128b009a220b899e22ffeb25 100644 (file)
@@ -94,9 +94,11 @@ ENTRY(startup_32)
        addl    %eax, %ebx
        notl    %eax
        andl    %eax, %ebx
-#else
-       movl    $LOAD_PHYSICAL_ADDR, %ebx
+       cmpl    $LOAD_PHYSICAL_ADDR, %ebx
+       jge     1f
 #endif
+       movl    $LOAD_PHYSICAL_ADDR, %ebx
+1:
 
        /* Target address to relocate to for decompression */
        addl    $z_extract_offset, %ebx
@@ -269,9 +271,11 @@ preferred_addr:
        addq    %rax, %rbp
        notq    %rax
        andq    %rax, %rbp
-#else
-       movq    $LOAD_PHYSICAL_ADDR, %rbp
+       cmpq    $LOAD_PHYSICAL_ADDR, %rbp
+       jge     1f
 #endif
+       movq    $LOAD_PHYSICAL_ADDR, %rbp
+1:
 
        /* Target address to relocate to for decompression */
        leaq    z_extract_offset(%rbp), %rbx
@@ -339,13 +343,13 @@ relocated:
        movl    $z_input_len, %ecx      /* input_len */
        movq    %rbp, %r8               /* output target address */
        movq    $z_output_len, %r9      /* decompressed length */
-       call    decompress_kernel
+       call    decompress_kernel       /* returns kernel location in %rax */
        popq    %rsi
 
 /*
  * Jump to the decompressed kernel.
  */
-       jmp     *%rbp
+       jmp     *%rax
 
        .code32
 no_longmode:
index 434f077d2c4d7b664216e6adaa22ac44ea51786a..196eaf373a06ad89c11bc9133a5c97b0e5ebc6d9 100644 (file)
@@ -112,14 +112,8 @@ struct boot_params *real_mode;             /* Pointer to real-mode data */
 void *memset(void *s, int c, size_t n);
 void *memcpy(void *dest, const void *src, size_t n);
 
-#ifdef CONFIG_X86_64
-#define memptr long
-#else
-#define memptr unsigned
-#endif
-
-static memptr free_mem_ptr;
-static memptr free_mem_end_ptr;
+memptr free_mem_ptr;
+memptr free_mem_end_ptr;
 
 static char *vidmem;
 static int vidport;
@@ -395,7 +389,7 @@ static void parse_elf(void *output)
        free(phdrs);
 }
 
-asmlinkage void decompress_kernel(void *rmode, memptr heap,
+asmlinkage void *decompress_kernel(void *rmode, memptr heap,
                                  unsigned char *input_data,
                                  unsigned long input_len,
                                  unsigned char *output,
@@ -422,6 +416,10 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
        free_mem_ptr     = heap;        /* Heap */
        free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
 
+       output = choose_kernel_location(input_data, input_len,
+                                       output, output_len);
+
+       /* Validate memory location choices. */
        if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1))
                error("Destination address inappropriately aligned");
 #ifdef CONFIG_X86_64
@@ -441,5 +439,5 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
        parse_elf(output);
        handle_relocations(output, output_len);
        debug_putstr("done.\nBooting the kernel.\n");
-       return;
+       return output;
 }
index 674019d8e2355901b69de5c55cfb92669c5628be..24e3e569a13ce9bf1ba620811ff4b09d6fa6e32d 100644 (file)
 #define BOOT_BOOT_H
 #include "../ctype.h"
 
+#ifdef CONFIG_X86_64
+#define memptr long
+#else
+#define memptr unsigned
+#endif
+
 /* misc.c */
+extern memptr free_mem_ptr;
+extern memptr free_mem_end_ptr;
 extern struct boot_params *real_mode;          /* Pointer to real-mode data */
 void __putstr(const char *s);
 #define error_putstr(__x)  __putstr(__x)
@@ -39,23 +47,40 @@ static inline void debug_putstr(const char *s)
 
 #endif
 
-#ifdef CONFIG_EARLY_PRINTK
-
+#if CONFIG_EARLY_PRINTK || CONFIG_RANDOMIZE_BASE
 /* cmdline.c */
 int cmdline_find_option(const char *option, char *buffer, int bufsize);
 int cmdline_find_option_bool(const char *option);
+#endif
 
-/* early_serial_console.c */
-extern int early_serial_base;
-void console_init(void);
 
+#if CONFIG_RANDOMIZE_BASE
+/* aslr.c */
+unsigned char *choose_kernel_location(unsigned char *input,
+                                     unsigned long input_size,
+                                     unsigned char *output,
+                                     unsigned long output_size);
+/* cpuflags.c */
+bool has_cpuflag(int flag);
 #else
+static inline
+unsigned char *choose_kernel_location(unsigned char *input,
+                                     unsigned long input_size,
+                                     unsigned char *output,
+                                     unsigned long output_size)
+{
+       return output;
+}
+#endif
 
+#ifdef CONFIG_EARLY_PRINTK
 /* early_serial_console.c */
+extern int early_serial_base;
+void console_init(void);
+#else
 static const int early_serial_base;
 static inline void console_init(void)
 { }
-
 #endif
 
 #endif
index 4d3ff037201ffbee0bb468e04d069b02909d094d..100a9a10076a649e7e7008a3579867391ca16fa4 100644 (file)
@@ -28,8 +28,6 @@
 #include <asm/required-features.h>
 #include <asm/msr-index.h>
 
-struct cpu_features cpu;
-static u32 cpu_vendor[3];
 static u32 err_flags[NCAPINTS];
 
 static const int req_level = CONFIG_X86_MINIMUM_CPU_FAMILY;
@@ -69,92 +67,8 @@ static int is_transmeta(void)
               cpu_vendor[2] == A32('M', 'x', '8', '6');
 }
 
-static int has_fpu(void)
-{
-       u16 fcw = -1, fsw = -1;
-       u32 cr0;
-
-       asm("movl %%cr0,%0" : "=r" (cr0));
-       if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
-               cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
-               asm volatile("movl %0,%%cr0" : : "r" (cr0));
-       }
-
-       asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
-                    : "+m" (fsw), "+m" (fcw));
-
-       return fsw == 0 && (fcw & 0x103f) == 0x003f;
-}
-
-static int has_eflag(u32 mask)
-{
-       u32 f0, f1;
-
-       asm("pushfl ; "
-           "pushfl ; "
-           "popl %0 ; "
-           "movl %0,%1 ; "
-           "xorl %2,%1 ; "
-           "pushl %1 ; "
-           "popfl ; "
-           "pushfl ; "
-           "popl %1 ; "
-           "popfl"
-           : "=&r" (f0), "=&r" (f1)
-           : "ri" (mask));
-
-       return !!((f0^f1) & mask);
-}
-
-static void get_flags(void)
-{
-       u32 max_intel_level, max_amd_level;
-       u32 tfms;
-
-       if (has_fpu())
-               set_bit(X86_FEATURE_FPU, cpu.flags);
-
-       if (has_eflag(X86_EFLAGS_ID)) {
-               asm("cpuid"
-                   : "=a" (max_intel_level),
-                     "=b" (cpu_vendor[0]),
-                     "=d" (cpu_vendor[1]),
-                     "=c" (cpu_vendor[2])
-                   : "a" (0));
-
-               if (max_intel_level >= 0x00000001 &&
-                   max_intel_level <= 0x0000ffff) {
-                       asm("cpuid"
-                           : "=a" (tfms),
-                             "=c" (cpu.flags[4]),
-                             "=d" (cpu.flags[0])
-                           : "a" (0x00000001)
-                           : "ebx");
-                       cpu.level = (tfms >> 8) & 15;
-                       cpu.model = (tfms >> 4) & 15;
-                       if (cpu.level >= 6)
-                               cpu.model += ((tfms >> 16) & 0xf) << 4;
-               }
-
-               asm("cpuid"
-                   : "=a" (max_amd_level)
-                   : "a" (0x80000000)
-                   : "ebx", "ecx", "edx");
-
-               if (max_amd_level >= 0x80000001 &&
-                   max_amd_level <= 0x8000ffff) {
-                       u32 eax = 0x80000001;
-                       asm("cpuid"
-                           : "+a" (eax),
-                             "=c" (cpu.flags[6]),
-                             "=d" (cpu.flags[1])
-                           : : "ebx");
-               }
-       }
-}
-
 /* Returns a bitmask of which words we have error bits in */
-static int check_flags(void)
+static int check_cpuflags(void)
 {
        u32 err;
        int i;
@@ -187,8 +101,8 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
        if (has_eflag(X86_EFLAGS_AC))
                cpu.level = 4;
 
-       get_flags();
-       err = check_flags();
+       get_cpuflags();
+       err = check_cpuflags();
 
        if (test_bit(X86_FEATURE_LM, cpu.flags))
                cpu.level = 64;
@@ -207,8 +121,8 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
                eax &= ~(1 << 15);
                asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
 
-               get_flags();    /* Make sure it really did something */
-               err = check_flags();
+               get_cpuflags(); /* Make sure it really did something */
+               err = check_cpuflags();
        } else if (err == 0x01 &&
                   !(err_flags[0] & ~(1 << X86_FEATURE_CX8)) &&
                   is_centaur() && cpu.model >= 6) {
@@ -223,7 +137,7 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
                asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
 
                set_bit(X86_FEATURE_CX8, cpu.flags);
-               err = check_flags();
+               err = check_cpuflags();
        } else if (err == 0x01 && is_transmeta()) {
                /* Transmeta might have masked feature bits in word 0 */
 
@@ -238,7 +152,7 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
                    : : "ecx", "ebx");
                asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
 
-               err = check_flags();
+               err = check_cpuflags();
        }
 
        if (err_flags_ptr)
diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c
new file mode 100644 (file)
index 0000000..a9fcb7c
--- /dev/null
@@ -0,0 +1,104 @@
+#include <linux/types.h>
+#include "bitops.h"
+
+#include <asm/processor-flags.h>
+#include <asm/required-features.h>
+#include <asm/msr-index.h>
+#include "cpuflags.h"
+
+struct cpu_features cpu;
+u32 cpu_vendor[3];
+
+static bool loaded_flags;
+
+static int has_fpu(void)
+{
+       u16 fcw = -1, fsw = -1;
+       unsigned long cr0;
+
+       asm volatile("mov %%cr0,%0" : "=r" (cr0));
+       if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
+               cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
+               asm volatile("mov %0,%%cr0" : : "r" (cr0));
+       }
+
+       asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
+                    : "+m" (fsw), "+m" (fcw));
+
+       return fsw == 0 && (fcw & 0x103f) == 0x003f;
+}
+
+int has_eflag(unsigned long mask)
+{
+       unsigned long f0, f1;
+
+       asm volatile("pushf     \n\t"
+                    "pushf     \n\t"
+                    "pop %0    \n\t"
+                    "mov %0,%1 \n\t"
+                    "xor %2,%1 \n\t"
+                    "push %1   \n\t"
+                    "popf      \n\t"
+                    "pushf     \n\t"
+                    "pop %1    \n\t"
+                    "popf"
+                    : "=&r" (f0), "=&r" (f1)
+                    : "ri" (mask));
+
+       return !!((f0^f1) & mask);
+}
+
+/* Handle x86_32 PIC using ebx. */
+#if defined(__i386__) && defined(__PIC__)
+# define EBX_REG "=r"
+#else
+# define EBX_REG "=b"
+#endif
+
+static inline void cpuid(u32 id, u32 *a, u32 *b, u32 *c, u32 *d)
+{
+       asm volatile(".ifnc %%ebx,%3 ; movl  %%ebx,%3 ; .endif  \n\t"
+                    "cpuid                                     \n\t"
+                    ".ifnc %%ebx,%3 ; xchgl %%ebx,%3 ; .endif  \n\t"
+                   : "=a" (*a), "=c" (*c), "=d" (*d), EBX_REG (*b)
+                   : "a" (id)
+       );
+}
+
+void get_cpuflags(void)
+{
+       u32 max_intel_level, max_amd_level;
+       u32 tfms;
+       u32 ignored;
+
+       if (loaded_flags)
+               return;
+       loaded_flags = true;
+
+       if (has_fpu())
+               set_bit(X86_FEATURE_FPU, cpu.flags);
+
+       if (has_eflag(X86_EFLAGS_ID)) {
+               cpuid(0x0, &max_intel_level, &cpu_vendor[0], &cpu_vendor[2],
+                     &cpu_vendor[1]);
+
+               if (max_intel_level >= 0x00000001 &&
+                   max_intel_level <= 0x0000ffff) {
+                       cpuid(0x1, &tfms, &ignored, &cpu.flags[4],
+                             &cpu.flags[0]);
+                       cpu.level = (tfms >> 8) & 15;
+                       cpu.model = (tfms >> 4) & 15;
+                       if (cpu.level >= 6)
+                               cpu.model += ((tfms >> 16) & 0xf) << 4;
+               }
+
+               cpuid(0x80000000, &max_amd_level, &ignored, &ignored,
+                     &ignored);
+
+               if (max_amd_level >= 0x80000001 &&
+                   max_amd_level <= 0x8000ffff) {
+                       cpuid(0x80000001, &ignored, &ignored, &cpu.flags[6],
+                             &cpu.flags[1]);
+               }
+       }
+}
diff --git a/arch/x86/boot/cpuflags.h b/arch/x86/boot/cpuflags.h
new file mode 100644 (file)
index 0000000..ea97697
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef BOOT_CPUFLAGS_H
+#define BOOT_CPUFLAGS_H
+
+#include <asm/cpufeature.h>
+#include <asm/processor-flags.h>
+
+struct cpu_features {
+       int level;              /* Family, or 64 for x86-64 */
+       int model;
+       u32 flags[NCAPINTS];
+};
+
+extern struct cpu_features cpu;
+extern u32 cpu_vendor[3];
+
+int has_eflag(unsigned long mask);
+void get_cpuflags(void);
+
+#endif
index 7d6ba9db1be99696784aeba62343eeebff9c32dd..e0fc24db234ac1263c96fdc18d0bf4f553647198 100644 (file)
@@ -3,8 +3,9 @@
 #
 
 avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no)
+avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
+                               $(comma)4)$(comma)%ymm2,yes,no)
 
-obj-$(CONFIG_CRYPTO_ABLK_HELPER_X86) += ablk_helper.o
 obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o
 
 obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
index f80e668785c0bf5f36383e5ab49495c24f93f843..835488b745eed5ce9484a40dfe56bf839f51d33d 100644 (file)
@@ -34,7 +34,7 @@
 #include <asm/cpu_device_id.h>
 #include <asm/i387.h>
 #include <asm/crypto/aes.h>
-#include <asm/crypto/ablk_helper.h>
+#include <crypto/ablk_helper.h>
 #include <crypto/scatterwalk.h>
 #include <crypto/internal/aead.h>
 #include <linux/workqueue.h>
index 414fe5d7946be077c25ba19160496c4bf910b1ab..4209a76fcdaad4225fb9c15fb954dfb5ad495c74 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <crypto/ctr.h>
 #include <crypto/lrw.h>
@@ -21,7 +22,6 @@
 #include <asm/xcr.h>
 #include <asm/xsave.h>
 #include <asm/crypto/camellia.h>
-#include <asm/crypto/ablk_helper.h>
 #include <asm/crypto/glue_helper.h>
 
 #define CAMELLIA_AESNI_PARALLEL_BLOCKS 16
index 37fd0c0a81ea8861f30a649b01cee8a6c11db4e5..87a041a10f4ac1fe7cceccc82eb24fcb03f92fa4 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <crypto/ctr.h>
 #include <crypto/lrw.h>
@@ -21,7 +22,6 @@
 #include <asm/xcr.h>
 #include <asm/xsave.h>
 #include <asm/crypto/camellia.h>
-#include <asm/crypto/ablk_helper.h>
 #include <asm/crypto/glue_helper.h>
 
 #define CAMELLIA_AESNI_PARALLEL_BLOCKS 16
index c6631813dc115c609e186044790aa5461cb6f0c7..e6a3700489b94119c514177f4a2a0b52e5423c13 100644 (file)
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <crypto/cast5.h>
 #include <crypto/cryptd.h>
 #include <crypto/ctr.h>
 #include <asm/xcr.h>
 #include <asm/xsave.h>
-#include <asm/crypto/ablk_helper.h>
 #include <asm/crypto/glue_helper.h>
 
 #define CAST5_PARALLEL_BLOCKS 16
index 8d0dfb86a5593554e0d536a48c28572ecc92c91d..09f3677393e4b888895c83bae05d114df0d5184c 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <crypto/cast6.h>
 #include <crypto/cryptd.h>
@@ -37,7 +38,6 @@
 #include <crypto/xts.h>
 #include <asm/xcr.h>
 #include <asm/xsave.h>
-#include <asm/crypto/ablk_helper.h>
 #include <asm/crypto/glue_helper.h>
 
 #define CAST6_PARALLEL_BLOCKS 8
index 23aabc6c20a5376fa81cf49ff9893ec76b6cdf05..2fae489b15246525991e6e606b8e01923e298263 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <crypto/ctr.h>
 #include <crypto/lrw.h>
@@ -22,7 +23,6 @@
 #include <asm/xcr.h>
 #include <asm/xsave.h>
 #include <asm/crypto/serpent-avx.h>
-#include <asm/crypto/ablk_helper.h>
 #include <asm/crypto/glue_helper.h>
 
 #define SERPENT_AVX2_PARALLEL_BLOCKS 16
index 9ae83cf8d21e987e2e3bf9656a51ecaf61644427..ff487087097254f8368d035db08d02472dc9b76e 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <crypto/serpent.h>
 #include <crypto/cryptd.h>
@@ -38,7 +39,6 @@
 #include <asm/xcr.h>
 #include <asm/xsave.h>
 #include <asm/crypto/serpent-avx.h>
-#include <asm/crypto/ablk_helper.h>
 #include <asm/crypto/glue_helper.h>
 
 /* 8-way parallel cipher functions */
index 97a356ece24d2b74d18090760e988c45d2bc914a..8c95f86373061680f4d8f4418d4da77f9123c111 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <crypto/serpent.h>
 #include <crypto/cryptd.h>
@@ -42,7 +43,6 @@
 #include <crypto/lrw.h>
 #include <crypto/xts.h>
 #include <asm/crypto/serpent-sse2.h>
-#include <asm/crypto/ablk_helper.h>
 #include <asm/crypto/glue_helper.h>
 
 static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src)
index 50226c4b86ed338da70cb285a53e1e86d210d5f4..f248546da1caa956014dfd9648814ad37f2ca8d3 100644 (file)
@@ -281,7 +281,7 @@ static int __init sha256_ssse3_mod_init(void)
        /* allow AVX to override SSSE3, it's a little faster */
        if (avx_usable()) {
 #ifdef CONFIG_AS_AVX2
-               if (boot_cpu_has(X86_FEATURE_AVX2))
+               if (boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_BMI2))
                        sha256_transform_asm = sha256_transform_rorx;
                else
 #endif
@@ -319,4 +319,4 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm, Supplemental SSE3 accelerated");
 
 MODULE_ALIAS("sha256");
-MODULE_ALIAS("sha384");
+MODULE_ALIAS("sha224");
index a62ba541884ef1a15da1082d9d2ca48296c563ec..4e3c665be1296f16cedde6f402249316b75bc4ed 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <crypto/twofish.h>
 #include <crypto/cryptd.h>
@@ -39,7 +40,6 @@
 #include <asm/xcr.h>
 #include <asm/xsave.h>
 #include <asm/crypto/twofish.h>
-#include <asm/crypto/ablk_helper.h>
 #include <asm/crypto/glue_helper.h>
 #include <crypto/scatterwalk.h>
 #include <linux/workqueue.h>
index 0d9ec770f2f8770f8e5a320300ea47f3bf39b9bb..e6a92455740e6a5dfc64c5b1a1193a693594feab 100644 (file)
 
 #ifdef CONFIG_ARCH_RANDOM
 
+/* Instead of arch_get_random_long() when alternatives haven't run. */
+static inline int rdrand_long(unsigned long *v)
+{
+       int ok;
+       asm volatile("1: " RDRAND_LONG "\n\t"
+                    "jc 2f\n\t"
+                    "decl %0\n\t"
+                    "jnz 1b\n\t"
+                    "2:"
+                    : "=r" (ok), "=a" (*v)
+                    : "0" (RDRAND_RETRY_LOOPS));
+       return ok;
+}
+
 #define GET_RANDOM(name, type, rdrand, nop)                    \
 static inline int name(type *v)                                        \
 {                                                              \
@@ -68,6 +82,13 @@ GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP3);
 
 #endif /* CONFIG_X86_64 */
 
+#else
+
+static inline int rdrand_long(unsigned long *v)
+{
+       return 0;
+}
+
 #endif  /* CONFIG_ARCH_RANDOM */
 
 extern void x86_init_rdrand(struct cpuinfo_x86 *c);
index 65c6e6e3a5521bc73e843a5459b63ec99e02d689..89a05b0507b98dbbb2ed83169c59058f044704a7 100644 (file)
@@ -1,6 +1,24 @@
 #ifndef _ASM_X86_EFI_H
 #define _ASM_X86_EFI_H
 
+/*
+ * We map the EFI regions needed for runtime services non-contiguously,
+ * with preserved alignment on virtual addresses starting from -4G down
+ * for a total max space of 64G. This way, we provide for stable runtime
+ * services addresses across kernels so that a kexec'd kernel can still
+ * use them.
+ *
+ * This is the main reason why we're doing stable VA mappings for RT
+ * services.
+ *
+ * This flag is used in conjuction with a chicken bit called
+ * "efi=old_map" which can be used as a fallback to the old runtime
+ * services mapping method in case there's some b0rkage with a
+ * particular EFI implementation (haha, it is hard to hold up the
+ * sarcasm here...).
+ */
+#define EFI_OLD_MEMMAP         EFI_ARCH_1
+
 #ifdef CONFIG_X86_32
 
 #define EFI_LOADER_SIGNATURE   "EL32"
@@ -69,24 +87,31 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
        efi_call6((f), (u64)(a1), (u64)(a2), (u64)(a3),         \
                  (u64)(a4), (u64)(a5), (u64)(a6))
 
+#define _efi_call_virtX(x, f, ...)                                     \
+({                                                                     \
+       efi_status_t __s;                                               \
+                                                                       \
+       efi_sync_low_kernel_mappings();                                 \
+       preempt_disable();                                              \
+       __s = efi_call##x((void *)efi.systab->runtime->f, __VA_ARGS__); \
+       preempt_enable();                                               \
+       __s;                                                            \
+})
+
 #define efi_call_virt0(f)                              \
-       efi_call0((efi.systab->runtime->f))
-#define efi_call_virt1(f, a1)                                  \
-       efi_call1((efi.systab->runtime->f), (u64)(a1))
-#define efi_call_virt2(f, a1, a2)                                      \
-       efi_call2((efi.systab->runtime->f), (u64)(a1), (u64)(a2))
-#define efi_call_virt3(f, a1, a2, a3)                                  \
-       efi_call3((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
-                 (u64)(a3))
-#define efi_call_virt4(f, a1, a2, a3, a4)                              \
-       efi_call4((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
-                 (u64)(a3), (u64)(a4))
-#define efi_call_virt5(f, a1, a2, a3, a4, a5)                          \
-       efi_call5((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
-                 (u64)(a3), (u64)(a4), (u64)(a5))
-#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6)                      \
-       efi_call6((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
-                 (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
+       _efi_call_virtX(0, f)
+#define efi_call_virt1(f, a1)                          \
+       _efi_call_virtX(1, f, (u64)(a1))
+#define efi_call_virt2(f, a1, a2)                      \
+       _efi_call_virtX(2, f, (u64)(a1), (u64)(a2))
+#define efi_call_virt3(f, a1, a2, a3)                  \
+       _efi_call_virtX(3, f, (u64)(a1), (u64)(a2), (u64)(a3))
+#define efi_call_virt4(f, a1, a2, a3, a4)              \
+       _efi_call_virtX(4, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4))
+#define efi_call_virt5(f, a1, a2, a3, a4, a5)          \
+       _efi_call_virtX(5, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4), (u64)(a5))
+#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6)      \
+       _efi_call_virtX(6, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
 
 extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
                                 u32 type, u64 attribute);
@@ -95,12 +120,17 @@ extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
 
 extern int add_efi_memmap;
 extern unsigned long x86_efi_facility;
+extern struct efi_scratch efi_scratch;
 extern void efi_set_executable(efi_memory_desc_t *md, bool executable);
 extern int efi_memblock_x86_reserve_range(void);
 extern void efi_call_phys_prelog(void);
 extern void efi_call_phys_epilog(void);
 extern void efi_unmap_memmap(void);
 extern void efi_memory_uc(u64 addr, unsigned long size);
+extern void __init efi_map_region(efi_memory_desc_t *md);
+extern void efi_sync_low_kernel_mappings(void);
+extern void efi_setup_page_tables(void);
+extern void __init old_map_region(efi_memory_desc_t *md);
 
 #ifdef CONFIG_EFI
 
index c87892442e53d4081f4ff1276524e0298cf73617..775873d3be55617a49e15c3460ae22a94dabad75 100644 (file)
@@ -71,6 +71,7 @@ extern bool __virt_addr_valid(unsigned long kaddr);
 #include <asm-generic/getorder.h>
 
 #define __HAVE_ARCH_GATE_AREA 1
+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_X86_PAGE_H */
index 4d550d04b6099bf444e8291ffdfde9538a4e47df..904f528cc8e82ae638e25a2bdeec23fed332eb7a 100644 (file)
@@ -5,10 +5,6 @@
 
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_HUGETLB_PAGE
-#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-#endif
-
 #define __phys_addr_nodebug(x) ((x) - PAGE_OFFSET)
 #ifdef CONFIG_DEBUG_VIRTUAL
 extern unsigned long __phys_addr(unsigned long);
index 43dcd804ebd5732aea40415e6f4a419e363701c9..8de6d9cf3b954a7f31bcb756c92c20cc08db5759 100644 (file)
 #define __VIRTUAL_MASK_SHIFT   47
 
 /*
- * Kernel image size is limited to 512 MB (see level2_kernel_pgt in
- * arch/x86/kernel/head_64.S), and it is mapped here:
+ * Kernel image size is limited to 1GiB due to the fixmap living in the
+ * next 1GiB (see level2_kernel_pgt in arch/x86/kernel/head_64.S). Use
+ * 512MiB by default, leaving 1.5GiB for modules once the page tables
+ * are fully set up. If kernel ASLR is configured, it can extend the
+ * kernel page table mapping, reducing the size of the modules area.
  */
-#define KERNEL_IMAGE_SIZE      (512 * 1024 * 1024)
+#define KERNEL_IMAGE_SIZE_DEFAULT      (512 * 1024 * 1024)
+#if defined(CONFIG_RANDOMIZE_BASE) && \
+       CONFIG_RANDOMIZE_BASE_MAX_OFFSET > KERNEL_IMAGE_SIZE_DEFAULT
+#define KERNEL_IMAGE_SIZE   CONFIG_RANDOMIZE_BASE_MAX_OFFSET
+#else
+#define KERNEL_IMAGE_SIZE      KERNEL_IMAGE_SIZE_DEFAULT
+#endif
 
 #endif /* _ASM_X86_PAGE_64_DEFS_H */
index 3bf2dd0cf61fec9615253fe3b70d3c3764a35e93..0d193e23464707e3d56111e2d429664104a3649f 100644 (file)
@@ -55,6 +55,13 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
 #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp)
 #endif
 
+/* Bit manipulation helper on pte/pgoff entry */
+static inline unsigned long pte_bitop(unsigned long value, unsigned int rightshift,
+                                     unsigned long mask, unsigned int leftshift)
+{
+       return ((value >> rightshift) & mask) << leftshift;
+}
+
 #ifdef CONFIG_MEM_SOFT_DIRTY
 
 /*
@@ -71,31 +78,34 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
 #define PTE_FILE_BITS2         (PTE_FILE_SHIFT3 - PTE_FILE_SHIFT2 - 1)
 #define PTE_FILE_BITS3         (PTE_FILE_SHIFT4 - PTE_FILE_SHIFT3 - 1)
 
-#define pte_to_pgoff(pte)                                              \
-       ((((pte).pte_low >> (PTE_FILE_SHIFT1))                          \
-         & ((1U << PTE_FILE_BITS1) - 1)))                              \
-       + ((((pte).pte_low >> (PTE_FILE_SHIFT2))                        \
-           & ((1U << PTE_FILE_BITS2) - 1))                             \
-          << (PTE_FILE_BITS1))                                         \
-       + ((((pte).pte_low >> (PTE_FILE_SHIFT3))                        \
-           & ((1U << PTE_FILE_BITS3) - 1))                             \
-          << (PTE_FILE_BITS1 + PTE_FILE_BITS2))                        \
-       + ((((pte).pte_low >> (PTE_FILE_SHIFT4)))                       \
-           << (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3))
-
-#define pgoff_to_pte(off)                                              \
-       ((pte_t) { .pte_low =                                           \
-        ((((off)) & ((1U << PTE_FILE_BITS1) - 1)) << PTE_FILE_SHIFT1)  \
-        + ((((off) >> PTE_FILE_BITS1)                                  \
-            & ((1U << PTE_FILE_BITS2) - 1))                            \
-           << PTE_FILE_SHIFT2)                                         \
-        + ((((off) >> (PTE_FILE_BITS1 + PTE_FILE_BITS2))               \
-            & ((1U << PTE_FILE_BITS3) - 1))                            \
-           << PTE_FILE_SHIFT3)                                         \
-        + ((((off) >>                                                  \
-             (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)))      \
-           << PTE_FILE_SHIFT4)                                         \
-        + _PAGE_FILE })
+#define PTE_FILE_MASK1         ((1U << PTE_FILE_BITS1) - 1)
+#define PTE_FILE_MASK2         ((1U << PTE_FILE_BITS2) - 1)
+#define PTE_FILE_MASK3         ((1U << PTE_FILE_BITS3) - 1)
+
+#define PTE_FILE_LSHIFT2       (PTE_FILE_BITS1)
+#define PTE_FILE_LSHIFT3       (PTE_FILE_BITS1 + PTE_FILE_BITS2)
+#define PTE_FILE_LSHIFT4       (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)
+
+static __always_inline pgoff_t pte_to_pgoff(pte_t pte)
+{
+       return (pgoff_t)
+               (pte_bitop(pte.pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1,  0)                +
+                pte_bitop(pte.pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2,  PTE_FILE_LSHIFT2) +
+                pte_bitop(pte.pte_low, PTE_FILE_SHIFT3, PTE_FILE_MASK3,  PTE_FILE_LSHIFT3) +
+                pte_bitop(pte.pte_low, PTE_FILE_SHIFT4,           -1UL,  PTE_FILE_LSHIFT4));
+}
+
+static __always_inline pte_t pgoff_to_pte(pgoff_t off)
+{
+       return (pte_t){
+               .pte_low =
+                       pte_bitop(off,                0, PTE_FILE_MASK1,  PTE_FILE_SHIFT1) +
+                       pte_bitop(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2,  PTE_FILE_SHIFT2) +
+                       pte_bitop(off, PTE_FILE_LSHIFT3, PTE_FILE_MASK3,  PTE_FILE_SHIFT3) +
+                       pte_bitop(off, PTE_FILE_LSHIFT4,           -1UL,  PTE_FILE_SHIFT4) +
+                       _PAGE_FILE,
+       };
+}
 
 #else /* CONFIG_MEM_SOFT_DIRTY */
 
@@ -115,22 +125,30 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
 #define PTE_FILE_BITS1         (PTE_FILE_SHIFT2 - PTE_FILE_SHIFT1 - 1)
 #define PTE_FILE_BITS2         (PTE_FILE_SHIFT3 - PTE_FILE_SHIFT2 - 1)
 
-#define pte_to_pgoff(pte)                                              \
-       ((((pte).pte_low >> PTE_FILE_SHIFT1)                            \
-         & ((1U << PTE_FILE_BITS1) - 1))                               \
-        + ((((pte).pte_low >> PTE_FILE_SHIFT2)                         \
-            & ((1U << PTE_FILE_BITS2) - 1)) << PTE_FILE_BITS1)         \
-        + (((pte).pte_low >> PTE_FILE_SHIFT3)                          \
-           << (PTE_FILE_BITS1 + PTE_FILE_BITS2)))
-
-#define pgoff_to_pte(off)                                              \
-       ((pte_t) { .pte_low =                                           \
-        (((off) & ((1U << PTE_FILE_BITS1) - 1)) << PTE_FILE_SHIFT1)    \
-        + ((((off) >> PTE_FILE_BITS1) & ((1U << PTE_FILE_BITS2) - 1))  \
-           << PTE_FILE_SHIFT2)                                         \
-        + (((off) >> (PTE_FILE_BITS1 + PTE_FILE_BITS2))                \
-           << PTE_FILE_SHIFT3)                                         \
-        + _PAGE_FILE })
+#define PTE_FILE_MASK1         ((1U << PTE_FILE_BITS1) - 1)
+#define PTE_FILE_MASK2         ((1U << PTE_FILE_BITS2) - 1)
+
+#define PTE_FILE_LSHIFT2       (PTE_FILE_BITS1)
+#define PTE_FILE_LSHIFT3       (PTE_FILE_BITS1 + PTE_FILE_BITS2)
+
+static __always_inline pgoff_t pte_to_pgoff(pte_t pte)
+{
+       return (pgoff_t)
+               (pte_bitop(pte.pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1,  0)                +
+                pte_bitop(pte.pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2,  PTE_FILE_LSHIFT2) +
+                pte_bitop(pte.pte_low, PTE_FILE_SHIFT3,           -1UL,  PTE_FILE_LSHIFT3));
+}
+
+static __always_inline pte_t pgoff_to_pte(pgoff_t off)
+{
+       return (pte_t){
+               .pte_low =
+                       pte_bitop(off,                0, PTE_FILE_MASK1,  PTE_FILE_SHIFT1) +
+                       pte_bitop(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2,  PTE_FILE_SHIFT2) +
+                       pte_bitop(off, PTE_FILE_LSHIFT3,           -1UL,  PTE_FILE_SHIFT3) +
+                       _PAGE_FILE,
+       };
+}
 
 #endif /* CONFIG_MEM_SOFT_DIRTY */
 
index 2d883440cb9a282f948d7062684c52789e95d90f..c883bf726398a2556d50b984736ad068bc0dd44c 100644 (file)
@@ -58,7 +58,7 @@ typedef struct { pteval_t pte; } pte_t;
 #define VMALLOC_START    _AC(0xffffc90000000000, UL)
 #define VMALLOC_END      _AC(0xffffe8ffffffffff, UL)
 #define VMEMMAP_START   _AC(0xffffea0000000000, UL)
-#define MODULES_VADDR    _AC(0xffffffffa0000000, UL)
+#define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
 #define MODULES_END      _AC(0xffffffffff000000, UL)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 
index 0ecac257fb26cffd2bb9a6ece7b7a5976eca3c84..a83aa44bb1fb831cac7cda82a590c05ea0e47235 100644 (file)
@@ -382,7 +382,8 @@ static inline void update_page_count(int level, unsigned long pages) { }
  */
 extern pte_t *lookup_address(unsigned long address, unsigned int *level);
 extern phys_addr_t slow_virt_to_phys(void *__address);
-
+extern int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
+                                  unsigned numpages, unsigned long page_flags);
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_X86_PGTABLE_DEFS_H */
diff --git a/arch/x86/include/asm/simd.h b/arch/x86/include/asm/simd.h
new file mode 100644 (file)
index 0000000..ee80b92
--- /dev/null
@@ -0,0 +1,11 @@
+
+#include <asm/i387.h>
+
+/*
+ * may_use_simd - whether it is allowable at this time to issue SIMD
+ *                instructions or access the SIMD register file
+ */
+static __must_check inline bool may_use_simd(void)
+{
+       return irq_fpu_usable();
+}
index 2874df24e7a448cd56631d87f5ac9e0fdd00cbc7..4cab890007a7267ecc7ce148eaa1fdfbee4a49df 100644 (file)
@@ -71,6 +71,17 @@ DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi);
  */
 DEFINE_IRQ_VECTOR_EVENT(irq_work);
 
+/*
+ * We must dis-allow sampling irq_work_exit() because perf event sampling
+ * itself can cause irq_work, which would lead to an infinite loop;
+ *
+ *  1) irq_work_exit happens
+ *  2) generates perf sample
+ *  3) generates irq_work
+ *  4) goto 1
+ */
+TRACE_EVENT_PERF_PERM(irq_work_exit, is_sampling_event(p_event) ? -EPERM : 0);
+
 /*
  * call_function - called when entering/exiting a call function interrupt
  * vector handler
index 00c77cf78e9e1839973923076053fdf92d75a54e..ccbf857d1d558461eb59139784faa2d0f43cabc9 100644 (file)
@@ -21,9 +21,7 @@
 #include <asm/apic.h>
 #include <asm/ipi.h>
 
-#ifdef CONFIG_ACPI
-#include <acpi/acpi_bus.h>
-#endif
+#include <linux/acpi.h>
 
 static struct apic apic_physflat;
 static struct apic apic_flat;
index e63a5bd2a78f55de2c356b665751558a73bc18da..4d67a7531d4558c6016c9a6e1f16dc07b97205c2 100644 (file)
@@ -37,9 +37,6 @@
 #include <linux/kthread.h>
 #include <linux/jiffies.h>     /* time_after() */
 #include <linux/slab.h>
-#ifdef CONFIG_ACPI
-#include <acpi/acpi_bus.h>
-#endif
 #include <linux/bootmem.h>
 #include <linux/dmar.h>
 #include <linux/hpet.h>
index 47b56a7e99cbcf2e4387fd087cddbfb1c35060bc..6359506a19ee6bbc22ca634b42e0ecec689c86c3 100644 (file)
@@ -36,7 +36,7 @@ obj-$(CONFIG_CPU_SUP_AMD)             += perf_event_amd_iommu.o
 endif
 obj-$(CONFIG_CPU_SUP_INTEL)            += perf_event_p6.o perf_event_knc.o perf_event_p4.o
 obj-$(CONFIG_CPU_SUP_INTEL)            += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
-obj-$(CONFIG_CPU_SUP_INTEL)            += perf_event_intel_uncore.o
+obj-$(CONFIG_CPU_SUP_INTEL)            += perf_event_intel_uncore.o perf_event_intel_rapl.o
 endif
 
 
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c
new file mode 100644 (file)
index 0000000..bf8e4a7
--- /dev/null
@@ -0,0 +1,661 @@
+/*
+ * perf_event_intel_rapl.c: support Intel RAPL energy consumption counters
+ * Copyright (C) 2013 Google, Inc., Stephane Eranian
+ *
+ * Intel RAPL interface is specified in the IA-32 Manual Vol3b
+ * section 14.7.1 (September 2013)
+ *
+ * RAPL provides more controls than just reporting energy consumption
+ * however here we only expose the 3 energy consumption free running
+ * counters (pp0, pkg, dram).
+ *
+ * Each of those counters increments in a power unit defined by the
+ * RAPL_POWER_UNIT MSR. On SandyBridge, this unit is 1/(2^16) Joules
+ * but it can vary.
+ *
+ * Counter to rapl events mappings:
+ *
+ *  pp0 counter: consumption of all physical cores (power plane 0)
+ *       event: rapl_energy_cores
+ *    perf code: 0x1
+ *
+ *  pkg counter: consumption of the whole processor package
+ *       event: rapl_energy_pkg
+ *    perf code: 0x2
+ *
+ * dram counter: consumption of the dram domain (servers only)
+ *       event: rapl_energy_dram
+ *    perf code: 0x3
+ *
+ * We manage those counters as free running (read-only). They may be
+ * use simultaneously by other tools, such as turbostat.
+ *
+ * The events only support system-wide mode counting. There is no
+ * sampling support because it does not make sense and is not
+ * supported by the RAPL hardware.
+ *
+ * Because we want to avoid floating-point operations in the kernel,
+ * the events are all reported in fixed point arithmetic (32.32).
+ * Tools must adjust the counts to convert them to Watts using
+ * the duration of the measurement. Tools may use a function such as
+ * ldexp(raw_count, -32);
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/perf_event.h>
+#include <asm/cpu_device_id.h>
+#include "perf_event.h"
+
+/*
+ * RAPL energy status counters
+ */
+#define RAPL_IDX_PP0_NRG_STAT  0       /* all cores */
+#define INTEL_RAPL_PP0         0x1     /* pseudo-encoding */
+#define RAPL_IDX_PKG_NRG_STAT  1       /* entire package */
+#define INTEL_RAPL_PKG         0x2     /* pseudo-encoding */
+#define RAPL_IDX_RAM_NRG_STAT  2       /* DRAM */
+#define INTEL_RAPL_RAM         0x3     /* pseudo-encoding */
+
+/* Clients have PP0, PKG */
+#define RAPL_IDX_CLN   (1<<RAPL_IDX_PP0_NRG_STAT|\
+                        1<<RAPL_IDX_PKG_NRG_STAT)
+
+/* Servers have PP0, PKG, RAM */
+#define RAPL_IDX_SRV   (1<<RAPL_IDX_PP0_NRG_STAT|\
+                        1<<RAPL_IDX_PKG_NRG_STAT|\
+                        1<<RAPL_IDX_RAM_NRG_STAT)
+
+/*
+ * event code: LSB 8 bits, passed in attr->config
+ * any other bit is reserved
+ */
+#define RAPL_EVENT_MASK        0xFFULL
+
+#define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format)          \
+static ssize_t __rapl_##_var##_show(struct kobject *kobj,      \
+                               struct kobj_attribute *attr,    \
+                               char *page)                     \
+{                                                              \
+       BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE);             \
+       return sprintf(page, _format "\n");                     \
+}                                                              \
+static struct kobj_attribute format_attr_##_var =              \
+       __ATTR(_name, 0444, __rapl_##_var##_show, NULL)
+
+#define RAPL_EVENT_DESC(_name, _config)                                \
+{                                                              \
+       .attr   = __ATTR(_name, 0444, rapl_event_show, NULL),   \
+       .config = _config,                                      \
+}
+
+#define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */
+
+struct rapl_pmu {
+       spinlock_t       lock;
+       int              hw_unit;  /* 1/2^hw_unit Joule */
+       int              n_active; /* number of active events */
+       struct list_head active_list;
+       struct pmu       *pmu; /* pointer to rapl_pmu_class */
+       ktime_t          timer_interval; /* in ktime_t unit */
+       struct hrtimer   hrtimer;
+};
+
+static struct pmu rapl_pmu_class;
+static cpumask_t rapl_cpu_mask;
+static int rapl_cntr_mask;
+
+static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu);
+static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu_to_free);
+
+static inline u64 rapl_read_counter(struct perf_event *event)
+{
+       u64 raw;
+       rdmsrl(event->hw.event_base, raw);
+       return raw;
+}
+
+static inline u64 rapl_scale(u64 v)
+{
+       /*
+        * scale delta to smallest unit (1/2^32)
+        * users must then scale back: count * 1/(1e9*2^32) to get Joules
+        * or use ldexp(count, -32).
+        * Watts = Joules/Time delta
+        */
+       return v << (32 - __get_cpu_var(rapl_pmu)->hw_unit);
+}
+
+static u64 rapl_event_update(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       u64 prev_raw_count, new_raw_count;
+       s64 delta, sdelta;
+       int shift = RAPL_CNTR_WIDTH;
+
+again:
+       prev_raw_count = local64_read(&hwc->prev_count);
+       rdmsrl(event->hw.event_base, new_raw_count);
+
+       if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+                           new_raw_count) != prev_raw_count) {
+               cpu_relax();
+               goto again;
+       }
+
+       /*
+        * Now we have the new raw value and have updated the prev
+        * timestamp already. We can now calculate the elapsed delta
+        * (event-)time and add that to the generic event.
+        *
+        * Careful, not all hw sign-extends above the physical width
+        * of the count.
+        */
+       delta = (new_raw_count << shift) - (prev_raw_count << shift);
+       delta >>= shift;
+
+       sdelta = rapl_scale(delta);
+
+       local64_add(sdelta, &event->count);
+
+       return new_raw_count;
+}
+
+static void rapl_start_hrtimer(struct rapl_pmu *pmu)
+{
+       __hrtimer_start_range_ns(&pmu->hrtimer,
+                       pmu->timer_interval, 0,
+                       HRTIMER_MODE_REL_PINNED, 0);
+}
+
+static void rapl_stop_hrtimer(struct rapl_pmu *pmu)
+{
+       hrtimer_cancel(&pmu->hrtimer);
+}
+
+static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer)
+{
+       struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu);
+       struct perf_event *event;
+       unsigned long flags;
+
+       if (!pmu->n_active)
+               return HRTIMER_NORESTART;
+
+       spin_lock_irqsave(&pmu->lock, flags);
+
+       list_for_each_entry(event, &pmu->active_list, active_entry) {
+               rapl_event_update(event);
+       }
+
+       spin_unlock_irqrestore(&pmu->lock, flags);
+
+       hrtimer_forward_now(hrtimer, pmu->timer_interval);
+
+       return HRTIMER_RESTART;
+}
+
+static void rapl_hrtimer_init(struct rapl_pmu *pmu)
+{
+       struct hrtimer *hr = &pmu->hrtimer;
+
+       hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       hr->function = rapl_hrtimer_handle;
+}
+
+static void __rapl_pmu_event_start(struct rapl_pmu *pmu,
+                                  struct perf_event *event)
+{
+       if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+               return;
+
+       event->hw.state = 0;
+
+       list_add_tail(&event->active_entry, &pmu->active_list);
+
+       local64_set(&event->hw.prev_count, rapl_read_counter(event));
+
+       pmu->n_active++;
+       if (pmu->n_active == 1)
+               rapl_start_hrtimer(pmu);
+}
+
+static void rapl_pmu_event_start(struct perf_event *event, int mode)
+{
+       struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu);
+       unsigned long flags;
+
+       spin_lock_irqsave(&pmu->lock, flags);
+       __rapl_pmu_event_start(pmu, event);
+       spin_unlock_irqrestore(&pmu->lock, flags);
+}
+
+static void rapl_pmu_event_stop(struct perf_event *event, int mode)
+{
+       struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu);
+       struct hw_perf_event *hwc = &event->hw;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pmu->lock, flags);
+
+       /* mark event as deactivated and stopped */
+       if (!(hwc->state & PERF_HES_STOPPED)) {
+               WARN_ON_ONCE(pmu->n_active <= 0);
+               pmu->n_active--;
+               if (pmu->n_active == 0)
+                       rapl_stop_hrtimer(pmu);
+
+               list_del(&event->active_entry);
+
+               WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+               hwc->state |= PERF_HES_STOPPED;
+       }
+
+       /* check if update of sw counter is necessary */
+       if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+               /*
+                * Drain the remaining delta count out of a event
+                * that we are disabling:
+                */
+               rapl_event_update(event);
+               hwc->state |= PERF_HES_UPTODATE;
+       }
+
+       spin_unlock_irqrestore(&pmu->lock, flags);
+}
+
+static int rapl_pmu_event_add(struct perf_event *event, int mode)
+{
+       struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu);
+       struct hw_perf_event *hwc = &event->hw;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pmu->lock, flags);
+
+       hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+       if (mode & PERF_EF_START)
+               __rapl_pmu_event_start(pmu, event);
+
+       spin_unlock_irqrestore(&pmu->lock, flags);
+
+       return 0;
+}
+
+static void rapl_pmu_event_del(struct perf_event *event, int flags)
+{
+       rapl_pmu_event_stop(event, PERF_EF_UPDATE);
+}
+
+static int rapl_pmu_event_init(struct perf_event *event)
+{
+       u64 cfg = event->attr.config & RAPL_EVENT_MASK;
+       int bit, msr, ret = 0;
+
+       /* only look at RAPL events */
+       if (event->attr.type != rapl_pmu_class.type)
+               return -ENOENT;
+
+       /* check only supported bits are set */
+       if (event->attr.config & ~RAPL_EVENT_MASK)
+               return -EINVAL;
+
+       /*
+        * check event is known (determines counter)
+        */
+       switch (cfg) {
+       case INTEL_RAPL_PP0:
+               bit = RAPL_IDX_PP0_NRG_STAT;
+               msr = MSR_PP0_ENERGY_STATUS;
+               break;
+       case INTEL_RAPL_PKG:
+               bit = RAPL_IDX_PKG_NRG_STAT;
+               msr = MSR_PKG_ENERGY_STATUS;
+               break;
+       case INTEL_RAPL_RAM:
+               bit = RAPL_IDX_RAM_NRG_STAT;
+               msr = MSR_DRAM_ENERGY_STATUS;
+               break;
+       default:
+               return -EINVAL;
+       }
+       /* check event supported */
+       if (!(rapl_cntr_mask & (1 << bit)))
+               return -EINVAL;
+
+       /* unsupported modes and filters */
+       if (event->attr.exclude_user   ||
+           event->attr.exclude_kernel ||
+           event->attr.exclude_hv     ||
+           event->attr.exclude_idle   ||
+           event->attr.exclude_host   ||
+           event->attr.exclude_guest  ||
+           event->attr.sample_period) /* no sampling */
+               return -EINVAL;
+
+       /* must be done before validate_group */
+       event->hw.event_base = msr;
+       event->hw.config = cfg;
+       event->hw.idx = bit;
+
+       return ret;
+}
+
+static void rapl_pmu_event_read(struct perf_event *event)
+{
+       rapl_event_update(event);
+}
+
+static ssize_t rapl_get_attr_cpumask(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &rapl_cpu_mask);
+
+       buf[n++] = '\n';
+       buf[n] = '\0';
+       return n;
+}
+
+static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL);
+
+static struct attribute *rapl_pmu_attrs[] = {
+       &dev_attr_cpumask.attr,
+       NULL,
+};
+
+static struct attribute_group rapl_pmu_attr_group = {
+       .attrs = rapl_pmu_attrs,
+};
+
+EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01");
+EVENT_ATTR_STR(energy-pkg  , rapl_pkg, "event=0x02");
+EVENT_ATTR_STR(energy-ram  , rapl_ram, "event=0x03");
+
+EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
+EVENT_ATTR_STR(energy-pkg.unit  , rapl_pkg_unit, "Joules");
+EVENT_ATTR_STR(energy-ram.unit  , rapl_ram_unit, "Joules");
+
+/*
+ * we compute in 0.23 nJ increments regardless of MSR
+ */
+EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10");
+EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10");
+EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10");
+
+static struct attribute *rapl_events_srv_attr[] = {
+       EVENT_PTR(rapl_cores),
+       EVENT_PTR(rapl_pkg),
+       EVENT_PTR(rapl_ram),
+
+       EVENT_PTR(rapl_cores_unit),
+       EVENT_PTR(rapl_pkg_unit),
+       EVENT_PTR(rapl_ram_unit),
+
+       EVENT_PTR(rapl_cores_scale),
+       EVENT_PTR(rapl_pkg_scale),
+       EVENT_PTR(rapl_ram_scale),
+       NULL,
+};
+
+static struct attribute *rapl_events_cln_attr[] = {
+       EVENT_PTR(rapl_cores),
+       EVENT_PTR(rapl_pkg),
+
+       EVENT_PTR(rapl_cores_unit),
+       EVENT_PTR(rapl_pkg_unit),
+
+       EVENT_PTR(rapl_cores_scale),
+       EVENT_PTR(rapl_pkg_scale),
+       NULL,
+};
+
+static struct attribute_group rapl_pmu_events_group = {
+       .name = "events",
+       .attrs = NULL, /* patched at runtime */
+};
+
+DEFINE_RAPL_FORMAT_ATTR(event, event, "config:0-7");
+static struct attribute *rapl_formats_attr[] = {
+       &format_attr_event.attr,
+       NULL,
+};
+
+static struct attribute_group rapl_pmu_format_group = {
+       .name = "format",
+       .attrs = rapl_formats_attr,
+};
+
+const struct attribute_group *rapl_attr_groups[] = {
+       &rapl_pmu_attr_group,
+       &rapl_pmu_format_group,
+       &rapl_pmu_events_group,
+       NULL,
+};
+
+static struct pmu rapl_pmu_class = {
+       .attr_groups    = rapl_attr_groups,
+       .task_ctx_nr    = perf_invalid_context, /* system-wide only */
+       .event_init     = rapl_pmu_event_init,
+       .add            = rapl_pmu_event_add, /* must have */
+       .del            = rapl_pmu_event_del, /* must have */
+       .start          = rapl_pmu_event_start,
+       .stop           = rapl_pmu_event_stop,
+       .read           = rapl_pmu_event_read,
+};
+
+static void rapl_cpu_exit(int cpu)
+{
+       struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
+       int i, phys_id = topology_physical_package_id(cpu);
+       int target = -1;
+
+       /* find a new cpu on same package */
+       for_each_online_cpu(i) {
+               if (i == cpu)
+                       continue;
+               if (phys_id == topology_physical_package_id(i)) {
+                       target = i;
+                       break;
+               }
+       }
+       /*
+        * clear cpu from cpumask
+        * if was set in cpumask and still some cpu on package,
+        * then move to new cpu
+        */
+       if (cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask) && target >= 0)
+               cpumask_set_cpu(target, &rapl_cpu_mask);
+
+       WARN_ON(cpumask_empty(&rapl_cpu_mask));
+       /*
+        * migrate events and context to new cpu
+        */
+       if (target >= 0)
+               perf_pmu_migrate_context(pmu->pmu, cpu, target);
+
+       /* cancel overflow polling timer for CPU */
+       rapl_stop_hrtimer(pmu);
+}
+
+static void rapl_cpu_init(int cpu)
+{
+       int i, phys_id = topology_physical_package_id(cpu);
+
+       /* check if phys_is is already covered */
+       for_each_cpu(i, &rapl_cpu_mask) {
+               if (phys_id == topology_physical_package_id(i))
+                       return;
+       }
+       /* was not found, so add it */
+       cpumask_set_cpu(cpu, &rapl_cpu_mask);
+}
+
+static int rapl_cpu_prepare(int cpu)
+{
+       struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
+       int phys_id = topology_physical_package_id(cpu);
+       u64 ms;
+
+       if (pmu)
+               return 0;
+
+       if (phys_id < 0)
+               return -1;
+
+       pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
+       if (!pmu)
+               return -1;
+
+       spin_lock_init(&pmu->lock);
+
+       INIT_LIST_HEAD(&pmu->active_list);
+
+       /*
+        * grab power unit as: 1/2^unit Joules
+        *
+        * we cache in local PMU instance
+        */
+       rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit);
+       pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL;
+       pmu->pmu = &rapl_pmu_class;
+
+       /*
+        * use reference of 200W for scaling the timeout
+        * to avoid missing counter overflows.
+        * 200W = 200 Joules/sec
+        * divide interval by 2 to avoid lockstep (2 * 100)
+        * if hw unit is 32, then we use 2 ms 1/200/2
+        */
+       if (pmu->hw_unit < 32)
+               ms = (1000 / (2 * 100)) * (1ULL << (32 - pmu->hw_unit - 1));
+       else
+               ms = 2;
+
+       pmu->timer_interval = ms_to_ktime(ms);
+
+       rapl_hrtimer_init(pmu);
+
+       /* set RAPL pmu for this cpu for now */
+       per_cpu(rapl_pmu, cpu) = pmu;
+       per_cpu(rapl_pmu_to_free, cpu) = NULL;
+
+       return 0;
+}
+
+static void rapl_cpu_kfree(int cpu)
+{
+       struct rapl_pmu *pmu = per_cpu(rapl_pmu_to_free, cpu);
+
+       kfree(pmu);
+
+       per_cpu(rapl_pmu_to_free, cpu) = NULL;
+}
+
+static int rapl_cpu_dying(int cpu)
+{
+       struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
+
+       if (!pmu)
+               return 0;
+
+       per_cpu(rapl_pmu, cpu) = NULL;
+
+       per_cpu(rapl_pmu_to_free, cpu) = pmu;
+
+       return 0;
+}
+
+static int rapl_cpu_notifier(struct notifier_block *self,
+                            unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (long)hcpu;
+
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_UP_PREPARE:
+               rapl_cpu_prepare(cpu);
+               break;
+       case CPU_STARTING:
+               rapl_cpu_init(cpu);
+               break;
+       case CPU_UP_CANCELED:
+       case CPU_DYING:
+               rapl_cpu_dying(cpu);
+               break;
+       case CPU_ONLINE:
+       case CPU_DEAD:
+               rapl_cpu_kfree(cpu);
+               break;
+       case CPU_DOWN_PREPARE:
+               rapl_cpu_exit(cpu);
+               break;
+       default:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static const struct x86_cpu_id rapl_cpu_match[] = {
+       [0] = { .vendor = X86_VENDOR_INTEL, .family = 6 },
+       [1] = {},
+};
+
+static int __init rapl_pmu_init(void)
+{
+       struct rapl_pmu *pmu;
+       int cpu, ret;
+
+       /*
+        * check for Intel processor family 6
+        */
+       if (!x86_match_cpu(rapl_cpu_match))
+               return 0;
+
+       /* check supported CPU */
+       switch (boot_cpu_data.x86_model) {
+       case 42: /* Sandy Bridge */
+       case 58: /* Ivy Bridge */
+       case 60: /* Haswell */
+               rapl_cntr_mask = RAPL_IDX_CLN;
+               rapl_pmu_events_group.attrs = rapl_events_cln_attr;
+               break;
+       case 45: /* Sandy Bridge-EP */
+       case 62: /* IvyTown */
+               rapl_cntr_mask = RAPL_IDX_SRV;
+               rapl_pmu_events_group.attrs = rapl_events_srv_attr;
+               break;
+
+       default:
+               /* unsupported */
+               return 0;
+       }
+       get_online_cpus();
+
+       for_each_online_cpu(cpu) {
+               rapl_cpu_prepare(cpu);
+               rapl_cpu_init(cpu);
+       }
+
+       perf_cpu_notifier(rapl_cpu_notifier);
+
+       ret = perf_pmu_register(&rapl_pmu_class, "power", -1);
+       if (WARN_ON(ret)) {
+               pr_info("RAPL PMU detected, registration failed (%d), RAPL PMU disabled\n", ret);
+               put_online_cpus();
+               return -1;
+       }
+
+       pmu = __get_cpu_var(rapl_pmu);
+
+       pr_info("RAPL PMU detected, hw unit 2^-%d Joules,"
+               " API unit is 2^-32 Joules,"
+               " %d fixed counters"
+               " %llu ms ovfl timer\n",
+               pmu->hw_unit,
+               hweight32(rapl_cntr_mask),
+               ktime_to_ms(pmu->timer_interval));
+
+       put_online_cpus();
+
+       return 0;
+}
+device_initcall(rapl_pmu_init);
index 88db010845cb26a2594170acc2387cee75a20bbc..384df5105fbc9883626ec5482151babd43ce482a 100644 (file)
@@ -31,20 +31,6 @@ static int __init x86_rdrand_setup(char *s)
 }
 __setup("nordrand", x86_rdrand_setup);
 
-/* We can't use arch_get_random_long() here since alternatives haven't run */
-static inline int rdrand_long(unsigned long *v)
-{
-       int ok;
-       asm volatile("1: " RDRAND_LONG "\n\t"
-                    "jc 2f\n\t"
-                    "decl %0\n\t"
-                    "jnz 1b\n\t"
-                    "2:"
-                    : "=r" (ok), "=a" (*v)
-                    : "0" (RDRAND_RETRY_LOOPS));
-       return ok;
-}
-
 /*
  * Force a reseed cycle; we are architecturally guaranteed a reseed
  * after no more than 512 128-bit chunks of random data.  This also
index cb233bc9dee35681ccf85a2385ece964ee96847d..f97cf4dd4b76fab01db0a7e0db7d33411c0041e4 100644 (file)
@@ -823,6 +823,20 @@ static void __init trim_low_memory_range(void)
        memblock_reserve(0, ALIGN(reserve_low, PAGE_SIZE));
 }
        
+/*
+ * Dump out kernel offset information on panic.
+ */
+static int
+dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
+{
+       pr_emerg("Kernel Offset: 0x%lx from 0x%lx "
+                "(relocation range: 0x%lx-0x%lx)\n",
+                (unsigned long)&_text - __START_KERNEL, __START_KERNEL,
+                __START_KERNEL_map, MODULES_VADDR-1);
+
+       return 0;
+}
+
 /*
  * Determine if we were loaded by an EFI loader.  If so, then we have also been
  * passed the efi memmap, systab, etc., so we should use these data structures
@@ -1248,3 +1262,15 @@ void __init i386_reserve_resources(void)
 }
 
 #endif /* CONFIG_X86_32 */
+
+static struct notifier_block kernel_offset_notifier = {
+       .notifier_call = dump_kernel_offset
+};
+
+static int __init register_kernel_offset_dumper(void)
+{
+       atomic_notifier_chain_register(&panic_notifier_list,
+                                       &kernel_offset_notifier);
+       return 0;
+}
+__initcall(register_kernel_offset_dumper);
index a30ca15be21c8a182b3bb937ac612d1863a046ee..dee945d555941a078f40049b24b8b4731aba6f2c 100644 (file)
@@ -186,7 +186,7 @@ ENTRY(copy_user_generic_unrolled)
 30:    shll $6,%ecx
        addl %ecx,%edx
        jmp 60f
-40:    lea (%rdx,%rcx,8),%rdx
+40:    leal (%rdx,%rcx,8),%edx
        jmp 60f
 50:    movl %ecx,%edx
 60:    jmp copy_user_handle_tail /* ecx is zerorest also */
@@ -236,8 +236,6 @@ ENDPROC(copy_user_generic_unrolled)
 ENTRY(copy_user_generic_string)
        CFI_STARTPROC
        ASM_STAC
-       andl %edx,%edx
-       jz 4f
        cmpl $8,%edx
        jb 2f           /* less than 8 bytes, go to byte copy loop */
        ALIGN_DESTINATION
@@ -249,12 +247,12 @@ ENTRY(copy_user_generic_string)
 2:     movl %edx,%ecx
 3:     rep
        movsb
-4:     xorl %eax,%eax
+       xorl %eax,%eax
        ASM_CLAC
        ret
 
        .section .fixup,"ax"
-11:    lea (%rdx,%rcx,8),%rcx
+11:    leal (%rdx,%rcx,8),%ecx
 12:    movl %ecx,%edx          /* ecx is zerorest also */
        jmp copy_user_handle_tail
        .previous
@@ -279,12 +277,10 @@ ENDPROC(copy_user_generic_string)
 ENTRY(copy_user_enhanced_fast_string)
        CFI_STARTPROC
        ASM_STAC
-       andl %edx,%edx
-       jz 2f
        movl %edx,%ecx
 1:     rep
        movsb
-2:     xorl %eax,%eax
+       xorl %eax,%eax
        ASM_CLAC
        ret
 
index 9d980d88b7477a82f757e75d0efda0c867c76d43..8c9f647ff9e111203af86f894a13b450e4513013 100644 (file)
@@ -87,9 +87,7 @@ int pmd_huge_support(void)
 }
 #endif
 
-/* x86_64 also uses this file */
-
-#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+#ifdef CONFIG_HUGETLB_PAGE
 static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
                unsigned long addr, unsigned long len,
                unsigned long pgoff, unsigned long flags)
@@ -99,7 +97,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
 
        info.flags = 0;
        info.length = len;
-       info.low_limit = TASK_UNMAPPED_BASE;
+       info.low_limit = current->mm->mmap_legacy_base;
        info.high_limit = TASK_SIZE;
        info.align_mask = PAGE_MASK & ~huge_page_mask(h);
        info.align_offset = 0;
@@ -172,8 +170,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
                return hugetlb_get_unmapped_area_topdown(file, addr, len,
                                pgoff, flags);
 }
-
-#endif /*HAVE_ARCH_HUGETLB_UNMAPPED_AREA*/
+#endif /* CONFIG_HUGETLB_PAGE */
 
 #ifdef CONFIG_X86_64
 static __init int setup_hugepagesz(char *opt)
index 4287f1ffba7ef2e42cc68839a38c3ecc0d6b1304..5bdc5430597cfea9056e08edb7902a098f28535c 100644 (file)
@@ -806,6 +806,9 @@ void __init mem_init(void)
        BUILD_BUG_ON(VMALLOC_START                      >= VMALLOC_END);
 #undef high_memory
 #undef __FIXADDR_TOP
+#ifdef CONFIG_RANDOMIZE_BASE
+       BUILD_BUG_ON(CONFIG_RANDOMIZE_BASE_MAX_OFFSET > KERNEL_IMAGE_SIZE);
+#endif
 
 #ifdef CONFIG_HIGHMEM
        BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE        > FIXADDR_START);
index bb32480c2d713d57a52747f2f6e119a70286dc07..b3b19f46c0164c7169c9259a68836afbaeae1943 100644 (file)
@@ -30,6 +30,7 @@
  */
 struct cpa_data {
        unsigned long   *vaddr;
+       pgd_t           *pgd;
        pgprot_t        mask_set;
        pgprot_t        mask_clr;
        int             numpages;
@@ -322,17 +323,9 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
        return prot;
 }
 
-/*
- * Lookup the page table entry for a virtual address. Return a pointer
- * to the entry and the level of the mapping.
- *
- * Note: We return pud and pmd either when the entry is marked large
- * or when the present bit is not set. Otherwise we would return a
- * pointer to a nonexisting mapping.
- */
-pte_t *lookup_address(unsigned long address, unsigned int *level)
+static pte_t *__lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
+                                     unsigned int *level)
 {
-       pgd_t *pgd = pgd_offset_k(address);
        pud_t *pud;
        pmd_t *pmd;
 
@@ -361,8 +354,31 @@ pte_t *lookup_address(unsigned long address, unsigned int *level)
 
        return pte_offset_kernel(pmd, address);
 }
+
+/*
+ * Lookup the page table entry for a virtual address. Return a pointer
+ * to the entry and the level of the mapping.
+ *
+ * Note: We return pud and pmd either when the entry is marked large
+ * or when the present bit is not set. Otherwise we would return a
+ * pointer to a nonexisting mapping.
+ */
+pte_t *lookup_address(unsigned long address, unsigned int *level)
+{
+        return __lookup_address_in_pgd(pgd_offset_k(address), address, level);
+}
 EXPORT_SYMBOL_GPL(lookup_address);
 
+static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address,
+                                 unsigned int *level)
+{
+        if (cpa->pgd)
+               return __lookup_address_in_pgd(cpa->pgd + pgd_index(address),
+                                              address, level);
+
+        return lookup_address(address, level);
+}
+
 /*
  * This is necessary because __pa() does not work on some
  * kinds of memory, like vmalloc() or the alloc_remap()
@@ -437,7 +453,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
         * Check for races, another CPU might have split this page
         * up already:
         */
-       tmp = lookup_address(address, &level);
+       tmp = _lookup_address_cpa(cpa, address, &level);
        if (tmp != kpte)
                goto out_unlock;
 
@@ -543,7 +559,8 @@ out_unlock:
 }
 
 static int
-__split_large_page(pte_t *kpte, unsigned long address, struct page *base)
+__split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
+                  struct page *base)
 {
        pte_t *pbase = (pte_t *)page_address(base);
        unsigned long pfn, pfninc = 1;
@@ -556,7 +573,7 @@ __split_large_page(pte_t *kpte, unsigned long address, struct page *base)
         * Check for races, another CPU might have split this page
         * up for us already:
         */
-       tmp = lookup_address(address, &level);
+       tmp = _lookup_address_cpa(cpa, address, &level);
        if (tmp != kpte) {
                spin_unlock(&pgd_lock);
                return 1;
@@ -632,7 +649,8 @@ __split_large_page(pte_t *kpte, unsigned long address, struct page *base)
        return 0;
 }
 
-static int split_large_page(pte_t *kpte, unsigned long address)
+static int split_large_page(struct cpa_data *cpa, pte_t *kpte,
+                           unsigned long address)
 {
        struct page *base;
 
@@ -644,15 +662,390 @@ static int split_large_page(pte_t *kpte, unsigned long address)
        if (!base)
                return -ENOMEM;
 
-       if (__split_large_page(kpte, address, base))
+       if (__split_large_page(cpa, kpte, address, base))
                __free_page(base);
 
        return 0;
 }
 
+static bool try_to_free_pte_page(pte_t *pte)
+{
+       int i;
+
+       for (i = 0; i < PTRS_PER_PTE; i++)
+               if (!pte_none(pte[i]))
+                       return false;
+
+       free_page((unsigned long)pte);
+       return true;
+}
+
+static bool try_to_free_pmd_page(pmd_t *pmd)
+{
+       int i;
+
+       for (i = 0; i < PTRS_PER_PMD; i++)
+               if (!pmd_none(pmd[i]))
+                       return false;
+
+       free_page((unsigned long)pmd);
+       return true;
+}
+
+static bool unmap_pte_range(pmd_t *pmd, unsigned long start, unsigned long end)
+{
+       pte_t *pte = pte_offset_kernel(pmd, start);
+
+       while (start < end) {
+               set_pte(pte, __pte(0));
+
+               start += PAGE_SIZE;
+               pte++;
+       }
+
+       if (try_to_free_pte_page((pte_t *)pmd_page_vaddr(*pmd))) {
+               pmd_clear(pmd);
+               return true;
+       }
+       return false;
+}
+
+static void __unmap_pmd_range(pud_t *pud, pmd_t *pmd,
+                             unsigned long start, unsigned long end)
+{
+       if (unmap_pte_range(pmd, start, end))
+               if (try_to_free_pmd_page((pmd_t *)pud_page_vaddr(*pud)))
+                       pud_clear(pud);
+}
+
+static void unmap_pmd_range(pud_t *pud, unsigned long start, unsigned long end)
+{
+       pmd_t *pmd = pmd_offset(pud, start);
+
+       /*
+        * Not on a 2MB page boundary?
+        */
+       if (start & (PMD_SIZE - 1)) {
+               unsigned long next_page = (start + PMD_SIZE) & PMD_MASK;
+               unsigned long pre_end = min_t(unsigned long, end, next_page);
+
+               __unmap_pmd_range(pud, pmd, start, pre_end);
+
+               start = pre_end;
+               pmd++;
+       }
+
+       /*
+        * Try to unmap in 2M chunks.
+        */
+       while (end - start >= PMD_SIZE) {
+               if (pmd_large(*pmd))
+                       pmd_clear(pmd);
+               else
+                       __unmap_pmd_range(pud, pmd, start, start + PMD_SIZE);
+
+               start += PMD_SIZE;
+               pmd++;
+       }
+
+       /*
+        * 4K leftovers?
+        */
+       if (start < end)
+               return __unmap_pmd_range(pud, pmd, start, end);
+
+       /*
+        * Try again to free the PMD page if haven't succeeded above.
+        */
+       if (!pud_none(*pud))
+               if (try_to_free_pmd_page((pmd_t *)pud_page_vaddr(*pud)))
+                       pud_clear(pud);
+}
+
+static void unmap_pud_range(pgd_t *pgd, unsigned long start, unsigned long end)
+{
+       pud_t *pud = pud_offset(pgd, start);
+
+       /*
+        * Not on a GB page boundary?
+        */
+       if (start & (PUD_SIZE - 1)) {
+               unsigned long next_page = (start + PUD_SIZE) & PUD_MASK;
+               unsigned long pre_end   = min_t(unsigned long, end, next_page);
+
+               unmap_pmd_range(pud, start, pre_end);
+
+               start = pre_end;
+               pud++;
+       }
+
+       /*
+        * Try to unmap in 1G chunks?
+        */
+       while (end - start >= PUD_SIZE) {
+
+               if (pud_large(*pud))
+                       pud_clear(pud);
+               else
+                       unmap_pmd_range(pud, start, start + PUD_SIZE);
+
+               start += PUD_SIZE;
+               pud++;
+       }
+
+       /*
+        * 2M leftovers?
+        */
+       if (start < end)
+               unmap_pmd_range(pud, start, end);
+
+       /*
+        * No need to try to free the PUD page because we'll free it in
+        * populate_pgd's error path
+        */
+}
+
+static int alloc_pte_page(pmd_t *pmd)
+{
+       pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL | __GFP_NOTRACK);
+       if (!pte)
+               return -1;
+
+       set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
+       return 0;
+}
+
+static int alloc_pmd_page(pud_t *pud)
+{
+       pmd_t *pmd = (pmd_t *)get_zeroed_page(GFP_KERNEL | __GFP_NOTRACK);
+       if (!pmd)
+               return -1;
+
+       set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
+       return 0;
+}
+
+static void populate_pte(struct cpa_data *cpa,
+                        unsigned long start, unsigned long end,
+                        unsigned num_pages, pmd_t *pmd, pgprot_t pgprot)
+{
+       pte_t *pte;
+
+       pte = pte_offset_kernel(pmd, start);
+
+       while (num_pages-- && start < end) {
+
+               /* deal with the NX bit */
+               if (!(pgprot_val(pgprot) & _PAGE_NX))
+                       cpa->pfn &= ~_PAGE_NX;
+
+               set_pte(pte, pfn_pte(cpa->pfn >> PAGE_SHIFT, pgprot));
+
+               start    += PAGE_SIZE;
+               cpa->pfn += PAGE_SIZE;
+               pte++;
+       }
+}
+
+static int populate_pmd(struct cpa_data *cpa,
+                       unsigned long start, unsigned long end,
+                       unsigned num_pages, pud_t *pud, pgprot_t pgprot)
+{
+       unsigned int cur_pages = 0;
+       pmd_t *pmd;
+
+       /*
+        * Not on a 2M boundary?
+        */
+       if (start & (PMD_SIZE - 1)) {
+               unsigned long pre_end = start + (num_pages << PAGE_SHIFT);
+               unsigned long next_page = (start + PMD_SIZE) & PMD_MASK;
+
+               pre_end   = min_t(unsigned long, pre_end, next_page);
+               cur_pages = (pre_end - start) >> PAGE_SHIFT;
+               cur_pages = min_t(unsigned int, num_pages, cur_pages);
+
+               /*
+                * Need a PTE page?
+                */
+               pmd = pmd_offset(pud, start);
+               if (pmd_none(*pmd))
+                       if (alloc_pte_page(pmd))
+                               return -1;
+
+               populate_pte(cpa, start, pre_end, cur_pages, pmd, pgprot);
+
+               start = pre_end;
+       }
+
+       /*
+        * We mapped them all?
+        */
+       if (num_pages == cur_pages)
+               return cur_pages;
+
+       while (end - start >= PMD_SIZE) {
+
+               /*
+                * We cannot use a 1G page so allocate a PMD page if needed.
+                */
+               if (pud_none(*pud))
+                       if (alloc_pmd_page(pud))
+                               return -1;
+
+               pmd = pmd_offset(pud, start);
+
+               set_pmd(pmd, __pmd(cpa->pfn | _PAGE_PSE | massage_pgprot(pgprot)));
+
+               start     += PMD_SIZE;
+               cpa->pfn  += PMD_SIZE;
+               cur_pages += PMD_SIZE >> PAGE_SHIFT;
+       }
+
+       /*
+        * Map trailing 4K pages.
+        */
+       if (start < end) {
+               pmd = pmd_offset(pud, start);
+               if (pmd_none(*pmd))
+                       if (alloc_pte_page(pmd))
+                               return -1;
+
+               populate_pte(cpa, start, end, num_pages - cur_pages,
+                            pmd, pgprot);
+       }
+       return num_pages;
+}
+
+static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd,
+                       pgprot_t pgprot)
+{
+       pud_t *pud;
+       unsigned long end;
+       int cur_pages = 0;
+
+       end = start + (cpa->numpages << PAGE_SHIFT);
+
+       /*
+        * Not on a Gb page boundary? => map everything up to it with
+        * smaller pages.
+        */
+       if (start & (PUD_SIZE - 1)) {
+               unsigned long pre_end;
+               unsigned long next_page = (start + PUD_SIZE) & PUD_MASK;
+
+               pre_end   = min_t(unsigned long, end, next_page);
+               cur_pages = (pre_end - start) >> PAGE_SHIFT;
+               cur_pages = min_t(int, (int)cpa->numpages, cur_pages);
+
+               pud = pud_offset(pgd, start);
+
+               /*
+                * Need a PMD page?
+                */
+               if (pud_none(*pud))
+                       if (alloc_pmd_page(pud))
+                               return -1;
+
+               cur_pages = populate_pmd(cpa, start, pre_end, cur_pages,
+                                        pud, pgprot);
+               if (cur_pages < 0)
+                       return cur_pages;
+
+               start = pre_end;
+       }
+
+       /* We mapped them all? */
+       if (cpa->numpages == cur_pages)
+               return cur_pages;
+
+       pud = pud_offset(pgd, start);
+
+       /*
+        * Map everything starting from the Gb boundary, possibly with 1G pages
+        */
+       while (end - start >= PUD_SIZE) {
+               set_pud(pud, __pud(cpa->pfn | _PAGE_PSE | massage_pgprot(pgprot)));
+
+               start     += PUD_SIZE;
+               cpa->pfn  += PUD_SIZE;
+               cur_pages += PUD_SIZE >> PAGE_SHIFT;
+               pud++;
+       }
+
+       /* Map trailing leftover */
+       if (start < end) {
+               int tmp;
+
+               pud = pud_offset(pgd, start);
+               if (pud_none(*pud))
+                       if (alloc_pmd_page(pud))
+                               return -1;
+
+               tmp = populate_pmd(cpa, start, end, cpa->numpages - cur_pages,
+                                  pud, pgprot);
+               if (tmp < 0)
+                       return cur_pages;
+
+               cur_pages += tmp;
+       }
+       return cur_pages;
+}
+
+/*
+ * Restrictions for kernel page table do not necessarily apply when mapping in
+ * an alternate PGD.
+ */
+static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
+{
+       pgprot_t pgprot = __pgprot(_KERNPG_TABLE);
+       bool allocd_pgd = false;
+       pgd_t *pgd_entry;
+       pud_t *pud = NULL;      /* shut up gcc */
+       int ret;
+
+       pgd_entry = cpa->pgd + pgd_index(addr);
+
+       /*
+        * Allocate a PUD page and hand it down for mapping.
+        */
+       if (pgd_none(*pgd_entry)) {
+               pud = (pud_t *)get_zeroed_page(GFP_KERNEL | __GFP_NOTRACK);
+               if (!pud)
+                       return -1;
+
+               set_pgd(pgd_entry, __pgd(__pa(pud) | _KERNPG_TABLE));
+               allocd_pgd = true;
+       }
+
+       pgprot_val(pgprot) &= ~pgprot_val(cpa->mask_clr);
+       pgprot_val(pgprot) |=  pgprot_val(cpa->mask_set);
+
+       ret = populate_pud(cpa, addr, pgd_entry, pgprot);
+       if (ret < 0) {
+               unmap_pud_range(pgd_entry, addr,
+                               addr + (cpa->numpages << PAGE_SHIFT));
+
+               if (allocd_pgd) {
+                       /*
+                        * If I allocated this PUD page, I can just as well
+                        * free it in this error path.
+                        */
+                       pgd_clear(pgd_entry);
+                       free_page((unsigned long)pud);
+               }
+               return ret;
+       }
+       cpa->numpages = ret;
+       return 0;
+}
+
 static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
                               int primary)
 {
+       if (cpa->pgd)
+               return populate_pgd(cpa, vaddr);
+
        /*
         * Ignore all non primary paths.
         */
@@ -697,7 +1090,7 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)
        else
                address = *cpa->vaddr;
 repeat:
-       kpte = lookup_address(address, &level);
+       kpte = _lookup_address_cpa(cpa, address, &level);
        if (!kpte)
                return __cpa_process_fault(cpa, address, primary);
 
@@ -761,7 +1154,7 @@ repeat:
        /*
         * We have to split the large page:
         */
-       err = split_large_page(kpte, address);
+       err = split_large_page(cpa, kpte, address);
        if (!err) {
                /*
                 * Do a global flush tlb after splitting the large page
@@ -910,6 +1303,8 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
        int ret, cache, checkalias;
        unsigned long baddr = 0;
 
+       memset(&cpa, 0, sizeof(cpa));
+
        /*
         * Check, if we are requested to change a not supported
         * feature:
@@ -1356,6 +1751,7 @@ static int __set_pages_p(struct page *page, int numpages)
 {
        unsigned long tempaddr = (unsigned long) page_address(page);
        struct cpa_data cpa = { .vaddr = &tempaddr,
+                               .pgd = NULL,
                                .numpages = numpages,
                                .mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW),
                                .mask_clr = __pgprot(0),
@@ -1374,6 +1770,7 @@ static int __set_pages_np(struct page *page, int numpages)
 {
        unsigned long tempaddr = (unsigned long) page_address(page);
        struct cpa_data cpa = { .vaddr = &tempaddr,
+                               .pgd = NULL,
                                .numpages = numpages,
                                .mask_set = __pgprot(0),
                                .mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW),
@@ -1434,6 +1831,36 @@ bool kernel_page_present(struct page *page)
 
 #endif /* CONFIG_DEBUG_PAGEALLOC */
 
+int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
+                           unsigned numpages, unsigned long page_flags)
+{
+       int retval = -EINVAL;
+
+       struct cpa_data cpa = {
+               .vaddr = &address,
+               .pfn = pfn,
+               .pgd = pgd,
+               .numpages = numpages,
+               .mask_set = __pgprot(0),
+               .mask_clr = __pgprot(0),
+               .flags = 0,
+       };
+
+       if (!(__supported_pte_mask & _PAGE_NX))
+               goto out;
+
+       if (!(page_flags & _PAGE_NX))
+               cpa.mask_clr = __pgprot(_PAGE_NX);
+
+       cpa.mask_set = __pgprot(_PAGE_PRESENT | page_flags);
+
+       retval = __change_page_attr_set_clr(&cpa, 0);
+       __flush_tlb_all();
+
+out:
+       return retval;
+}
+
 /*
  * The testcases use internal knowledge of the implementation that shouldn't
  * be exposed to the rest of the kernel. Include these directly here.
index 5c90975cdf0f8242db167fa9c471c1ea2bf3e512..43984bc1665a917303ae574b27345138cc9560b6 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/rcupdate.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
-#include <acpi/acpi.h>
 
 /* Assume systems with more busses have correct MCFG */
 #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
index 6599a0027b76bb9ab3b390fe31e5ba0ae10ed124..81b506d5befd46e5a494d6cbef7aa71edceca7f1 100644 (file)
@@ -142,7 +142,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num)
                        efi_y += font->height;
                }
 
-               if (efi_y + font->height >= si->lfb_height) {
+               if (efi_y + font->height > si->lfb_height) {
                        u32 i;
 
                        efi_y -= font->height;
index 92c02344a060f2dacc7997185d6fd6bc04ed225e..f8ec4dafc74e5e94011c3f092f17f4c1b3f40109 100644 (file)
@@ -12,6 +12,8 @@
  *     Bibo Mao <bibo.mao@intel.com>
  *     Chandramouli Narayanan <mouli@linux.intel.com>
  *     Huang Ying <ying.huang@intel.com>
+ * Copyright (C) 2013 SuSE Labs
+ *     Borislav Petkov <bp@suse.de> - runtime services VA mapping
  *
  * Copied from efi_32.c to eliminate the duplicated code between EFI
  * 32/64 support code. --ying 2007-10-26
@@ -51,7 +53,7 @@
 #include <asm/x86_init.h>
 #include <asm/rtc.h>
 
-#define EFI_DEBUG      1
+#define EFI_DEBUG
 
 #define EFI_MIN_RESERVE 5120
 
@@ -398,9 +400,9 @@ int __init efi_memblock_x86_reserve_range(void)
        return 0;
 }
 
-#if EFI_DEBUG
 static void __init print_efi_memmap(void)
 {
+#ifdef EFI_DEBUG
        efi_memory_desc_t *md;
        void *p;
        int i;
@@ -415,8 +417,8 @@ static void __init print_efi_memmap(void)
                        md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
                        (md->num_pages >> (20 - EFI_PAGE_SHIFT)));
        }
-}
 #endif  /*  EFI_DEBUG  */
+}
 
 void __init efi_reserve_boot_services(void)
 {
@@ -696,10 +698,7 @@ void __init efi_init(void)
                x86_platform.set_wallclock = efi_set_rtc_mmss;
        }
 #endif
-
-#if EFI_DEBUG
        print_efi_memmap();
-#endif
 }
 
 void __init efi_late_init(void)
@@ -748,21 +747,56 @@ void efi_memory_uc(u64 addr, unsigned long size)
        set_memory_uc(addr, npages);
 }
 
+void __init old_map_region(efi_memory_desc_t *md)
+{
+       u64 start_pfn, end_pfn, end;
+       unsigned long size;
+       void *va;
+
+       start_pfn = PFN_DOWN(md->phys_addr);
+       size      = md->num_pages << PAGE_SHIFT;
+       end       = md->phys_addr + size;
+       end_pfn   = PFN_UP(end);
+
+       if (pfn_range_is_mapped(start_pfn, end_pfn)) {
+               va = __va(md->phys_addr);
+
+               if (!(md->attribute & EFI_MEMORY_WB))
+                       efi_memory_uc((u64)(unsigned long)va, size);
+       } else
+               va = efi_ioremap(md->phys_addr, size,
+                                md->type, md->attribute);
+
+       md->virt_addr = (u64) (unsigned long) va;
+       if (!va)
+               pr_err("ioremap of 0x%llX failed!\n",
+                      (unsigned long long)md->phys_addr);
+}
+
 /*
  * This function will switch the EFI runtime services to virtual mode.
- * Essentially, look through the EFI memmap and map every region that
- * has the runtime attribute bit set in its memory descriptor and update
- * that memory descriptor with the virtual address obtained from ioremap().
- * This enables the runtime services to be called without having to
+ * Essentially, we look through the EFI memmap and map every region that
+ * has the runtime attribute bit set in its memory descriptor into the
+ * ->trampoline_pgd page table using a top-down VA allocation scheme.
+ *
+ * The old method which used to update that memory descriptor with the
+ * virtual address obtained from ioremap() is still supported when the
+ * kernel is booted with efi=old_map on its command line. Same old
+ * method enabled the runtime services to be called without having to
  * thunk back into physical mode for every invocation.
+ *
+ * The new method does a pagetable switch in a preemption-safe manner
+ * so that we're in a different address space when calling a runtime
+ * function. For function arguments passing we do copy the PGDs of the
+ * kernel page table into ->trampoline_pgd prior to each call.
  */
 void __init efi_enter_virtual_mode(void)
 {
        efi_memory_desc_t *md, *prev_md = NULL;
-       efi_status_t status;
+       void *p, *new_memmap = NULL;
        unsigned long size;
-       u64 end, systab, start_pfn, end_pfn;
-       void *p, *va, *new_memmap = NULL;
+       efi_status_t status;
+       u64 end, systab;
        int count = 0;
 
        efi.systab = NULL;
@@ -771,7 +805,6 @@ void __init efi_enter_virtual_mode(void)
         * We don't do virtual mode, since we don't do runtime services, on
         * non-native EFI
         */
-
        if (!efi_is_native()) {
                efi_unmap_memmap();
                return;
@@ -802,6 +835,7 @@ void __init efi_enter_virtual_mode(void)
                        continue;
                }
                prev_md = md;
+
        }
 
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
@@ -814,36 +848,24 @@ void __init efi_enter_virtual_mode(void)
                                continue;
                }
 
+               efi_map_region(md);
+
                size = md->num_pages << EFI_PAGE_SHIFT;
                end = md->phys_addr + size;
 
-               start_pfn = PFN_DOWN(md->phys_addr);
-               end_pfn = PFN_UP(end);
-               if (pfn_range_is_mapped(start_pfn, end_pfn)) {
-                       va = __va(md->phys_addr);
-
-                       if (!(md->attribute & EFI_MEMORY_WB))
-                               efi_memory_uc((u64)(unsigned long)va, size);
-               } else
-                       va = efi_ioremap(md->phys_addr, size,
-                                        md->type, md->attribute);
-
-               md->virt_addr = (u64) (unsigned long) va;
-
-               if (!va) {
-                       pr_err("ioremap of 0x%llX failed!\n",
-                              (unsigned long long)md->phys_addr);
-                       continue;
-               }
-
                systab = (u64) (unsigned long) efi_phys.systab;
                if (md->phys_addr <= systab && systab < end) {
                        systab += md->virt_addr - md->phys_addr;
+
                        efi.systab = (efi_system_table_t *) (unsigned long) systab;
                }
+
                new_memmap = krealloc(new_memmap,
                                      (count + 1) * memmap.desc_size,
                                      GFP_KERNEL);
+               if (!new_memmap)
+                       goto err_out;
+
                memcpy(new_memmap + (count * memmap.desc_size), md,
                       memmap.desc_size);
                count++;
@@ -851,6 +873,9 @@ void __init efi_enter_virtual_mode(void)
 
        BUG_ON(!efi.systab);
 
+       efi_setup_page_tables();
+       efi_sync_low_kernel_mappings();
+
        status = phys_efi_set_virtual_address_map(
                memmap.desc_size * count,
                memmap.desc_size,
@@ -883,7 +908,8 @@ void __init efi_enter_virtual_mode(void)
        efi.query_variable_info = virt_efi_query_variable_info;
        efi.update_capsule = virt_efi_update_capsule;
        efi.query_capsule_caps = virt_efi_query_capsule_caps;
-       if (__supported_pte_mask & _PAGE_NX)
+
+       if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX))
                runtime_code_page_mkexec();
 
        kfree(new_memmap);
@@ -894,6 +920,11 @@ void __init efi_enter_virtual_mode(void)
                         EFI_VARIABLE_BOOTSERVICE_ACCESS |
                         EFI_VARIABLE_RUNTIME_ACCESS,
                         0, NULL);
+
+       return;
+
+ err_out:
+       pr_err("Error reallocating memory, EFI runtime non-functional!\n");
 }
 
 /*
@@ -1013,3 +1044,15 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
        return EFI_SUCCESS;
 }
 EXPORT_SYMBOL_GPL(efi_query_variable_store);
+
+static int __init parse_efi_cmdline(char *str)
+{
+       if (*str == '=')
+               str++;
+
+       if (!strncmp(str, "old_map", 7))
+               set_bit(EFI_OLD_MEMMAP, &x86_efi_facility);
+
+       return 0;
+}
+early_param("efi", parse_efi_cmdline);
index 40e446941dd7eceb587b2b4572c96279631e5f56..e94557cf54878f1c8111a9e800a484d3880192d3 100644 (file)
  * claim EFI runtime service handler exclusively and to duplicate a memory in
  * low memory space say 0 - 3G.
  */
-
 static unsigned long efi_rt_eflags;
 
+void efi_sync_low_kernel_mappings(void) {}
+void efi_setup_page_tables(void) {}
+
+void __init efi_map_region(efi_memory_desc_t *md)
+{
+       old_map_region(md);
+}
+
 void efi_call_phys_prelog(void)
 {
        struct desc_ptr gdt_descr;
index 39a0e7f1f0a3ec1c7601888d30c724a5b8660e19..bf286c386d330272fdb2e4d7cef99ddf108d489c 100644 (file)
 #include <asm/efi.h>
 #include <asm/cacheflush.h>
 #include <asm/fixmap.h>
+#include <asm/realmode.h>
 
 static pgd_t *save_pgd __initdata;
 static unsigned long efi_flags __initdata;
 
+/*
+ * We allocate runtime services regions bottom-up, starting from -4G, i.e.
+ * 0xffff_ffff_0000_0000 and limit EFI VA mapping space to 64G.
+ */
+static u64 efi_va      = -4 * (1UL << 30);
+#define EFI_VA_END     (-68 * (1UL << 30))
+
+/*
+ * Scratch space used for switching the pagetable in the EFI stub
+ */
+struct efi_scratch {
+       u64 r15;
+       u64 prev_cr3;
+       pgd_t *efi_pgt;
+       bool use_pgd;
+};
+
 static void __init early_code_mapping_set_exec(int executable)
 {
        efi_memory_desc_t *md;
@@ -65,6 +83,9 @@ void __init efi_call_phys_prelog(void)
        int pgd;
        int n_pgds;
 
+       if (!efi_enabled(EFI_OLD_MEMMAP))
+               return;
+
        early_code_mapping_set_exec(1);
        local_irq_save(efi_flags);
 
@@ -86,6 +107,10 @@ void __init efi_call_phys_epilog(void)
         */
        int pgd;
        int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);
+
+       if (!efi_enabled(EFI_OLD_MEMMAP))
+               return;
+
        for (pgd = 0; pgd < n_pgds; pgd++)
                set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]);
        kfree(save_pgd);
@@ -94,6 +119,90 @@ void __init efi_call_phys_epilog(void)
        early_code_mapping_set_exec(0);
 }
 
+/*
+ * Add low kernel mappings for passing arguments to EFI functions.
+ */
+void efi_sync_low_kernel_mappings(void)
+{
+       unsigned num_pgds;
+       pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd);
+
+       if (efi_enabled(EFI_OLD_MEMMAP))
+               return;
+
+       num_pgds = pgd_index(MODULES_END - 1) - pgd_index(PAGE_OFFSET);
+
+       memcpy(pgd + pgd_index(PAGE_OFFSET),
+               init_mm.pgd + pgd_index(PAGE_OFFSET),
+               sizeof(pgd_t) * num_pgds);
+}
+
+void efi_setup_page_tables(void)
+{
+       efi_scratch.efi_pgt = (pgd_t *)(unsigned long)real_mode_header->trampoline_pgd;
+
+       if (!efi_enabled(EFI_OLD_MEMMAP))
+               efi_scratch.use_pgd = true;
+}
+
+static void __init __map_region(efi_memory_desc_t *md, u64 va)
+{
+       pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd);
+       unsigned long pf = 0, size;
+       u64 end;
+
+       if (!(md->attribute & EFI_MEMORY_WB))
+               pf |= _PAGE_PCD;
+
+       size = md->num_pages << PAGE_SHIFT;
+       end  = va + size;
+
+       if (kernel_map_pages_in_pgd(pgd, md->phys_addr, va, md->num_pages, pf))
+               pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n",
+                          md->phys_addr, va);
+}
+
+void __init efi_map_region(efi_memory_desc_t *md)
+{
+       unsigned long size = md->num_pages << PAGE_SHIFT;
+       u64 pa = md->phys_addr;
+
+       if (efi_enabled(EFI_OLD_MEMMAP))
+               return old_map_region(md);
+
+       /*
+        * Make sure the 1:1 mappings are present as a catch-all for b0rked
+        * firmware which doesn't update all internal pointers after switching
+        * to virtual mode and would otherwise crap on us.
+        */
+       __map_region(md, md->phys_addr);
+
+       efi_va -= size;
+
+       /* Is PA 2M-aligned? */
+       if (!(pa & (PMD_SIZE - 1))) {
+               efi_va &= PMD_MASK;
+       } else {
+               u64 pa_offset = pa & (PMD_SIZE - 1);
+               u64 prev_va = efi_va;
+
+               /* get us the same offset within this 2M page */
+               efi_va = (efi_va & PMD_MASK) + pa_offset;
+
+               if (efi_va > prev_va)
+                       efi_va -= PMD_SIZE;
+       }
+
+       if (efi_va < EFI_VA_END) {
+               pr_warn(FW_WARN "VA address range overflow!\n");
+               return;
+       }
+
+       /* Do the VA map */
+       __map_region(md, efi_va);
+       md->virt_addr = efi_va;
+}
+
 void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
                                 u32 type, u64 attribute)
 {
index 4c07ccab8146f0bbed2850f586a68f126b2bc7eb..88073b1402988b49eb6c5e95f9f801a14d40f144 100644 (file)
        mov %rsi, %cr0;                 \
        mov (%rsp), %rsp
 
+       /* stolen from gcc */
+       .macro FLUSH_TLB_ALL
+       movq %r15, efi_scratch(%rip)
+       movq %r14, efi_scratch+8(%rip)
+       movq %cr4, %r15
+       movq %r15, %r14
+       andb $0x7f, %r14b
+       movq %r14, %cr4
+       movq %r15, %cr4
+       movq efi_scratch+8(%rip), %r14
+       movq efi_scratch(%rip), %r15
+       .endm
+
+       .macro SWITCH_PGT
+       cmpb $0, efi_scratch+24(%rip)
+       je 1f
+       movq %r15, efi_scratch(%rip)            # r15
+       # save previous CR3
+       movq %cr3, %r15
+       movq %r15, efi_scratch+8(%rip)          # prev_cr3
+       movq efi_scratch+16(%rip), %r15         # EFI pgt
+       movq %r15, %cr3
+       1:
+       .endm
+
+       .macro RESTORE_PGT
+       cmpb $0, efi_scratch+24(%rip)
+       je 2f
+       movq efi_scratch+8(%rip), %r15
+       movq %r15, %cr3
+       movq efi_scratch(%rip), %r15
+       FLUSH_TLB_ALL
+       2:
+       .endm
+
 ENTRY(efi_call0)
        SAVE_XMM
        subq $32, %rsp
+       SWITCH_PGT
        call *%rdi
+       RESTORE_PGT
        addq $32, %rsp
        RESTORE_XMM
        ret
@@ -47,7 +84,9 @@ ENTRY(efi_call1)
        SAVE_XMM
        subq $32, %rsp
        mov  %rsi, %rcx
+       SWITCH_PGT
        call *%rdi
+       RESTORE_PGT
        addq $32, %rsp
        RESTORE_XMM
        ret
@@ -57,7 +96,9 @@ ENTRY(efi_call2)
        SAVE_XMM
        subq $32, %rsp
        mov  %rsi, %rcx
+       SWITCH_PGT
        call *%rdi
+       RESTORE_PGT
        addq $32, %rsp
        RESTORE_XMM
        ret
@@ -68,7 +109,9 @@ ENTRY(efi_call3)
        subq $32, %rsp
        mov  %rcx, %r8
        mov  %rsi, %rcx
+       SWITCH_PGT
        call *%rdi
+       RESTORE_PGT
        addq $32, %rsp
        RESTORE_XMM
        ret
@@ -80,7 +123,9 @@ ENTRY(efi_call4)
        mov %r8, %r9
        mov %rcx, %r8
        mov %rsi, %rcx
+       SWITCH_PGT
        call *%rdi
+       RESTORE_PGT
        addq $32, %rsp
        RESTORE_XMM
        ret
@@ -93,7 +138,9 @@ ENTRY(efi_call5)
        mov %r8, %r9
        mov %rcx, %r8
        mov %rsi, %rcx
+       SWITCH_PGT
        call *%rdi
+       RESTORE_PGT
        addq $48, %rsp
        RESTORE_XMM
        ret
@@ -109,8 +156,15 @@ ENTRY(efi_call6)
        mov %r8, %r9
        mov %rcx, %r8
        mov %rsi, %rcx
+       SWITCH_PGT
        call *%rdi
+       RESTORE_PGT
        addq $48, %rsp
        RESTORE_XMM
        ret
 ENDPROC(efi_call6)
+
+       .data
+ENTRY(efi_scratch)
+       .fill 3,8,0
+       .byte 0
index 649a12befba92f399895b947cc779e0269ac750d..08e350e757dcd189c29e06d4d0b199a2cd920b9f 100644 (file)
@@ -15,8 +15,7 @@
 #include <linux/power_supply.h>
 #include <linux/olpc-ec.h>
 
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <asm/olpc.h>
 
 #define DRV_NAME                       "olpc-xo15-sci"
index f7bab68a4b83e4094db9b70c50292fddd88098c1..11f9285a2ff66726b6c62c7eb608e03f516dcc27 100644 (file)
@@ -722,15 +722,25 @@ static void percpu_init(void)
 
 /*
  * Check to see if a symbol lies in the .data..percpu section.
- * For some as yet not understood reason the "__init_begin"
- * symbol which immediately preceeds the .data..percpu section
- * also shows up as it it were part of it so we do an explict
- * check for that symbol name and ignore it.
+ *
+ * The linker incorrectly associates some symbols with the
+ * .data..percpu section so we also need to check the symbol
+ * name to make sure that we classify the symbol correctly.
+ *
+ * The GNU linker incorrectly associates:
+ *     __init_begin
+ *     __per_cpu_load
+ *
+ * The "gold" linker incorrectly associates:
+ *     init_per_cpu__irq_stack_union
+ *     init_per_cpu__gdt_page
  */
 static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
 {
        return (sym->st_shndx == per_cpu_shndx) &&
-               strcmp(symname, "__init_begin");
+               strcmp(symname, "__init_begin") &&
+               strcmp(symname, "__per_cpu_load") &&
+               strncmp(symname, "init_per_cpu_", 13);
 }
 
 
index 8d24dcb7cdac6df122e6779080b5e31b234a6ee5..70a160be3464aa0858e87d5c29816085308d1ef7 100644 (file)
@@ -9,7 +9,6 @@ config XTENSA
        select GENERIC_CLOCKEVENTS
        select VIRT_TO_BUS
        select GENERIC_IRQ_SHOW
-       select GENERIC_CPU_DEVICES
        select GENERIC_SCHED_CLOCK
        select MODULES_USE_ELF_RELA
        select GENERIC_PCI_IOMAP
@@ -19,6 +18,7 @@ config XTENSA
        select IRQ_DOMAIN
        select HAVE_OPROFILE
        select HAVE_FUNCTION_TRACER
+       select HAVE_IRQ_TIME_ACCOUNTING
        help
          Xtensa processors are 32-bit RISC machines designed by Tensilica
          primarily for embedded systems.  These processors are both
@@ -64,6 +64,9 @@ config MMU
 config VARIANT_IRQ_SWITCH
        def_bool n
 
+config MAY_HAVE_SMP
+       def_bool n
+
 menu "Processor type and features"
 
 choice
@@ -104,6 +107,48 @@ config XTENSA_UNALIGNED_USER
 
 source "kernel/Kconfig.preempt"
 
+config HAVE_SMP
+       bool "System Supports SMP (MX)"
+       depends on MAY_HAVE_SMP
+       select XTENSA_MX
+       help
+         This option is use to indicate that the system-on-a-chip (SOC)
+         supports Multiprocessing. Multiprocessor support implemented above
+         the CPU core definition and currently needs to be selected manually.
+
+         Multiprocessor support in implemented with external cache and
+         interrupt controlers.
+
+         The MX interrupt distributer adds Interprocessor Interrupts
+         and causes the IRQ numbers to be increased by 4 for devices
+         like the open cores ethernet driver and the serial interface.
+
+         You still have to select "Enable SMP" to enable SMP on this SOC.
+
+config SMP
+       bool "Enable Symmetric multi-processing support"
+       depends on HAVE_SMP
+       select USE_GENERIC_SMP_HELPERS
+       select GENERIC_SMP_IDLE_THREAD
+       help
+         Enabled SMP Software; allows more than one CPU/CORE
+         to be activated during startup.
+
+config NR_CPUS
+       depends on SMP
+       int "Maximum number of CPUs (2-32)"
+       range 2 32
+       default "4"
+
+config HOTPLUG_CPU
+       bool "Enable CPU hotplug support"
+       depends on SMP
+       help
+         Say Y here to allow turning CPUs off and on. CPUs can be
+         controlled through /sys/devices/system/cpu.
+
+         Say N if you want to disable CPU hotplug.
+
 config MATH_EMULATION
        bool "Math emulation"
        help
index 228d6aee3a16528f0e5972371e5a1fd6feac9a79..5851db291583face7d032c2929dd5c91b58204d6 100644 (file)
@@ -8,7 +8,6 @@ generic-y += emergency-restart.h
 generic-y += errno.h
 generic-y += exec.h
 generic-y += fcntl.h
-generic-y += futex.h
 generic-y += hardirq.h
 generic-y += ioctl.h
 generic-y += irq_regs.h
index ef021677d536538c817021c89f0841ada0ed0c30..8e5e5c980a7a4b1b01708c8160e0559f5ad63963 100644 (file)
@@ -17,7 +17,9 @@
 #define wmb() mb()
 
 #ifdef CONFIG_SMP
-#error smp_* not defined
+#define smp_mb()       mb()
+#define smp_rmb()      rmb()
+#define smp_wmb()      wmb()
 #else
 #define smp_mb()       barrier()
 #define smp_rmb()      barrier()
index 84afe58d5d374bc7cc19f8d02dbcc279b3b0014a..7b6873ae84c295740d8183b52610ba0ce91aad91 100644 (file)
 #include <asm/processor.h>
 #include <asm/byteorder.h>
 
-#ifdef CONFIG_SMP
-# error SMP not supported on this architecture
-#endif
-
-#define smp_mb__before_clear_bit()     barrier()
-#define smp_mb__after_clear_bit()      barrier()
+#define smp_mb__before_clear_bit()     smp_mb()
+#define smp_mb__after_clear_bit()      smp_mb()
 
 #include <asm-generic/bitops/non-atomic.h>
 
index 127cd48883c4274526c63631b181bea6dc366941..555a98a1845363588ced5fd3ec26a2269846e3d8 100644 (file)
@@ -1,18 +1,14 @@
 /*
- * include/asm-xtensa/cacheflush.h
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * (C) 2001 - 2007 Tensilica Inc.
+ * (C) 2001 - 2013 Tensilica Inc.
  */
 
 #ifndef _XTENSA_CACHEFLUSH_H
 #define _XTENSA_CACHEFLUSH_H
 
-#ifdef __KERNEL__
-
 #include <linux/mm.h>
 #include <asm/processor.h>
 #include <asm/page.h>
@@ -51,7 +47,6 @@ extern void __invalidate_icache_page(unsigned long);
 extern void __invalidate_icache_range(unsigned long, unsigned long);
 extern void __invalidate_dcache_range(unsigned long, unsigned long);
 
-
 #if XCHAL_DCACHE_IS_WRITEBACK
 extern void __flush_invalidate_dcache_all(void);
 extern void __flush_dcache_page(unsigned long);
@@ -87,9 +82,22 @@ static inline void __invalidate_icache_page_alias(unsigned long virt,
  * (see also Documentation/cachetlb.txt)
  */
 
-#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) || defined(CONFIG_SMP)
+
+#ifdef CONFIG_SMP
+void flush_cache_all(void);
+void flush_cache_range(struct vm_area_struct*, ulong, ulong);
+void flush_icache_range(unsigned long start, unsigned long end);
+void flush_cache_page(struct vm_area_struct*,
+                            unsigned long, unsigned long);
+#else
+#define flush_cache_all local_flush_cache_all
+#define flush_cache_range local_flush_cache_range
+#define flush_icache_range local_flush_icache_range
+#define flush_cache_page  local_flush_cache_page
+#endif
 
-#define flush_cache_all()                                              \
+#define local_flush_cache_all()                                                \
        do {                                                            \
                __flush_invalidate_dcache_all();                        \
                __invalidate_icache_all();                              \
@@ -103,9 +111,11 @@ static inline void __invalidate_icache_page_alias(unsigned long virt,
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page*);
-extern void flush_cache_range(struct vm_area_struct*, ulong, ulong);
-extern void flush_cache_page(struct vm_area_struct*,
-                            unsigned long, unsigned long);
+
+void local_flush_cache_range(struct vm_area_struct *vma,
+               unsigned long start, unsigned long end);
+void local_flush_cache_page(struct vm_area_struct *vma,
+               unsigned long address, unsigned long pfn);
 
 #else
 
@@ -119,13 +129,14 @@ extern void flush_cache_page(struct vm_area_struct*,
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)                                do { } while (0)
 
-#define flush_cache_page(vma,addr,pfn)                 do { } while (0)
-#define flush_cache_range(vma,start,end)               do { } while (0)
+#define flush_icache_range local_flush_icache_range
+#define flush_cache_page(vma, addr, pfn)               do { } while (0)
+#define flush_cache_range(vma, start, end)             do { } while (0)
 
 #endif
 
 /* Ensure consistency between data and instruction cache. */
-#define flush_icache_range(start,end)                                  \
+#define local_flush_icache_range(start, end)                           \
        do {                                                            \
                __flush_dcache_range(start, (end) - (start));           \
                __invalidate_icache_range(start,(end) - (start));       \
@@ -253,5 +264,4 @@ static inline void flush_invalidate_dcache_unaligned(u32 addr, u32 size)
        }
 }
 
-#endif /* __KERNEL__ */
 #endif /* _XTENSA_CACHEFLUSH_H */
index 3899610c1dfff71a53e0144969fd990e59e75f62..742b89f3ca2cf22d535b21441383b97256bf5903 100644 (file)
@@ -19,9 +19,12 @@ extern unsigned long loops_per_jiffy;
 
 static inline void __delay(unsigned long loops)
 {
-       /* 2 cycles per loop. */
-       __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b"
-                             : "=r" (loops) : "0" (loops));
+       if (__builtin_constant_p(loops) && loops < 2)
+               __asm__ __volatile__ ("nop");
+       else if (loops >= 2)
+               /* 2 cycles per loop. */
+               __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b"
+                               : "+r" (loops));
 }
 
 /* For SMP/NUMA systems, change boot_cpu_data to something like
index 73cc3f482304e35f9144d451e3fefab59fe8c6c0..736b9d214d8016012393c7914d03d89fb5eacfa6 100644 (file)
@@ -18,7 +18,7 @@
                __asm__ __volatile__ ( \
                        "mov %0, a0\n" \
                        "mov %1, a1\n" \
-                       : "=r"(a0), "=r"(a1) : : ); \
+                       : "=r"(a0), "=r"(a1)); \
                MAKE_PC_FROM_RA(a0, a1); })
 #ifdef CONFIG_FRAME_POINTER
 extern unsigned long return_address(unsigned level);
diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h
new file mode 100644 (file)
index 0000000..b39531b
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Atomic futex routines
+ *
+ * Based on the PowerPC implementataion
+ *
+ * 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.
+ *
+ * Copyright (C) 2013 TangoTec Ltd.
+ *
+ * Baruch Siach <baruch@tkos.co.il>
+ */
+
+#ifndef _ASM_XTENSA_FUTEX_H
+#define _ASM_XTENSA_FUTEX_H
+
+#ifdef __KERNEL__
+
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <linux/errno.h>
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
+       __asm__ __volatile(                             \
+       "1:     l32i    %0, %2, 0\n"                    \
+               insn "\n"                               \
+       "       wsr     %0, scompare1\n"                \
+       "2:     s32c1i  %1, %2, 0\n"                    \
+       "       bne     %1, %0, 1b\n"                   \
+       "       movi    %1, 0\n"                        \
+       "3:\n"                                          \
+       "       .section .fixup,\"ax\"\n"               \
+       "       .align 4\n"                             \
+       "4:     .long   3b\n"                           \
+       "5:     l32r    %0, 4b\n"                       \
+       "       movi    %1, %3\n"                       \
+       "       jx      %0\n"                           \
+       "       .previous\n"                            \
+       "       .section __ex_table,\"a\"\n"            \
+       "       .long 1b,5b,2b,5b\n"                    \
+       "       .previous\n"                            \
+       : "=&r" (oldval), "=&r" (ret)                   \
+       : "r" (uaddr), "I" (-EFAULT), "r" (oparg)       \
+       : "memory")
+
+static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
+{
+       int op = (encoded_op >> 28) & 7;
+       int cmp = (encoded_op >> 24) & 15;
+       int oparg = (encoded_op << 8) >> 20;
+       int cmparg = (encoded_op << 20) >> 20;
+       int oldval = 0, ret;
+       if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+               oparg = 1 << oparg;
+
+       if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+               return -EFAULT;
+
+#if !XCHAL_HAVE_S32C1I
+       return -ENOSYS;
+#endif
+
+       pagefault_disable();
+
+       switch (op) {
+       case FUTEX_OP_SET:
+               __futex_atomic_op("mov %1, %4", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_ADD:
+               __futex_atomic_op("add %1, %0, %4", ret, oldval, uaddr,
+                               oparg);
+               break;
+       case FUTEX_OP_OR:
+               __futex_atomic_op("or %1, %0, %4", ret, oldval, uaddr,
+                               oparg);
+               break;
+       case FUTEX_OP_ANDN:
+               __futex_atomic_op("and %1, %0, %4", ret, oldval, uaddr,
+                               ~oparg);
+               break;
+       case FUTEX_OP_XOR:
+               __futex_atomic_op("xor %1, %0, %4", ret, oldval, uaddr,
+                               oparg);
+               break;
+       default:
+               ret = -ENOSYS;
+       }
+
+       pagefault_enable();
+
+       if (ret)
+               return ret;
+
+       switch (cmp) {
+       case FUTEX_OP_CMP_EQ: return (oldval == cmparg);
+       case FUTEX_OP_CMP_NE: return (oldval != cmparg);
+       case FUTEX_OP_CMP_LT: return (oldval < cmparg);
+       case FUTEX_OP_CMP_GE: return (oldval >= cmparg);
+       case FUTEX_OP_CMP_LE: return (oldval <= cmparg);
+       case FUTEX_OP_CMP_GT: return (oldval > cmparg);
+       }
+
+       return -ENOSYS;
+}
+
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+                             u32 oldval, u32 newval)
+{
+       int ret = 0;
+       u32 prev;
+
+       if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+               return -EFAULT;
+
+#if !XCHAL_HAVE_S32C1I
+       return -ENOSYS;
+#endif
+
+       __asm__ __volatile__ (
+       "       # futex_atomic_cmpxchg_inatomic\n"
+       "1:     l32i    %1, %3, 0\n"
+       "       mov     %0, %5\n"
+       "       wsr     %1, scompare1\n"
+       "2:     s32c1i  %0, %3, 0\n"
+       "3:\n"
+       "       .section .fixup,\"ax\"\n"
+       "       .align 4\n"
+       "4:     .long   3b\n"
+       "5:     l32r    %1, 4b\n"
+       "       movi    %0, %6\n"
+       "       jx      %1\n"
+       "       .previous\n"
+       "       .section __ex_table,\"a\"\n"
+       "       .long 1b,5b,2b,5b\n"
+       "       .previous\n"
+       : "+r" (ret), "=&r" (prev), "+m" (*uaddr)
+       : "r" (uaddr), "r" (oldval), "r" (newval), "I" (-EFAULT)
+       : "memory");
+
+       *uval = prev;
+       return ret;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_XTENSA_FUTEX_H */
index 4c0ccc9c4f4c0adf0a8ac6212818567749147fed..f71f88ea7646dcc798067e984dddefa8a659037d 100644 (file)
@@ -43,5 +43,14 @@ static __inline__ int irq_canonicalize(int irq)
 }
 
 struct irqaction;
+struct irq_domain;
+
+void migrate_irqs(void);
+int xtensa_irq_domain_xlate(const u32 *intspec, unsigned int intsize,
+               unsigned long int_irq, unsigned long ext_irq,
+               unsigned long *out_hwirq, unsigned int *out_type);
+int xtensa_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw);
+unsigned xtensa_map_ext_irq(unsigned ext_irq);
+unsigned xtensa_get_ext_irq_no(unsigned irq);
 
 #endif /* _XTENSA_IRQ_H */
index 8554b2c8b17a0128bc873f2d67b194462f89c2bf..71afe418d0e53e2d9239b261cd34a2efc8d4f9ac 100644 (file)
@@ -1,11 +1,9 @@
 /*
- * include/asm-xtensa/mmu.h
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2013 Tensilica Inc.
  */
 
 #ifndef _XTENSA_MMU_H
 #include <asm-generic/mmu.h>
 #else
 
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_t;
+typedef struct {
+       unsigned long asid[NR_CPUS];
+       unsigned int cpu;
+} mm_context_t;
 
 #endif /* CONFIG_MMU */
 #endif /* _XTENSA_MMU_H */
index d43525a286bbf248b43e36fb878f6ee7fb31fa1e..d33c71a8c9ec69285fc508e653a0acfee3a691fa 100644 (file)
@@ -1,13 +1,11 @@
 /*
- * include/asm-xtensa/mmu_context.h
- *
  * Switch an MMU context.
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2013 Tensilica Inc.
  */
 
 #ifndef _XTENSA_MMU_CONTEXT_H
 #include <linux/stringify.h>
 #include <linux/sched.h>
 
-#include <variant/core.h>
+#include <asm/vectors.h>
 
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm-generic/mm_hooks.h>
+#include <asm-generic/percpu.h>
 
 #if (XCHAL_HAVE_TLBS != 1)
 # error "Linux must have an MMU!"
 #endif
 
-extern unsigned long asid_cache;
+DECLARE_PER_CPU(unsigned long, asid_cache);
+#define cpu_asid_cache(cpu) per_cpu(asid_cache, cpu)
 
 /*
  * NO_CONTEXT is the invalid ASID value that we don't ever assign to
- * any user or kernel context.
+ * any user or kernel context.  We use the reserved values in the
+ * ASID_INSERT macro below.
  *
  * 0 invalid
  * 1 kernel
@@ -49,6 +50,12 @@ extern unsigned long asid_cache;
 #define ASID_MASK      ((1 << XCHAL_MMU_ASID_BITS) - 1)
 #define ASID_INSERT(x) (0x03020001 | (((x) & ASID_MASK) << 8))
 
+#ifdef CONFIG_MMU
+void init_mmu(void);
+#else
+static inline void init_mmu(void) { }
+#endif
+
 static inline void set_rasid_register (unsigned long val)
 {
        __asm__ __volatile__ (" wsr %0, rasid\n\t"
@@ -62,64 +69,77 @@ static inline unsigned long get_rasid_register (void)
        return tmp;
 }
 
-static inline void
-__get_new_mmu_context(struct mm_struct *mm)
+static inline void get_new_mmu_context(struct mm_struct *mm, unsigned int cpu)
 {
-       extern void flush_tlb_all(void);
-       if (! (++asid_cache & ASID_MASK) ) {
-               flush_tlb_all(); /* start new asid cycle */
-               asid_cache += ASID_USER_FIRST;
+       unsigned long asid = cpu_asid_cache(cpu);
+       if ((++asid & ASID_MASK) == 0) {
+               /*
+                * Start new asid cycle; continue counting with next
+                * incarnation bits; skipping over 0, 1, 2, 3.
+                */
+               local_flush_tlb_all();
+               asid += ASID_USER_FIRST;
        }
-       mm->context = asid_cache;
+       cpu_asid_cache(cpu) = asid;
+       mm->context.asid[cpu] = asid;
+       mm->context.cpu = cpu;
 }
 
-static inline void
-__load_mmu_context(struct mm_struct *mm)
+static inline void get_mmu_context(struct mm_struct *mm, unsigned int cpu)
 {
-       set_rasid_register(ASID_INSERT(mm->context));
+       /*
+        * Check if our ASID is of an older version and thus invalid.
+        */
+
+       if (mm) {
+               unsigned long asid = mm->context.asid[cpu];
+
+               if (asid == NO_CONTEXT ||
+                               ((asid ^ cpu_asid_cache(cpu)) & ~ASID_MASK))
+                       get_new_mmu_context(mm, cpu);
+       }
+}
+
+static inline void activate_context(struct mm_struct *mm, unsigned int cpu)
+{
+       get_mmu_context(mm, cpu);
+       set_rasid_register(ASID_INSERT(mm->context.asid[cpu]));
        invalidate_page_directory();
 }
 
 /*
  * Initialize the context related info for a new mm_struct
- * instance.
+ * instance.  Valid cpu values are 0..(NR_CPUS-1), so initializing
+ * to -1 says the process has never run on any core.
  */
 
-static inline int
-init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+static inline int init_new_context(struct task_struct *tsk,
+               struct mm_struct *mm)
 {
-       mm->context = NO_CONTEXT;
+       int cpu;
+       for_each_possible_cpu(cpu) {
+               mm->context.asid[cpu] = NO_CONTEXT;
+       }
+       mm->context.cpu = -1;
        return 0;
 }
 
-/*
- * After we have set current->mm to a new value, this activates
- * the context for the new mm so we see the new mappings.
- */
-static inline void
-activate_mm(struct mm_struct *prev, struct mm_struct *next)
-{
-       /* Unconditionally get a new ASID.  */
-
-       __get_new_mmu_context(next);
-       __load_mmu_context(next);
-}
-
-
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
                             struct task_struct *tsk)
 {
-       unsigned long asid = asid_cache;
-
-       /* Check if our ASID is of an older version and thus invalid */
-
-       if (next->context == NO_CONTEXT || ((next->context^asid) & ~ASID_MASK))
-               __get_new_mmu_context(next);
-
-       __load_mmu_context(next);
+       unsigned int cpu = smp_processor_id();
+       int migrated = next->context.cpu != cpu;
+       /* Flush the icache if we migrated to a new core. */
+       if (migrated) {
+               __invalidate_icache_all();
+               next->context.cpu = cpu;
+       }
+       if (migrated || prev != next)
+               activate_context(next, cpu);
 }
 
-#define deactivate_mm(tsk, mm) do { } while(0)
+#define activate_mm(prev, next)        switch_mm((prev), (next), NULL)
+#define deactivate_mm(tsk, mm) do { } while (0)
 
 /*
  * Destroy context related info for an mm_struct that is about
diff --git a/arch/xtensa/include/asm/mxregs.h b/arch/xtensa/include/asm/mxregs.h
new file mode 100644 (file)
index 0000000..73dcc54
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Xtensa MX interrupt distributor
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 - 2013 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_MXREGS_H
+#define _XTENSA_MXREGS_H
+
+/*
+ * RER/WER at, as      Read/write external register
+ *     at: value
+ *     as: address
+ *
+ * Address     Value
+ * 00nn                0...0p..p       Interrupt Routing, route IRQ n to processor p
+ * 01pp                0...0d..d       16 bits (d) 'ored' as single IPI to processor p
+ * 0180                0...0m..m       Clear enable specified by mask (m)
+ * 0184                0...0m..m       Set enable specified by mask (m)
+ * 0190                0...0x..x       8-bit IPI partition register
+ *                             VVVVVVVVPPPPUUUUUUUUUUUUUUUUU
+ *                             V (10-bit) Release/Version
+ *                             P ( 4-bit) Number of cores - 1
+ *                             U (18-bit) ID
+ * 01a0                i.......i       32-bit ConfigID
+ * 0200                0...0m..m       RunStall core 'n'
+ * 0220                c               Cache coherency enabled
+ */
+
+#define MIROUT(irq)    (0x000 + (irq))
+#define MIPICAUSE(cpu) (0x100 + (cpu))
+#define MIPISET(cause) (0x140 + (cause))
+#define MIENG          0x180
+#define MIENGSET       0x184
+#define MIASG          0x188   /* Read Global Assert Register */
+#define MIASGSET       0x18c   /* Set Global Addert Regiter */
+#define MIPIPART       0x190
+#define SYSCFGID       0x1a0
+#define MPSCORE                0x200
+#define CCON           0x220
+
+#endif /* _XTENSA_MXREGS_H */
index 7e409a5b0ec50d8bf38848ff54b9ec4d058141dc..abb59708a3b75bf6ac8398be37e4fc90c349dff0 100644 (file)
@@ -191,5 +191,25 @@ extern unsigned long get_wchan(struct task_struct *p);
 #define set_sr(x,sr) ({unsigned int v=(unsigned int)x; WSR(v,sr);})
 #define get_sr(sr) ({unsigned int v; RSR(v,sr); v; })
 
+#ifndef XCHAL_HAVE_EXTERN_REGS
+#define XCHAL_HAVE_EXTERN_REGS 0
+#endif
+
+#if XCHAL_HAVE_EXTERN_REGS
+
+static inline void set_er(unsigned long value, unsigned long addr)
+{
+       asm volatile ("wer %0, %1" : : "a" (value), "a" (addr) : "memory");
+}
+
+static inline unsigned long get_er(unsigned long addr)
+{
+       register unsigned long value;
+       asm volatile ("rer %0, %1" : "=a" (value) : "a" (addr) : "memory");
+       return value;
+}
+
+#endif /* XCHAL_HAVE_EXTERN_REGS */
+
 #endif /* __ASSEMBLY__ */
 #endif /* _XTENSA_PROCESSOR_H */
index 81f31bc9dde0a857a95e9f794e09e84fa6f6c1d7..598e752dcbcd009392230869af2851afd14e4085 100644 (file)
@@ -59,9 +59,17 @@ struct pt_regs {
        (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1)
 # define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
 # define instruction_pointer(regs) ((regs)->pc)
+# define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \
+                                              (regs)->areg[1]))
 
 # ifndef CONFIG_SMP
 #  define profile_pc(regs) instruction_pointer(regs)
+# else
+#  define profile_pc(regs)                                             \
+       ({                                                              \
+               in_lock_functions(instruction_pointer(regs)) ?          \
+               return_pointer(regs) : instruction_pointer(regs);       \
+       })
 # endif
 
 #define user_stack_pointer(regs) ((regs)->areg[1])
index 83c569e3bdbd23245dccf2e3ea7e92010589eafe..4e43f564389161687441c59168acb0e2f638b45b 100644 (file)
@@ -1,27 +1,43 @@
 /*
- * include/asm-xtensa/smp.h
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2013 Tensilica Inc.
  */
 
 #ifndef _XTENSA_SMP_H
 #define _XTENSA_SMP_H
 
-extern struct xtensa_cpuinfo boot_cpu_data;
+#ifdef CONFIG_SMP
 
-#define cpu_data (&boot_cpu_data)
-#define current_cpu_data boot_cpu_data
+#define raw_smp_processor_id() (current_thread_info()->cpu)
+#define cpu_logical_map(cpu)   (cpu)
 
-struct xtensa_cpuinfo {
-       unsigned long   *pgd_cache;
-       unsigned long   *pte_cache;
-       unsigned long   pgtable_cache_sz;
+struct start_info {
+       unsigned long stack;
 };
+extern struct start_info start_info;
 
-#define cpu_logical_map(cpu)   (cpu)
+struct cpumask;
+void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+void arch_send_call_function_single_ipi(int cpu);
+
+void smp_init_cpus(void);
+void secondary_init_irq(void);
+void ipi_init(void);
+struct seq_file;
+void show_ipi_list(struct seq_file *p, int prec);
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+void __cpu_die(unsigned int cpu);
+int __cpu_disable(void);
+void cpu_die(void);
+void cpu_restart(void);
+
+#endif /* CONFIG_HOTPLUG_CPU */
+
+#endif /* CONFIG_SMP */
 
 #endif /* _XTENSA_SMP_H */
index 03975906b36fc34dc6a47abbe979c899ddc4f3e0..1d95fa5dcd10f0121f394e22fb108682c17741aa 100644 (file)
  *    1         somebody owns the spinlock
  */
 
-#define __raw_spin_is_locked(x) ((x)->slock != 0)
-#define __raw_spin_unlock_wait(lock) \
-       do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+#define arch_spin_is_locked(x) ((x)->slock != 0)
+#define arch_spin_unlock_wait(lock) \
+       do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
        unsigned long tmp;
 
@@ -51,7 +51,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
 
 /* Returns 1 if the lock is obtained, 0 otherwise. */
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
        unsigned long tmp;
 
@@ -67,7 +67,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock)
        return tmp == 0 ? 1 : 0;
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
        unsigned long tmp;
 
@@ -96,9 +96,9 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
  *  0x80000000  one writer owns the rwlock, no other writers, no readers
  */
 
-#define __raw_write_can_lock(x)  ((x)->lock == 0)
+#define arch_write_can_lock(x)  ((x)->lock == 0)
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
        unsigned long tmp;
 
@@ -116,7 +116,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
 
 /* Returns 1 if the lock is obtained, 0 otherwise. */
 
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
        unsigned long tmp;
 
@@ -133,7 +133,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
        return tmp == 0 ? 1 : 0;
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
        unsigned long tmp;
 
@@ -145,7 +145,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
                        : "memory");
 }
 
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
        unsigned long tmp;
        unsigned long result;
@@ -164,7 +164,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
 
 /* Returns 1 if the lock is obtained, 0 otherwise. */
 
-static inline int __raw_read_trylock(raw_rwlock_t *rw)
+static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
        unsigned long result;
        unsigned long tmp;
@@ -184,7 +184,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
        return result == 0;
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
        unsigned long tmp1, tmp2;
 
@@ -199,4 +199,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
                        : "memory");
 }
 
+#define arch_read_lock_flags(lock, flags)      arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags)     arch_write_lock(lock)
+
 #endif /* _XTENSA_SPINLOCK_H */
diff --git a/arch/xtensa/include/asm/spinlock_types.h b/arch/xtensa/include/asm/spinlock_types.h
new file mode 100644 (file)
index 0000000..7ec5ce1
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+       volatile unsigned int slock;
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED      { 0 }
+
+typedef struct {
+       volatile unsigned int lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED                { 0 }
+
+#endif
index 27fa3c1706623805168f6914f952d777993edbf2..ca929e6a38b5f70a5e1e2d1492b1cdde5e5f0e2a 100644 (file)
@@ -1,18 +1,14 @@
 /*
- * include/asm-xtensa/timex.h
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 - 2008 Tensilica Inc.
+ * Copyright (C) 2001 - 2013 Tensilica Inc.
  */
 
 #ifndef _XTENSA_TIMEX_H
 #define _XTENSA_TIMEX_H
 
-#ifdef __KERNEL__
-
 #include <asm/processor.h>
 #include <linux/stringify.h>
 
@@ -39,14 +35,9 @@ extern unsigned long ccount_freq;
 
 typedef unsigned long long cycles_t;
 
-/*
- * Only used for SMP.
- */
-
-extern cycles_t cacheflush_time;
-
 #define get_cycles()   (0)
 
+void local_timer_setup(unsigned cpu);
 
 /*
  * Register access.
@@ -81,5 +72,4 @@ static inline void set_linux_timer (unsigned long ccompare)
        WSR_CCOMPARE(LINUX_TIMER, ccompare);
 }
 
-#endif /* __KERNEL__ */
 #endif /* _XTENSA_TIMEX_H */
index 43dd348a5a478d27daa70f2e8b019b8cfa0fcd22..fc34274ce41bc81b3ddaa167fe887179f04c8ad7 100644 (file)
@@ -1,18 +1,14 @@
 /*
- * include/asm-xtensa/tlbflush.h
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2013 Tensilica Inc.
  */
 
 #ifndef _XTENSA_TLBFLUSH_H
 #define _XTENSA_TLBFLUSH_H
 
-#ifdef __KERNEL__
-
 #include <linux/stringify.h>
 #include <asm/processor.h>
 
  *  - flush_tlb_range(mm, start, end) flushes a range of pages
  */
 
-extern void flush_tlb_all(void);
-extern void flush_tlb_mm(struct mm_struct*);
-extern void flush_tlb_page(struct vm_area_struct*,unsigned long);
-extern void flush_tlb_range(struct vm_area_struct*,unsigned long,unsigned long);
+void local_flush_tlb_all(void);
+void local_flush_tlb_mm(struct mm_struct *mm);
+void local_flush_tlb_page(struct vm_area_struct *vma,
+               unsigned long page);
+void local_flush_tlb_range(struct vm_area_struct *vma,
+               unsigned long start, unsigned long end);
+
+#ifdef CONFIG_SMP
+
+void flush_tlb_all(void);
+void flush_tlb_mm(struct mm_struct *);
+void flush_tlb_page(struct vm_area_struct *, unsigned long);
+void flush_tlb_range(struct vm_area_struct *, unsigned long,
+               unsigned long);
+
+static inline void flush_tlb_kernel_range(unsigned long start,
+               unsigned long end)
+{
+       flush_tlb_all();
+}
+
+#else /* !CONFIG_SMP */
+
+#define flush_tlb_all()                           local_flush_tlb_all()
+#define flush_tlb_mm(mm)                  local_flush_tlb_mm(mm)
+#define flush_tlb_page(vma, page)         local_flush_tlb_page(vma, page)
+#define flush_tlb_range(vma, vmaddr, end)  local_flush_tlb_range(vma, vmaddr, \
+                                                                end)
+#define flush_tlb_kernel_range(start, end) local_flush_tlb_all()
 
-#define flush_tlb_kernel_range(start,end) flush_tlb_all()
+#endif /* CONFIG_SMP */
 
 /* TLB operations. */
 
@@ -187,5 +208,4 @@ static inline unsigned long read_itlb_translation (int way)
 }
 
 #endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
 #endif /* _XTENSA_TLBFLUSH_H */
index 917488a0ab00f12b9c49ac7e13b72ea5ea28eecb..8c194f6af45e09932976b3f71d8d70a8f556488f 100644 (file)
@@ -19,6 +19,7 @@
  */
 extern void * __init trap_set_handler(int cause, void *handler);
 extern void do_unhandled(struct pt_regs *regs, unsigned long exccause);
+void secondary_trap_init(void);
 
 static inline void spill_registers(void)
 {
index c52b656d0310cb994085844a9b90e32543b36d5b..37e073b21a50e7d0d713ca002fa745ebe3305349 100644 (file)
 
 #if defined(XCHAL_HAVE_PTP_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
   /* MMU v3  - XCHAL_HAVE_PTP_MMU  == 1 */
-  #define PHYSICAL_MEMORY_ADDRESS      0x00000000
   #define LOAD_MEMORY_ADDRESS          0x00003000
 #else
   /* MMU V2 -  XCHAL_HAVE_PTP_MMU  == 0 */
-  #define PHYSICAL_MEMORY_ADDRESS      0xD0000000
   #define LOAD_MEMORY_ADDRESS          0xD0003000
 #endif
 
@@ -46,7 +44,6 @@
 
   /* Location of the start of the kernel text, _start */
   #define KERNELOFFSET                 0x00003000
-  #define PHYSICAL_MEMORY_ADDRESS      0x00000000
 
   /* Loaded just above possibly live vectors */
   #define LOAD_MEMORY_ADDRESS          0x00003000
@@ -54,7 +51,6 @@
 #endif /* CONFIG_MMU */
 
 #define XC_VADDR(offset)               (VIRTUAL_MEMORY_ADDRESS  + offset)
-#define XC_PADDR(offset)               (PHYSICAL_MEMORY_ADDRESS + offset)
 
 /* Used to set VECBASE register */
 #define VECBASE_RESET_VADDR            VIRTUAL_MEMORY_ADDRESS
@@ -67,7 +63,7 @@
                                                VECBASE_RESET_VADDR)
 #define RESET_VECTOR1_VADDR            XC_VADDR(RESET_VECTOR1_VECOFS)
 
-#if XCHAL_HAVE_VECBASE
+#if defined(XCHAL_HAVE_VECBASE) && XCHAL_HAVE_VECBASE
 
 #define USER_VECTOR_VADDR              XC_VADDR(XCHAL_USER_VECOFS)
 #define KERNEL_VECTOR_VADDR            XC_VADDR(XCHAL_KERNEL_VECOFS)
 
 #define DEBUG_VECTOR_VADDR             XC_VADDR(XCHAL_DEBUG_VECOFS)
 
-#undef  XCHAL_NMI_VECTOR_VADDR
-#define XCHAL_NMI_VECTOR_VADDR         XC_VADDR(XCHAL_NMI_VECOFS)
+#define NMI_VECTOR_VADDR               XC_VADDR(XCHAL_NMI_VECOFS)
 
-#undef  XCHAL_INTLEVEL7_VECTOR_VADDR
-#define XCHAL_INTLEVEL7_VECTOR_VADDR   XC_VADDR(XCHAL_INTLEVEL7_VECOFS)
+#define INTLEVEL7_VECTOR_VADDR         XC_VADDR(XCHAL_INTLEVEL7_VECOFS)
 
 /*
  * These XCHAL_* #defines from varian/core.h
index f90265ec1ccca1bd5fed0849ffb708d6f7d965e8..18d962a8c0c2d1fccc5411fadbdc087bb5b05573 100644 (file)
@@ -12,6 +12,7 @@ obj-$(CONFIG_KGDB) += xtensa-stub.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
 obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
+obj-$(CONFIG_SMP) += smp.o mxhead.o
 
 AFLAGS_head.o += -mtext-section-literals
 
index 7d740ebbe198ec77a8011601f4172ebc809b9be8..aeeb3cc8a4109e59bc6ce5f23fd88c21c0450f3f 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/page.h>
 #include <asm/cacheasm.h>
 #include <asm/initialize_mmu.h>
+#include <asm/mxregs.h>
 
 #include <linux/init.h>
 #include <linux/linkage.h>
@@ -54,7 +55,7 @@ ENTRY(_start)
 
        /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
        wsr     a2, excsave1
-       _j      _SetupMMU
+       _j      _SetupOCD
 
        .align  4
        .literal_position
@@ -62,6 +63,23 @@ ENTRY(_start)
        .word   _startup
 
        .align  4
+_SetupOCD:
+       /*
+        * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions).
+        * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow
+        * xt-gdb to single step via DEBUG exceptions received directly
+        * by ocd.
+        */
+       movi    a1, 1
+       movi    a0, 0
+       wsr     a1, windowstart
+       wsr     a0, windowbase
+       rsync
+
+       movi    a1, LOCKLEVEL
+       wsr     a1, ps
+       rsync
+
        .global _SetupMMU
 _SetupMMU:
        Offset = _SetupMMU - _start
@@ -85,24 +103,11 @@ _SetupMMU:
 
 ENDPROC(_start)
 
-       __INIT
+       __REF
        .literal_position
 
 ENTRY(_startup)
 
-       /* Disable interrupts and exceptions. */
-
-       movi    a0, LOCKLEVEL
-       wsr     a0, ps
-
-       /* Start with a fresh windowbase and windowstart.  */
-
-       movi    a1, 1
-       movi    a0, 0
-       wsr     a1, windowstart
-       wsr     a0, windowbase
-       rsync
-
        /* Set a0 to 0 for the remaining initialization. */
 
        movi    a0, 0
@@ -154,17 +159,6 @@ ENTRY(_startup)
        wsr     a0, cpenable
 #endif
 
-       /* Set PS.INTLEVEL=LOCKLEVEL, PS.WOE=0, kernel stack, PS.EXCM=0
-        *
-        * Note: PS.EXCM must be cleared before using any loop
-        *       instructions; otherwise, they are silently disabled, and
-        *       at most one iteration of the loop is executed.
-        */
-
-       movi    a1, LOCKLEVEL
-       wsr     a1, ps
-       rsync
-
        /*  Initialize the caches.
         *  a2, a3 are just working registers (clobbered).
         */
@@ -182,6 +176,37 @@ ENTRY(_startup)
 
        isync
 
+#ifdef CONFIG_HAVE_SMP
+       movi    a2, CCON        # MX External Register to Configure Cache
+       movi    a3, 1
+       wer     a3, a2
+#endif
+
+       /* Setup stack and enable window exceptions (keep irqs disabled) */
+
+       movi    a1, start_info
+       l32i    a1, a1, 0
+
+       movi    a2, (1 << PS_WOE_BIT) | LOCKLEVEL
+                                       # WOE=1, INTLEVEL=LOCKLEVEL, UM=0
+       wsr     a2, ps                  # (enable reg-windows; progmode stack)
+       rsync
+
+       /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/
+
+       movi    a2, debug_exception
+       wsr     a2, SREG_EXCSAVE + XCHAL_DEBUGLEVEL
+
+#ifdef CONFIG_SMP
+       /*
+        * Notice that we assume with SMP that cores have PRID
+        * supported by the cores.
+        */
+       rsr     a2, prid
+       bnez    a2, .Lboot_secondary
+
+#endif  /* CONFIG_SMP */
+
        /* Unpack data sections
         *
         * The linker script used to build the Linux kernel image
@@ -234,24 +259,7 @@ ENTRY(_startup)
        ___invalidate_icache_all a2 a3
        isync
 
-       /* Setup stack and enable window exceptions (keep irqs disabled) */
-
-       movi    a1, init_thread_union
-       addi    a1, a1, KERNEL_STACK_SIZE
-
-       movi    a2, (1 << PS_WOE_BIT) | LOCKLEVEL
-                                       # WOE=1, INTLEVEL=LOCKLEVEL, UM=0
-       wsr     a2, ps                  # (enable reg-windows; progmode stack)
-       rsync
-
-       /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/
-
-       movi    a2, debug_exception
-       wsr     a2, SREG_EXCSAVE + XCHAL_DEBUGLEVEL
-
-       /* Set up EXCSAVE[1] to point to the exc_table. */
-
-       movi    a6, exc_table
+       movi    a6, 0
        xsr     a6, excsave1
 
        /* init_arch kick-starts the linux kernel */
@@ -265,8 +273,93 @@ ENTRY(_startup)
 should_never_return:
        j       should_never_return
 
+#ifdef CONFIG_SMP
+.Lboot_secondary:
+
+       movi    a2, cpu_start_ccount
+1:
+       l32i    a3, a2, 0
+       beqi    a3, 0, 1b
+       movi    a3, 0
+       s32i    a3, a2, 0
+       memw
+1:
+       l32i    a3, a2, 0
+       beqi    a3, 0, 1b
+       wsr     a3, ccount
+       movi    a3, 0
+       s32i    a3, a2, 0
+       memw
+
+       movi    a6, 0
+       wsr     a6, excsave1
+
+       movi    a4, secondary_start_kernel
+       callx4  a4
+       j       should_never_return
+
+#endif  /* CONFIG_SMP */
+
 ENDPROC(_startup)
 
+#ifdef CONFIG_HOTPLUG_CPU
+
+ENTRY(cpu_restart)
+
+#if XCHAL_DCACHE_IS_WRITEBACK
+       ___flush_invalidate_dcache_all a2 a3
+#else
+       ___invalidate_dcache_all a2 a3
+#endif
+       memw
+       movi    a2, CCON        # MX External Register to Configure Cache
+       movi    a3, 0
+       wer     a3, a2
+       extw
+
+       rsr     a0, prid
+       neg     a2, a0
+       movi    a3, cpu_start_id
+       s32i    a2, a3, 0
+#if XCHAL_DCACHE_IS_WRITEBACK
+       dhwbi   a3, 0
+#endif
+1:
+       l32i    a2, a3, 0
+       dhi     a3, 0
+       bne     a2, a0, 1b
+
+       /*
+        * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions).
+        * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow
+        * xt-gdb to single step via DEBUG exceptions received directly
+        * by ocd.
+        */
+       movi    a1, 1
+       movi    a0, 0
+       wsr     a1, windowstart
+       wsr     a0, windowbase
+       rsync
+
+       movi    a1, LOCKLEVEL
+       wsr     a1, ps
+       rsync
+
+       j       _startup
+
+ENDPROC(cpu_restart)
+
+#endif  /* CONFIG_HOTPLUG_CPU */
+
+/*
+ * DATA section
+ */
+
+        .section ".data.init.refok"
+        .align  4
+ENTRY(start_info)
+        .long   init_thread_union + KERNEL_STACK_SIZE
+
 /*
  * BSS section
  */
index 6f4f9749cff773f229a76a35bf50373ec18731ab..482868a2de6ebde7995002509445859bf7a002b0 100644 (file)
@@ -4,7 +4,7 @@
  * Xtensa built-in interrupt controller and some generic functions copied
  * from i386.
  *
- * Copyright (C) 2002 - 2006 Tensilica, Inc.
+ * Copyright (C) 2002 - 2013 Tensilica, Inc.
  * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
  *
  *
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kernel_stat.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/xtensa-mx.h>
+#include <linux/irqchip/xtensa-pic.h>
 #include <linux/irqdomain.h>
 #include <linux/of.h>
 
+#include <asm/mxregs.h>
 #include <asm/uaccess.h>
 #include <asm/platform.h>
 
-static unsigned int cached_irq_mask;
-
 atomic_t irq_err_count;
 
-static struct irq_domain *root_domain;
-
-/*
- * do_IRQ handles all normal device IRQ's (the special
- * SMP cross-CPU interrupts have their own specific
- * handlers).
- */
-
 asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
 {
-       struct pt_regs *old_regs = set_irq_regs(regs);
-       int irq = irq_find_mapping(root_domain, hwirq);
+       int irq = irq_find_mapping(NULL, hwirq);
 
        if (hwirq >= NR_IRQS) {
                printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
                                __func__, hwirq);
        }
 
-       irq_enter();
-
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
        /* Debugging check for stack overflow: is there less than 1KB free? */
        {
@@ -62,95 +53,69 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
        }
 #endif
        generic_handle_irq(irq);
-
-       irq_exit();
-       set_irq_regs(old_regs);
 }
 
 int arch_show_interrupts(struct seq_file *p, int prec)
 {
+#ifdef CONFIG_SMP
+       show_ipi_list(p, prec);
+#endif
        seq_printf(p, "%*s: ", prec, "ERR");
        seq_printf(p, "%10u\n", atomic_read(&irq_err_count));
        return 0;
 }
 
-static void xtensa_irq_mask(struct irq_data *d)
-{
-       cached_irq_mask &= ~(1 << d->hwirq);
-       set_sr (cached_irq_mask, intenable);
-}
-
-static void xtensa_irq_unmask(struct irq_data *d)
-{
-       cached_irq_mask |= 1 << d->hwirq;
-       set_sr (cached_irq_mask, intenable);
-}
-
-static void xtensa_irq_enable(struct irq_data *d)
-{
-       variant_irq_enable(d->hwirq);
-       xtensa_irq_unmask(d);
-}
-
-static void xtensa_irq_disable(struct irq_data *d)
-{
-       xtensa_irq_mask(d);
-       variant_irq_disable(d->hwirq);
-}
-
-static void xtensa_irq_ack(struct irq_data *d)
-{
-       set_sr(1 << d->hwirq, intclear);
-}
-
-static int xtensa_irq_retrigger(struct irq_data *d)
+int xtensa_irq_domain_xlate(const u32 *intspec, unsigned int intsize,
+               unsigned long int_irq, unsigned long ext_irq,
+               unsigned long *out_hwirq, unsigned int *out_type)
 {
-       set_sr(1 << d->hwirq, intset);
-       return 1;
+       if (WARN_ON(intsize < 1 || intsize > 2))
+               return -EINVAL;
+       if (intsize == 2 && intspec[1] == 1) {
+               int_irq = xtensa_map_ext_irq(ext_irq);
+               if (int_irq < XCHAL_NUM_INTERRUPTS)
+                       *out_hwirq = int_irq;
+               else
+                       return -EINVAL;
+       } else {
+               *out_hwirq = int_irq;
+       }
+       *out_type = IRQ_TYPE_NONE;
+       return 0;
 }
 
-static struct irq_chip xtensa_irq_chip = {
-       .name           = "xtensa",
-       .irq_enable     = xtensa_irq_enable,
-       .irq_disable    = xtensa_irq_disable,
-       .irq_mask       = xtensa_irq_mask,
-       .irq_unmask     = xtensa_irq_unmask,
-       .irq_ack        = xtensa_irq_ack,
-       .irq_retrigger  = xtensa_irq_retrigger,
-};
-
-static int xtensa_irq_map(struct irq_domain *d, unsigned int irq,
+int xtensa_irq_map(struct irq_domain *d, unsigned int irq,
                irq_hw_number_t hw)
 {
+       struct irq_chip *irq_chip = d->host_data;
        u32 mask = 1 << hw;
 
        if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) {
-               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
+               irq_set_chip_and_handler_name(irq, irq_chip,
                                handle_simple_irq, "level");
                irq_set_status_flags(irq, IRQ_LEVEL);
        } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) {
-               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
+               irq_set_chip_and_handler_name(irq, irq_chip,
                                handle_edge_irq, "edge");
                irq_clear_status_flags(irq, IRQ_LEVEL);
        } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) {
-               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
+               irq_set_chip_and_handler_name(irq, irq_chip,
                                handle_level_irq, "level");
                irq_set_status_flags(irq, IRQ_LEVEL);
        } else if (mask & XCHAL_INTTYPE_MASK_TIMER) {
-               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
-                               handle_edge_irq, "edge");
+               irq_set_chip_and_handler_name(irq, irq_chip,
+                               handle_percpu_irq, "timer");
                irq_clear_status_flags(irq, IRQ_LEVEL);
        } else {/* XCHAL_INTTYPE_MASK_WRITE_ERROR */
                /* XCHAL_INTTYPE_MASK_NMI */
-
-               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
+               irq_set_chip_and_handler_name(irq, irq_chip,
                                handle_level_irq, "level");
                irq_set_status_flags(irq, IRQ_LEVEL);
        }
        return 0;
 }
 
-static unsigned map_ext_irq(unsigned ext_irq)
+unsigned xtensa_map_ext_irq(unsigned ext_irq)
 {
        unsigned mask = XCHAL_INTTYPE_MASK_EXTERN_EDGE |
                XCHAL_INTTYPE_MASK_EXTERN_LEVEL;
@@ -163,55 +128,77 @@ static unsigned map_ext_irq(unsigned ext_irq)
        return XCHAL_NUM_INTERRUPTS;
 }
 
-/*
- * Device Tree IRQ specifier translation function which works with one or
- * two cell bindings. First cell value maps directly to the hwirq number.
- * Second cell if present specifies whether hwirq number is external (1) or
- * internal (0).
- */
-int xtensa_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
-               const u32 *intspec, unsigned int intsize,
-               unsigned long *out_hwirq, unsigned int *out_type)
+unsigned xtensa_get_ext_irq_no(unsigned irq)
 {
-       if (WARN_ON(intsize < 1 || intsize > 2))
-               return -EINVAL;
-       if (intsize == 2 && intspec[1] == 1) {
-               unsigned int_irq = map_ext_irq(intspec[0]);
-               if (int_irq < XCHAL_NUM_INTERRUPTS)
-                       *out_hwirq = int_irq;
-               else
-                       return -EINVAL;
-       } else {
-               *out_hwirq = intspec[0];
-       }
-       *out_type = IRQ_TYPE_NONE;
-       return 0;
+       unsigned mask = (XCHAL_INTTYPE_MASK_EXTERN_EDGE |
+               XCHAL_INTTYPE_MASK_EXTERN_LEVEL) &
+               ((1u << irq) - 1);
+       return hweight32(mask);
 }
 
-static const struct irq_domain_ops xtensa_irq_domain_ops = {
-       .xlate = xtensa_irq_domain_xlate,
-       .map = xtensa_irq_map,
-};
-
 void __init init_IRQ(void)
 {
-       struct device_node *intc = NULL;
-
-       cached_irq_mask = 0;
-       set_sr(~0, intclear);
-
 #ifdef CONFIG_OF
-       /* The interrupt controller device node is mandatory */
-       intc = of_find_compatible_node(NULL, NULL, "xtensa,pic");
-       BUG_ON(!intc);
-
-       root_domain = irq_domain_add_linear(intc, NR_IRQS,
-                       &xtensa_irq_domain_ops, NULL);
+       irqchip_init();
+#else
+#ifdef CONFIG_HAVE_SMP
+       xtensa_mx_init_legacy(NULL);
 #else
-       root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0,
-                       &xtensa_irq_domain_ops, NULL);
+       xtensa_pic_init_legacy(NULL);
+#endif
 #endif
-       irq_set_default_host(root_domain);
 
+#ifdef CONFIG_SMP
+       ipi_init();
+#endif
        variant_init_irq();
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void route_irq(struct irq_data *data, unsigned int irq, unsigned int cpu)
+{
+       struct irq_desc *desc = irq_to_desc(irq);
+       struct irq_chip *chip = irq_data_get_irq_chip(data);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&desc->lock, flags);
+       if (chip->irq_set_affinity)
+               chip->irq_set_affinity(data, cpumask_of(cpu), false);
+       raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/*
+ * The CPU has been marked offline.  Migrate IRQs off this CPU.  If
+ * the affinity settings do not allow other CPUs, force them onto any
+ * available CPU.
+ */
+void migrate_irqs(void)
+{
+       unsigned int i, cpu = smp_processor_id();
+       struct irq_desc *desc;
+
+       for_each_irq_desc(i, desc) {
+               struct irq_data *data = irq_desc_get_irq_data(desc);
+               unsigned int newcpu;
+
+               if (irqd_is_per_cpu(data))
+                       continue;
+
+               if (!cpumask_test_cpu(cpu, data->affinity))
+                       continue;
+
+               newcpu = cpumask_any_and(data->affinity, cpu_online_mask);
+
+               if (newcpu >= nr_cpu_ids) {
+                       pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n",
+                                           i, cpu);
+
+                       cpumask_setall(data->affinity);
+                       newcpu = cpumask_any_and(data->affinity,
+                                                cpu_online_mask);
+               }
+
+               route_irq(data, i, newcpu);
+       }
+}
+#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/xtensa/kernel/mxhead.S b/arch/xtensa/kernel/mxhead.S
new file mode 100644 (file)
index 0000000..77a161a
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Xtensa Secondary Processors startup code.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2013 Tensilica Inc.
+ *
+ * Joe Taylor <joe@tensilica.com>
+ * Chris Zankel <chris@zankel.net>
+ * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
+ * Pete Delaney <piet@tensilica.com>
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/cacheasm.h>
+#include <asm/initialize_mmu.h>
+#include <asm/mxregs.h>
+#include <asm/regs.h>
+
+
+       .section .SecondaryResetVector.text, "ax"
+
+
+ENTRY(_SecondaryResetVector)
+       _j _SetupOCD
+
+       .begin  no-absolute-literals
+       .literal_position
+
+_SetupOCD:
+       /*
+        * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions).
+        * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow
+        * xt-gdb to single step via DEBUG exceptions received directly
+        * by ocd.
+        */
+       movi    a1, 1
+       movi    a0, 0
+       wsr     a1, windowstart
+       wsr     a0, windowbase
+       rsync
+
+       movi    a1, LOCKLEVEL
+       wsr     a1, ps
+       rsync
+
+_SetupMMU:
+       Offset = _SetupMMU - _SecondaryResetVector
+
+#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
+       initialize_mmu
+#endif
+
+       /*
+        * Start Secondary Processors with NULL pointer to boot params.
+        */
+       movi    a2, 0                           #  a2 == NULL
+       movi    a3, _startup
+       jx      a3
+
+       .end    no-absolute-literals
+
+
+       .section        .SecondaryResetVector.remapped_text, "ax"
+       .global         _RemappedSecondaryResetVector
+
+       .org 0                                  # Need to do org before literals
+
+_RemappedSecondaryResetVector:
+       .begin  no-absolute-literals
+       .literal_position
+
+       _j      _RemappedSetupMMU
+       . = _RemappedSecondaryResetVector + Offset
+
+_RemappedSetupMMU:
+
+#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
+       initialize_mmu
+#endif
+
+       .end    no-absolute-literals
index 6e2b6638122de71374c99ac0be7df584b0cf7fd9..d21bfa7a28e0f026b7e28b170279d2aa4dac64bb 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/screen_info.h>
 #include <linux/bootmem.h>
 #include <linux/kernel.h>
+#include <linux/percpu.h>
+#include <linux/cpu.h>
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
 
@@ -37,6 +39,7 @@
 #endif
 
 #include <asm/bootparam.h>
+#include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/timex.h>
@@ -45,6 +48,7 @@
 #include <asm/setup.h>
 #include <asm/param.h>
 #include <asm/traps.h>
+#include <asm/smp.h>
 
 #include <platform/hardware.h>
 
@@ -85,12 +89,6 @@ static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
 
 sysmem_info_t __initdata sysmem;
 
-#ifdef CONFIG_MMU
-extern void init_mmu(void);
-#else
-static inline void init_mmu(void) { }
-#endif
-
 extern int mem_reserve(unsigned long, unsigned long, int);
 extern void bootmem_init(void);
 extern void zones_init(void);
@@ -354,7 +352,8 @@ static inline int probed_compare_swap(int *v, int cmp, int set)
 
 /* Handle probed exception */
 
-void __init do_probed_exception(struct pt_regs *regs, unsigned long exccause)
+static void __init do_probed_exception(struct pt_regs *regs,
+               unsigned long exccause)
 {
        if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */
                regs->pc += 3;          /* skip the s32c1i instruction */
@@ -366,7 +365,7 @@ void __init do_probed_exception(struct pt_regs *regs, unsigned long exccause)
 
 /* Simple test of S32C1I (soc bringup assist) */
 
-void __init check_s32c1i(void)
+static int __init check_s32c1i(void)
 {
        int n, cause1, cause2;
        void *handbus, *handdata, *handaddr; /* temporarily saved handlers */
@@ -421,24 +420,21 @@ void __init check_s32c1i(void)
        trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus);
        trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata);
        trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr);
+       return 0;
 }
 
 #else /* XCHAL_HAVE_S32C1I */
 
 /* This condition should not occur with a commercially deployed processor.
    Display reminder for early engr test or demo chips / FPGA bitstreams */
-void __init check_s32c1i(void)
+static int __init check_s32c1i(void)
 {
        pr_warn("Processor configuration lacks atomic compare-and-swap support!\n");
+       return 0;
 }
 
 #endif /* XCHAL_HAVE_S32C1I */
-#else /* CONFIG_S32C1I_SELFTEST */
-
-void __init check_s32c1i(void)
-{
-}
-
+early_initcall(check_s32c1i);
 #endif /* CONFIG_S32C1I_SELFTEST */
 
 
@@ -447,8 +443,6 @@ void __init setup_arch(char **cmdline_p)
        strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
        *cmdline_p = command_line;
 
-       check_s32c1i();
-
        /* Reserve some memory regions */
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -505,6 +499,10 @@ void __init setup_arch(char **cmdline_p)
 
        platform_setup(cmdline_p);
 
+#ifdef CONFIG_SMP
+       smp_init_cpus();
+#endif
+
        paging_init();
        zones_init();
 
@@ -521,6 +519,22 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
+static DEFINE_PER_CPU(struct cpu, cpu_data);
+
+static int __init topology_init(void)
+{
+       int i;
+
+       for_each_possible_cpu(i) {
+               struct cpu *cpu = &per_cpu(cpu_data, i);
+               cpu->hotpluggable = !!i;
+               register_cpu(cpu, i);
+       }
+
+       return 0;
+}
+subsys_initcall(topology_init);
+
 void machine_restart(char * cmd)
 {
        platform_restart();
@@ -546,21 +560,27 @@ void machine_power_off(void)
 static int
 c_show(struct seq_file *f, void *slot)
 {
+       char buf[NR_CPUS * 5];
+
+       cpulist_scnprintf(buf, sizeof(buf), cpu_online_mask);
        /* high-level stuff */
-       seq_printf(f,"processor\t: 0\n"
-                    "vendor_id\t: Tensilica\n"
-                    "model\t\t: Xtensa " XCHAL_HW_VERSION_NAME "\n"
-                    "core ID\t\t: " XCHAL_CORE_ID "\n"
-                    "build ID\t: 0x%x\n"
-                    "byte order\t: %s\n"
-                    "cpu MHz\t\t: %lu.%02lu\n"
-                    "bogomips\t: %lu.%02lu\n",
-                    XCHAL_BUILD_UNIQUE_ID,
-                    XCHAL_HAVE_BE ?  "big" : "little",
-                    ccount_freq/1000000,
-                    (ccount_freq/10000) % 100,
-                    loops_per_jiffy/(500000/HZ),
-                    (loops_per_jiffy/(5000/HZ)) % 100);
+       seq_printf(f, "CPU count\t: %u\n"
+                     "CPU list\t: %s\n"
+                     "vendor_id\t: Tensilica\n"
+                     "model\t\t: Xtensa " XCHAL_HW_VERSION_NAME "\n"
+                     "core ID\t\t: " XCHAL_CORE_ID "\n"
+                     "build ID\t: 0x%x\n"
+                     "byte order\t: %s\n"
+                     "cpu MHz\t\t: %lu.%02lu\n"
+                     "bogomips\t: %lu.%02lu\n",
+                     num_online_cpus(),
+                     buf,
+                     XCHAL_BUILD_UNIQUE_ID,
+                     XCHAL_HAVE_BE ?  "big" : "little",
+                     ccount_freq/1000000,
+                     (ccount_freq/10000) % 100,
+                     loops_per_jiffy/(500000/HZ),
+                     (loops_per_jiffy/(5000/HZ)) % 100);
 
        seq_printf(f,"flags\t\t: "
 #if XCHAL_HAVE_NMI
@@ -672,7 +692,7 @@ c_show(struct seq_file *f, void *slot)
 static void *
 c_start(struct seq_file *f, loff_t *pos)
 {
-       return (void *) ((*pos == 0) ? (void *)1 : NULL);
+       return (*pos == 0) ? (void *)1 : NULL;
 }
 
 static void *
@@ -688,10 +708,10 @@ c_stop(struct seq_file *f, void *v)
 
 const struct seq_operations cpuinfo_op =
 {
-       start:  c_start,
-       next:   c_next,
-       stop:   c_stop,
-       show:   c_show
+       .start  = c_start,
+       .next   = c_next,
+       .stop   = c_stop,
+       .show   = c_show,
 };
 
 #endif /* CONFIG_PROC_FS */
diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c
new file mode 100644 (file)
index 0000000..1c7a209
--- /dev/null
@@ -0,0 +1,591 @@
+/*
+ * Xtensa SMP support functions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 - 2013 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ * Joe Taylor <joe@tensilica.com>
+ * Pete Delaney <piet@tensilica.com
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/kdebug.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/seq_file.h>
+#include <linux/smp.h>
+#include <linux/thread_info.h>
+
+#include <asm/cacheflush.h>
+#include <asm/kdebug.h>
+#include <asm/mmu_context.h>
+#include <asm/mxregs.h>
+#include <asm/platform.h>
+#include <asm/tlbflush.h>
+#include <asm/traps.h>
+
+#ifdef CONFIG_SMP
+# if XCHAL_HAVE_S32C1I == 0
+#  error "The S32C1I option is required for SMP."
+# endif
+#endif
+
+static void system_invalidate_dcache_range(unsigned long start,
+               unsigned long size);
+static void system_flush_invalidate_dcache_range(unsigned long start,
+               unsigned long size);
+
+/* IPI (Inter Process Interrupt) */
+
+#define IPI_IRQ        0
+
+static irqreturn_t ipi_interrupt(int irq, void *dev_id);
+static struct irqaction ipi_irqaction = {
+       .handler =      ipi_interrupt,
+       .flags =        IRQF_PERCPU,
+       .name =         "ipi",
+};
+
+void ipi_init(void)
+{
+       unsigned irq = irq_create_mapping(NULL, IPI_IRQ);
+       setup_irq(irq, &ipi_irqaction);
+}
+
+static inline unsigned int get_core_count(void)
+{
+       /* Bits 18..21 of SYSCFGID contain the core count minus 1. */
+       unsigned int syscfgid = get_er(SYSCFGID);
+       return ((syscfgid >> 18) & 0xf) + 1;
+}
+
+static inline int get_core_id(void)
+{
+       /* Bits 0...18 of SYSCFGID contain the core id  */
+       unsigned int core_id = get_er(SYSCFGID);
+       return core_id & 0x3fff;
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+       unsigned i;
+
+       for (i = 0; i < max_cpus; ++i)
+               set_cpu_present(i, true);
+}
+
+void __init smp_init_cpus(void)
+{
+       unsigned i;
+       unsigned int ncpus = get_core_count();
+       unsigned int core_id = get_core_id();
+
+       pr_info("%s: Core Count = %d\n", __func__, ncpus);
+       pr_info("%s: Core Id = %d\n", __func__, core_id);
+
+       for (i = 0; i < ncpus; ++i)
+               set_cpu_possible(i, true);
+}
+
+void __init smp_prepare_boot_cpu(void)
+{
+       unsigned int cpu = smp_processor_id();
+       BUG_ON(cpu != 0);
+       cpu_asid_cache(cpu) = ASID_USER_FIRST;
+}
+
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+}
+
+static int boot_secondary_processors = 1; /* Set with xt-gdb via .xt-gdb */
+static DECLARE_COMPLETION(cpu_running);
+
+void secondary_start_kernel(void)
+{
+       struct mm_struct *mm = &init_mm;
+       unsigned int cpu = smp_processor_id();
+
+       init_mmu();
+
+#ifdef CONFIG_DEBUG_KERNEL
+       if (boot_secondary_processors == 0) {
+               pr_debug("%s: boot_secondary_processors:%d; Hanging cpu:%d\n",
+                       __func__, boot_secondary_processors, cpu);
+               for (;;)
+                       __asm__ __volatile__ ("waiti " __stringify(LOCKLEVEL));
+       }
+
+       pr_debug("%s: boot_secondary_processors:%d; Booting cpu:%d\n",
+               __func__, boot_secondary_processors, cpu);
+#endif
+       /* Init EXCSAVE1 */
+
+       secondary_trap_init();
+
+       /* All kernel threads share the same mm context. */
+
+       atomic_inc(&mm->mm_users);
+       atomic_inc(&mm->mm_count);
+       current->active_mm = mm;
+       cpumask_set_cpu(cpu, mm_cpumask(mm));
+       enter_lazy_tlb(mm, current);
+
+       preempt_disable();
+       trace_hardirqs_off();
+
+       calibrate_delay();
+
+       notify_cpu_starting(cpu);
+
+       secondary_init_irq();
+       local_timer_setup(cpu);
+
+       local_irq_enable();
+
+       set_cpu_online(cpu, true);
+       complete(&cpu_running);
+
+       cpu_startup_entry(CPUHP_ONLINE);
+}
+
+static void mx_cpu_start(void *p)
+{
+       unsigned cpu = (unsigned)p;
+       unsigned long run_stall_mask = get_er(MPSCORE);
+
+       set_er(run_stall_mask & ~(1u << cpu), MPSCORE);
+       pr_debug("%s: cpu: %d, run_stall_mask: %lx ---> %lx\n",
+                       __func__, cpu, run_stall_mask, get_er(MPSCORE));
+}
+
+static void mx_cpu_stop(void *p)
+{
+       unsigned cpu = (unsigned)p;
+       unsigned long run_stall_mask = get_er(MPSCORE);
+
+       set_er(run_stall_mask | (1u << cpu), MPSCORE);
+       pr_debug("%s: cpu: %d, run_stall_mask: %lx ---> %lx\n",
+                       __func__, cpu, run_stall_mask, get_er(MPSCORE));
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+unsigned long cpu_start_id __cacheline_aligned;
+#endif
+unsigned long cpu_start_ccount;
+
+static int boot_secondary(unsigned int cpu, struct task_struct *ts)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+       unsigned long ccount;
+       int i;
+
+#ifdef CONFIG_HOTPLUG_CPU
+       cpu_start_id = cpu;
+       system_flush_invalidate_dcache_range(
+                       (unsigned long)&cpu_start_id, sizeof(cpu_start_id));
+#endif
+       smp_call_function_single(0, mx_cpu_start, (void *)cpu, 1);
+
+       for (i = 0; i < 2; ++i) {
+               do
+                       ccount = get_ccount();
+               while (!ccount);
+
+               cpu_start_ccount = ccount;
+
+               while (time_before(jiffies, timeout)) {
+                       mb();
+                       if (!cpu_start_ccount)
+                               break;
+               }
+
+               if (cpu_start_ccount) {
+                       smp_call_function_single(0, mx_cpu_stop,
+                                       (void *)cpu, 1);
+                       cpu_start_ccount = 0;
+                       return -EIO;
+               }
+       }
+       return 0;
+}
+
+int __cpu_up(unsigned int cpu, struct task_struct *idle)
+{
+       int ret = 0;
+
+       if (cpu_asid_cache(cpu) == 0)
+               cpu_asid_cache(cpu) = ASID_USER_FIRST;
+
+       start_info.stack = (unsigned long)task_pt_regs(idle);
+       wmb();
+
+       pr_debug("%s: Calling wakeup_secondary(cpu:%d, idle:%p, sp: %08lx)\n",
+                       __func__, cpu, idle, start_info.stack);
+
+       ret = boot_secondary(cpu, idle);
+       if (ret == 0) {
+               wait_for_completion_timeout(&cpu_running,
+                               msecs_to_jiffies(1000));
+               if (!cpu_online(cpu))
+                       ret = -EIO;
+       }
+
+       if (ret)
+               pr_err("CPU %u failed to boot\n", cpu);
+
+       return ret;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * __cpu_disable runs on the processor to be shutdown.
+ */
+int __cpu_disable(void)
+{
+       unsigned int cpu = smp_processor_id();
+
+       /*
+        * Take this CPU offline.  Once we clear this, we can't return,
+        * and we must not schedule until we're ready to give up the cpu.
+        */
+       set_cpu_online(cpu, false);
+
+       /*
+        * OK - migrate IRQs away from this CPU
+        */
+       migrate_irqs();
+
+       /*
+        * Flush user cache and TLB mappings, and then remove this CPU
+        * from the vm mask set of all processes.
+        */
+       local_flush_cache_all();
+       local_flush_tlb_all();
+       invalidate_page_directory();
+
+       clear_tasks_mm_cpumask(cpu);
+
+       return 0;
+}
+
+static void platform_cpu_kill(unsigned int cpu)
+{
+       smp_call_function_single(0, mx_cpu_stop, (void *)cpu, true);
+}
+
+/*
+ * called on the thread which is asking for a CPU to be shutdown -
+ * waits until shutdown has completed, or it is timed out.
+ */
+void __cpu_die(unsigned int cpu)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+       while (time_before(jiffies, timeout)) {
+               system_invalidate_dcache_range((unsigned long)&cpu_start_id,
+                               sizeof(cpu_start_id));
+               if (cpu_start_id == -cpu) {
+                       platform_cpu_kill(cpu);
+                       return;
+               }
+       }
+       pr_err("CPU%u: unable to kill\n", cpu);
+}
+
+void arch_cpu_idle_dead(void)
+{
+       cpu_die();
+}
+/*
+ * Called from the idle thread for the CPU which has been shutdown.
+ *
+ * Note that we disable IRQs here, but do not re-enable them
+ * before returning to the caller. This is also the behaviour
+ * of the other hotplug-cpu capable cores, so presumably coming
+ * out of idle fixes this.
+ */
+void __ref cpu_die(void)
+{
+       idle_task_exit();
+       local_irq_disable();
+       __asm__ __volatile__(
+                       "       movi    a2, cpu_restart\n"
+                       "       jx      a2\n");
+}
+
+#endif /* CONFIG_HOTPLUG_CPU */
+
+enum ipi_msg_type {
+       IPI_RESCHEDULE = 0,
+       IPI_CALL_FUNC,
+       IPI_CPU_STOP,
+       IPI_MAX
+};
+
+static const struct {
+       const char *short_text;
+       const char *long_text;
+} ipi_text[] = {
+       { .short_text = "RES", .long_text = "Rescheduling interrupts" },
+       { .short_text = "CAL", .long_text = "Function call interrupts" },
+       { .short_text = "DIE", .long_text = "CPU shutdown interrupts" },
+};
+
+struct ipi_data {
+       unsigned long ipi_count[IPI_MAX];
+};
+
+static DEFINE_PER_CPU(struct ipi_data, ipi_data);
+
+static void send_ipi_message(const struct cpumask *callmask,
+               enum ipi_msg_type msg_id)
+{
+       int index;
+       unsigned long mask = 0;
+
+       for_each_cpu(index, callmask)
+               if (index != smp_processor_id())
+                       mask |= 1 << index;
+
+       set_er(mask, MIPISET(msg_id));
+}
+
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+       send_ipi_message(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+       send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC);
+}
+
+void smp_send_reschedule(int cpu)
+{
+       send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE);
+}
+
+void smp_send_stop(void)
+{
+       struct cpumask targets;
+
+       cpumask_copy(&targets, cpu_online_mask);
+       cpumask_clear_cpu(smp_processor_id(), &targets);
+       send_ipi_message(&targets, IPI_CPU_STOP);
+}
+
+static void ipi_cpu_stop(unsigned int cpu)
+{
+       set_cpu_online(cpu, false);
+       machine_halt();
+}
+
+irqreturn_t ipi_interrupt(int irq, void *dev_id)
+{
+       unsigned int cpu = smp_processor_id();
+       struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
+       unsigned int msg;
+       unsigned i;
+
+       msg = get_er(MIPICAUSE(cpu));
+       for (i = 0; i < IPI_MAX; i++)
+               if (msg & (1 << i)) {
+                       set_er(1 << i, MIPICAUSE(cpu));
+                       ++ipi->ipi_count[i];
+               }
+
+       if (msg & (1 << IPI_RESCHEDULE))
+               scheduler_ipi();
+       if (msg & (1 << IPI_CALL_FUNC))
+               generic_smp_call_function_interrupt();
+       if (msg & (1 << IPI_CPU_STOP))
+               ipi_cpu_stop(cpu);
+
+       return IRQ_HANDLED;
+}
+
+void show_ipi_list(struct seq_file *p, int prec)
+{
+       unsigned int cpu;
+       unsigned i;
+
+       for (i = 0; i < IPI_MAX; ++i) {
+               seq_printf(p, "%*s:", prec, ipi_text[i].short_text);
+               for_each_online_cpu(cpu)
+                       seq_printf(p, " %10lu",
+                                       per_cpu(ipi_data, cpu).ipi_count[i]);
+               seq_printf(p, "   %s\n", ipi_text[i].long_text);
+       }
+}
+
+int setup_profiling_timer(unsigned int multiplier)
+{
+       pr_debug("setup_profiling_timer %d\n", multiplier);
+       return 0;
+}
+
+/* TLB flush functions */
+
+struct flush_data {
+       struct vm_area_struct *vma;
+       unsigned long addr1;
+       unsigned long addr2;
+};
+
+static void ipi_flush_tlb_all(void *arg)
+{
+       local_flush_tlb_all();
+}
+
+void flush_tlb_all(void)
+{
+       on_each_cpu(ipi_flush_tlb_all, NULL, 1);
+}
+
+static void ipi_flush_tlb_mm(void *arg)
+{
+       local_flush_tlb_mm(arg);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+       on_each_cpu(ipi_flush_tlb_mm, mm, 1);
+}
+
+static void ipi_flush_tlb_page(void *arg)
+{
+       struct flush_data *fd = arg;
+       local_flush_tlb_page(fd->vma, fd->addr1);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+       struct flush_data fd = {
+               .vma = vma,
+               .addr1 = addr,
+       };
+       on_each_cpu(ipi_flush_tlb_page, &fd, 1);
+}
+
+static void ipi_flush_tlb_range(void *arg)
+{
+       struct flush_data *fd = arg;
+       local_flush_tlb_range(fd->vma, fd->addr1, fd->addr2);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma,
+                    unsigned long start, unsigned long end)
+{
+       struct flush_data fd = {
+               .vma = vma,
+               .addr1 = start,
+               .addr2 = end,
+       };
+       on_each_cpu(ipi_flush_tlb_range, &fd, 1);
+}
+
+/* Cache flush functions */
+
+static void ipi_flush_cache_all(void *arg)
+{
+       local_flush_cache_all();
+}
+
+void flush_cache_all(void)
+{
+       on_each_cpu(ipi_flush_cache_all, NULL, 1);
+}
+
+static void ipi_flush_cache_page(void *arg)
+{
+       struct flush_data *fd = arg;
+       local_flush_cache_page(fd->vma, fd->addr1, fd->addr2);
+}
+
+void flush_cache_page(struct vm_area_struct *vma,
+                    unsigned long address, unsigned long pfn)
+{
+       struct flush_data fd = {
+               .vma = vma,
+               .addr1 = address,
+               .addr2 = pfn,
+       };
+       on_each_cpu(ipi_flush_cache_page, &fd, 1);
+}
+
+static void ipi_flush_cache_range(void *arg)
+{
+       struct flush_data *fd = arg;
+       local_flush_cache_range(fd->vma, fd->addr1, fd->addr2);
+}
+
+void flush_cache_range(struct vm_area_struct *vma,
+                    unsigned long start, unsigned long end)
+{
+       struct flush_data fd = {
+               .vma = vma,
+               .addr1 = start,
+               .addr2 = end,
+       };
+       on_each_cpu(ipi_flush_cache_range, &fd, 1);
+}
+
+static void ipi_flush_icache_range(void *arg)
+{
+       struct flush_data *fd = arg;
+       local_flush_icache_range(fd->addr1, fd->addr2);
+}
+
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+       struct flush_data fd = {
+               .addr1 = start,
+               .addr2 = end,
+       };
+       on_each_cpu(ipi_flush_icache_range, &fd, 1);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void ipi_invalidate_dcache_range(void *arg)
+{
+       struct flush_data *fd = arg;
+       __invalidate_dcache_range(fd->addr1, fd->addr2);
+}
+
+static void system_invalidate_dcache_range(unsigned long start,
+               unsigned long size)
+{
+       struct flush_data fd = {
+               .addr1 = start,
+               .addr2 = size,
+       };
+       on_each_cpu(ipi_invalidate_dcache_range, &fd, 1);
+}
+
+static void ipi_flush_invalidate_dcache_range(void *arg)
+{
+       struct flush_data *fd = arg;
+       __flush_invalidate_dcache_range(fd->addr1, fd->addr2);
+}
+
+static void system_flush_invalidate_dcache_range(unsigned long start,
+               unsigned long size)
+{
+       struct flush_data fd = {
+               .addr1 = start,
+               .addr2 = size,
+       };
+       on_each_cpu(ipi_flush_invalidate_dcache_range, &fd, 1);
+}
index 9af3dd88ad7eac172e4fb835e94c70e369547438..60dcb3fcaeae8ad978f8eeec4d073a88abb9f064 100644 (file)
@@ -46,24 +46,19 @@ static struct clocksource ccount_clocksource = {
        .rating = 200,
        .read = ccount_read,
        .mask = CLOCKSOURCE_MASK(32),
+       .flags = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 static int ccount_timer_set_next_event(unsigned long delta,
                struct clock_event_device *dev);
 static void ccount_timer_set_mode(enum clock_event_mode mode,
                struct clock_event_device *evt);
-static struct ccount_timer_t {
+struct ccount_timer {
        struct clock_event_device evt;
        int irq_enabled;
-} ccount_timer = {
-       .evt = {
-               .name           = "ccount_clockevent",
-               .features       = CLOCK_EVT_FEAT_ONESHOT,
-               .rating         = 300,
-               .set_next_event = ccount_timer_set_next_event,
-               .set_mode       = ccount_timer_set_mode,
-       },
+       char name[24];
 };
+static DEFINE_PER_CPU(struct ccount_timer, ccount_timer);
 
 static int ccount_timer_set_next_event(unsigned long delta,
                struct clock_event_device *dev)
@@ -84,8 +79,8 @@ static int ccount_timer_set_next_event(unsigned long delta,
 static void ccount_timer_set_mode(enum clock_event_mode mode,
                struct clock_event_device *evt)
 {
-       struct ccount_timer_t *timer =
-               container_of(evt, struct ccount_timer_t, evt);
+       struct ccount_timer *timer =
+               container_of(evt, struct ccount_timer, evt);
 
        /*
         * There is no way to disable the timer interrupt at the device level,
@@ -117,9 +112,28 @@ static struct irqaction timer_irqaction = {
        .handler =      timer_interrupt,
        .flags =        IRQF_TIMER,
        .name =         "timer",
-       .dev_id =       &ccount_timer,
 };
 
+void local_timer_setup(unsigned cpu)
+{
+       struct ccount_timer *timer = &per_cpu(ccount_timer, cpu);
+       struct clock_event_device *clockevent = &timer->evt;
+
+       timer->irq_enabled = 1;
+       clockevent->name = timer->name;
+       snprintf(timer->name, sizeof(timer->name), "ccount_clockevent_%u", cpu);
+       clockevent->features = CLOCK_EVT_FEAT_ONESHOT;
+       clockevent->rating = 300;
+       clockevent->set_next_event = ccount_timer_set_next_event;
+       clockevent->set_mode = ccount_timer_set_mode;
+       clockevent->cpumask = cpumask_of(cpu);
+       clockevent->irq = irq_create_mapping(NULL, LINUX_TIMER_INT);
+       if (WARN(!clockevent->irq, "error: can't map timer irq"))
+               return;
+       clockevents_config_and_register(clockevent, ccount_freq,
+                                       0xf, 0xffffffff);
+}
+
 void __init time_init(void)
 {
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
@@ -131,16 +145,8 @@ void __init time_init(void)
        ccount_freq = CONFIG_XTENSA_CPU_CLOCK*1000000UL;
 #endif
        clocksource_register_hz(&ccount_clocksource, ccount_freq);
-
-       ccount_timer.evt.cpumask = cpumask_of(0);
-       ccount_timer.evt.irq = irq_create_mapping(NULL, LINUX_TIMER_INT);
-       if (WARN(!ccount_timer.evt.irq, "error: can't map timer irq"))
-               return;
-       clockevents_config_and_register(&ccount_timer.evt, ccount_freq, 0xf,
-                       0xffffffff);
-       setup_irq(ccount_timer.evt.irq, &timer_irqaction);
-       ccount_timer.irq_enabled = 1;
-
+       local_timer_setup(0);
+       setup_irq(this_cpu_ptr(&ccount_timer)->evt.irq, &timer_irqaction);
        setup_sched_clock(ccount_sched_clock_read, 32, ccount_freq);
 }
 
@@ -148,11 +154,11 @@ void __init time_init(void)
  * The timer interrupt is called HZ times per second.
  */
 
-irqreturn_t timer_interrupt (int irq, void *dev_id)
+irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
-       struct ccount_timer_t *timer = dev_id;
-       struct clock_event_device *evt = &timer->evt;
+       struct clock_event_device *evt = &this_cpu_ptr(&ccount_timer)->evt;
 
+       set_linux_timer(get_linux_timer());
        evt->event_handler(evt);
 
        /* Allow platform to do something useful (Wdog). */
index 3e8a05c874cd2719951929ff348b4d24f34c773e..eebbfd8c26fc25121bced6cb18c074a55c6cb5f5 100644 (file)
@@ -157,7 +157,7 @@ COPROCESSOR(7),
  * 2. it is a temporary memory buffer for the exception handlers.
  */
 
-unsigned long exc_table[EXC_TABLE_SIZE/4];
+DEFINE_PER_CPU(unsigned long, exc_table[EXC_TABLE_SIZE/4]);
 
 void die(const char*, struct pt_regs*, long);
 
@@ -212,6 +212,9 @@ void do_interrupt(struct pt_regs *regs)
                XCHAL_INTLEVEL6_MASK,
                XCHAL_INTLEVEL7_MASK,
        };
+       struct pt_regs *old_regs = set_irq_regs(regs);
+
+       irq_enter();
 
        for (;;) {
                unsigned intread = get_sr(interrupt);
@@ -227,21 +230,13 @@ void do_interrupt(struct pt_regs *regs)
                }
 
                if (level == 0)
-                       return;
-
-               /*
-                * Clear the interrupt before processing, in case it's
-                *  edge-triggered or software-generated
-                */
-               while (int_at_level) {
-                       unsigned i = __ffs(int_at_level);
-                       unsigned mask = 1 << i;
-
-                       int_at_level ^= mask;
-                       set_sr(mask, intclear);
-                       do_IRQ(i, regs);
-               }
+                       break;
+
+               do_IRQ(__ffs(int_at_level), regs);
        }
+
+       irq_exit();
+       set_irq_regs(old_regs);
 }
 
 /*
@@ -318,17 +313,31 @@ do_debug(struct pt_regs *regs)
 }
 
 
+static void set_handler(int idx, void *handler)
+{
+       unsigned int cpu;
+
+       for_each_possible_cpu(cpu)
+               per_cpu(exc_table, cpu)[idx] = (unsigned long)handler;
+}
+
 /* Set exception C handler - for temporary use when probing exceptions */
 
 void * __init trap_set_handler(int cause, void *handler)
 {
-       unsigned long *entry = &exc_table[EXC_TABLE_DEFAULT / 4 + cause];
-       void *previous = (void *)*entry;
-       *entry = (unsigned long)handler;
+       void *previous = (void *)per_cpu(exc_table, 0)[
+               EXC_TABLE_DEFAULT / 4 + cause];
+       set_handler(EXC_TABLE_DEFAULT / 4 + cause, handler);
        return previous;
 }
 
 
+static void trap_init_excsave(void)
+{
+       unsigned long excsave1 = (unsigned long)this_cpu_ptr(exc_table);
+       __asm__ __volatile__("wsr  %0, excsave1\n" : : "a" (excsave1));
+}
+
 /*
  * Initialize dispatch tables.
  *
@@ -342,8 +351,6 @@ void * __init trap_set_handler(int cause, void *handler)
  * See vectors.S for more details.
  */
 
-#define set_handler(idx,handler) (exc_table[idx] = (unsigned long) (handler))
-
 void __init trap_init(void)
 {
        int i;
@@ -373,10 +380,15 @@ void __init trap_init(void)
        }
 
        /* Initialize EXCSAVE_1 to hold the address of the exception table. */
+       trap_init_excsave();
+}
 
-       i = (unsigned long)exc_table;
-       __asm__ __volatile__("wsr  %0, excsave1\n" : : "a" (i));
+#ifdef CONFIG_SMP
+void secondary_trap_init(void)
+{
+       trap_init_excsave();
 }
+#endif
 
 /*
  * This function dumps the current valid window frame and other base registers.
index 21acd11b5df2f689f0079f47a3910aaaa4ffbf41..ee32c0085dff4296fb9290e3706733db9402460d 100644 (file)
@@ -165,6 +165,13 @@ SECTIONS
                   .DoubleExceptionVector.text);
     RELOCATE_ENTRY(_DebugInterruptVector_text,
                   .DebugInterruptVector.text);
+#if defined(CONFIG_SMP)
+    RELOCATE_ENTRY(_SecondaryResetVector_literal,
+                  .SecondaryResetVector.literal);
+    RELOCATE_ENTRY(_SecondaryResetVector_text,
+                  .SecondaryResetVector.text);
+#endif
+
   
     __boot_reloc_table_end = ABSOLUTE(.) ;
 
@@ -272,6 +279,25 @@ SECTIONS
                  .DoubleExceptionVector.literal)
 
   . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
+
+#if defined(CONFIG_SMP)
+
+  SECTION_VECTOR (_SecondaryResetVector_literal,
+                 .SecondaryResetVector.literal,
+                 RESET_VECTOR1_VADDR - 4,
+                 SIZEOF(.DoubleExceptionVector.text),
+                 .DoubleExceptionVector.text)
+
+  SECTION_VECTOR (_SecondaryResetVector_text,
+                 .SecondaryResetVector.text,
+                 RESET_VECTOR1_VADDR,
+                 4,
+                 .SecondaryResetVector.literal)
+
+  . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
+
+#endif
+
   . = ALIGN(PAGE_SIZE);
 
   __init_end = .;
index 81edeab82d174eb478ad303001da881d6758f2bb..ba4c47f291b17843047a410549b09cb59ba52967 100644 (file)
@@ -118,7 +118,7 @@ void flush_dcache_page(struct page *page)
  * For now, flush the whole cache. FIXME??
  */
 
-void flush_cache_range(struct vm_area_struct* vma,
+void local_flush_cache_range(struct vm_area_struct *vma,
                       unsigned long start, unsigned long end)
 {
        __flush_invalidate_dcache_all();
@@ -132,7 +132,7 @@ void flush_cache_range(struct vm_area_struct* vma,
  * alias versions of the cache flush functions.
  */
 
-void flush_cache_page(struct vm_area_struct* vma, unsigned long address,
+void local_flush_cache_page(struct vm_area_struct *vma, unsigned long address,
                      unsigned long pfn)
 {
        /* Note that we have to use the 'alias' address to avoid multi-hit */
@@ -159,8 +159,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
 
        /* Invalidate old entry in TLBs */
 
-       invalidate_itlb_mapping(addr);
-       invalidate_dtlb_mapping(addr);
+       flush_tlb_page(vma, addr);
 
 #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
 
index 70fa7bc42b4a0853012af6f6daaeb254f9c5a086..b57c4f91f487efdc6b2f3f44fe43cfb12e9a7e0c 100644 (file)
@@ -21,7 +21,7 @@
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 
-unsigned long asid_cache = ASID_USER_FIRST;
+DEFINE_PER_CPU(unsigned long, asid_cache) = ASID_USER_FIRST;
 void bad_page_fault(struct pt_regs*, unsigned long, int);
 
 #undef DEBUG_PAGE_FAULT
index d97ed1ba7b0addd36d81782469ead96889535fc0..1f68558dbcc2264f99f917fcb18659d90f46a8cb 100644 (file)
@@ -140,7 +140,7 @@ ENTRY(clear_user_page)
 
        /* Setup a temporary DTLB with the color of the VPN */
 
-       movi    a4, -PAGE_OFFSET + (PAGE_KERNEL | _PAGE_HW_WRITE)
+       movi    a4, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff
        movi    a5, TLBTEMP_BASE_1                      # virt
        add     a6, a2, a4                              # ppn
        add     a2, a5, a3                              # add 'color'
@@ -194,7 +194,7 @@ ENTRY(copy_user_page)
        or      a9, a9, a8
        slli    a4, a4, PAGE_SHIFT
        s32i    a9, a5, PAGE_FLAGS
-       movi    a5, -PAGE_OFFSET + (PAGE_KERNEL | _PAGE_HW_WRITE)
+       movi    a5, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff
 
        beqz    a6, 1f
 
index c43771c974be94ceea2152bf77cec9777b3c4b1a..5bb8e3c61d850ca05cde23dbdf9872ffe7b262af 100644 (file)
@@ -22,7 +22,7 @@ void __init paging_init(void)
 /*
  * Flush the mmu and reset associated register to default values.
  */
-void __init init_mmu(void)
+void init_mmu(void)
 {
 #if !(XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY)
        /*
@@ -37,7 +37,7 @@ void __init init_mmu(void)
        set_itlbcfg_register(0);
        set_dtlbcfg_register(0);
 #endif
-       flush_tlb_all();
+       local_flush_tlb_all();
 
        /* Set rasid register to a known value. */
 
index ca9d2366bf12b5b85dad9c4fd1295ed14a02d2a5..ade623826788b387f150cfae5a90821f07f6b028 100644 (file)
@@ -48,7 +48,7 @@ static inline void __flush_dtlb_all (void)
 }
 
 
-void flush_tlb_all (void)
+void local_flush_tlb_all(void)
 {
        __flush_itlb_all();
        __flush_dtlb_all();
@@ -60,19 +60,23 @@ void flush_tlb_all (void)
  * a new context will be assigned to it.
  */
 
-void flush_tlb_mm(struct mm_struct *mm)
+void local_flush_tlb_mm(struct mm_struct *mm)
 {
+       int cpu = smp_processor_id();
+
        if (mm == current->active_mm) {
                unsigned long flags;
                local_irq_save(flags);
-               __get_new_mmu_context(mm);
-               __load_mmu_context(mm);
+               mm->context.asid[cpu] = NO_CONTEXT;
+               activate_context(mm, cpu);
                local_irq_restore(flags);
+       } else {
+               mm->context.asid[cpu] = NO_CONTEXT;
+               mm->context.cpu = -1;
        }
-       else
-               mm->context = 0;
 }
 
+
 #define _ITLB_ENTRIES (ITLB_ARF_WAYS << XCHAL_ITLB_ARF_ENTRIES_LOG2)
 #define _DTLB_ENTRIES (DTLB_ARF_WAYS << XCHAL_DTLB_ARF_ENTRIES_LOG2)
 #if _ITLB_ENTRIES > _DTLB_ENTRIES
@@ -81,24 +85,26 @@ void flush_tlb_mm(struct mm_struct *mm)
 # define _TLB_ENTRIES _DTLB_ENTRIES
 #endif
 
-void flush_tlb_range (struct vm_area_struct *vma,
-                     unsigned long start, unsigned long end)
+void local_flush_tlb_range(struct vm_area_struct *vma,
+               unsigned long start, unsigned long end)
 {
+       int cpu = smp_processor_id();
        struct mm_struct *mm = vma->vm_mm;
        unsigned long flags;
 
-       if (mm->context == NO_CONTEXT)
+       if (mm->context.asid[cpu] == NO_CONTEXT)
                return;
 
 #if 0
        printk("[tlbrange<%02lx,%08lx,%08lx>]\n",
-                       (unsigned long)mm->context, start, end);
+                       (unsigned long)mm->context.asid[cpu], start, end);
 #endif
        local_irq_save(flags);
 
        if (end-start + (PAGE_SIZE-1) <= _TLB_ENTRIES << PAGE_SHIFT) {
                int oldpid = get_rasid_register();
-               set_rasid_register (ASID_INSERT(mm->context));
+
+               set_rasid_register(ASID_INSERT(mm->context.asid[cpu]));
                start &= PAGE_MASK;
                if (vma->vm_flags & VM_EXEC)
                        while(start < end) {
@@ -114,24 +120,25 @@ void flush_tlb_range (struct vm_area_struct *vma,
 
                set_rasid_register(oldpid);
        } else {
-               flush_tlb_mm(mm);
+               local_flush_tlb_mm(mm);
        }
        local_irq_restore(flags);
 }
 
-void flush_tlb_page (struct vm_area_struct *vma, unsigned long page)
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
+       int cpu = smp_processor_id();
        struct mm_struct* mm = vma->vm_mm;
        unsigned long flags;
        int oldpid;
 
-       if(mm->context == NO_CONTEXT)
+       if (mm->context.asid[cpu] == NO_CONTEXT)
                return;
 
        local_irq_save(flags);
 
        oldpid = get_rasid_register();
-       set_rasid_register(ASID_INSERT(mm->context));
+       set_rasid_register(ASID_INSERT(mm->context.asid[cpu]));
 
        if (vma->vm_flags & VM_EXEC)
                invalidate_itlb_mapping(page);
index e9e1aad8c271048d4fde5bdac7ebef7e1cc79a96..5ae928275db67c6044f348e8922a2a4454050c7b 100644 (file)
@@ -38,7 +38,7 @@
 #define DRIVER_NAME "iss-netdev"
 #define ETH_MAX_PACKET 1500
 #define ETH_HEADER_OTHER 14
-#define ISS_NET_TIMER_VALUE (2 * HZ)
+#define ISS_NET_TIMER_VALUE (HZ / 10)
 
 
 static DEFINE_SPINLOCK(opened_lock);
@@ -56,8 +56,6 @@ static LIST_HEAD(devices);
 
 struct tuntap_info {
        char dev_name[IFNAMSIZ];
-       int fixed_config;
-       unsigned char gw[ETH_ALEN];
        int fd;
 };
 
@@ -67,7 +65,6 @@ struct tuntap_info {
 /* This structure contains out private information for the driver. */
 
 struct iss_net_private {
-
        struct list_head device_list;
        struct list_head opened_list;
 
@@ -83,9 +80,6 @@ struct iss_net_private {
        int index;
        int mtu;
 
-       unsigned char mac[ETH_ALEN];
-       int have_mac;
-
        struct {
                union {
                        struct tuntap_info tuntap;
@@ -118,68 +112,55 @@ static char *split_if_spec(char *str, ...)
                        *arg = str;
                if (end == NULL)
                        return NULL;
-               *end ++ = '\0';
+               *end++ = '\0';
                str = end;
        }
        va_end(ap);
        return str;
 }
 
+/* Set Ethernet address of the specified device. */
 
-#if 0
-/* Adjust SKB. */
-
-struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
+static void setup_etheraddr(struct net_device *dev, char *str)
 {
-       if ((skb != NULL) && (skb_tailroom(skb) < extra)) {
-               struct sk_buff *skb2;
-
-               skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
-               dev_kfree_skb(skb);
-               skb = skb2;
+       unsigned char *addr = dev->dev_addr;
+       char *end;
+       int i;
+
+       if (str == NULL)
+               goto random;
+
+       for (i = 0; i < ETH_ALEN; i++) {
+               addr[i] = kstrtoul(str, 16, &end);
+               if ((end == str) ||
+                   ((*end != ':') && (*end != ',') && (*end != '\0'))) {
+                       pr_err("%s: failed to parse '%s' as an ethernet address\n",
+                              dev->name, str);
+                       goto random;
+               }
+               str = end + 1;
        }
-       if (skb != NULL)
-               skb_put(skb, extra);
-
-       return skb;
-}
-#endif
-
-/* Return the IP address as a string for a given device. */
-
-static void dev_ip_addr(void *d, char *buf, char *bin_buf)
-{
-       struct net_device *dev = d;
-       struct in_device *ip = dev->ip_ptr;
-       struct in_ifaddr *in;
-       __be32 addr;
-
-       if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) {
-               printk(KERN_WARNING "Device not assigned an IP address!\n");
-               return;
+       if (is_multicast_ether_addr(addr)) {
+               pr_err("%s: attempt to assign a multicast ethernet address\n",
+                      dev->name);
+               goto random;
        }
-
-       addr = in->ifa_address;
-       sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
-               (addr >> 16) & 0xff, addr >> 24);
-
-       if (bin_buf) {
-               bin_buf[0] = addr & 0xff;
-               bin_buf[1] = (addr >> 8) & 0xff;
-               bin_buf[2] = (addr >> 16) & 0xff;
-               bin_buf[3] = addr >> 24;
+       if (!is_valid_ether_addr(addr)) {
+               pr_err("%s: attempt to assign an invalid ethernet address\n",
+                      dev->name);
+               goto random;
        }
+       if (!is_local_ether_addr(addr))
+               pr_warn("%s: assigning a globally valid ethernet address\n",
+                       dev->name);
+       return;
+
+random:
+       pr_info("%s: choosing a random ethernet address\n",
+               dev->name);
+       eth_hw_addr_random(dev);
 }
 
-/* Set Ethernet address of the specified device. */
-
-static void inline set_ether_mac(void *d, unsigned char *addr)
-{
-       struct net_device *dev = d;
-       memcpy(dev->dev_addr, addr, ETH_ALEN);
-}
-
-
 /* ======================= TUNTAP TRANSPORT INTERFACE ====================== */
 
 static int tuntap_open(struct iss_net_private *lp)
@@ -189,24 +170,21 @@ static int tuntap_open(struct iss_net_private *lp)
        int err = -EINVAL;
        int fd;
 
-       /* We currently only support a fixed configuration. */
-
-       if (!lp->tp.info.tuntap.fixed_config)
-               return -EINVAL;
-
-       if ((fd = simc_open("/dev/net/tun", 02, 0)) < 0) {      /* O_RDWR */
-               printk("Failed to open /dev/net/tun, returned %d "
-                      "(errno = %d)\n", fd, errno);
+       fd = simc_open("/dev/net/tun", 02, 0); /* O_RDWR */
+       if (fd < 0) {
+               pr_err("%s: failed to open /dev/net/tun, returned %d (errno = %d)\n",
+                      lp->dev->name, fd, errno);
                return fd;
        }
 
-       memset(&ifr, 0, sizeof ifr);
+       memset(&ifr, 0, sizeof(ifr));
        ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
-       strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name);
+       strlcpy(ifr.ifr_name, dev_name, sizeof(ifr.ifr_name));
 
-       if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) {
-               printk("Failed to set interface, returned %d "
-                      "(errno = %d)\n", err, errno);
+       err = simc_ioctl(fd, TUNSETIFF, &ifr);
+       if (err < 0) {
+               pr_err("%s: failed to set interface %s, returned %d (errno = %d)\n",
+                      lp->dev->name, dev_name, err, errno);
                simc_close(fd);
                return err;
        }
@@ -217,27 +195,17 @@ static int tuntap_open(struct iss_net_private *lp)
 
 static void tuntap_close(struct iss_net_private *lp)
 {
-#if 0
-       if (lp->tp.info.tuntap.fixed_config)
-               iter_addresses(lp->tp.info.tuntap.dev, close_addr, lp->host.dev_name);
-#endif
        simc_close(lp->tp.info.tuntap.fd);
        lp->tp.info.tuntap.fd = -1;
 }
 
-static int tuntap_read (struct iss_net_private *lp, struct sk_buff **skb)
+static int tuntap_read(struct iss_net_private *lp, struct sk_buff **skb)
 {
-#if 0
-       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
-       if (*skb == NULL)
-               return -ENOMEM;
-#endif
-
        return simc_read(lp->tp.info.tuntap.fd,
                        (*skb)->data, (*skb)->dev->mtu + ETH_HEADER_OTHER);
 }
 
-static int tuntap_write (struct iss_net_private *lp, struct sk_buff **skb)
+static int tuntap_write(struct iss_net_private *lp, struct sk_buff **skb)
 {
        return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len);
 }
@@ -253,45 +221,45 @@ static int tuntap_poll(struct iss_net_private *lp)
 }
 
 /*
- * Currently only a device name is supported.
- * ethX=tuntap[,[mac address][,[device name]]]
+ * ethX=tuntap,[mac address],device name
  */
 
 static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
 {
-       const int len = strlen(TRANSPORT_TUNTAP_NAME);
+       struct net_device *dev = lp->dev;
        char *dev_name = NULL, *mac_str = NULL, *rem = NULL;
 
        /* Transport should be 'tuntap': ethX=tuntap,mac,dev_name */
 
-       if (strncmp(init, TRANSPORT_TUNTAP_NAME, len))
+       if (strncmp(init, TRANSPORT_TUNTAP_NAME,
+                   sizeof(TRANSPORT_TUNTAP_NAME) - 1))
                return 0;
 
-       if (*(init += strlen(TRANSPORT_TUNTAP_NAME)) == ',') {
-               if ((rem=split_if_spec(init+1, &mac_str, &dev_name)) != NULL) {
-                       printk("Extra garbage on specification : '%s'\n", rem);
+       init += sizeof(TRANSPORT_TUNTAP_NAME) - 1;
+       if (*init == ',') {
+               rem = split_if_spec(init + 1, &mac_str, &dev_name);
+               if (rem != NULL) {
+                       pr_err("%s: extra garbage on specification : '%s'\n",
+                              dev->name, rem);
                        return 0;
                }
        } else if (*init != '\0') {
-               printk("Invalid argument: %s. Skipping device!\n", init);
+               pr_err("%s: invalid argument: %s. Skipping device!\n",
+                      dev->name, init);
                return 0;
        }
 
-       if (dev_name) {
-               strncpy(lp->tp.info.tuntap.dev_name, dev_name,
-                        sizeof lp->tp.info.tuntap.dev_name);
-               lp->tp.info.tuntap.fixed_config = 1;
-       } else
-               strcpy(lp->tp.info.tuntap.dev_name, TRANSPORT_TUNTAP_NAME);
+       if (!dev_name) {
+               pr_err("%s: missing tuntap device name\n", dev->name);
+               return 0;
+       }
 
+       strlcpy(lp->tp.info.tuntap.dev_name, dev_name,
+               sizeof(lp->tp.info.tuntap.dev_name));
 
-#if 0
-       if (setup_etheraddr(mac_str, lp->mac))
-               lp->have_mac = 1;
-#endif
-       lp->mtu = TRANSPORT_TUNTAP_MTU;
+       setup_etheraddr(dev, mac_str);
 
-       //lp->info.tuntap.gate_addr = gate_addr;
+       lp->mtu = TRANSPORT_TUNTAP_MTU;
 
        lp->tp.info.tuntap.fd = -1;
 
@@ -302,13 +270,6 @@ static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
        lp->tp.protocol = tuntap_protocol;
        lp->tp.poll = tuntap_poll;
 
-       printk("TUN/TAP backend - ");
-#if 0
-       if (lp->host.gate_addr != NULL)
-               printk("IP = %s", lp->host.gate_addr);
-#endif
-       printk("\n");
-
        return 1;
 }
 
@@ -327,7 +288,8 @@ static int iss_net_rx(struct net_device *dev)
 
        /* Try to allocate memory, if it fails, try again next round. */
 
-       if ((skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER)) == NULL) {
+       skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER);
+       if (skb == NULL) {
                lp->stats.rx_dropped++;
                return 0;
        }
@@ -347,7 +309,6 @@ static int iss_net_rx(struct net_device *dev)
 
                lp->stats.rx_bytes += skb->len;
                lp->stats.rx_packets++;
-       //      netif_rx(skb);
                netif_rx_ni(skb);
                return pkt_len;
        }
@@ -378,11 +339,11 @@ static int iss_net_poll(void)
                spin_unlock(&lp->lock);
 
                if (err < 0) {
-                       printk(KERN_ERR "Device '%s' read returned %d, "
-                              "shutting it down\n", lp->dev->name, err);
+                       pr_err("Device '%s' read returned %d, shutting it down\n",
+                              lp->dev->name, err);
                        dev_close(lp->dev);
                } else {
-                       // FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ);
+                       /* FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ); */
                }
        }
 
@@ -393,14 +354,11 @@ static int iss_net_poll(void)
 
 static void iss_net_timer(unsigned long priv)
 {
-       struct iss_net_private* lp = (struct iss_net_private*) priv;
+       struct iss_net_private *lp = (struct iss_net_private *)priv;
 
        spin_lock(&lp->lock);
-
        iss_net_poll();
-
        mod_timer(&lp->timer, jiffies + lp->timer_val);
-
        spin_unlock(&lp->lock);
 }
 
@@ -408,19 +366,14 @@ static void iss_net_timer(unsigned long priv)
 static int iss_net_open(struct net_device *dev)
 {
        struct iss_net_private *lp = netdev_priv(dev);
-       char addr[sizeof "255.255.255.255\0"];
        int err;
 
        spin_lock(&lp->lock);
 
-       if ((err = lp->tp.open(lp)) < 0)
+       err = lp->tp.open(lp);
+       if (err < 0)
                goto out;
 
-       if (!lp->have_mac) {
-               dev_ip_addr(dev, addr, &lp->mac[2]);
-               set_ether_mac(dev, lp->mac);
-       }
-
        netif_start_queue(dev);
 
        /* clear buffer - it can happen that the host side of the interface
@@ -448,7 +401,6 @@ out:
 static int iss_net_close(struct net_device *dev)
 {
        struct iss_net_private *lp = netdev_priv(dev);
-printk("iss_net_close!\n");
        netif_stop_queue(dev);
        spin_lock(&lp->lock);
 
@@ -490,7 +442,7 @@ static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        } else {
                netif_start_queue(dev);
-               printk(KERN_ERR "iss_net_start_xmit: failed(%d)\n", len);
+               pr_err("%s: %s failed(%d)\n", dev->name, __func__, len);
        }
 
        spin_unlock_irqrestore(&lp->lock, flags);
@@ -508,56 +460,27 @@ static struct net_device_stats *iss_net_get_stats(struct net_device *dev)
 
 static void iss_net_set_multicast_list(struct net_device *dev)
 {
-#if 0
-       if (dev->flags & IFF_PROMISC)
-               return;
-       else if (!netdev_mc_empty(dev))
-               dev->flags |= IFF_ALLMULTI;
-       else
-               dev->flags &= ~IFF_ALLMULTI;
-#endif
 }
 
 static void iss_net_tx_timeout(struct net_device *dev)
 {
-#if 0
-       dev->trans_start = jiffies;
-       netif_wake_queue(dev);
-#endif
 }
 
 static int iss_net_set_mac(struct net_device *dev, void *addr)
 {
-#if 0
        struct iss_net_private *lp = netdev_priv(dev);
        struct sockaddr *hwaddr = addr;
 
+       if (!is_valid_ether_addr(hwaddr->sa_data))
+               return -EADDRNOTAVAIL;
        spin_lock(&lp->lock);
        memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
        spin_unlock(&lp->lock);
-#endif
-
        return 0;
 }
 
 static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
 {
-#if 0
-       struct iss_net_private *lp = netdev_priv(dev);
-       int err = 0;
-
-       spin_lock(&lp->lock);
-
-       // FIXME not needed new_mtu = transport_set_mtu(new_mtu, &lp->user);
-
-       if (new_mtu < 0)
-               err = new_mtu;
-       else
-               dev->mtu = new_mtu;
-
-       spin_unlock(&lp->lock);
-       return err;
-#endif
        return -EINVAL;
 }
 
@@ -582,7 +505,6 @@ static const struct net_device_ops iss_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = iss_net_change_mtu,
        .ndo_set_mac_address    = iss_net_set_mac,
-       //.ndo_do_ioctl         = iss_net_ioctl,
        .ndo_tx_timeout         = iss_net_tx_timeout,
        .ndo_set_rx_mode        = iss_net_set_multicast_list,
 };
@@ -593,24 +515,29 @@ static int iss_net_configure(int index, char *init)
        struct iss_net_private *lp;
        int err;
 
-       if ((dev = alloc_etherdev(sizeof *lp)) == NULL) {
-               printk(KERN_ERR "eth_configure: failed to allocate device\n");
+       dev = alloc_etherdev(sizeof(*lp));
+       if (dev == NULL) {
+               pr_err("eth_configure: failed to allocate device\n");
                return 1;
        }
 
        /* Initialize private element. */
 
        lp = netdev_priv(dev);
-       *lp = ((struct iss_net_private) {
+       *lp = (struct iss_net_private) {
                .device_list            = LIST_HEAD_INIT(lp->device_list),
                .opened_list            = LIST_HEAD_INIT(lp->opened_list),
                .lock                   = __SPIN_LOCK_UNLOCKED(lp.lock),
                .dev                    = dev,
                .index                  = index,
-               //.fd                   = -1,
-               .mac                    = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 },
-               .have_mac               = 0,
-               });
+               };
+
+       /*
+        * If this name ends up conflicting with an existing registered
+        * netdevice, that is OK, register_netdev{,ice}() will notice this
+        * and fail.
+        */
+       snprintf(dev->name, sizeof(dev->name), "eth%d", index);
 
        /*
         * Try all transport protocols.
@@ -618,14 +545,12 @@ static int iss_net_configure(int index, char *init)
         */
 
        if (!tuntap_probe(lp, index, init)) {
-               printk("Invalid arguments. Skipping device!\n");
+               pr_err("%s: invalid arguments. Skipping device!\n",
+                      dev->name);
                goto errout;
        }
 
-       printk(KERN_INFO "Netdevice %d ", index);
-       if (lp->have_mac)
-               printk("(%pM) ", lp->mac);
-       printk(": ");
+       pr_info("Netdevice %d (%pM)\n", index, dev->dev_addr);
 
        /* sysfs register */
 
@@ -641,14 +566,7 @@ static int iss_net_configure(int index, char *init)
        lp->pdev.id = index;
        lp->pdev.name = DRIVER_NAME;
        platform_device_register(&lp->pdev);
-       SET_NETDEV_DEV(dev,&lp->pdev.dev);
-
-       /*
-        * If this name ends up conflicting with an existing registered
-        * netdevice, that is OK, register_netdev{,ice}() will notice this
-        * and fail.
-        */
-       snprintf(dev->name, sizeof dev->name, "eth%d", index);
+       SET_NETDEV_DEV(dev, &lp->pdev.dev);
 
        dev->netdev_ops = &iss_netdev_ops;
        dev->mtu = lp->mtu;
@@ -660,7 +578,7 @@ static int iss_net_configure(int index, char *init)
        rtnl_unlock();
 
        if (err) {
-               printk("Error registering net device!\n");
+               pr_err("%s: error registering net device!\n", dev->name);
                /* XXX: should we call ->remove() here? */
                free_netdev(dev);
                return 1;
@@ -669,16 +587,11 @@ static int iss_net_configure(int index, char *init)
        init_timer(&lp->tl);
        lp->tl.function = iss_net_user_timer_expire;
 
-#if 0
-       if (lp->have_mac)
-               set_ether_mac(dev, lp->mac);
-#endif
        return 0;
 
 errout:
-       // FIXME: unregister; free, etc..
+       /* FIXME: unregister; free, etc.. */
        return -EIO;
-
 }
 
 /* ------------------------------------------------------------------------- */
@@ -717,7 +630,8 @@ static int __init iss_net_setup(char *str)
                printk(ERR "Device %d is negative\n", n);
                return 1;
        }
-       if (*(str = end) != '=') {
+       str = end;
+       if (*str != '=') {
                printk(ERR "Expected '=' after device number\n");
                return 1;
        }
@@ -739,7 +653,7 @@ static int __init iss_net_setup(char *str)
 
        new = alloc_bootmem(sizeof(*new));
        if (new == NULL) {
-               printk("Alloc_bootmem failed\n");
+               printk(ERR "Alloc_bootmem failed\n");
                return 1;
        }
 
@@ -753,7 +667,7 @@ static int __init iss_net_setup(char *str)
 
 #undef ERR
 
-__setup("eth=", iss_net_setup);
+__setup("eth", iss_net_setup);
 
 /*
  * Initialize all ISS Ethernet devices previously registered in iss_net_setup.
index 4416773cbde5c1755c17abf3d5028babaf80ef6c..aeb316b7ff8838f9bcff5d8f29202bac7043823c 100644 (file)
 #ifndef __XTENSA_XTAVNET_HARDWARE_H
 #define __XTENSA_XTAVNET_HARDWARE_H
 
-/* By default NO_IRQ is defined to 0 in Linux, but we use the
-   interrupt 0 for UART... */
-#define NO_IRQ                 -1
-
 /* Memory configuration. */
 
 #define PLATFORM_DEFAULT_MEM_START 0x00000000
@@ -30,7 +26,7 @@
 
 /* Default assignment of LX60 devices to external interrupts. */
 
-#ifdef CONFIG_ARCH_HAS_SMP
+#ifdef CONFIG_XTENSA_MX
 #define DUART16552_INTNUM      XCHAL_EXTINT3_NUM
 #define OETH_IRQ               XCHAL_EXTINT4_NUM
 #else
index 97d6fc48deff036b1ea5a1bd940b3d998411deec..39ca751a62551c72cc2d0582a08b0ba8667ca43a 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef _XTENSA_S6000_IRQ_H
 #define _XTENSA_S6000_IRQ_H
 
-#define NO_IRQ         (-1)
 #define VARIANT_NR_IRQS 8 /* GPIO interrupts */
 
 extern void variant_irq_enable(unsigned int irq);
index 8bdd0121212a51a1dba3c568c5a6a3e070447318..5da8e900d3b18747a90840e0beb286a8bd348185 100644 (file)
@@ -130,7 +130,7 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
        bio_advance(bio, nbytes);
 
        /* don't actually finish bio if it's part of flush sequence */
-       if (bio->bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ))
+       if (bio->bi_iter.bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ))
                bio_endio(bio, error);
 }
 
@@ -1326,7 +1326,7 @@ void blk_add_request_payload(struct request *rq, struct page *page,
        bio->bi_io_vec->bv_offset = 0;
        bio->bi_io_vec->bv_len = len;
 
-       bio->bi_size = len;
+       bio->bi_iter.bi_size = len;
        bio->bi_vcnt = 1;
        bio->bi_phys_segments = 1;
 
@@ -1351,7 +1351,7 @@ bool bio_attempt_back_merge(struct request_queue *q, struct request *req,
 
        req->biotail->bi_next = bio;
        req->biotail = bio;
-       req->__data_len += bio->bi_size;
+       req->__data_len += bio->bi_iter.bi_size;
        req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
        blk_account_io_start(req, false);
@@ -1380,8 +1380,8 @@ bool bio_attempt_front_merge(struct request_queue *q, struct request *req,
         * not touch req->buffer either...
         */
        req->buffer = bio_data(bio);
-       req->__sector = bio->bi_sector;
-       req->__data_len += bio->bi_size;
+       req->__sector = bio->bi_iter.bi_sector;
+       req->__data_len += bio->bi_iter.bi_size;
        req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
        blk_account_io_start(req, false);
@@ -1459,7 +1459,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
                req->cmd_flags |= REQ_FAILFAST_MASK;
 
        req->errors = 0;
-       req->__sector = bio->bi_sector;
+       req->__sector = bio->bi_iter.bi_sector;
        req->ioprio = bio_prio(bio);
        blk_rq_bio_prep(req->q, req, bio);
 }
@@ -1583,12 +1583,12 @@ static inline void blk_partition_remap(struct bio *bio)
        if (bio_sectors(bio) && bdev != bdev->bd_contains) {
                struct hd_struct *p = bdev->bd_part;
 
-               bio->bi_sector += p->start_sect;
+               bio->bi_iter.bi_sector += p->start_sect;
                bio->bi_bdev = bdev->bd_contains;
 
                trace_block_bio_remap(bdev_get_queue(bio->bi_bdev), bio,
                                      bdev->bd_dev,
-                                     bio->bi_sector - p->start_sect);
+                                     bio->bi_iter.bi_sector - p->start_sect);
        }
 }
 
@@ -1654,7 +1654,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
        /* Test device or partition size, when known. */
        maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9;
        if (maxsector) {
-               sector_t sector = bio->bi_sector;
+               sector_t sector = bio->bi_iter.bi_sector;
 
                if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
                        /*
@@ -1690,7 +1690,7 @@ generic_make_request_checks(struct bio *bio)
                       "generic_make_request: Trying to access "
                        "nonexistent block-device %s (%Lu)\n",
                        bdevname(bio->bi_bdev, b),
-                       (long long) bio->bi_sector);
+                       (long long) bio->bi_iter.bi_sector);
                goto end_io;
        }
 
@@ -1704,9 +1704,9 @@ generic_make_request_checks(struct bio *bio)
        }
 
        part = bio->bi_bdev->bd_part;
-       if (should_fail_request(part, bio->bi_size) ||
+       if (should_fail_request(part, bio->bi_iter.bi_size) ||
            should_fail_request(&part_to_disk(part)->part0,
-                               bio->bi_size))
+                               bio->bi_iter.bi_size))
                goto end_io;
 
        /*
@@ -1865,7 +1865,7 @@ void submit_bio(int rw, struct bio *bio)
                if (rw & WRITE) {
                        count_vm_events(PGPGOUT, count);
                } else {
-                       task_io_account_read(bio->bi_size);
+                       task_io_account_read(bio->bi_iter.bi_size);
                        count_vm_events(PGPGIN, count);
                }
 
@@ -1874,7 +1874,7 @@ void submit_bio(int rw, struct bio *bio)
                        printk(KERN_DEBUG "%s(%d): %s block %Lu on %s (%u sectors)\n",
                        current->comm, task_pid_nr(current),
                                (rw & WRITE) ? "WRITE" : "READ",
-                               (unsigned long long)bio->bi_sector,
+                               (unsigned long long)bio->bi_iter.bi_sector,
                                bdevname(bio->bi_bdev, b),
                                count);
                }
@@ -2007,7 +2007,7 @@ unsigned int blk_rq_err_bytes(const struct request *rq)
        for (bio = rq->bio; bio; bio = bio->bi_next) {
                if ((bio->bi_rw & ff) != ff)
                        break;
-               bytes += bio->bi_size;
+               bytes += bio->bi_iter.bi_size;
        }
 
        /* this could lead to infinite loop */
@@ -2378,9 +2378,9 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
        total_bytes = 0;
        while (req->bio) {
                struct bio *bio = req->bio;
-               unsigned bio_bytes = min(bio->bi_size, nr_bytes);
+               unsigned bio_bytes = min(bio->bi_iter.bi_size, nr_bytes);
 
-               if (bio_bytes == bio->bi_size)
+               if (bio_bytes == bio->bi_iter.bi_size)
                        req->bio = bio->bi_next;
 
                req_bio_endio(req, bio, bio_bytes, error);
@@ -2728,7 +2728,7 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
                rq->nr_phys_segments = bio_phys_segments(q, bio);
                rq->buffer = bio_data(bio);
        }
-       rq->__data_len = bio->bi_size;
+       rq->__data_len = bio->bi_iter.bi_size;
        rq->bio = rq->biotail = bio;
 
        if (bio->bi_bdev)
@@ -2746,10 +2746,10 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
 void rq_flush_dcache_pages(struct request *rq)
 {
        struct req_iterator iter;
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
 
        rq_for_each_segment(bvec, rq, iter)
-               flush_dcache_page(bvec->bv_page);
+               flush_dcache_page(bvec.bv_page);
 }
 EXPORT_SYMBOL_GPL(rq_flush_dcache_pages);
 #endif
index 331e627301eaacbced43537469cb9f9914b6747c..9288aaf35c21fc8c0f579fa001f316e697a4dfbb 100644 (file)
@@ -502,15 +502,6 @@ void blk_abort_flushes(struct request_queue *q)
        }
 }
 
-static void bio_end_flush(struct bio *bio, int err)
-{
-       if (err)
-               clear_bit(BIO_UPTODATE, &bio->bi_flags);
-       if (bio->bi_private)
-               complete(bio->bi_private);
-       bio_put(bio);
-}
-
 /**
  * blkdev_issue_flush - queue a flush
  * @bdev:      blockdev to issue flush for
@@ -526,7 +517,6 @@ static void bio_end_flush(struct bio *bio, int err)
 int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
                sector_t *error_sector)
 {
-       DECLARE_COMPLETION_ONSTACK(wait);
        struct request_queue *q;
        struct bio *bio;
        int ret = 0;
@@ -548,13 +538,9 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
                return -ENXIO;
 
        bio = bio_alloc(gfp_mask, 0);
-       bio->bi_end_io = bio_end_flush;
        bio->bi_bdev = bdev;
-       bio->bi_private = &wait;
 
-       bio_get(bio);
-       submit_bio(WRITE_FLUSH, bio);
-       wait_for_completion_io(&wait);
+       ret = submit_bio_wait(WRITE_FLUSH, bio);
 
        /*
         * The driver must store the error location in ->bi_sector, if
@@ -562,10 +548,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;
-
-       if (!bio_flagged(bio, BIO_UPTODATE))
-               ret = -EIO;
+               *error_sector = bio->bi_iter.bi_sector;
 
        bio_put(bio);
        return ret;
index 03cf7179e8ef1aac2f1698eae57377e65a94f275..7fbab84399e6c9c602c52c8157596535a2ce2e05 100644 (file)
@@ -43,30 +43,32 @@ static const char *bi_unsupported_name = "unsupported";
  */
 int blk_rq_count_integrity_sg(struct request_queue *q, struct bio *bio)
 {
-       struct bio_vec *iv, *ivprv = NULL;
+       struct bio_vec iv, ivprv = { NULL };
        unsigned int segments = 0;
        unsigned int seg_size = 0;
-       unsigned int i = 0;
+       struct bvec_iter iter;
+       int prev = 0;
 
-       bio_for_each_integrity_vec(iv, bio, i) {
+       bio_for_each_integrity_vec(iv, bio, iter) {
 
-               if (ivprv) {
-                       if (!BIOVEC_PHYS_MERGEABLE(ivprv, iv))
+               if (prev) {
+                       if (!BIOVEC_PHYS_MERGEABLE(&ivprv, &iv))
                                goto new_segment;
 
-                       if (!BIOVEC_SEG_BOUNDARY(q, ivprv, iv))
+                       if (!BIOVEC_SEG_BOUNDARY(q, &ivprv, &iv))
                                goto new_segment;
 
-                       if (seg_size + iv->bv_len > queue_max_segment_size(q))
+                       if (seg_size + iv.bv_len > queue_max_segment_size(q))
                                goto new_segment;
 
-                       seg_size += iv->bv_len;
+                       seg_size += iv.bv_len;
                } else {
 new_segment:
                        segments++;
-                       seg_size = iv->bv_len;
+                       seg_size = iv.bv_len;
                }
 
+               prev = 1;
                ivprv = iv;
        }
 
@@ -87,24 +89,25 @@ EXPORT_SYMBOL(blk_rq_count_integrity_sg);
 int blk_rq_map_integrity_sg(struct request_queue *q, struct bio *bio,
                            struct scatterlist *sglist)
 {
-       struct bio_vec *iv, *ivprv = NULL;
+       struct bio_vec iv, ivprv = { NULL };
        struct scatterlist *sg = NULL;
        unsigned int segments = 0;
-       unsigned int i = 0;
+       struct bvec_iter iter;
+       int prev = 0;
 
-       bio_for_each_integrity_vec(iv, bio, i) {
+       bio_for_each_integrity_vec(iv, bio, iter) {
 
-               if (ivprv) {
-                       if (!BIOVEC_PHYS_MERGEABLE(ivprv, iv))
+               if (prev) {
+                       if (!BIOVEC_PHYS_MERGEABLE(&ivprv, &iv))
                                goto new_segment;
 
-                       if (!BIOVEC_SEG_BOUNDARY(q, ivprv, iv))
+                       if (!BIOVEC_SEG_BOUNDARY(q, &ivprv, &iv))
                                goto new_segment;
 
-                       if (sg->length + iv->bv_len > queue_max_segment_size(q))
+                       if (sg->length + iv.bv_len > queue_max_segment_size(q))
                                goto new_segment;
 
-                       sg->length += iv->bv_len;
+                       sg->length += iv.bv_len;
                } else {
 new_segment:
                        if (!sg)
@@ -114,10 +117,11 @@ new_segment:
                                sg = sg_next(sg);
                        }
 
-                       sg_set_page(sg, iv->bv_page, iv->bv_len, iv->bv_offset);
+                       sg_set_page(sg, iv.bv_page, iv.bv_len, iv.bv_offset);
                        segments++;
                }
 
+               prev = 1;
                ivprv = iv;
        }
 
index 9b5b561cb92812fba2562b3bdb6c5bd8be012905..2da76c999ef3f37bd965f9d91b48dac43196a208 100644 (file)
@@ -108,12 +108,12 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
                        req_sects = end_sect - sector;
                }
 
-               bio->bi_sector = sector;
+               bio->bi_iter.bi_sector = sector;
                bio->bi_end_io = bio_batch_end_io;
                bio->bi_bdev = bdev;
                bio->bi_private = &bb;
 
-               bio->bi_size = req_sects << 9;
+               bio->bi_iter.bi_size = req_sects << 9;
                nr_sects -= req_sects;
                sector = end_sect;
 
@@ -174,7 +174,7 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
                        break;
                }
 
-               bio->bi_sector = sector;
+               bio->bi_iter.bi_sector = sector;
                bio->bi_end_io = bio_batch_end_io;
                bio->bi_bdev = bdev;
                bio->bi_private = &bb;
@@ -184,11 +184,11 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
                bio->bi_io_vec->bv_len = bdev_logical_block_size(bdev);
 
                if (nr_sects > max_write_same_sectors) {
-                       bio->bi_size = max_write_same_sectors << 9;
+                       bio->bi_iter.bi_size = max_write_same_sectors << 9;
                        nr_sects -= max_write_same_sectors;
                        sector += max_write_same_sectors;
                } else {
-                       bio->bi_size = nr_sects << 9;
+                       bio->bi_iter.bi_size = nr_sects << 9;
                        nr_sects = 0;
                }
 
@@ -240,7 +240,7 @@ int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
                        break;
                }
 
-               bio->bi_sector = sector;
+               bio->bi_iter.bi_sector = sector;
                bio->bi_bdev   = bdev;
                bio->bi_end_io = bio_batch_end_io;
                bio->bi_private = &bb;
index 623e1cd4cffe997e71fbb54577bd42f220af64b3..ae4ae1047fd99575473a8b251dff562a151f0719 100644 (file)
@@ -20,7 +20,7 @@ int blk_rq_append_bio(struct request_queue *q, struct request *rq,
                rq->biotail->bi_next = bio;
                rq->biotail = bio;
 
-               rq->__data_len += bio->bi_size;
+               rq->__data_len += bio->bi_iter.bi_size;
        }
        return 0;
 }
@@ -76,7 +76,7 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
 
        ret = blk_rq_append_bio(q, rq, bio);
        if (!ret)
-               return bio->bi_size;
+               return bio->bi_iter.bi_size;
 
        /* if it was boucned we must call the end io function */
        bio_endio(bio, 0);
@@ -220,7 +220,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
        if (IS_ERR(bio))
                return PTR_ERR(bio);
 
-       if (bio->bi_size != len) {
+       if (bio->bi_iter.bi_size != len) {
                /*
                 * Grab an extra reference to this bio, as bio_unmap_user()
                 * expects to be able to drop it twice as it happens on the
index 1ffc58977835ff2e581c97faa35ee85ebc9a5095..0b097f6b1778606b874b2127695dda617bd3463f 100644 (file)
 static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
                                             struct bio *bio)
 {
-       struct bio_vec *bv, *bvprv = NULL;
-       int cluster, i, high, highprv = 1;
+       struct bio_vec bv, bvprv = { NULL };
+       int cluster, high, highprv = 1;
        unsigned int seg_size, nr_phys_segs;
        struct bio *fbio, *bbio;
+       struct bvec_iter iter;
 
        if (!bio)
                return 0;
@@ -25,25 +26,23 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
        seg_size = 0;
        nr_phys_segs = 0;
        for_each_bio(bio) {
-               bio_for_each_segment(bv, bio, i) {
+               bio_for_each_segment(bv, bio, iter) {
                        /*
                         * the trick here is making sure that a high page is
                         * never considered part of another segment, since that
                         * might change with the bounce page.
                         */
-                       high = page_to_pfn(bv->bv_page) > queue_bounce_pfn(q);
-                       if (high || highprv)
-                               goto new_segment;
-                       if (cluster) {
-                               if (seg_size + bv->bv_len
+                       high = page_to_pfn(bv.bv_page) > queue_bounce_pfn(q);
+                       if (!high && !highprv && cluster) {
+                               if (seg_size + bv.bv_len
                                    > queue_max_segment_size(q))
                                        goto new_segment;
-                               if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
+                               if (!BIOVEC_PHYS_MERGEABLE(&bvprv, &bv))
                                        goto new_segment;
-                               if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
+                               if (!BIOVEC_SEG_BOUNDARY(q, &bvprv, &bv))
                                        goto new_segment;
 
-                               seg_size += bv->bv_len;
+                               seg_size += bv.bv_len;
                                bvprv = bv;
                                continue;
                        }
@@ -54,7 +53,7 @@ new_segment:
 
                        nr_phys_segs++;
                        bvprv = bv;
-                       seg_size = bv->bv_len;
+                       seg_size = bv.bv_len;
                        highprv = high;
                }
                bbio = bio;
@@ -87,6 +86,11 @@ EXPORT_SYMBOL(blk_recount_segments);
 static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
                                   struct bio *nxt)
 {
+       struct bio_vec end_bv, nxt_bv;
+       struct bvec_iter iter;
+
+       uninitialized_var(end_bv);
+
        if (!blk_queue_cluster(q))
                return 0;
 
@@ -97,34 +101,40 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
        if (!bio_has_data(bio))
                return 1;
 
-       if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
+       bio_for_each_segment(end_bv, bio, iter)
+               if (end_bv.bv_len == iter.bi_size)
+                       break;
+
+       nxt_bv = bio_iovec(nxt);
+
+       if (!BIOVEC_PHYS_MERGEABLE(&end_bv, &nxt_bv))
                return 0;
 
        /*
         * bio and nxt are contiguous in memory; check if the queue allows
         * these two to be merged into one
         */
-       if (BIO_SEG_BOUNDARY(q, bio, nxt))
+       if (BIOVEC_SEG_BOUNDARY(q, &end_bv, &nxt_bv))
                return 1;
 
        return 0;
 }
 
-static void
+static inline void
 __blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec,
-                    struct scatterlist *sglist, struct bio_vec **bvprv,
+                    struct scatterlist *sglist, struct bio_vec *bvprv,
                     struct scatterlist **sg, int *nsegs, int *cluster)
 {
 
        int nbytes = bvec->bv_len;
 
-       if (*bvprv && *cluster) {
+       if (*sg && *cluster) {
                if ((*sg)->length + nbytes > queue_max_segment_size(q))
                        goto new_segment;
 
-               if (!BIOVEC_PHYS_MERGEABLE(*bvprv, bvec))
+               if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
                        goto new_segment;
-               if (!BIOVEC_SEG_BOUNDARY(q, *bvprv, bvec))
+               if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
                        goto new_segment;
 
                (*sg)->length += nbytes;
@@ -150,7 +160,7 @@ new_segment:
                sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset);
                (*nsegs)++;
        }
-       *bvprv = bvec;
+       *bvprv = *bvec;
 }
 
 /*
@@ -160,21 +170,22 @@ new_segment:
 int blk_rq_map_sg(struct request_queue *q, struct request *rq,
                  struct scatterlist *sglist)
 {
-       struct bio_vec *bvec, *bvprv;
+       struct bio_vec bvec, bvprv;
        struct req_iterator iter;
        struct scatterlist *sg;
        int nsegs, cluster;
 
+       uninitialized_var(bvprv);
+
        nsegs = 0;
        cluster = blk_queue_cluster(q);
 
        /*
         * for each bio in rq
         */
-       bvprv = NULL;
        sg = NULL;
        rq_for_each_segment(bvec, rq, iter) {
-               __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+               __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
                                     &nsegs, &cluster);
        } /* segments in rq */
 
@@ -223,18 +234,19 @@ EXPORT_SYMBOL(blk_rq_map_sg);
 int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
                   struct scatterlist *sglist)
 {
-       struct bio_vec *bvec, *bvprv;
+       struct bio_vec bvec, bvprv;
        struct scatterlist *sg;
        int nsegs, cluster;
-       unsigned long i;
+       struct bvec_iter iter;
+
+       uninitialized_var(bvprv);
 
        nsegs = 0;
        cluster = blk_queue_cluster(q);
 
-       bvprv = NULL;
        sg = NULL;
-       bio_for_each_segment(bvec, bio, i) {
-               __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+       bio_for_each_segment(bvec, bio, iter) {
+               __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
                                     &nsegs, &cluster);
        } /* segments in bio */
 
@@ -543,9 +555,9 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 
 int blk_try_merge(struct request *rq, struct bio *bio)
 {
-       if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_sector)
+       if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_iter.bi_sector)
                return ELEVATOR_BACK_MERGE;
-       else if (blk_rq_pos(rq) - bio_sectors(bio) == bio->bi_sector)
+       else if (blk_rq_pos(rq) - bio_sectors(bio) == bio->bi_iter.bi_sector)
                return ELEVATOR_FRONT_MERGE;
        return ELEVATOR_NO_MERGE;
 }
index cdc629cf075b74f27f7801565ec3d90f3e299ce0..e4fbcc3fd2db00859269d87ea588abd439b02afb 100644 (file)
@@ -301,7 +301,7 @@ void blk_mq_complete_request(struct request *rq, int error)
                struct bio *next = bio->bi_next;
 
                bio->bi_next = NULL;
-               bytes += bio->bi_size;
+               bytes += bio->bi_iter.bi_size;
                blk_mq_bio_endio(rq, bio, error);
                bio = next;
        }
index 06534049afbac1eb9d1c9ba77f7fc8369150a139..20f82003777511798659a467666c3a8f6d4b8cbb 100644 (file)
@@ -877,14 +877,14 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio,
        do_div(tmp, HZ);
        bytes_allowed = tmp;
 
-       if (tg->bytes_disp[rw] + bio->bi_size <= bytes_allowed) {
+       if (tg->bytes_disp[rw] + bio->bi_iter.bi_size <= bytes_allowed) {
                if (wait)
                        *wait = 0;
                return 1;
        }
 
        /* Calc approx time to dispatch */
-       extra_bytes = tg->bytes_disp[rw] + bio->bi_size - bytes_allowed;
+       extra_bytes = tg->bytes_disp[rw] + bio->bi_iter.bi_size - bytes_allowed;
        jiffy_wait = div64_u64(extra_bytes * HZ, tg->bps[rw]);
 
        if (!jiffy_wait)
@@ -987,7 +987,7 @@ static void throtl_charge_bio(struct throtl_grp *tg, struct bio *bio)
        bool rw = bio_data_dir(bio);
 
        /* Charge the bio to the group */
-       tg->bytes_disp[rw] += bio->bi_size;
+       tg->bytes_disp[rw] += bio->bi_iter.bi_size;
        tg->io_disp[rw]++;
 
        /*
@@ -1003,8 +1003,8 @@ static void throtl_charge_bio(struct throtl_grp *tg, struct bio *bio)
         */
        if (!(bio->bi_rw & REQ_THROTTLED)) {
                bio->bi_rw |= REQ_THROTTLED;
-               throtl_update_dispatch_stats(tg_to_blkg(tg), bio->bi_size,
-                                            bio->bi_rw);
+               throtl_update_dispatch_stats(tg_to_blkg(tg),
+                                            bio->bi_iter.bi_size, bio->bi_rw);
        }
 }
 
@@ -1508,7 +1508,7 @@ bool blk_throtl_bio(struct request_queue *q, struct bio *bio)
        if (tg) {
                if (!tg->has_rules[rw]) {
                        throtl_update_dispatch_stats(tg_to_blkg(tg),
-                                                    bio->bi_size, bio->bi_rw);
+                                       bio->bi_iter.bi_size, bio->bi_rw);
                        goto out_unlock_rcu;
                }
        }
@@ -1564,7 +1564,7 @@ bool blk_throtl_bio(struct request_queue *q, struct bio *bio)
        /* out-of-limit, queue to @tg */
        throtl_log(sq, "[%c] bio. bdisp=%llu sz=%u bps=%llu iodisp=%u iops=%u queued=%d/%d",
                   rw == READ ? 'R' : 'W',
-                  tg->bytes_disp[rw], bio->bi_size, tg->bps[rw],
+                  tg->bytes_disp[rw], bio->bi_iter.bi_size, tg->bps[rw],
                   tg->io_disp[rw], tg->iops[rw],
                   sq->nr_queued[READ], sq->nr_queued[WRITE]);
 
index b7ff2861b6bdc0bd8e57528ac776fc9b923b5c70..42c45a7d67144a5598f5d7b2242a63eb9d58e292 100644 (file)
@@ -440,7 +440,7 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
        /*
         * See if our hash lookup can find a potential backmerge.
         */
-       __rq = elv_rqhash_find(q, bio->bi_sector);
+       __rq = elv_rqhash_find(q, bio->bi_iter.bi_sector);
        if (__rq && elv_rq_merge_ok(__rq, bio)) {
                *req = __rq;
                return ELEVATOR_BACK_MERGE;
index 4ae5734fb4733bb8e264565867fa6d73d7b11f6b..7bcb70d216e14b1b811e8924bb15cbf01f5acf80 100644 (file)
@@ -174,9 +174,8 @@ config CRYPTO_TEST
        help
          Quick & dirty crypto test module.
 
-config CRYPTO_ABLK_HELPER_X86
+config CRYPTO_ABLK_HELPER
        tristate
-       depends on X86
        select CRYPTO_CRYPTD
 
 config CRYPTO_GLUE_HELPER_X86
@@ -695,7 +694,7 @@ config CRYPTO_AES_NI_INTEL
        select CRYPTO_AES_X86_64 if 64BIT
        select CRYPTO_AES_586 if !64BIT
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_ALGAPI
        select CRYPTO_GLUE_HELPER_X86 if 64BIT
        select CRYPTO_LRW
@@ -895,7 +894,7 @@ config CRYPTO_CAMELLIA_AESNI_AVX_X86_64
        depends on CRYPTO
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_CAMELLIA_X86_64
        select CRYPTO_LRW
@@ -917,7 +916,7 @@ config CRYPTO_CAMELLIA_AESNI_AVX2_X86_64
        depends on CRYPTO
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_CAMELLIA_X86_64
        select CRYPTO_CAMELLIA_AESNI_AVX_X86_64
@@ -969,7 +968,7 @@ config CRYPTO_CAST5_AVX_X86_64
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_CAST_COMMON
        select CRYPTO_CAST5
        help
@@ -992,7 +991,7 @@ config CRYPTO_CAST6_AVX_X86_64
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_CAST_COMMON
        select CRYPTO_CAST6
@@ -1110,7 +1109,7 @@ config CRYPTO_SERPENT_SSE2_X86_64
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_SERPENT
        select CRYPTO_LRW
@@ -1132,7 +1131,7 @@ config CRYPTO_SERPENT_SSE2_586
        depends on X86 && !64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_SERPENT
        select CRYPTO_LRW
@@ -1154,7 +1153,7 @@ config CRYPTO_SERPENT_AVX_X86_64
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_SERPENT
        select CRYPTO_LRW
@@ -1176,7 +1175,7 @@ config CRYPTO_SERPENT_AVX2_X86_64
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_SERPENT
        select CRYPTO_SERPENT_AVX_X86_64
@@ -1292,7 +1291,7 @@ config CRYPTO_TWOFISH_AVX_X86_64
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_TWOFISH_COMMON
        select CRYPTO_TWOFISH_X86_64
index b3a7e807e08bca306619a3e7250afbc9160fecbe..989c510da8cc98af911976874d6c16db865ee1b3 100644 (file)
@@ -2,8 +2,13 @@
 # Cryptographic API
 #
 
+# memneq MUST be built with -Os or -O0 to prevent early-return optimizations
+# that will defeat memneq's actual purpose to prevent timing attacks.
+CFLAGS_REMOVE_memneq.o := -O1 -O2 -O3
+CFLAGS_memneq.o := -Os
+
 obj-$(CONFIG_CRYPTO) += crypto.o
-crypto-y := api.o cipher.o compress.o
+crypto-y := api.o cipher.o compress.o memneq.o
 
 obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o
 
@@ -105,3 +110,4 @@ obj-$(CONFIG_XOR_BLOCKS) += xor.o
 obj-$(CONFIG_ASYNC_CORE) += async_tx/
 obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
 obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o
+obj-$(CONFIG_CRYPTO_ABLK_HELPER) += ablk_helper.o
similarity index 95%
rename from arch/x86/crypto/ablk_helper.c
rename to crypto/ablk_helper.c
index 43282fe04a8b726e57048d8e67fd96d209c76041..ffe7278d4bd83bd9b8ee5e7392af7bd417e037ae 100644 (file)
 #include <linux/crypto.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/hardirq.h>
 #include <crypto/algapi.h>
 #include <crypto/cryptd.h>
-#include <asm/i387.h>
-#include <asm/crypto/ablk_helper.h>
+#include <crypto/ablk_helper.h>
+#include <asm/simd.h>
 
 int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
                 unsigned int key_len)
@@ -70,11 +71,11 @@ int ablk_encrypt(struct ablkcipher_request *req)
        struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
        struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 
-       if (!irq_fpu_usable()) {
+       if (!may_use_simd()) {
                struct ablkcipher_request *cryptd_req =
                        ablkcipher_request_ctx(req);
 
-               memcpy(cryptd_req, req, sizeof(*req));
+               *cryptd_req = *req;
                ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
 
                return crypto_ablkcipher_encrypt(cryptd_req);
@@ -89,11 +90,11 @@ int ablk_decrypt(struct ablkcipher_request *req)
        struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
        struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 
-       if (!irq_fpu_usable()) {
+       if (!may_use_simd()) {
                struct ablkcipher_request *cryptd_req =
                        ablkcipher_request_ctx(req);
 
-               memcpy(cryptd_req, req, sizeof(*req));
+               *cryptd_req = *req;
                ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
 
                return crypto_ablkcipher_decrypt(cryptd_req);
index 7d4a8d28277e181386981dcef2d73ec377aefe9a..40886c489903b72a50c1b718869c38744d142aa4 100644 (file)
@@ -16,9 +16,7 @@
 #include <crypto/internal/skcipher.h>
 #include <linux/cpumask.h>
 #include <linux/err.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/rtnetlink.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -30,8 +28,6 @@
 
 #include "internal.h"
 
-static const char *skcipher_default_geniv __read_mostly;
-
 struct ablkcipher_buffer {
        struct list_head        entry;
        struct scatter_walk     dst;
@@ -527,8 +523,7 @@ const char *crypto_default_geniv(const struct crypto_alg *alg)
            alg->cra_blocksize)
                return "chainiv";
 
-       return alg->cra_flags & CRYPTO_ALG_ASYNC ?
-              "eseqiv" : skcipher_default_geniv;
+       return "eseqiv";
 }
 
 static int crypto_givcipher_default(struct crypto_alg *alg, u32 type, u32 mask)
@@ -709,17 +704,3 @@ err:
        return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(crypto_alloc_ablkcipher);
-
-static int __init skcipher_module_init(void)
-{
-       skcipher_default_geniv = num_possible_cpus() > 1 ?
-                                "eseqiv" : "chainiv";
-       return 0;
-}
-
-static void skcipher_module_exit(void)
-{
-}
-
-module_init(skcipher_module_init);
-module_exit(skcipher_module_exit);
index ef5356cd280a54c086e4f8ff964245e38748a391..850246206b1258a697f83e86c39acc9b0a17f973 100644 (file)
@@ -114,6 +114,9 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
        struct hash_ctx *ctx = ask->private;
        int err;
 
+       if (flags & MSG_SENDPAGE_NOTLAST)
+               flags |= MSG_MORE;
+
        lock_sock(sk);
        sg_init_table(ctx->sgl.sg, 1);
        sg_set_page(ctx->sgl.sg, page, size, offset);
index 6a6dfc062d2a47f04449fbb0e1c3f3852be337dc..a19c027b29bde504ac8eae4b4572947a69ed2335 100644 (file)
@@ -378,6 +378,9 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page,
        struct skcipher_sg_list *sgl;
        int err = -EINVAL;
 
+       if (flags & MSG_SENDPAGE_NOTLAST)
+               flags |= MSG_MORE;
+
        lock_sock(sk);
        if (!ctx->more && ctx->used)
                goto unlock;
index c0bb3778f1ae06976fbaf07c7e1b075fc0c581e7..666f1962a160f5d547579b918b6229de0232607b 100644 (file)
@@ -230,11 +230,11 @@ remainder:
         */
        if (byte_count < DEFAULT_BLK_SZ) {
 empty_rbuf:
-               for (; ctx->rand_data_valid < DEFAULT_BLK_SZ;
-                       ctx->rand_data_valid++) {
+               while (ctx->rand_data_valid < DEFAULT_BLK_SZ) {
                        *ptr = ctx->rand_data[ctx->rand_data_valid];
                        ptr++;
                        byte_count--;
+                       ctx->rand_data_valid++;
                        if (byte_count == 0)
                                goto done;
                }
index 90a17f59ba2800d197366dbcb0835a9adc598320..459cf97a75e2e223798e2cd157a60bf048f01117 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <crypto/algapi.h>
 #include "public_key.h"
 
 MODULE_LICENSE("GPL");
@@ -189,12 +190,12 @@ static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
                }
        }
 
-       if (memcmp(asn1_template, EM + T_offset, asn1_size) != 0) {
+       if (crypto_memneq(asn1_template, EM + T_offset, asn1_size) != 0) {
                kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]");
                return -EBADMSG;
        }
 
-       if (memcmp(H, EM + T_offset + asn1_size, hash_size) != 0) {
+       if (crypto_memneq(H, EM + T_offset + asn1_size, hash_size) != 0) {
                kleave(" = -EKEYREJECTED [EM[T] hash mismatch]");
                return -EKEYREJECTED;
        }
index f83300b6e8c13033e5e239be8d48e7fb379668de..382ef0d2ff2e5e030c0068d1076155364d48f43d 100644 (file)
 #include <linux/asn1_decoder.h>
 #include <keys/asymmetric-subtype.h>
 #include <keys/asymmetric-parser.h>
-#include <keys/system_keyring.h>
 #include <crypto/hash.h>
 #include "asymmetric_keys.h"
 #include "public_key.h"
 #include "x509_parser.h"
 
-/*
- * Find a key in the given keyring by issuer and authority.
- */
-static struct key *x509_request_asymmetric_key(
-       struct key *keyring,
-       const char *signer, size_t signer_len,
-       const char *authority, size_t auth_len)
-{
-       key_ref_t key;
-       char *id;
-
-       /* Construct an identifier. */
-       id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL);
-       if (!id)
-               return ERR_PTR(-ENOMEM);
-
-       memcpy(id, signer, signer_len);
-       id[signer_len + 0] = ':';
-       id[signer_len + 1] = ' ';
-       memcpy(id + signer_len + 2, authority, auth_len);
-       id[signer_len + 2 + auth_len] = 0;
-
-       pr_debug("Look up: \"%s\"\n", id);
-
-       key = keyring_search(make_key_ref(keyring, 1),
-                            &key_type_asymmetric, id);
-       if (IS_ERR(key))
-               pr_debug("Request for module key '%s' err %ld\n",
-                        id, PTR_ERR(key));
-       kfree(id);
-
-       if (IS_ERR(key)) {
-               switch (PTR_ERR(key)) {
-                       /* Hide some search errors */
-               case -EACCES:
-               case -ENOTDIR:
-               case -EAGAIN:
-                       return ERR_PTR(-ENOKEY);
-               default:
-                       return ERR_CAST(key);
-               }
-       }
-
-       pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key_ref_to_ptr(key)));
-       return key_ref_to_ptr(key);
-}
-
 /*
  * Set up the signature parameters in an X.509 certificate.  This involves
  * digesting the signed data and extracting the signature.
@@ -150,33 +102,6 @@ int x509_check_signature(const struct public_key *pub,
 }
 EXPORT_SYMBOL_GPL(x509_check_signature);
 
-/*
- * Check the new certificate against the ones in the trust keyring.  If one of
- * those is the signing key and validates the new certificate, then mark the
- * new certificate as being trusted.
- *
- * Return 0 if the new certificate was successfully validated, 1 if we couldn't
- * find a matching parent certificate in the trusted list and an error if there
- * is a matching certificate but the signature check fails.
- */
-static int x509_validate_trust(struct x509_certificate *cert,
-                              struct key *trust_keyring)
-{
-       const struct public_key *pk;
-       struct key *key;
-       int ret = 1;
-
-       key = x509_request_asymmetric_key(trust_keyring,
-                                         cert->issuer, strlen(cert->issuer),
-                                         cert->authority,
-                                         strlen(cert->authority));
-       if (!IS_ERR(key))  {
-               pk = key->payload.data;
-               ret = x509_check_signature(pk, cert);
-       }
-       return ret;
-}
-
 /*
  * Attempt to parse a data blob for a key as an X509 certificate.
  */
@@ -230,13 +155,9 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
        /* Check the signature on the key if it appears to be self-signed */
        if (!cert->authority ||
            strcmp(cert->fingerprint, cert->authority) == 0) {
-               ret = x509_check_signature(cert->pub, cert); /* self-signed */
+               ret = x509_check_signature(cert->pub, cert);
                if (ret < 0)
                        goto error_free_cert;
-       } else {
-               ret = x509_validate_trust(cert, system_trusted_keyring);
-               if (!ret)
-                       prep->trusted = 1;
        }
 
        /* Propose a description */
index ffce19de05cf958853dc0e13f7e3cf1efa30cd4f..e1223559d5dfd233cbc15184c9dc607fb34fae2e 100644 (file)
@@ -52,40 +52,52 @@ static void authenc_request_complete(struct aead_request *req, int err)
                aead_request_complete(req, err);
 }
 
-static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
-                                unsigned int keylen)
+int crypto_authenc_extractkeys(struct crypto_authenc_keys *keys, const u8 *key,
+                              unsigned int keylen)
 {
-       unsigned int authkeylen;
-       unsigned int enckeylen;
-       struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-       struct crypto_ahash *auth = ctx->auth;
-       struct crypto_ablkcipher *enc = ctx->enc;
-       struct rtattr *rta = (void *)key;
+       struct rtattr *rta = (struct rtattr *)key;
        struct crypto_authenc_key_param *param;
-       int err = -EINVAL;
 
        if (!RTA_OK(rta, keylen))
-               goto badkey;
+               return -EINVAL;
        if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
-               goto badkey;
+               return -EINVAL;
        if (RTA_PAYLOAD(rta) < sizeof(*param))
-               goto badkey;
+               return -EINVAL;
 
        param = RTA_DATA(rta);
-       enckeylen = be32_to_cpu(param->enckeylen);
+       keys->enckeylen = be32_to_cpu(param->enckeylen);
 
        key += RTA_ALIGN(rta->rta_len);
        keylen -= RTA_ALIGN(rta->rta_len);
 
-       if (keylen < enckeylen)
-               goto badkey;
+       if (keylen < keys->enckeylen)
+               return -EINVAL;
 
-       authkeylen = keylen - enckeylen;
+       keys->authkeylen = keylen - keys->enckeylen;
+       keys->authkey = key;
+       keys->enckey = key + keys->authkeylen;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_authenc_extractkeys);
+
+static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
+                                unsigned int keylen)
+{
+       struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
+       struct crypto_ahash *auth = ctx->auth;
+       struct crypto_ablkcipher *enc = ctx->enc;
+       struct crypto_authenc_keys keys;
+       int err = -EINVAL;
+
+       if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
+               goto badkey;
 
        crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
        crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) &
                                    CRYPTO_TFM_REQ_MASK);
-       err = crypto_ahash_setkey(auth, keyauthkeylen);
+       err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen);
        crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) &
                                       CRYPTO_TFM_RES_MASK);
 
@@ -95,7 +107,7 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
        crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
        crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc) &
                                         CRYPTO_TFM_REQ_MASK);
-       err = crypto_ablkcipher_setkey(enc, key + authkeylen, enckeylen);
+       err = crypto_ablkcipher_setkey(enc, keys.enckey, keys.enckeylen);
        crypto_aead_set_flags(authenc, crypto_ablkcipher_get_flags(enc) &
                                       CRYPTO_TFM_RES_MASK);
 
@@ -188,7 +200,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
        scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
                                 authsize, 0);
 
-       err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+       err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
        if (err)
                goto out;
 
@@ -227,7 +239,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq,
        scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
                                 authsize, 0);
 
-       err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+       err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
        if (err)
                goto out;
 
@@ -368,9 +380,10 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
        if (!err) {
                struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
                struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-               struct ablkcipher_request *abreq = aead_request_ctx(areq);
-               u8 *iv = (u8 *)(abreq + 1) +
-                        crypto_ablkcipher_reqsize(ctx->enc);
+               struct authenc_request_ctx *areq_ctx = aead_request_ctx(areq);
+               struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
+                                                           + ctx->reqoff);
+               u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(ctx->enc);
 
                err = crypto_authenc_genicv(areq, iv, 0);
        }
@@ -462,7 +475,7 @@ static int crypto_authenc_verify(struct aead_request *req,
        ihash = ohash + authsize;
        scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
                                 authsize, 0);
-       return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
+       return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
 }
 
 static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
index ab53762fc309c5db55ccaab948f1862bcc7a237a..4be0dd4373a9a2e8a15b62adbf8dbdd6e374eacd 100644 (file)
@@ -59,37 +59,19 @@ static void authenc_esn_request_complete(struct aead_request *req, int err)
 static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 *key,
                                     unsigned int keylen)
 {
-       unsigned int authkeylen;
-       unsigned int enckeylen;
        struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
        struct crypto_ahash *auth = ctx->auth;
        struct crypto_ablkcipher *enc = ctx->enc;
-       struct rtattr *rta = (void *)key;
-       struct crypto_authenc_key_param *param;
+       struct crypto_authenc_keys keys;
        int err = -EINVAL;
 
-       if (!RTA_OK(rta, keylen))
+       if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
                goto badkey;
-       if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
-               goto badkey;
-       if (RTA_PAYLOAD(rta) < sizeof(*param))
-               goto badkey;
-
-       param = RTA_DATA(rta);
-       enckeylen = be32_to_cpu(param->enckeylen);
-
-       key += RTA_ALIGN(rta->rta_len);
-       keylen -= RTA_ALIGN(rta->rta_len);
-
-       if (keylen < enckeylen)
-               goto badkey;
-
-       authkeylen = keylen - enckeylen;
 
        crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
        crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc_esn) &
                                     CRYPTO_TFM_REQ_MASK);
-       err = crypto_ahash_setkey(auth, keyauthkeylen);
+       err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen);
        crypto_aead_set_flags(authenc_esn, crypto_ahash_get_flags(auth) &
                                           CRYPTO_TFM_RES_MASK);
 
@@ -99,7 +81,7 @@ static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 *
        crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
        crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc_esn) &
                                         CRYPTO_TFM_REQ_MASK);
-       err = crypto_ablkcipher_setkey(enc, key + authkeylen, enckeylen);
+       err = crypto_ablkcipher_setkey(enc, keys.enckey, keys.enckeylen);
        crypto_aead_set_flags(authenc_esn, crypto_ablkcipher_get_flags(enc) &
                                           CRYPTO_TFM_RES_MASK);
 
@@ -247,7 +229,7 @@ static void authenc_esn_verify_ahash_update_done(struct crypto_async_request *ar
        scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
                                 authsize, 0);
 
-       err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+       err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
        if (err)
                goto out;
 
@@ -296,7 +278,7 @@ static void authenc_esn_verify_ahash_update_done2(struct crypto_async_request *a
        scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
                                 authsize, 0);
 
-       err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+       err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
        if (err)
                goto out;
 
@@ -336,7 +318,7 @@ static void authenc_esn_verify_ahash_done(struct crypto_async_request *areq,
        scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
                                 authsize, 0);
 
-       err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+       err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
        if (err)
                goto out;
 
@@ -568,7 +550,7 @@ static int crypto_authenc_esn_verify(struct aead_request *req)
        ihash = ohash + authsize;
        scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
                                 authsize, 0);
-       return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
+       return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
 }
 
 static int crypto_authenc_esn_iverify(struct aead_request *req, u8 *iv,
index 499c91717d937bfaba9364a5bcde94988626195c..1df84217f7c9320dbfc5174f91ce394667c36447 100644 (file)
@@ -271,7 +271,8 @@ static int crypto_ccm_auth(struct aead_request *req, struct scatterlist *plain,
        }
 
        /* compute plaintext into mac */
-       get_data_to_compute(cipher, pctx, plain, cryptlen);
+       if (cryptlen)
+               get_data_to_compute(cipher, pctx, plain, cryptlen);
 
 out:
        return err;
@@ -363,7 +364,7 @@ static void crypto_ccm_decrypt_done(struct crypto_async_request *areq,
 
        if (!err) {
                err = crypto_ccm_auth(req, req->dst, cryptlen);
-               if (!err && memcmp(pctx->auth_tag, pctx->odata, authsize))
+               if (!err && crypto_memneq(pctx->auth_tag, pctx->odata, authsize))
                        err = -EBADMSG;
        }
        aead_request_complete(req, err);
@@ -422,7 +423,7 @@ static int crypto_ccm_decrypt(struct aead_request *req)
                return err;
 
        /* verify */
-       if (memcmp(authtag, odata, authsize))
+       if (crypto_memneq(authtag, odata, authsize))
                return -EBADMSG;
 
        return err;
index 43e1fb05ea54878cbe136231a1a92c847b6d3119..b4f01793900409a0398faeb958b74416a5d1637d 100644 (file)
@@ -582,7 +582,7 @@ static int crypto_gcm_verify(struct aead_request *req,
 
        crypto_xor(auth_tag, iauth_tag, 16);
        scatterwalk_map_and_copy(iauth_tag, req->src, cryptlen, authsize, 0);
-       return memcmp(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
+       return crypto_memneq(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
 }
 
 static void gcm_decrypt_done(struct crypto_async_request *areq, int err)
diff --git a/crypto/memneq.c b/crypto/memneq.c
new file mode 100644 (file)
index 0000000..cd01622
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Constant-time equality testing of memory regions.
+ *
+ * Authors:
+ *
+ *   James Yonan <james@openvpn.net>
+ *   Daniel Borkmann <dborkman@redhat.com>
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of OpenVPN Technologies nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <crypto/algapi.h>
+
+#ifndef __HAVE_ARCH_CRYPTO_MEMNEQ
+
+/* Generic path for arbitrary size */
+static inline unsigned long
+__crypto_memneq_generic(const void *a, const void *b, size_t size)
+{
+       unsigned long neq = 0;
+
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+       while (size >= sizeof(unsigned long)) {
+               neq |= *(unsigned long *)a ^ *(unsigned long *)b;
+               a += sizeof(unsigned long);
+               b += sizeof(unsigned long);
+               size -= sizeof(unsigned long);
+       }
+#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
+       while (size > 0) {
+               neq |= *(unsigned char *)a ^ *(unsigned char *)b;
+               a += 1;
+               b += 1;
+               size -= 1;
+       }
+       return neq;
+}
+
+/* Loop-free fast-path for frequently used 16-byte size */
+static inline unsigned long __crypto_memneq_16(const void *a, const void *b)
+{
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+       if (sizeof(unsigned long) == 8)
+               return ((*(unsigned long *)(a)   ^ *(unsigned long *)(b))
+                     | (*(unsigned long *)(a+8) ^ *(unsigned long *)(b+8)));
+       else if (sizeof(unsigned int) == 4)
+               return ((*(unsigned int *)(a)    ^ *(unsigned int *)(b))
+                      | (*(unsigned int *)(a+4)  ^ *(unsigned int *)(b+4))
+                     | (*(unsigned int *)(a+8)  ^ *(unsigned int *)(b+8))
+                     | (*(unsigned int *)(a+12) ^ *(unsigned int *)(b+12)));
+       else
+#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
+               return ((*(unsigned char *)(a)    ^ *(unsigned char *)(b))
+                     | (*(unsigned char *)(a+1)  ^ *(unsigned char *)(b+1))
+                     | (*(unsigned char *)(a+2)  ^ *(unsigned char *)(b+2))
+                     | (*(unsigned char *)(a+3)  ^ *(unsigned char *)(b+3))
+                     | (*(unsigned char *)(a+4)  ^ *(unsigned char *)(b+4))
+                     | (*(unsigned char *)(a+5)  ^ *(unsigned char *)(b+5))
+                     | (*(unsigned char *)(a+6)  ^ *(unsigned char *)(b+6))
+                     | (*(unsigned char *)(a+7)  ^ *(unsigned char *)(b+7))
+                     | (*(unsigned char *)(a+8)  ^ *(unsigned char *)(b+8))
+                     | (*(unsigned char *)(a+9)  ^ *(unsigned char *)(b+9))
+                     | (*(unsigned char *)(a+10) ^ *(unsigned char *)(b+10))
+                     | (*(unsigned char *)(a+11) ^ *(unsigned char *)(b+11))
+                     | (*(unsigned char *)(a+12) ^ *(unsigned char *)(b+12))
+                     | (*(unsigned char *)(a+13) ^ *(unsigned char *)(b+13))
+                     | (*(unsigned char *)(a+14) ^ *(unsigned char *)(b+14))
+                     | (*(unsigned char *)(a+15) ^ *(unsigned char *)(b+15)));
+}
+
+/* Compare two areas of memory without leaking timing information,
+ * and with special optimizations for common sizes.  Users should
+ * not call this function directly, but should instead use
+ * crypto_memneq defined in crypto/algapi.h.
+ */
+noinline unsigned long __crypto_memneq(const void *a, const void *b,
+                                      size_t size)
+{
+       switch (size) {
+       case 16:
+               return __crypto_memneq_16(a, b);
+       default:
+               return __crypto_memneq_generic(a, b, size);
+       }
+}
+EXPORT_SYMBOL(__crypto_memneq);
+
+#endif /* __HAVE_ARCH_CRYPTO_MEMNEQ */
index 1ab8258fcf560735237a198b2037c102e229d20b..001f07cdb828d59101521162109b9f101c34a319 100644 (file)
@@ -1242,6 +1242,10 @@ static int do_test(int m)
                ret += tcrypt_test("cmac(des3_ede)");
                break;
 
+       case 155:
+               ret += tcrypt_test("authenc(hmac(sha1),cbc(aes))");
+               break;
+
        case 200:
                test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
                                speed_template_16_24_32);
index 432afc03e7c3f9c1040ac54033950eb9e17c0727..77955507f6f1f73a044554a7d738074c98f9829e 100644 (file)
@@ -503,16 +503,16 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
                                goto out;
                        }
 
-                       sg_init_one(&sg[0], input,
-                                   template[i].ilen + (enc ? authsize : 0));
-
                        if (diff_dst) {
                                output = xoutbuf[0];
                                output += align_offset;
+                               sg_init_one(&sg[0], input, template[i].ilen);
                                sg_init_one(&sgout[0], output,
+                                           template[i].rlen);
+                       } else {
+                               sg_init_one(&sg[0], input,
                                            template[i].ilen +
                                                (enc ? authsize : 0));
-                       } else {
                                output = input;
                        }
 
@@ -612,12 +612,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
                                memcpy(q, template[i].input + temp,
                                       template[i].tap[k]);
 
-                               n = template[i].tap[k];
-                               if (k == template[i].np - 1 && enc)
-                                       n += authsize;
-                               if (offset_in_page(q) + n < PAGE_SIZE)
-                                       q[n] = 0;
-
                                sg_set_buf(&sg[k], q, template[i].tap[k]);
 
                                if (diff_dst) {
@@ -625,13 +619,17 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
                                            offset_in_page(IDX[k]);
 
                                        memset(q, 0, template[i].tap[k]);
-                                       if (offset_in_page(q) + n < PAGE_SIZE)
-                                               q[n] = 0;
 
                                        sg_set_buf(&sgout[k], q,
                                                   template[i].tap[k]);
                                }
 
+                               n = template[i].tap[k];
+                               if (k == template[i].np - 1 && enc)
+                                       n += authsize;
+                               if (offset_in_page(q) + n < PAGE_SIZE)
+                                       q[n] = 0;
+
                                temp += template[i].tap[k];
                        }
 
@@ -650,10 +648,10 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
                                        goto out;
                                }
 
-                               sg[k - 1].length += authsize;
-
                                if (diff_dst)
                                        sgout[k - 1].length += authsize;
+                               else
+                                       sg[k - 1].length += authsize;
                        }
 
                        sg_init_table(asg, template[i].anp);
index 3cc8214f9b26630e86eddcb37ac35f7a5f57e4a1..8e3b8b06c0b2e26a90308b9f15457bfa9da06b13 100644 (file)
@@ -118,7 +118,7 @@ obj-$(CONFIG_SGI_SN)                += sn/
 obj-y                          += firmware/
 obj-$(CONFIG_CRYPTO)           += crypto/
 obj-$(CONFIG_SUPERH)           += sh/
-obj-$(CONFIG_ARCH_SHMOBILE)    += sh/
+obj-$(CONFIG_ARCH_SHMOBILE_LEGACY)     += sh/
 ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
 obj-y                          += clocksource/
 endif
index 8711e3797165fa73fd0c401cedbb54c61eb68e4a..8095943e6e112da4b0dd3e77b92e331270624020 100644 (file)
@@ -32,8 +32,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 #define PREFIX "ACPI: "
 
index a6869e110ce5650a86b6f666bc28347031c16275..2635a01c5b3edc077eb80a704db6e316b2395857 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/module.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_bus.h>
 #include <linux/cper.h>
 #include <linux/ratelimit.h>
 #include <asm/cpu.h>
index 6745fe137b9ea541ae729429035eaeca8fc8fc07..e603905973721c415a912c04e2c7f3926fcd5634 100644 (file)
@@ -162,6 +162,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
        { "80860F14", (unsigned long)&byt_sdio_dev_desc },
        { "80860F41", (unsigned long)&byt_i2c_dev_desc },
        { "INT33B2", },
+       { "INT33FC", },
 
        { "INT3430", (unsigned long)&lpt_dev_desc },
        { "INT3431", (unsigned long)&lpt_dev_desc },
index 551dad712ffec451364a08c01487a1987c10d7db..9aeacdfca4106ac8376d74d049293bd26d4e3075 100644 (file)
@@ -180,14 +180,14 @@ static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info)
 
 static int acpi_bind_memblk(struct memory_block *mem, void *arg)
 {
-       return acpi_bind_one(&mem->dev, (acpi_handle)arg);
+       return acpi_bind_one(&mem->dev, arg);
 }
 
 static int acpi_bind_memory_blocks(struct acpi_memory_info *info,
-                                  acpi_handle handle)
+                                  struct acpi_device *adev)
 {
        return walk_memory_range(acpi_meminfo_start_pfn(info),
-                                acpi_meminfo_end_pfn(info), (void *)handle,
+                                acpi_meminfo_end_pfn(info), adev,
                                 acpi_bind_memblk);
 }
 
@@ -197,8 +197,7 @@ static int acpi_unbind_memblk(struct memory_block *mem, void *arg)
        return 0;
 }
 
-static void acpi_unbind_memory_blocks(struct acpi_memory_info *info,
-                                     acpi_handle handle)
+static void acpi_unbind_memory_blocks(struct acpi_memory_info *info)
 {
        walk_memory_range(acpi_meminfo_start_pfn(info),
                          acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk);
@@ -242,9 +241,9 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
                if (result && result != -EEXIST)
                        continue;
 
-               result = acpi_bind_memory_blocks(info, handle);
+               result = acpi_bind_memory_blocks(info, mem_device->device);
                if (result) {
-                       acpi_unbind_memory_blocks(info, handle);
+                       acpi_unbind_memory_blocks(info);
                        return -ENODEV;
                }
 
@@ -285,7 +284,7 @@ static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
                if (nid == NUMA_NO_NODE)
                        nid = memory_add_physaddr_to_nid(info->start_addr);
 
-               acpi_unbind_memory_blocks(info, handle);
+               acpi_unbind_memory_blocks(info);
                remove_memory(nid, info->start_addr, info->length);
                list_del(&info->list);
                kfree(info);
index fc6008fbce35bd99f390d15af6e7471b1ca0438a..65610c0e7243d3d9cd4f8e5d757ca9d602b94816 100644 (file)
@@ -28,8 +28,7 @@
 #include <linux/cpu.h>
 #include <linux/clockchips.h>
 #include <linux/slab.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <asm/mwait.h>
 
 #define ACPI_PROCESSOR_AGGREGATOR_CLASS        "acpi_pad"
index 3c1d6b0c09a4b7d1eeeb9347a7c743d1c7487988..d58a2aba09308a31fd6f80355bba51fb6df6724f 100644 (file)
@@ -395,7 +395,7 @@ static int acpi_processor_add(struct acpi_device *device,
                goto err;
        }
 
-       result = acpi_bind_one(dev, pr->handle);
+       result = acpi_bind_one(dev, device);
        if (result)
                goto err;
 
index f691d0e4d9fa091faeb0ebc231e8701b399c264b..ff97430455cbe923d3bad4f453635371b9388867 100644 (file)
@@ -184,7 +184,7 @@ acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer,
                             struct acpi_buffer *output_buffer);
 
 acpi_status
-acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
+acpi_rs_create_aml_resources(struct acpi_buffer *resource_list,
                             struct acpi_buffer *output_buffer);
 
 acpi_status
@@ -227,8 +227,8 @@ acpi_rs_get_list_length(u8 * aml_buffer,
                        u32 aml_buffer_length, acpi_size * size_needed);
 
 acpi_status
-acpi_rs_get_aml_length(struct acpi_resource *linked_list_buffer,
-                      acpi_size * size_needed);
+acpi_rs_get_aml_length(struct acpi_resource *resource_list,
+                      acpi_size resource_list_size, acpi_size * size_needed);
 
 acpi_status
 acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
index 243737363fb8ea51c80f77a16908659a29271a48..fd1ff54cda1911a1e520440afd8a48125d927069 100644 (file)
@@ -106,6 +106,7 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)
 void acpi_ns_delete_node(struct acpi_namespace_node *node)
 {
        union acpi_operand_object *obj_desc;
+       union acpi_operand_object *next_desc;
 
        ACPI_FUNCTION_NAME(ns_delete_node);
 
@@ -114,12 +115,13 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
        acpi_ns_detach_object(node);
 
        /*
-        * Delete an attached data object if present (an object that was created
-        * and attached via acpi_attach_data). Note: After any normal object is
-        * detached above, the only possible remaining object is a data object.
+        * Delete an attached data object list if present (objects that were
+        * attached via acpi_attach_data). Note: After any normal object is
+        * detached above, the only possible remaining object(s) are data
+        * objects, in a linked list.
         */
        obj_desc = node->object;
-       if (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
+       while (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
 
                /* Invoke the attached data deletion handler if present */
 
@@ -127,7 +129,15 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
                        obj_desc->data.handler(node, obj_desc->data.pointer);
                }
 
+               next_desc = obj_desc->common.next_object;
                acpi_ut_remove_reference(obj_desc);
+               obj_desc = next_desc;
+       }
+
+       /* Special case for the statically allocated root node */
+
+       if (node == acpi_gbl_root_node) {
+               return;
        }
 
        /* Now we can delete the node */
index cc2fea94c5f0939fcbfe87c676c0e869171a14f5..4a0665b6bcc11c6c6eb8aad3ee62be15b6122694 100644 (file)
@@ -593,24 +593,26 @@ struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle)
 
 void acpi_ns_terminate(void)
 {
-       union acpi_operand_object *obj_desc;
+       acpi_status status;
 
        ACPI_FUNCTION_TRACE(ns_terminate);
 
        /*
-        * 1) Free the entire namespace -- all nodes and objects
-        *
-        * Delete all object descriptors attached to namepsace nodes
+        * Free the entire namespace -- all nodes and all objects
+        * attached to the nodes
         */
        acpi_ns_delete_namespace_subtree(acpi_gbl_root_node);
 
-       /* Detach any objects attached to the root */
+       /* Delete any objects attached to the root node */
 
-       obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node);
-       if (obj_desc) {
-               acpi_ns_detach_object(acpi_gbl_root_node);
+       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+       if (ACPI_FAILURE(status)) {
+               return_VOID;
        }
 
+       acpi_ns_delete_node(acpi_gbl_root_node);
+       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
        return_VOID;
 }
index b62a0f4f4f9bb527cd49fc95279b7032ba1a689a..b60c9cf82862f9e94dfb254b6a30b003e2dd5426 100644 (file)
@@ -174,6 +174,7 @@ acpi_rs_stream_option_length(u32 resource_length,
  * FUNCTION:    acpi_rs_get_aml_length
  *
  * PARAMETERS:  resource            - Pointer to the resource linked list
+ *              resource_list_size  - Size of the resource linked list
  *              size_needed         - Where the required size is returned
  *
  * RETURN:      Status
@@ -185,16 +186,20 @@ acpi_rs_stream_option_length(u32 resource_length,
  ******************************************************************************/
 
 acpi_status
-acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
+acpi_rs_get_aml_length(struct acpi_resource *resource,
+                      acpi_size resource_list_size, acpi_size * size_needed)
 {
        acpi_size aml_size_needed = 0;
+       struct acpi_resource *resource_end;
        acpi_rs_length total_size;
 
        ACPI_FUNCTION_TRACE(rs_get_aml_length);
 
        /* Traverse entire list of internal resource descriptors */
 
-       while (resource) {
+       resource_end =
+           ACPI_ADD_PTR(struct acpi_resource, resource, resource_list_size);
+       while (resource < resource_end) {
 
                /* Validate the descriptor type */
 
index 65f3e1c5b5989f61bdcb03e6620cdd1a7371dba9..3a2ace93e62cf5d11690a4a4a907ae5539007f9e 100644 (file)
@@ -418,22 +418,21 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
  *
  * FUNCTION:    acpi_rs_create_aml_resources
  *
- * PARAMETERS:  linked_list_buffer      - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's buffer
+ * PARAMETERS:  resource_list           - Pointer to the resource list buffer
+ *              output_buffer           - Where the AML buffer is returned
  *
  * RETURN:      Status  AE_OK if okay, else a valid acpi_status code.
  *              If the output_buffer is too small, the error will be
  *              AE_BUFFER_OVERFLOW and output_buffer->Length will point
  *              to the size buffer needed.
  *
- * DESCRIPTION: Takes the linked list of device resources and
- *              creates a bytestream to be used as input for the
- *              _SRS control method.
+ * DESCRIPTION: Converts a list of device resources to an AML bytestream
+ *              to be used as input for the _SRS control method.
  *
  ******************************************************************************/
 
 acpi_status
-acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
+acpi_rs_create_aml_resources(struct acpi_buffer *resource_list,
                             struct acpi_buffer *output_buffer)
 {
        acpi_status status;
@@ -441,16 +440,16 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
 
        ACPI_FUNCTION_TRACE(rs_create_aml_resources);
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "LinkedListBuffer = %p\n",
-                         linked_list_buffer));
+       /* Params already validated, no need to re-validate here */
 
-       /*
-        * Params already validated, so we don't re-validate here
-        *
-        * Pass the linked_list_buffer into a module that calculates
-        * the buffer size needed for the byte stream.
-        */
-       status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed);
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ResourceList Buffer = %p\n",
+                         resource_list->pointer));
+
+       /* Get the buffer size needed for the AML byte stream */
+
+       status = acpi_rs_get_aml_length(resource_list->pointer,
+                                       resource_list->length,
+                                       &aml_size_needed);
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n",
                          (u32)aml_size_needed, acpi_format_exception(status)));
@@ -467,10 +466,9 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
 
        /* Do the conversion */
 
-       status =
-           acpi_rs_convert_resources_to_aml(linked_list_buffer,
-                                            aml_size_needed,
-                                            output_buffer->pointer);
+       status = acpi_rs_convert_resources_to_aml(resource_list->pointer,
+                                                 aml_size_needed,
+                                                 output_buffer->pointer);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
index aef303d56d86fecc84e397cad3c24280a874dbb4..14a7982c9961088ae50c0283bfefb4b4b5ccb488 100644 (file)
@@ -753,7 +753,7 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
         * Convert the linked list into a byte stream
         */
        buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
-       status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer);
+       status = acpi_rs_create_aml_resources(in_buffer, &buffer);
        if (ACPI_FAILURE(status)) {
                goto cleanup;
        }
index 1a67b3944b3b8db426fb3edf7b878153785b7631..03ae8affe48f097b1aae7346edd25a165f23186a 100644 (file)
@@ -185,6 +185,7 @@ acpi_debug_print(u32 requested_debug_level,
                }
 
                acpi_gbl_prev_thread_id = thread_id;
+               acpi_gbl_nesting_level = 0;
        }
 
        /*
@@ -193,13 +194,21 @@ acpi_debug_print(u32 requested_debug_level,
         */
        acpi_os_printf("%9s-%04ld ", module_name, line_number);
 
+#ifdef ACPI_EXEC_APP
+       /*
+        * For acpi_exec only, emit the thread ID and nesting level.
+        * Note: nesting level is really only useful during a single-thread
+        * execution. Otherwise, multiple threads will keep resetting the
+        * level.
+        */
        if (ACPI_LV_THREADS & acpi_dbg_level) {
                acpi_os_printf("[%u] ", (u32)thread_id);
        }
 
-       acpi_os_printf("[%02ld] %-22.22s: ",
-                      acpi_gbl_nesting_level,
-                      acpi_ut_trim_function_name(function_name));
+       acpi_os_printf("[%02ld] ", acpi_gbl_nesting_level);
+#endif
+
+       acpi_os_printf("%-22.22s: ", acpi_ut_trim_function_name(function_name));
 
        va_start(args, format);
        acpi_os_vprintf(format, args);
@@ -420,7 +429,9 @@ acpi_ut_exit(u32 line_number,
                                 component_id, "%s\n", acpi_gbl_fn_exit_str);
        }
 
-       acpi_gbl_nesting_level--;
+       if (acpi_gbl_nesting_level) {
+               acpi_gbl_nesting_level--;
+       }
 }
 
 ACPI_EXPORT_SYMBOL(acpi_ut_exit)
@@ -467,7 +478,9 @@ acpi_ut_status_exit(u32 line_number,
                }
        }
 
-       acpi_gbl_nesting_level--;
+       if (acpi_gbl_nesting_level) {
+               acpi_gbl_nesting_level--;
+       }
 }
 
 ACPI_EXPORT_SYMBOL(acpi_ut_status_exit)
@@ -504,7 +517,9 @@ acpi_ut_value_exit(u32 line_number,
                                 ACPI_FORMAT_UINT64(value));
        }
 
-       acpi_gbl_nesting_level--;
+       if (acpi_gbl_nesting_level) {
+               acpi_gbl_nesting_level--;
+       }
 }
 
 ACPI_EXPORT_SYMBOL(acpi_ut_value_exit)
@@ -540,7 +555,9 @@ acpi_ut_ptr_exit(u32 line_number,
                                 ptr);
        }
 
-       acpi_gbl_nesting_level--;
+       if (acpi_gbl_nesting_level) {
+               acpi_gbl_nesting_level--;
+       }
 }
 
 #endif
index fb57d03e698bd3b7ae2d4194d69dc3478ca09025..ca0c6d7ec0d4181cfdd3fa9b91547a84cd545e2f 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/nmi.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
-#include <acpi/acpi.h>
 
 #include "apei-internal.h"
 
index fbf1aceda8b8ab915a7d2476d78db2b6e2b94e68..e90ef8b96f266086ade6178162d3f87e2b3f6aa1 100644 (file)
@@ -36,8 +36,7 @@
 #include <linux/suspend.h>
 #include <asm/unaligned.h>
 
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <linux/power_supply.h>
 
 #define PREFIX "ACPI: "
index 078c4f7fe2dd97c42d3e13ea11ebde804e3ae4f0..05ee8f61bfb59d8a53d75347d468eb9d56bc463c 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_bus.h>
 #include <linux/dmi.h>
 
 #include "internal.h"
index bba9b72e25f8235e6d12593bdd16bb378c7af25a..2c38ae22c17f1dad8283f4c6aa03b365a0232a69 100644 (file)
@@ -37,8 +37,6 @@
 #include <asm/mpspec.h>
 #endif
 #include <linux/pci.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
@@ -52,9 +50,6 @@ struct acpi_device *acpi_root;
 struct proc_dir_entry *acpi_root_dir;
 EXPORT_SYMBOL(acpi_root_dir);
 
-#define STRUCT_TO_INT(s)       (*((int*)&s))
-
-
 #ifdef CONFIG_X86
 static int set_copy_dsdt(const struct dmi_system_id *id)
 {
@@ -115,18 +110,16 @@ int acpi_bus_get_status(struct acpi_device *device)
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       STRUCT_TO_INT(device->status) = (int) sta;
+       acpi_set_device_status(device, sta);
 
        if (device->status.functional && !device->status.present) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
                       "functional but not present;\n",
-                       device->pnp.bus_id,
-                       (u32) STRUCT_TO_INT(device->status)));
+                       device->pnp.bus_id, (u32)sta));
        }
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
-                         device->pnp.bus_id,
-                         (u32) STRUCT_TO_INT(device->status)));
+                         device->pnp.bus_id, (u32)sta));
        return 0;
 }
 EXPORT_SYMBOL(acpi_bus_get_status);
@@ -329,58 +322,6 @@ static void acpi_bus_osc_support(void)
                              Notification Handling
    -------------------------------------------------------------------------- */
 
-static void acpi_bus_check_device(acpi_handle handle)
-{
-       struct acpi_device *device;
-       acpi_status status;
-       struct acpi_device_status old_status;
-
-       if (acpi_bus_get_device(handle, &device))
-               return;
-       if (!device)
-               return;
-
-       old_status = device->status;
-
-       /*
-        * Make sure this device's parent is present before we go about
-        * messing with the device.
-        */
-       if (device->parent && !device->parent->status.present) {
-               device->status = device->parent->status;
-               return;
-       }
-
-       status = acpi_bus_get_status(device);
-       if (ACPI_FAILURE(status))
-               return;
-
-       if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
-               return;
-
-       /*
-        * Device Insertion/Removal
-        */
-       if ((device->status.present) && !(old_status.present)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
-               /* TBD: Handle device insertion */
-       } else if (!(device->status.present) && (old_status.present)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
-               /* TBD: Handle device removal */
-       }
-}
-
-static void acpi_bus_check_scope(acpi_handle handle)
-{
-       /* Status Change? */
-       acpi_bus_check_device(handle);
-
-       /*
-        * TBD: Enumerate child devices within this device's scope and
-        *       run acpi_bus_check_device()'s on them.
-        */
-}
-
 /**
  * acpi_bus_notify
  * ---------------
@@ -397,19 +338,11 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
        switch (type) {
 
        case ACPI_NOTIFY_BUS_CHECK:
-               acpi_bus_check_scope(handle);
-               /*
-                * TBD: We'll need to outsource certain events to non-ACPI
-                *      drivers via the device manager (device.c).
-                */
+               /* TBD */
                break;
 
        case ACPI_NOTIFY_DEVICE_CHECK:
-               acpi_bus_check_device(handle);
-               /*
-                * TBD: We'll need to outsource certain events to non-ACPI
-                *      drivers via the device manager (device.c).
-                */
+               /* TBD */
                break;
 
        case ACPI_NOTIFY_DEVICE_WAKE:
index c971929d75c20090b69afda2ab65b073bc95b140..9e3a6cb99f90eb7de2e4c0f078ef316fc0cb895a 100644 (file)
@@ -31,8 +31,7 @@
 #include <linux/seq_file.h>
 #include <linux/input.h>
 #include <linux/slab.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <acpi/button.h>
 
 #define PREFIX "ACPI: "
index e2315166765501b479259269ea5888d44042868b..83d232c10f139d697513be3e718cbff8b2342bb9 100644 (file)
@@ -44,19 +44,24 @@ static const struct acpi_device_id container_device_ids[] = {
        {"", 0},
 };
 
-static int container_device_attach(struct acpi_device *device,
+static int container_device_attach(struct acpi_device *adev,
                                   const struct acpi_device_id *not_used)
 {
-       /* This is necessary for container hotplug to work. */
+       kobject_uevent(&adev->dev.kobj, KOBJ_ONLINE);
        return 1;
 }
 
+static void container_device_detach(struct acpi_device *adev)
+{
+       kobject_uevent(&adev->dev.kobj, KOBJ_OFFLINE);
+}
+
 static struct acpi_scan_handler container_handler = {
        .ids = container_device_ids,
        .attach = container_device_attach,
+       .detach = container_device_detach,
        .hotplug = {
                .enabled = true,
-               .mode = AHM_CONTAINER,
        },
 };
 
index 12b62f2cdb3f0ad507748e9280a961eb1d7667b3..c68e72414a67a9b00231b095335945d5cdd2f31e 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/uaccess.h>
 #include <linux/debugfs.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 #include "internal.h"
 
index b55d6a20dc0eda9a78419f29bb8eb229cc157930..6b1919f6bd8212248f8a7399c21f73b1303a254e 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/export.h>
 #include <linux/init.h>
 #include <linux/debugfs.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 #define _COMPONENT             ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("debugfs");
index b3480cf7db1a1d1eba0e8d884cb456f92b76b660..d49f1e46470370908d72b6efb7677d70f80ded98 100644 (file)
@@ -256,6 +256,8 @@ int acpi_bus_init_power(struct acpi_device *device)
                return -EINVAL;
 
        device->power.state = ACPI_STATE_UNKNOWN;
+       if (!acpi_device_is_present(device))
+               return 0;
 
        result = acpi_device_get_power(device, &state);
        if (result)
@@ -302,15 +304,18 @@ int acpi_device_fix_up_power(struct acpi_device *device)
        return ret;
 }
 
-int acpi_bus_update_power(acpi_handle handle, int *state_p)
+int acpi_device_update_power(struct acpi_device *device, int *state_p)
 {
-       struct acpi_device *device;
        int state;
        int result;
 
-       result = acpi_bus_get_device(handle, &device);
-       if (result)
+       if (device->power.state == ACPI_STATE_UNKNOWN) {
+               result = acpi_bus_init_power(device);
+               if (!result && state_p)
+                       *state_p = device->power.state;
+
                return result;
+       }
 
        result = acpi_device_get_power(device, &state);
        if (result)
@@ -338,6 +343,15 @@ int acpi_bus_update_power(acpi_handle handle, int *state_p)
 
        return 0;
 }
+
+int acpi_bus_update_power(acpi_handle handle, int *state_p)
+{
+       struct acpi_device *device;
+       int result;
+
+       result = acpi_bus_get_device(handle, &device);
+       return result ? result : acpi_device_update_power(device, state_p);
+}
 EXPORT_SYMBOL_GPL(acpi_bus_update_power);
 
 bool acpi_bus_power_manageable(acpi_handle handle)
index dcd73ccb514c601df4efdee7043f2a7cffeb718e..8da6be99ba4206b8ebc82eb669be2f447e53b3ab 100644 (file)
@@ -32,8 +32,6 @@
 #include <linux/jiffies.h>
 #include <linux/stddef.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 
 #define PREFIX "ACPI: "
 
@@ -323,14 +321,11 @@ static int dock_present(struct dock_station *ds)
  */
 static void dock_create_acpi_device(acpi_handle handle)
 {
-       struct acpi_device *device;
+       struct acpi_device *device = NULL;
        int ret;
 
-       if (acpi_bus_get_device(handle, &device)) {
-               /*
-                * no device created for this object,
-                * so we should create one.
-                */
+       acpi_bus_get_device(handle, &device);
+       if (!acpi_device_enumerated(device)) {
                ret = acpi_bus_scan(handle);
                if (ret)
                        pr_debug("error adding bus, %x\n", -ret);
index ba5b56db9d27c7fafa3b19c6d1f5d2549308aea6..ff40120e930e5ae3c3506db53481f4fe6809a680 100644 (file)
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <asm/io.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <linux/dmi.h>
+#include <asm/io.h>
 
 #include "internal.h"
 
index cae3b387b867a99ab7013cfc2b731b2125abc961..ef2d730734dcca90a9690e48021d1d9a1d925791 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/gfp.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
 
index ba3da88cee45a20479df62023ee560aa422dff22..1fb62900f32a9c57d329fd3e5480bc0dc7c305b8 100644 (file)
@@ -29,8 +29,7 @@
 #include <linux/types.h>
 #include <asm/uaccess.h>
 #include <linux/thermal.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 #define PREFIX "ACPI: "
 
index a22a295edb692347f16066bff26d145973ab2523..0c789224d40d4da34aa3c7f1a9314bb12ba7b459 100644 (file)
@@ -37,7 +37,7 @@ 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->match && type->find_companion) {
                down_write(&bus_type_sem);
                list_add_tail(&type->list, &bus_type_list);
                up_write(&bus_type_sem);
@@ -82,109 +82,74 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
 #define FIND_CHILD_MIN_SCORE   1
 #define FIND_CHILD_MAX_SCORE   2
 
-static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used,
-                                 void *not_used, void **ret_p)
-{
-       struct acpi_device *adev = NULL;
-
-       acpi_bus_get_device(handle, &adev);
-       if (adev) {
-               *ret_p = handle;
-               return AE_CTRL_TERMINATE;
-       }
-       return AE_OK;
-}
-
-static int do_find_child_checks(acpi_handle handle, bool is_bridge)
+static int find_child_checks(struct acpi_device *adev, bool check_children)
 {
        bool sta_present = true;
        unsigned long long sta;
        acpi_status status;
 
-       status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+       status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
        if (status == AE_NOT_FOUND)
                sta_present = false;
        else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED))
                return -ENODEV;
 
-       if (is_bridge) {
-               void *test = NULL;
+       if (check_children && list_empty(&adev->children))
+               return -ENODEV;
 
-               /* Check if this object has at least one child device. */
-               acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
-                                   acpi_dev_present, NULL, NULL, &test);
-               if (!test)
-                       return -ENODEV;
-       }
        return sta_present ? FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE;
 }
 
-struct find_child_context {
-       u64 addr;
-       bool is_bridge;
-       acpi_handle ret;
-       int ret_score;
-};
-
-static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
-                                void *data, void **not_used)
-{
-       struct find_child_context *context = data;
-       unsigned long long addr;
-       acpi_status status;
-       int score;
-
-       status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
-       if (ACPI_FAILURE(status) || addr != context->addr)
-               return AE_OK;
-
-       if (!context->ret) {
-               /* This is the first matching object.  Save its handle. */
-               context->ret = handle;
-               return AE_OK;
-       }
-       /*
-        * There is more than one matching object with the same _ADR value.
-        * That really is unexpected, so we are kind of beyond the scope of the
-        * spec here.  We have to choose which one to return, though.
-        *
-        * First, check if the previously found object is good enough and return
-        * its handle if so.  Second, check the same for the object that we've
-        * just found.
-        */
-       if (!context->ret_score) {
-               score = do_find_child_checks(context->ret, context->is_bridge);
-               if (score == FIND_CHILD_MAX_SCORE)
-                       return AE_CTRL_TERMINATE;
-               else
-                       context->ret_score = score;
-       }
-       score = do_find_child_checks(handle, context->is_bridge);
-       if (score == FIND_CHILD_MAX_SCORE) {
-               context->ret = handle;
-               return AE_CTRL_TERMINATE;
-       } else if (score > context->ret_score) {
-               context->ret = handle;
-               context->ret_score = score;
-       }
-       return AE_OK;
-}
-
-acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge)
+struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
+                                          u64 address, bool check_children)
 {
-       if (parent) {
-               struct find_child_context context = {
-                       .addr = addr,
-                       .is_bridge = is_bridge,
-               };
-
-               acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, do_find_child,
-                                   NULL, &context, NULL);
-               return context.ret;
+       struct acpi_device *adev, *ret = NULL;
+       int ret_score = 0;
+
+       if (!parent)
+               return NULL;
+
+       list_for_each_entry(adev, &parent->children, node) {
+               unsigned long long addr;
+               acpi_status status;
+               int score;
+
+               status = acpi_evaluate_integer(adev->handle, METHOD_NAME__ADR,
+                                              NULL, &addr);
+               if (ACPI_FAILURE(status) || addr != address)
+                       continue;
+
+               if (!ret) {
+                       /* This is the first matching object.  Save it. */
+                       ret = adev;
+                       continue;
+               }
+               /*
+                * There is more than one matching device object with the same
+                * _ADR value.  That really is unexpected, so we are kind of
+                * beyond the scope of the spec here.  We have to choose which
+                * one to return, though.
+                *
+                * First, check if the previously found object is good enough
+                * and return it if so.  Second, do the same for the object that
+                * we've just found.
+                */
+               if (!ret_score) {
+                       ret_score = find_child_checks(ret, check_children);
+                       if (ret_score == FIND_CHILD_MAX_SCORE)
+                               return ret;
+               }
+               score = find_child_checks(adev, check_children);
+               if (score == FIND_CHILD_MAX_SCORE) {
+                       return adev;
+               } else if (score > ret_score) {
+                       ret = adev;
+                       ret_score = score;
+               }
        }
-       return NULL;
+       return ret;
 }
-EXPORT_SYMBOL_GPL(acpi_find_child);
+EXPORT_SYMBOL_GPL(acpi_find_child_device);
 
 static void acpi_physnode_link_name(char *buf, unsigned int node_id)
 {
@@ -195,9 +160,8 @@ static void acpi_physnode_link_name(char *buf, unsigned int node_id)
                strcpy(buf, PHYSICAL_NODE_STRING);
 }
 
-int acpi_bind_one(struct device *dev, acpi_handle handle)
+int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 {
-       struct acpi_device *acpi_dev = NULL;
        struct acpi_device_physical_node *physical_node, *pn;
        char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
        struct list_head *physnode_list;
@@ -205,14 +169,12 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
        int retval = -EINVAL;
 
        if (ACPI_COMPANION(dev)) {
-               if (handle) {
+               if (acpi_dev) {
                        dev_warn(dev, "ACPI companion already set\n");
                        return -EINVAL;
                } else {
                        acpi_dev = ACPI_COMPANION(dev);
                }
-       } else {
-               acpi_bus_get_device(handle, &acpi_dev);
        }
        if (!acpi_dev)
                return -EINVAL;
@@ -322,29 +284,22 @@ int acpi_unbind_one(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(acpi_unbind_one);
 
-void acpi_preset_companion(struct device *dev, acpi_handle parent, u64 addr)
-{
-       struct acpi_device *adev;
-
-       if (!acpi_bus_get_device(acpi_get_child(parent, addr), &adev))
-               ACPI_COMPANION_SET(dev, adev);
-}
-EXPORT_SYMBOL_GPL(acpi_preset_companion);
-
 static int acpi_platform_notify(struct device *dev)
 {
        struct acpi_bus_type *type = acpi_get_bus_type(dev);
-       acpi_handle handle;
        int ret;
 
        ret = acpi_bind_one(dev, NULL);
        if (ret && type) {
-               ret = type->find_device(dev, &handle);
-               if (ret) {
+               struct acpi_device *adev;
+
+               adev = type->find_companion(dev);
+               if (!adev) {
                        DBG("Unable to get handle for %s\n", dev_name(dev));
+                       ret = -ENODEV;
                        goto out;
                }
-               ret = acpi_bind_one(dev, handle);
+               ret = acpi_bind_one(dev, adev);
                if (ret)
                        goto out;
        }
index 13b1d39d7cdf57c463534c3a29cfd797e22abfe0..aafe3ca829c28b4a22a8f2a708df6d69093349e9 100644 (file)
@@ -25,8 +25,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 #include <acpi/hed.h>
 
 static struct acpi_device_id acpi_hed_ids[] = {
index a29739c0ba790af9c967efc29ef6907bf06b63d6..b125fdb0b30cc4affcdf50c9c131a9ad7a9e842e 100644 (file)
@@ -28,7 +28,6 @@ int init_acpi_device_notify(void);
 int acpi_scan_init(void);
 void acpi_pci_root_init(void);
 void acpi_pci_link_init(void);
-void acpi_pci_root_hp_init(void);
 void acpi_processor_init(void);
 void acpi_platform_init(void);
 int acpi_sysfs_init(void);
@@ -73,6 +72,8 @@ void acpi_lpss_init(void);
 static inline void acpi_lpss_init(void) {}
 #endif
 
+bool acpi_queue_hotplug_work(struct work_struct *work);
+
 /* --------------------------------------------------------------------------
                      Device Node Initialization / Removal
    -------------------------------------------------------------------------- */
@@ -85,9 +86,9 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
                             int type, unsigned long long sta);
 void acpi_device_add_finalize(struct acpi_device *device);
 void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
-int acpi_bind_one(struct device *dev, acpi_handle handle);
+int acpi_bind_one(struct device *dev, struct acpi_device *adev);
 int acpi_unbind_one(struct device *dev);
-void acpi_bus_device_eject(void *data, u32 ost_src);
+bool acpi_device_is_present(struct acpi_device *adev);
 
 /* --------------------------------------------------------------------------
                                   Power Resource
@@ -105,6 +106,8 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
 int acpi_power_on_resources(struct acpi_device *device, int state);
 int acpi_power_transition(struct acpi_device *device, int state);
 
+int acpi_device_update_power(struct acpi_device *device, int *state_p);
+
 int acpi_wakeup_device_init(void);
 void acpi_early_processor_set_pdc(void);
 
index a2343a1d9e0b1a0e77f3b7a7caf6676499c5f989..9e6816ef280ab7a5def6586cfabd3f60b7cd0ccb 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/errno.h>
 #include <linux/acpi.h>
 #include <linux/numa.h>
-#include <acpi/acpi_bus.h>
 
 #define PREFIX "ACPI: "
 
index 266bc58ce0ce165eb4c1a6bf707c7af5d5080c36..386a9fe497b451d0da6ebed2bc4b6f1a2dacda71 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/acpi_io.h>
-#include <acpi/acpiosxf.h>
 
 /* ACPI NVS regions, APEI may use it */
 
index 54a20ff4b864d90881cf41be6fbebd33de1c32a9..7e2d8140c33464336cd1eff96bb4a132fceeef5a 100644 (file)
@@ -49,9 +49,6 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/processor.h>
 #include "internal.h"
 
 #define _COMPONENT             ACPI_OS_SERVICES
@@ -1215,6 +1212,10 @@ acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src)
        return AE_OK;
 }
 
+bool acpi_queue_hotplug_work(struct work_struct *work)
+{
+       return queue_work(kacpi_hotplug_wq, work);
+}
 
 acpi_status
 acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
@@ -1794,7 +1795,7 @@ acpi_status __init acpi_os_initialize1(void)
 {
        kacpid_wq = alloc_workqueue("kacpid", 0, 1);
        kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
-       kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1);
+       kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
        BUG_ON(!kacpid_wq);
        BUG_ON(!kacpi_notify_wq);
        BUG_ON(!kacpi_hotplug_wq);
index 41c5e1b799ef938ff1eed92e4cf48a7c7677f8bd..52d45ea2bc4f63efcfb7e8912b087b1a568d49cc 100644 (file)
@@ -37,8 +37,6 @@
 #include <linux/pci.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 
 #define PREFIX "ACPI: "
 
index 2652a614deebe8062c71bb4e3c7f26fe8d315a45..ea6b8d16dcc82efb90a8f61f8181d90608461774 100644 (file)
@@ -39,9 +39,7 @@
 #include <linux/pci.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
-
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 #define PREFIX "ACPI: "
 
index 0703bff5e60ecaf2f9d207f9ffc1691d50380384..afafee56cf8be2b7d1dfe5d2de91180ba30a370c 100644 (file)
@@ -35,9 +35,7 @@
 #include <linux/pci-aspm.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/apei.h>
+#include <acpi/apei.h> /* for acpi_hest_init() */
 
 #include "internal.h"
 
@@ -51,6 +49,12 @@ static int acpi_pci_root_add(struct acpi_device *device,
                             const struct acpi_device_id *not_used);
 static void acpi_pci_root_remove(struct acpi_device *device);
 
+static int acpi_pci_root_scan_dependent(struct acpi_device *adev)
+{
+       acpiphp_check_host_bridge(adev->handle);
+       return 0;
+}
+
 #define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \
                                | OSC_PCI_ASPM_SUPPORT \
                                | OSC_PCI_CLOCK_PM_SUPPORT \
@@ -65,6 +69,10 @@ static struct acpi_scan_handler pci_root_handler = {
        .ids = root_device_ids,
        .attach = acpi_pci_root_add,
        .detach = acpi_pci_root_remove,
+       .hotplug = {
+               .enabled = true,
+               .scan_dependent = acpi_pci_root_scan_dependent,
+       },
 };
 
 static DEFINE_MUTEX(osc_lock);
@@ -621,116 +629,9 @@ static void acpi_pci_root_remove(struct acpi_device *device)
 void __init acpi_pci_root_init(void)
 {
        acpi_hest_init();
-
-       if (!acpi_pci_disabled) {
-               pci_acpi_crs_quirks();
-               acpi_scan_add_handler(&pci_root_handler);
-       }
-}
-/* Support root bridge hotplug */
-
-static void handle_root_bridge_insertion(acpi_handle handle)
-{
-       struct acpi_device *device;
-
-       if (!acpi_bus_get_device(handle, &device)) {
-               dev_printk(KERN_DEBUG, &device->dev,
-                          "acpi device already exists; ignoring notify\n");
+       if (acpi_pci_disabled)
                return;
-       }
-
-       if (acpi_bus_scan(handle))
-               acpi_handle_err(handle, "cannot add bridge to acpi list\n");
-}
-
-static void hotplug_event_root(void *data, u32 type)
-{
-       acpi_handle handle = data;
-       struct acpi_pci_root *root;
-
-       acpi_scan_lock_acquire();
-
-       root = acpi_pci_find_root(handle);
-
-       switch (type) {
-       case ACPI_NOTIFY_BUS_CHECK:
-               /* bus enumerate */
-               acpi_handle_printk(KERN_DEBUG, handle,
-                                  "Bus check notify on %s\n", __func__);
-               if (root)
-                       acpiphp_check_host_bridge(handle);
-               else
-                       handle_root_bridge_insertion(handle);
-
-               break;
-
-       case ACPI_NOTIFY_DEVICE_CHECK:
-               /* device check */
-               acpi_handle_printk(KERN_DEBUG, handle,
-                                  "Device check notify on %s\n", __func__);
-               if (!root)
-                       handle_root_bridge_insertion(handle);
-               break;
-
-       case ACPI_NOTIFY_EJECT_REQUEST:
-               /* request device eject */
-               acpi_handle_printk(KERN_DEBUG, handle,
-                                  "Device eject notify on %s\n", __func__);
-               if (!root)
-                       break;
-
-               get_device(&root->device->dev);
-
-               acpi_scan_lock_release();
-
-               acpi_bus_device_eject(root->device, ACPI_NOTIFY_EJECT_REQUEST);
-               return;
-       default:
-               acpi_handle_warn(handle,
-                                "notify_handler: unknown event type 0x%x\n",
-                                type);
-               break;
-       }
-
-       acpi_scan_lock_release();
-}
-
-static void handle_hotplug_event_root(acpi_handle handle, u32 type,
-                                       void *context)
-{
-       acpi_hotplug_execute(hotplug_event_root, handle, type);
-}
-
-static acpi_status __init
-find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-       acpi_status status;
-       int *count = (int *)context;
-
-       if (!acpi_is_root_bridge(handle))
-               return AE_OK;
-
-       (*count)++;
-
-       status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-                                       handle_hotplug_event_root, NULL);
-       if (ACPI_FAILURE(status))
-               acpi_handle_printk(KERN_DEBUG, handle,
-                       "notify handler is not installed, exit status: %u\n",
-                        (unsigned int)status);
-       else
-               acpi_handle_printk(KERN_DEBUG, handle,
-                                  "notify handler is installed\n");
-
-       return AE_OK;
-}
-
-void __init acpi_pci_root_hp_init(void)
-{
-       int num = 0;
-
-       acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-               ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
 
-       printk(KERN_DEBUG "Found %d acpi root devices\n", num);
+       pci_acpi_crs_quirks();
+       acpi_scan_add_handler_with_hotplug(&pci_root_handler, "pci_root");
 }
index c2ad391d8041ecb6a354e2df07b9d813d817a744..ad7da686e6e6f8d9745a4edf866e174b99b08538 100644 (file)
@@ -42,8 +42,7 @@
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
 #include <linux/sysfs.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include "sleep.h"
 #include "internal.h"
 
index 6a5b152ad4d070511d08d74439155fa17a83ed8a..db061bfd95a8de20aea42e95ae0bda75c6b68a9f 100644 (file)
@@ -3,11 +3,9 @@
 #include <linux/export.h>
 #include <linux/suspend.h>
 #include <linux/bcd.h>
+#include <linux/acpi.h>
 #include <asm/uaccess.h>
 
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-
 #include "sleep.h"
 
 #define _COMPONENT             ACPI_SYSTEM_COMPONENT
index b3171f30b319c1244007e686a0b516833443191d..34e7b3c6a08de157c6c962bd0643ddb67176bd5e 100644 (file)
@@ -10,8 +10,7 @@
 #include <linux/export.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
-
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <acpi/processor.h>
 
 #include "internal.h"
index 644516d9bde6cf18a824d29c3ae1730de30fd1a6..d2d44e0190a31ba64970d3281698179767d08541 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/clockchips.h>
 #include <linux/cpuidle.h>
 #include <linux/syscore_ops.h>
+#include <acpi/processor.h>
 
 /*
  * Include the apic definitions for x86 to have the APIC timer related defines
@@ -46,9 +47,6 @@
 #include <asm/apic.h>
 #endif
 
-#include <acpi/acpi_bus.h>
-#include <acpi/processor.h>
-
 #define PREFIX "ACPI: "
 
 #define ACPI_PROCESSOR_CLASS            "processor"
index 60a7c28fc1674cc21bc38802fed869dc7daf0608..ff90054f04fdb88e15e1279b23b43d78884596f9 100644 (file)
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
-
+#include <linux/acpi.h>
+#include <acpi/processor.h>
 #ifdef CONFIG_X86
 #include <asm/cpufeature.h>
 #endif
 
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/processor.h>
-
 #define PREFIX "ACPI: "
 
 #define ACPI_PROCESSOR_CLASS           "processor"
index d1d2e7fb5b30778f26d46ce6e72eecb03350ddfc..f95e7584d6e680bfe2b8cc49bc16f7c3a492a517 100644 (file)
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
-
-#include <asm/uaccess.h>
-
-#include <acpi/acpi_bus.h>
+#include <linux/acpi.h>
 #include <acpi/processor.h>
-#include <acpi/acpi_drivers.h>
+#include <asm/uaccess.h>
 
 #define PREFIX "ACPI: "
 
index e7dd2c1fee79b4a097f9b3249a9b0bdaeaa2592a..28baa05b8018dd6c6e6e1db93c1a5ceed74d4d74 100644 (file)
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/cpufreq.h>
-
+#include <linux/acpi.h>
+#include <acpi/processor.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/processor.h>
-
 #define PREFIX "ACPI: "
 
 #define ACPI_PROCESSOR_CLASS            "processor"
index b78bc605837e19a8f7461f48a59cdc90d64f5128..26e5b50605230e2e34a46d8118486fb1ba2eb939 100644 (file)
@@ -8,8 +8,7 @@
  * the Free Software Foundation version 2.
  */
 
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <linux/wait.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
index 15daa21fcd056cf75b50eccf34a08482e0e24e8a..5383c81a8a1bdb4b2fe6b6d7d6547efa3b328cc5 100644 (file)
 #include <linux/dmi.h>
 #include <linux/nls.h>
 
-#include <acpi/acpi_drivers.h>
+#include <asm/pgtable.h>
 
 #include "internal.h"
 
 #define _COMPONENT             ACPI_BUS_COMPONENT
 ACPI_MODULE_NAME("scan");
-#define STRUCT_TO_INT(s)       (*((int*)&s))
 extern struct acpi_device *acpi_root;
 
 #define ACPI_BUS_CLASS                 "system_bus"
@@ -27,6 +26,8 @@ extern struct acpi_device *acpi_root;
 
 #define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
 
+#define INVALID_ACPI_HANDLE    ((acpi_handle)empty_zero_page)
+
 /*
  * If set, devices will be hot-removed even if they cannot be put offline
  * gracefully (from the kernel's standpoint).
@@ -202,13 +203,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
        acpi_status status;
        unsigned long long sta;
 
-       /* If there is no handle, the device node has been unregistered. */
-       if (!handle) {
-               dev_dbg(&device->dev, "ACPI handle missing\n");
-               put_device(&device->dev);
-               return -EINVAL;
-       }
-
        /*
         * Carry out two passes here and ignore errors in the first pass,
         * because if the devices in question are memory blocks and
@@ -226,7 +220,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
                dev_warn(errdev, "Offline disabled.\n");
                acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
                                    acpi_bus_online, NULL, NULL, NULL);
-               put_device(&device->dev);
                return -EPERM;
        }
        acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev);
@@ -245,7 +238,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
                        acpi_walk_namespace(ACPI_TYPE_ANY, handle,
                                            ACPI_UINT32_MAX, acpi_bus_online,
                                            NULL, NULL, NULL);
-                       put_device(&device->dev);
                        return -EBUSY;
                }
        }
@@ -255,10 +247,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
 
        acpi_bus_trim(device);
 
-       /* Device node has been unregistered. */
-       put_device(&device->dev);
-       device = NULL;
-
        acpi_evaluate_lck(handle, 0);
        /*
         * TBD: _EJD support.
@@ -285,115 +273,127 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
        return 0;
 }
 
-void acpi_bus_device_eject(void *data, u32 ost_src)
+static int acpi_scan_device_not_present(struct acpi_device *adev)
 {
-       struct acpi_device *device = data;
-       acpi_handle handle = device->handle;
-       u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
-       int error;
+       if (!acpi_device_enumerated(adev)) {
+               dev_warn(&adev->dev, "Still not present\n");
+               return -EALREADY;
+       }
+       acpi_bus_trim(adev);
+       return 0;
+}
 
-       lock_device_hotplug();
-       mutex_lock(&acpi_scan_lock);
+static int acpi_scan_device_check(struct acpi_device *adev)
+{
+       int error;
 
-       if (ost_src == ACPI_NOTIFY_EJECT_REQUEST)
-               acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
-                                         ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
+       acpi_bus_get_status(adev);
+       if (adev->status.present || adev->status.functional) {
+               /*
+                * This function is only called for device objects for which
+                * matching scan handlers exist.  The only situation in which
+                * the scan handler is not attached to this device object yet
+                * is when the device has just appeared (either it wasn't
+                * present at all before or it was removed and then added
+                * again).
+                */
+               if (adev->handler) {
+                       dev_warn(&adev->dev, "Already enumerated\n");
+                       return -EALREADY;
+               }
+               error = acpi_bus_scan(adev->handle);
+               if (error) {
+                       dev_warn(&adev->dev, "Namespace scan failure\n");
+                       return error;
+               }
+               if (!adev->handler) {
+                       dev_warn(&adev->dev, "Enumeration failure\n");
+                       error = -ENODEV;
+               }
+       } else {
+               error = acpi_scan_device_not_present(adev);
+       }
+       return error;
+}
 
-       if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER)
-               kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
+static int acpi_scan_bus_check(struct acpi_device *adev)
+{
+       struct acpi_scan_handler *handler = adev->handler;
+       struct acpi_device *child;
+       int error;
 
-       error = acpi_scan_hot_remove(device);
-       if (error == -EPERM) {
-               goto err_support;
-       } else if (error) {
-               goto err_out;
+       acpi_bus_get_status(adev);
+       if (!(adev->status.present || adev->status.functional)) {
+               acpi_scan_device_not_present(adev);
+               return 0;
        }
+       if (handler && handler->hotplug.scan_dependent)
+               return handler->hotplug.scan_dependent(adev);
 
- out:
-       mutex_unlock(&acpi_scan_lock);
-       unlock_device_hotplug();
-       return;
-
- err_support:
-       ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
- err_out:
-       acpi_evaluate_hotplug_ost(handle, ost_src, ost_code, NULL);
-       goto out;
+       error = acpi_bus_scan(adev->handle);
+       if (error) {
+               dev_warn(&adev->dev, "Namespace scan failure\n");
+               return error;
+       }
+       list_for_each_entry(child, &adev->children, node) {
+               error = acpi_scan_bus_check(child);
+               if (error)
+                       return error;
+       }
+       return 0;
 }
 
-static void acpi_scan_bus_device_check(void *data, u32 ost_source)
+static void acpi_device_hotplug(void *data, u32 src)
 {
-       acpi_handle handle = data;
-       struct acpi_device *device = NULL;
        u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
+       struct acpi_device *adev = data;
        int error;
 
        lock_device_hotplug();
        mutex_lock(&acpi_scan_lock);
 
-       if (ost_source != ACPI_NOTIFY_BUS_CHECK) {
-               acpi_bus_get_device(handle, &device);
-               if (device) {
-                       dev_warn(&device->dev, "Attempt to re-insert\n");
-                       goto out;
-               }
-       }
-       error = acpi_bus_scan(handle);
-       if (error) {
-               acpi_handle_warn(handle, "Namespace scan failure\n");
-               goto out;
-       }
-       error = acpi_bus_get_device(handle, &device);
-       if (error) {
-               acpi_handle_warn(handle, "Missing device node object\n");
+       /*
+        * The device object's ACPI handle cannot become invalid as long as we
+        * are holding acpi_scan_lock, but it may have become invalid before
+        * that lock was acquired.
+        */
+       if (adev->handle == INVALID_ACPI_HANDLE)
                goto out;
-       }
-       ost_code = ACPI_OST_SC_SUCCESS;
-       if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER)
-               kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
-
- out:
-       acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL);
-       mutex_unlock(&acpi_scan_lock);
-       unlock_device_hotplug();
-}
 
-static void acpi_hotplug_unsupported(acpi_handle handle, u32 type)
-{
-       u32 ost_status;
-
-       switch (type) {
+       switch (src) {
        case ACPI_NOTIFY_BUS_CHECK:
-               acpi_handle_debug(handle,
-                       "ACPI_NOTIFY_BUS_CHECK event: unsupported\n");
-               ost_status = ACPI_OST_SC_INSERT_NOT_SUPPORTED;
+               error = acpi_scan_bus_check(adev);
                break;
        case ACPI_NOTIFY_DEVICE_CHECK:
-               acpi_handle_debug(handle,
-                       "ACPI_NOTIFY_DEVICE_CHECK event: unsupported\n");
-               ost_status = ACPI_OST_SC_INSERT_NOT_SUPPORTED;
+               error = acpi_scan_device_check(adev);
                break;
        case ACPI_NOTIFY_EJECT_REQUEST:
-               acpi_handle_debug(handle,
-                       "ACPI_NOTIFY_EJECT_REQUEST event: unsupported\n");
-               ost_status = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
+       case ACPI_OST_EC_OSPM_EJECT:
+               error = acpi_scan_hot_remove(adev);
                break;
        default:
-               /* non-hotplug event; possibly handled by other handler */
-               return;
+               error = -EINVAL;
+               break;
        }
+       if (!error)
+               ost_code = ACPI_OST_SC_SUCCESS;
 
-       acpi_evaluate_hotplug_ost(handle, type, ost_status, NULL);
+ out:
+       acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL);
+       put_device(&adev->dev);
+       mutex_unlock(&acpi_scan_lock);
+       unlock_device_hotplug();
 }
 
 static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
 {
+       u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
        struct acpi_scan_handler *handler = data;
        struct acpi_device *adev;
        acpi_status status;
 
-       if (!handler->hotplug.enabled)
-               return acpi_hotplug_unsupported(handle, type);
+       if (acpi_bus_get_device(handle, &adev))
+               goto err_out;
 
        switch (type) {
        case ACPI_NOTIFY_BUS_CHECK:
@@ -404,27 +404,27 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
                break;
        case ACPI_NOTIFY_EJECT_REQUEST:
                acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n");
-               if (acpi_bus_get_device(handle, &adev))
+               if (!handler->hotplug.enabled) {
+                       acpi_handle_err(handle, "Eject disabled\n");
+                       ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
                        goto err_out;
-
-               get_device(&adev->dev);
-               status = acpi_hotplug_execute(acpi_bus_device_eject, adev, type);
-               if (ACPI_SUCCESS(status))
-                       return;
-
-               put_device(&adev->dev);
-               goto err_out;
+               }
+               acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
+                                         ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
+               break;
        default:
                /* non-hotplug event; possibly handled by other handler */
                return;
        }
-       status = acpi_hotplug_execute(acpi_scan_bus_device_check, handle, type);
+       get_device(&adev->dev);
+       status = acpi_hotplug_execute(acpi_device_hotplug, adev, type);
        if (ACPI_SUCCESS(status))
                return;
 
+       put_device(&adev->dev);
+
  err_out:
-       acpi_evaluate_hotplug_ost(handle, type,
-                                 ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
+       acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
 }
 
 static ssize_t real_power_state_show(struct device *dev,
@@ -475,7 +475,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
        acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
                                  ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
        get_device(&acpi_device->dev);
-       status = acpi_hotplug_execute(acpi_bus_device_eject, acpi_device,
+       status = acpi_hotplug_execute(acpi_device_hotplug, acpi_device,
                                      ACPI_OST_EC_OSPM_EJECT);
        if (ACPI_SUCCESS(status))
                return count;
@@ -907,9 +907,91 @@ struct bus_type acpi_bus_type = {
        .uevent         = acpi_device_uevent,
 };
 
-static void acpi_bus_data_handler(acpi_handle handle, void *context)
+static void acpi_device_del(struct acpi_device *device)
+{
+       mutex_lock(&acpi_device_lock);
+       if (device->parent)
+               list_del(&device->node);
+
+       list_del(&device->wakeup_list);
+       mutex_unlock(&acpi_device_lock);
+
+       acpi_power_add_remove_device(device, false);
+       acpi_device_remove_files(device);
+       if (device->remove)
+               device->remove(device);
+
+       device_del(&device->dev);
+}
+
+static LIST_HEAD(acpi_device_del_list);
+static DEFINE_MUTEX(acpi_device_del_lock);
+
+static void acpi_device_del_work_fn(struct work_struct *work_not_used)
+{
+       for (;;) {
+               struct acpi_device *adev;
+
+               mutex_lock(&acpi_device_del_lock);
+
+               if (list_empty(&acpi_device_del_list)) {
+                       mutex_unlock(&acpi_device_del_lock);
+                       break;
+               }
+               adev = list_first_entry(&acpi_device_del_list,
+                                       struct acpi_device, del_list);
+               list_del(&adev->del_list);
+
+               mutex_unlock(&acpi_device_del_lock);
+
+               acpi_device_del(adev);
+               /*
+                * Drop references to all power resources that might have been
+                * used by the device.
+                */
+               acpi_power_transition(adev, ACPI_STATE_D3_COLD);
+               put_device(&adev->dev);
+       }
+}
+
+/**
+ * acpi_scan_drop_device - Drop an ACPI device object.
+ * @handle: Handle of an ACPI namespace node, not used.
+ * @context: Address of the ACPI device object to drop.
+ *
+ * This is invoked by acpi_ns_delete_node() during the removal of the ACPI
+ * namespace node the device object pointed to by @context is attached to.
+ *
+ * The unregistration is carried out asynchronously to avoid running
+ * acpi_device_del() under the ACPICA's namespace mutex and the list is used to
+ * ensure the correct ordering (the device objects must be unregistered in the
+ * same order in which the corresponding namespace nodes are deleted).
+ */
+static void acpi_scan_drop_device(acpi_handle handle, void *context)
 {
-       /* Intentionally empty. */
+       static DECLARE_WORK(work, acpi_device_del_work_fn);
+       struct acpi_device *adev = context;
+
+       mutex_lock(&acpi_device_del_lock);
+
+       /*
+        * Use the ACPI hotplug workqueue which is ordered, so this work item
+        * won't run after any hotplug work items submitted subsequently.  That
+        * prevents attempts to register device objects identical to those being
+        * deleted from happening concurrently (such attempts result from
+        * hotplug events handled via the ACPI hotplug workqueue).  It also will
+        * run after all of the work items submitted previosuly, which helps
+        * those work items to ensure that they are not accessing stale device
+        * objects.
+        */
+       if (list_empty(&acpi_device_del_list))
+               acpi_queue_hotplug_work(&work);
+
+       list_add_tail(&adev->del_list, &acpi_device_del_list);
+       /* Make acpi_ns_validate_handle() return NULL for this handle. */
+       adev->handle = INVALID_ACPI_HANDLE;
+
+       mutex_unlock(&acpi_device_del_lock);
 }
 
 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
@@ -919,7 +1001,7 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
        if (!device)
                return -EINVAL;
 
-       status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
+       status = acpi_get_data(handle, acpi_scan_drop_device, (void **)device);
        if (ACPI_FAILURE(status) || !*device) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
                                  handle));
@@ -939,7 +1021,7 @@ int acpi_device_add(struct acpi_device *device,
        if (device->handle) {
                acpi_status status;
 
-               status = acpi_attach_data(device->handle, acpi_bus_data_handler,
+               status = acpi_attach_data(device->handle, acpi_scan_drop_device,
                                          device);
                if (ACPI_FAILURE(status)) {
                        acpi_handle_err(device->handle,
@@ -957,6 +1039,7 @@ int acpi_device_add(struct acpi_device *device,
        INIT_LIST_HEAD(&device->node);
        INIT_LIST_HEAD(&device->wakeup_list);
        INIT_LIST_HEAD(&device->physical_node_list);
+       INIT_LIST_HEAD(&device->del_list);
        mutex_init(&device->physical_node_lock);
 
        new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
@@ -1020,37 +1103,10 @@ int acpi_device_add(struct acpi_device *device,
        mutex_unlock(&acpi_device_lock);
 
  err_detach:
-       acpi_detach_data(device->handle, acpi_bus_data_handler);
+       acpi_detach_data(device->handle, acpi_scan_drop_device);
        return result;
 }
 
-static void acpi_device_unregister(struct acpi_device *device)
-{
-       mutex_lock(&acpi_device_lock);
-       if (device->parent)
-               list_del(&device->node);
-
-       list_del(&device->wakeup_list);
-       mutex_unlock(&acpi_device_lock);
-
-       acpi_detach_data(device->handle, acpi_bus_data_handler);
-
-       acpi_power_add_remove_device(device, false);
-       acpi_device_remove_files(device);
-       if (device->remove)
-               device->remove(device);
-
-       device_del(&device->dev);
-       /*
-        * Transition the device to D3cold to drop the reference counts of all
-        * power resources the device depends on and turn off the ones that have
-        * no more references.
-        */
-       acpi_device_set_power(device, ACPI_STATE_D3_COLD);
-       device->handle = NULL;
-       put_device(&device->dev);
-}
-
 /* --------------------------------------------------------------------------
                                  Driver Management
    -------------------------------------------------------------------------- */
@@ -1624,11 +1680,13 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
        device->device_type = type;
        device->handle = handle;
        device->parent = acpi_bus_get_parent(handle);
-       STRUCT_TO_INT(device->status) = sta;
+       acpi_set_device_status(device, sta);
        acpi_device_get_busid(device);
        acpi_set_pnp_ids(handle, &device->pnp, type);
        acpi_bus_get_flags(device);
        device->flags.match_driver = false;
+       device->flags.initialized = true;
+       device->flags.visited = false;
        device_initialize(&device->dev);
        dev_set_uevent_suppress(&device->dev, true);
 }
@@ -1713,6 +1771,15 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type,
        return 0;
 }
 
+bool acpi_device_is_present(struct acpi_device *adev)
+{
+       if (adev->status.present || adev->status.functional)
+               return true;
+
+       adev->flags.initialized = false;
+       return false;
+}
+
 static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
                                       char *idstr,
                                       const struct acpi_device_id **matchid)
@@ -1806,18 +1873,6 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
 
        acpi_scan_init_hotplug(handle, type);
 
-       if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
-           !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
-               struct acpi_device_wakeup wakeup;
-
-               if (acpi_has_method(handle, "_PRW")) {
-                       acpi_bus_extract_wakeup_device_power_package(handle,
-                                                                    &wakeup);
-                       acpi_power_resources_list_free(&wakeup.resources);
-               }
-               return AE_CTRL_DEPTH;
-       }
-
        acpi_add_single_object(&device, handle, type, sta);
        if (!device)
                return AE_CTRL_DEPTH;
@@ -1852,36 +1907,40 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
        return ret;
 }
 
-static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
-                                         void *not_used, void **ret_not_used)
+static void acpi_bus_attach(struct acpi_device *device)
 {
-       struct acpi_device *device;
-       unsigned long long sta_not_used;
+       struct acpi_device *child;
        int ret;
 
-       /*
-        * Ignore errors ignored by acpi_bus_check_add() to avoid terminating
-        * namespace walks prematurely.
-        */
-       if (acpi_bus_type_and_status(handle, &ret, &sta_not_used))
-               return AE_OK;
-
-       if (acpi_bus_get_device(handle, &device))
-               return AE_CTRL_DEPTH;
-
+       acpi_bus_get_status(device);
+       /* Skip devices that are not present. */
+       if (!acpi_device_is_present(device)) {
+               device->flags.visited = false;
+               return;
+       }
        if (device->handler)
-               return AE_OK;
+               goto ok;
 
+       if (!device->flags.initialized) {
+               acpi_bus_update_power(device, NULL);
+               device->flags.initialized = true;
+       }
+       device->flags.visited = false;
        ret = acpi_scan_attach_handler(device);
        if (ret < 0)
-               return AE_CTRL_DEPTH;
+               return;
 
        device->flags.match_driver = true;
-       if (ret > 0)
-               return AE_OK;
+       if (!ret) {
+               ret = device_attach(&device->dev);
+               if (ret < 0)
+                       return;
+       }
+       device->flags.visited = true;
 
-       ret = device_attach(&device->dev);
-       return ret >= 0 ? AE_OK : AE_CTRL_DEPTH;
+ ok:
+       list_for_each_entry(child, &device->children, node)
+               acpi_bus_attach(child);
 }
 
 /**
@@ -1901,75 +1960,48 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
 int acpi_bus_scan(acpi_handle handle)
 {
        void *device = NULL;
-       int error = 0;
 
        if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device)))
                acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
                                    acpi_bus_check_add, NULL, NULL, &device);
 
-       if (!device)
-               error = -ENODEV;
-       else if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL)))
-               acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
-                                   acpi_bus_device_attach, NULL, NULL, NULL);
-
-       return error;
-}
-EXPORT_SYMBOL(acpi_bus_scan);
-
-static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used,
-                                         void *not_used, void **ret_not_used)
-{
-       struct acpi_device *device = NULL;
-
-       if (!acpi_bus_get_device(handle, &device)) {
-               struct acpi_scan_handler *dev_handler = device->handler;
-
-               if (dev_handler) {
-                       if (dev_handler->detach)
-                               dev_handler->detach(device);
-
-                       device->handler = NULL;
-               } else {
-                       device_release_driver(&device->dev);
-               }
+       if (device) {
+               acpi_bus_attach(device);
+               return 0;
        }
-       return AE_OK;
-}
-
-static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used,
-                                  void *not_used, void **ret_not_used)
-{
-       struct acpi_device *device = NULL;
-
-       if (!acpi_bus_get_device(handle, &device))
-               acpi_device_unregister(device);
-
-       return AE_OK;
+       return -ENODEV;
 }
+EXPORT_SYMBOL(acpi_bus_scan);
 
 /**
- * acpi_bus_trim - Remove ACPI device node and all of its descendants
- * @start: Root of the ACPI device nodes subtree to remove.
+ * acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects.
+ * @adev: Root of the ACPI namespace scope to walk.
  *
  * Must be called under acpi_scan_lock.
  */
-void acpi_bus_trim(struct acpi_device *start)
+void acpi_bus_trim(struct acpi_device *adev)
 {
+       struct acpi_scan_handler *handler = adev->handler;
+       struct acpi_device *child;
+
+       list_for_each_entry_reverse(child, &adev->children, node)
+               acpi_bus_trim(child);
+
+       if (handler) {
+               if (handler->detach)
+                       handler->detach(adev);
+
+               adev->handler = NULL;
+       } else {
+               device_release_driver(&adev->dev);
+       }
        /*
-        * Execute acpi_bus_device_detach() as a post-order callback to detach
-        * all ACPI drivers from the device nodes being removed.
-        */
-       acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
-                           acpi_bus_device_detach, NULL, NULL);
-       acpi_bus_device_detach(start->handle, 0, NULL, NULL);
-       /*
-        * Execute acpi_bus_remove() as a post-order callback to remove device
-        * nodes in the given namespace scope.
+        * Most likely, the device is going away, so put it into D3cold before
+        * that.
         */
-       acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
-                           acpi_bus_remove, NULL, NULL);
-       acpi_bus_remove(start->handle, 0, NULL, NULL);
+       acpi_device_set_power(adev, ACPI_STATE_D3_COLD);
+       adev->flags.initialized = false;
+       adev->flags.visited = false;
 }
 EXPORT_SYMBOL_GPL(acpi_bus_trim);
 
@@ -2047,14 +2079,14 @@ int __init acpi_scan_init(void)
 
        result = acpi_bus_scan_fixed();
        if (result) {
-               acpi_device_unregister(acpi_root);
+               acpi_detach_data(acpi_root->handle, acpi_scan_drop_device);
+               acpi_device_del(acpi_root);
+               put_device(&acpi_root->dev);
                goto out;
        }
 
        acpi_update_all_gpes();
 
-       acpi_pci_root_hp_init();
-
  out:
        mutex_unlock(&acpi_scan_lock);
        return result;
index 14df30580e154802aca352176ada8214f7ea6067..208ac8c8503a7c6e702b99ca033da56b3aef935f 100644 (file)
 #include <linux/reboot.h>
 #include <linux/acpi.h>
 #include <linux/module.h>
-
 #include <asm/io.h>
 
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-
 #include "internal.h"
 #include "sleep.h"
 
@@ -525,7 +521,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
         * generate wakeup events.
         */
        if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) {
-               acpi_event_status pwr_btn_status;
+               acpi_event_status pwr_btn_status = ACPI_EVENT_FLAG_DISABLED;
 
                acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status);
 
index db5293650f622108e80a09124097f469c727547f..443dc9366052f623b14b6ce278a2bafff81e15ac 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 #include "internal.h"
 
@@ -309,7 +309,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
                sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
                        table_attr->instance);
 
-       table_attr->attr.size = 0;
+       table_attr->attr.size = table_header->length;
        table_attr->attr.read = acpi_table_show;
        table_attr->attr.attr.name = table_attr->name;
        table_attr->attr.attr.mode = 0400;
@@ -354,8 +354,9 @@ static int acpi_tables_sysfs_init(void)
 {
        struct acpi_table_attr *table_attr;
        struct acpi_table_header *table_header = NULL;
-       int table_index = 0;
-       int result;
+       int table_index;
+       acpi_status status;
+       int ret;
 
        tables_kobj = kobject_create_and_add("tables", acpi_kobj);
        if (!tables_kobj)
@@ -365,33 +366,34 @@ static int acpi_tables_sysfs_init(void)
        if (!dynamic_tables_kobj)
                goto err_dynamic_tables;
 
-       do {
-               result = acpi_get_table_by_index(table_index, &table_header);
-               if (!result) {
-                       table_index++;
-                       table_attr = NULL;
-                       table_attr =
-                           kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
-                       if (!table_attr)
-                               return -ENOMEM;
-
-                       acpi_table_attr_init(table_attr, table_header);
-                       result =
-                           sysfs_create_bin_file(tables_kobj,
-                                                 &table_attr->attr);
-                       if (result) {
-                               kfree(table_attr);
-                               return result;
-                       } else
-                               list_add_tail(&table_attr->node,
-                                             &acpi_table_attr_list);
+       for (table_index = 0;; table_index++) {
+               status = acpi_get_table_by_index(table_index, &table_header);
+
+               if (status == AE_BAD_PARAMETER)
+                       break;
+
+               if (ACPI_FAILURE(status))
+                       continue;
+
+               table_attr = NULL;
+               table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL);
+               if (!table_attr)
+                       return -ENOMEM;
+
+               acpi_table_attr_init(table_attr, table_header);
+               ret = sysfs_create_bin_file(tables_kobj, &table_attr->attr);
+               if (ret) {
+                       kfree(table_attr);
+                       return ret;
                }
-       } while (!result);
+               list_add_tail(&table_attr->node, &acpi_table_attr_list);
+       }
+
        kobject_uevent(tables_kobj, KOBJ_ADD);
        kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
-       result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
+       status = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
 
-       return result == AE_OK ? 0 : -EINVAL;
+       return ACPI_FAILURE(status) ? -EINVAL : 0;
 err_dynamic_tables:
        kobject_put(tables_kobj);
 err:
index 0d9f46b5ae6d100a64ca3c3410ab23ac2af361fe..1fd21ad69c98f5613743922d6a61224359c18e94 100644 (file)
 #include <linux/kmod.h>
 #include <linux/reboot.h>
 #include <linux/device.h>
-#include <asm/uaccess.h>
 #include <linux/thermal.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
+#include <asm/uaccess.h>
 
 #define PREFIX "ACPI: "
 
index 6d408bfbbb1d0c66dbef28d02137dbda0777d9f4..1336b9151479dd1cab2fa7972c2ba04996d7762c 100644 (file)
@@ -30,8 +30,6 @@
 #include <linux/types.h>
 #include <linux/hardirq.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 
 #include "internal.h"
 
index 995e91bcb97b7b4d5f21d585de1f5a7e46bd9ebd..b727d105046d234ae8ef2a5669e53e61b82e7123 100644 (file)
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include <linux/slab.h>
-#include <asm/uaccess.h>
 #include <linux/dmi.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 #include <linux/suspend.h>
+#include <linux/acpi.h>
 #include <acpi/video.h>
+#include <asm/uaccess.h>
 
 #include "internal.h"
 
index 7bfbe40bc43bcb5e736c4c77788d4b7d577de160..1638401ab282ef2dc554fff498ebaba8babf8daf 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <linux/init.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_drivers.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 
index e2903d03180e1190410c3054ee78990a007e93b2..ef8642e12a7627e364b92ff4002a7ed632d209db 100644 (file)
@@ -83,6 +83,8 @@ enum board_ids {
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
                                 unsigned long deadline);
+static void ahci_mcp89_apple_enable(struct pci_dev *pdev);
+static bool is_mcp89_apple(struct pci_dev *pdev);
 static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
                                unsigned long deadline);
 #ifdef CONFIG_PM
@@ -435,6 +437,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 on some Gigabyte */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
          .driver_data = board_ahci_yes_fbs },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
+         .driver_data = board_ahci_yes_fbs },
 
        /* Promise */
        { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci },   /* PDC42819 */
@@ -659,6 +663,10 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
        if (rc)
                return rc;
 
+       /* Apple BIOS helpfully mangles the registers on resume */
+       if (is_mcp89_apple(pdev))
+               ahci_mcp89_apple_enable(pdev);
+
        if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
                rc = ahci_pci_reset_controller(host);
                if (rc)
@@ -775,6 +783,48 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
        }
 }
 
+/*
+ * Macbook7,1 firmware forcibly disables MCP89 AHCI and changes PCI ID when
+ * booting in BIOS compatibility mode.  We restore the registers but not ID.
+ */
+static void ahci_mcp89_apple_enable(struct pci_dev *pdev)
+{
+       u32 val;
+
+       printk(KERN_INFO "ahci: enabling MCP89 AHCI mode\n");
+
+       pci_read_config_dword(pdev, 0xf8, &val);
+       val |= 1 << 0x1b;
+       /* the following changes the device ID, but appears not to affect function */
+       /* val = (val & ~0xf0000000) | 0x80000000; */
+       pci_write_config_dword(pdev, 0xf8, val);
+
+       pci_read_config_dword(pdev, 0x54c, &val);
+       val |= 1 << 0xc;
+       pci_write_config_dword(pdev, 0x54c, val);
+
+       pci_read_config_dword(pdev, 0x4a4, &val);
+       val &= 0xff;
+       val |= 0x01060100;
+       pci_write_config_dword(pdev, 0x4a4, val);
+
+       pci_read_config_dword(pdev, 0x54c, &val);
+       val &= ~(1 << 0xc);
+       pci_write_config_dword(pdev, 0x54c, val);
+
+       pci_read_config_dword(pdev, 0xf8, &val);
+       val &= ~(1 << 0x1b);
+       pci_write_config_dword(pdev, 0xf8, val);
+}
+
+static bool is_mcp89_apple(struct pci_dev *pdev)
+{
+       return pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
+               pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA &&
+               pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
+               pdev->subsystem_device == 0xcb89;
+}
+
 /* only some SB600 ahci controllers can do 64bit DMA */
 static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
 {
@@ -1207,15 +1257,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable)
                return -ENODEV;
 
-       /*
-        * For some reason, MCP89 on MacBook 7,1 doesn't work with
-        * ahci, use ata_generic instead.
-        */
-       if (pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
-           pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA &&
-           pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
-           pdev->subsystem_device == 0xcb89)
-               return -ENODEV;
+       /* Apple BIOS on MCP89 prevents us using AHCI */
+       if (is_mcp89_apple(pdev))
+               ahci_mcp89_apple_enable(pdev);
 
        /* Promise's PDC42819 is a SAS/SATA controller that has an AHCI mode.
         * At the moment, we can only use the AHCI mode. Let the users know
index f9554318504f8a401c97b2221831b1cdbdcdb67f..4b231baceb0995557c2cae40e501f6d3449dc365 100644 (file)
@@ -329,6 +329,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
 static const struct of_device_id ahci_of_match[] = {
        { .compatible = "snps,spear-ahci", },
        { .compatible = "snps,exynos5440-ahci", },
+       { .compatible = "ibm,476gtr-ahci", },
        {},
 };
 MODULE_DEVICE_TABLE(of, ahci_of_match);
index f8f38a08abc570e271b487f3ab761d26ceef0f27..7d196656adb5581533517a6ed0ec49d8c2966b58 100644 (file)
@@ -221,13 +221,6 @@ static struct pci_device_id ata_generic[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_OPTI,   PCI_DEVICE_ID_OPTI_82C558), },
        { PCI_DEVICE(PCI_VENDOR_ID_CENATEK,PCI_DEVICE_ID_CENATEK_IDE),
          .driver_data = ATA_GEN_FORCE_DMA },
-       /*
-        * For some reason, MCP89 on MacBook 7,1 doesn't work with
-        * ahci, use ata_generic instead.
-        */
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA,
-         PCI_VENDOR_ID_APPLE, 0xcb89,
-         .driver_data = ATA_GEN_FORCE_DMA },
 #if !defined(CONFIG_PATA_TOSHIBA) && !defined(CONFIG_PATA_TOSHIBA_MODULE)
        { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), },
        { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2),  },
index 4372cfa883c9c36cf2624f88186ef3e0e7b27d31..9e69a5308693de59abd5c596244033af43f7b3a8 100644 (file)
@@ -20,8 +20,6 @@
 #include <scsi/scsi_device.h>
 #include "libata.h"
 
-#include <acpi/acpi_bus.h>
-
 unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
 module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644);
 MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM, 0x8=FPDMA non-zero offset, 0x10=FPDMA DMA Setup FIS auto-activate)");
@@ -180,12 +178,12 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
 /* bind acpi handle to pata port */
 void ata_acpi_bind_port(struct ata_port *ap)
 {
-       acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
+       struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
 
-       if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_handle)
+       if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_companion)
                return;
 
-       acpi_preset_companion(&ap->tdev, host_handle, ap->port_no);
+       acpi_preset_companion(&ap->tdev, host_companion, ap->port_no);
 
        if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
                ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
@@ -198,17 +196,17 @@ void ata_acpi_bind_port(struct ata_port *ap)
 void ata_acpi_bind_dev(struct ata_device *dev)
 {
        struct ata_port *ap = dev->link->ap;
-       acpi_handle port_handle = ACPI_HANDLE(&ap->tdev);
-       acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
-       acpi_handle parent_handle;
+       struct acpi_device *port_companion = ACPI_COMPANION(&ap->tdev);
+       struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
+       struct acpi_device *parent;
        u64 adr;
 
        /*
-        * For both sata/pata devices, host handle is required.
-        * For pata device, port handle is also required.
+        * For both sata/pata devices, host companion device is required.
+        * For pata device, port companion device is also required.
         */
-       if (libata_noacpi || !host_handle ||
-                       (!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_handle))
+       if (libata_noacpi || !host_companion ||
+                       (!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_companion))
                return;
 
        if (ap->flags & ATA_FLAG_ACPI_SATA) {
@@ -216,13 +214,13 @@ void ata_acpi_bind_dev(struct ata_device *dev)
                        adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
                else
                        adr = SATA_ADR(ap->port_no, dev->link->pmp);
-               parent_handle = host_handle;
+               parent = host_companion;
        } else {
                adr = dev->devno;
-               parent_handle = port_handle;
+               parent = port_companion;
        }
 
-       acpi_preset_companion(&dev->tdev, parent_handle, adr);
+       acpi_preset_companion(&dev->tdev, parent, adr);
 
        register_hotplug_dock_device(ata_dev_acpi_handle(dev),
                                     &ata_acpi_dev_dock_ops, dev, NULL, NULL);
index 81a94a3919dbb0992c079e84130a1c850d81e587..dae73efe5dbf7efc4ea40cd0ee5c27958b12c5f3 100644 (file)
@@ -4156,6 +4156,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "ST3320[68]13AS",     "SD1[5-9]",     ATA_HORKAGE_NONCQ |
                                                ATA_HORKAGE_FIRMWARE_WARN },
 
+       /* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */
+       { "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA },
+
        /* Blacklist entries taken from Silicon Image 3124/3132
           Windows driver .inf file - also several Linux problem reports */
        { "HTS541060G9SA00",    "MB3OC60D",     ATA_HORKAGE_NONCQ, },
@@ -6304,10 +6307,9 @@ static void ata_port_detach(struct ata_port *ap)
                for (i = 0; i < SATA_PMP_MAX_PORTS; i++)
                        ata_tlink_delete(&ap->pmp_link[i]);
        }
-       ata_tport_delete(ap);
-
        /* remove the associated SCSI host */
        scsi_remove_host(ap->scsi_host);
+       ata_tport_delete(ap);
 }
 
 /**
index 92d7797223be12c41fb8cbcef92035781a779111..6d87570083187bbbe749fe566195f854707a641c 100644 (file)
@@ -2402,7 +2402,7 @@ static void ata_eh_link_report(struct ata_link *link)
        struct ata_port *ap = link->ap;
        struct ata_eh_context *ehc = &link->eh_context;
        const char *frozen, *desc;
-       char tries_buf[6];
+       char tries_buf[6] = "";
        int tag, nr_failed = 0;
 
        if (ehc->i.flags & ATA_EHI_QUIET)
@@ -2433,9 +2433,8 @@ static void ata_eh_link_report(struct ata_link *link)
        if (ap->pflags & ATA_PFLAG_FROZEN)
                frozen = " frozen";
 
-       memset(tries_buf, 0, sizeof(tries_buf));
        if (ap->eh_tries < ATA_EH_MAX_TRIES)
-               snprintf(tries_buf, sizeof(tries_buf) - 1, " t%d",
+               snprintf(tries_buf, sizeof(tries_buf), " t%d",
                         ap->eh_tries);
 
        if (ehc->i.dev) {
index db6dfcfa3e2ee932190069290814f2a71bc8f3f6..ab58556d347c19120c9724389583c2ae67a2d81e 100644 (file)
@@ -3625,6 +3625,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
                shost->max_lun = 1;
                shost->max_channel = 1;
                shost->max_cmd_len = 16;
+               shost->no_write_same = 1;
 
                /* Schedule policy is determined by ->qc_defer()
                 * callback and it needs to see every deferred qc.
index 68f9e3293e9c62971486937d6a5048c58b1a056c..88949c6d55ddd43b32b07accdb892256028d5e25 100644 (file)
@@ -88,15 +88,13 @@ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev)
 static bool odd_can_poweroff(struct ata_device *ata_dev)
 {
        acpi_handle handle;
-       acpi_status status;
        struct acpi_device *acpi_dev;
 
        handle = ata_dev_acpi_handle(ata_dev);
        if (!handle)
                return false;
 
-       status = acpi_bus_get_device(handle, &acpi_dev);
-       if (ACPI_FAILURE(status))
+       if (acpi_bus_get_device(handle, &acpi_dev))
                return false;
 
        return acpi_device_can_poweroff(acpi_dev);
index 73212c9c6d5bfb90b1193dddb2f30135b9edd9a9..62c9ac80c6e96ed1f0a4421fb22b7ee3629ae2e9 100644 (file)
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/gfp.h>
-#include <scsi/scsi_host.h>
-#include <acpi/acpi_bus.h>
-
+#include <linux/acpi.h>
 #include <linux/libata.h>
 #include <linux/ata.h>
+#include <scsi/scsi_host.h>
 
 #define DRV_NAME       "pata_acpi"
 #define DRV_VERSION    "0.2.3"
index e88690ebfd827b8a02558c4b611b474a4f8c4a1e..73492dd4a4bce8aade1f79a7dbdfd3926c7f6f6b 100644 (file)
@@ -319,6 +319,7 @@ static int cf_init(struct arasan_cf_dev *acdev)
        ret = clk_set_rate(acdev->clk, 166000000);
        if (ret) {
                dev_warn(acdev->host->dev, "clock set rate failed");
+               clk_disable_unprepare(acdev->clk);
                return ret;
        }
 
index 1dae9a9009f785d9e442bfac7e6552657161dd48..2b25bd83fc9d46a2682a0affb409ccf7488abe3d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/ata.h>
 #include <linux/libata.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 
 #define SATA_RCAR_DMA_BOUNDARY         0x1FFFFFFEUL
 
+/* Gen2 Physical Layer Control Registers */
+#define RCAR_GEN2_PHY_CTL1_REG         0x1704
+#define RCAR_GEN2_PHY_CTL1             0x34180002
+#define RCAR_GEN2_PHY_CTL1_SS          0xC180  /* Spread Spectrum */
+
+#define RCAR_GEN2_PHY_CTL2_REG         0x170C
+#define RCAR_GEN2_PHY_CTL2             0x00002303
+
+#define RCAR_GEN2_PHY_CTL3_REG         0x171C
+#define RCAR_GEN2_PHY_CTL3             0x000B0194
+
+#define RCAR_GEN2_PHY_CTL4_REG         0x1724
+#define RCAR_GEN2_PHY_CTL4             0x00030994
+
+#define RCAR_GEN2_PHY_CTL5_REG         0x1740
+#define RCAR_GEN2_PHY_CTL5             0x03004001
+#define RCAR_GEN2_PHY_CTL5_DC          BIT(1)  /* DC connection */
+#define RCAR_GEN2_PHY_CTL5_TR          BIT(2)  /* Termination Resistor */
+
+enum sata_rcar_type {
+       RCAR_GEN1_SATA,
+       RCAR_GEN2_SATA,
+};
+
 struct sata_rcar_priv {
        void __iomem *base;
        struct clk *clk;
+       enum sata_rcar_type type;
 };
 
-static void sata_rcar_phy_initialize(struct sata_rcar_priv *priv)
+static void sata_rcar_gen1_phy_preinit(struct sata_rcar_priv *priv)
 {
        void __iomem *base = priv->base;
 
@@ -141,8 +167,8 @@ static void sata_rcar_phy_initialize(struct sata_rcar_priv *priv)
        iowrite32(0, base + SATAPHYRESET_REG);
 }
 
-static void sata_rcar_phy_write(struct sata_rcar_priv *priv, u16 reg, u32 val,
-                               int group)
+static void sata_rcar_gen1_phy_write(struct sata_rcar_priv *priv, u16 reg,
+                                    u32 val, int group)
 {
        void __iomem *base = priv->base;
        int timeout;
@@ -170,6 +196,29 @@ static void sata_rcar_phy_write(struct sata_rcar_priv *priv, u16 reg, u32 val,
        iowrite32(0, base + SATAPHYADDR_REG);
 }
 
+static void sata_rcar_gen1_phy_init(struct sata_rcar_priv *priv)
+{
+       sata_rcar_gen1_phy_preinit(priv);
+       sata_rcar_gen1_phy_write(priv, SATAPCTLR1_REG, 0x00200188, 0);
+       sata_rcar_gen1_phy_write(priv, SATAPCTLR1_REG, 0x00200188, 1);
+       sata_rcar_gen1_phy_write(priv, SATAPCTLR3_REG, 0x0000A061, 0);
+       sata_rcar_gen1_phy_write(priv, SATAPCTLR2_REG, 0x20000000, 0);
+       sata_rcar_gen1_phy_write(priv, SATAPCTLR2_REG, 0x20000000, 1);
+       sata_rcar_gen1_phy_write(priv, SATAPCTLR4_REG, 0x28E80000, 0);
+}
+
+static void sata_rcar_gen2_phy_init(struct sata_rcar_priv *priv)
+{
+       void __iomem *base = priv->base;
+
+       iowrite32(RCAR_GEN2_PHY_CTL1, base + RCAR_GEN2_PHY_CTL1_REG);
+       iowrite32(RCAR_GEN2_PHY_CTL2, base + RCAR_GEN2_PHY_CTL2_REG);
+       iowrite32(RCAR_GEN2_PHY_CTL3, base + RCAR_GEN2_PHY_CTL3_REG);
+       iowrite32(RCAR_GEN2_PHY_CTL4, base + RCAR_GEN2_PHY_CTL4_REG);
+       iowrite32(RCAR_GEN2_PHY_CTL5 | RCAR_GEN2_PHY_CTL5_DC |
+                 RCAR_GEN2_PHY_CTL5_TR, base + RCAR_GEN2_PHY_CTL5_REG);
+}
+
 static void sata_rcar_freeze(struct ata_port *ap)
 {
        struct sata_rcar_priv *priv = ap->host->private_data;
@@ -738,13 +787,17 @@ static void sata_rcar_init_controller(struct ata_host *host)
        u32 val;
 
        /* reset and setup phy */
-       sata_rcar_phy_initialize(priv);
-       sata_rcar_phy_write(priv, SATAPCTLR1_REG, 0x00200188, 0);
-       sata_rcar_phy_write(priv, SATAPCTLR1_REG, 0x00200188, 1);
-       sata_rcar_phy_write(priv, SATAPCTLR3_REG, 0x0000A061, 0);
-       sata_rcar_phy_write(priv, SATAPCTLR2_REG, 0x20000000, 0);
-       sata_rcar_phy_write(priv, SATAPCTLR2_REG, 0x20000000, 1);
-       sata_rcar_phy_write(priv, SATAPCTLR4_REG, 0x28E80000, 0);
+       switch (priv->type) {
+       case RCAR_GEN1_SATA:
+               sata_rcar_gen1_phy_init(priv);
+               break;
+       case RCAR_GEN2_SATA:
+               sata_rcar_gen2_phy_init(priv);
+               break;
+       default:
+               dev_warn(host->dev, "SATA phy is not initialized\n");
+               break;
+       }
 
        /* SATA-IP reset state */
        val = ioread32(base + ATAPI_CONTROL1_REG);
@@ -770,8 +823,40 @@ static void sata_rcar_init_controller(struct ata_host *host)
        iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
 }
 
+static struct of_device_id sata_rcar_match[] = {
+       {
+               /* Deprecated by "renesas,sata-r8a7779" */
+               .compatible = "renesas,rcar-sata",
+               .data = (void *)RCAR_GEN1_SATA,
+       },
+       {
+               .compatible = "renesas,sata-r8a7779",
+               .data = (void *)RCAR_GEN1_SATA,
+       },
+       {
+               .compatible = "renesas,sata-r8a7790",
+               .data = (void *)RCAR_GEN2_SATA
+       },
+       {
+               .compatible = "renesas,sata-r8a7791",
+               .data = (void *)RCAR_GEN2_SATA
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, sata_rcar_match);
+
+static const struct platform_device_id sata_rcar_id_table[] = {
+       { "sata_rcar", RCAR_GEN1_SATA }, /* Deprecated by "sata-r8a7779" */
+       { "sata-r8a7779", RCAR_GEN1_SATA },
+       { "sata-r8a7790", RCAR_GEN2_SATA },
+       { "sata-r8a7791", RCAR_GEN2_SATA },
+       { },
+};
+MODULE_DEVICE_TABLE(platform, sata_rcar_id_table);
+
 static int sata_rcar_probe(struct platform_device *pdev)
 {
+       const struct of_device_id *of_id;
        struct ata_host *host;
        struct sata_rcar_priv *priv;
        struct resource *mem;
@@ -787,6 +872,12 @@ static int sata_rcar_probe(struct platform_device *pdev)
        if (!priv)
                return -ENOMEM;
 
+       of_id = of_match_device(sata_rcar_match, &pdev->dev);
+       if (of_id)
+               priv->type = (enum sata_rcar_type)of_id->data;
+       else
+               priv->type = platform_get_device_id(pdev)->driver_data;
+
        priv->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(priv->clk)) {
                dev_err(&pdev->dev, "failed to get access to sata clock\n");
@@ -892,15 +983,10 @@ static const struct dev_pm_ops sata_rcar_pm_ops = {
 };
 #endif
 
-static struct of_device_id sata_rcar_match[] = {
-       { .compatible = "renesas,rcar-sata", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, sata_rcar_match);
-
 static struct platform_driver sata_rcar_driver = {
        .probe          = sata_rcar_probe,
        .remove         = sata_rcar_remove,
+       .id_table       = sata_rcar_id_table,
        .driver = {
                .name           = DRV_NAME,
                .owner          = THIS_MODULE,
index 1b41fca3d65a54545c6c124e0df696998c29a1af..e3219dfd736c64fbf13976ce3fa7f66b89e6484e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/async.h>
 #include <linux/suspend.h>
 #include <trace/events/power.h>
+#include <linux/cpufreq.h>
 #include <linux/cpuidle.h>
 #include <linux/timer.h>
 
@@ -540,6 +541,7 @@ static void dpm_resume_noirq(pm_message_t state)
        dpm_show_time(starttime, state, "noirq");
        resume_device_irqs();
        cpuidle_resume();
+       cpufreq_resume();
 }
 
 /**
@@ -955,6 +957,7 @@ static int dpm_suspend_noirq(pm_message_t state)
        ktime_t starttime = ktime_get();
        int error = 0;
 
+       cpufreq_suspend();
        cpuidle_pause();
        suspend_device_irqs();
        mutex_lock(&dpm_list_mtx);
index 98745dd77e8ccfb75080d47fb099448d81d1eaa8..81f977510775460fa2bf8b0bd500c69027c02274 100644 (file)
@@ -40,7 +40,7 @@ static int regmap_mmio_gather_write(void *context,
 
        BUG_ON(reg_size != 4);
 
-       if (ctx->clk) {
+       if (!IS_ERR(ctx->clk)) {
                ret = clk_enable(ctx->clk);
                if (ret < 0)
                        return ret;
@@ -73,7 +73,7 @@ static int regmap_mmio_gather_write(void *context,
                offset += ctx->val_bytes;
        }
 
-       if (ctx->clk)
+       if (!IS_ERR(ctx->clk))
                clk_disable(ctx->clk);
 
        return 0;
@@ -96,7 +96,7 @@ static int regmap_mmio_read(void *context,
 
        BUG_ON(reg_size != 4);
 
-       if (ctx->clk) {
+       if (!IS_ERR(ctx->clk)) {
                ret = clk_enable(ctx->clk);
                if (ret < 0)
                        return ret;
@@ -129,7 +129,7 @@ static int regmap_mmio_read(void *context,
                offset += ctx->val_bytes;
        }
 
-       if (ctx->clk)
+       if (!IS_ERR(ctx->clk))
                clk_disable(ctx->clk);
 
        return 0;
@@ -139,7 +139,7 @@ static void regmap_mmio_free_context(void *context)
 {
        struct regmap_mmio_context *ctx = context;
 
-       if (ctx->clk) {
+       if (!IS_ERR(ctx->clk)) {
                clk_unprepare(ctx->clk);
                clk_put(ctx->clk);
        }
@@ -209,6 +209,7 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
 
        ctx->regs = regs;
        ctx->val_bytes = config->val_bits / 8;
+       ctx->clk = ERR_PTR(-ENODEV);
 
        if (clk_id == NULL)
                return ctx;
index 9c021d9cace0fcc74080ccec7b5a2b3933c65f2a..ae154d9c80e1e222d87901478330b32519d6c868 100644 (file)
@@ -1549,7 +1549,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
                                                val + (i * val_bytes),
                                                val_bytes);
                        if (ret != 0)
-                               return ret;
+                               goto out;
                }
        } else {
                ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
@@ -1743,7 +1743,7 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
 /**
  * regmap_read(): Read a value from a single register
  *
- * @map: Register map to write to
+ * @map: Register map to read from
  * @reg: Register to be read from
  * @val: Pointer to store read value
  *
@@ -1770,7 +1770,7 @@ EXPORT_SYMBOL_GPL(regmap_read);
 /**
  * regmap_raw_read(): Read raw data from the device
  *
- * @map: Register map to write to
+ * @map: Register map to read from
  * @reg: First register to be read from
  * @val: Pointer to store read value
  * @val_len: Size of data to read
@@ -1882,7 +1882,7 @@ EXPORT_SYMBOL_GPL(regmap_fields_read);
 /**
  * regmap_bulk_read(): Read multiple registers from the device
  *
- * @map: Register map to write to
+ * @map: Register map to read from
  * @reg: First register to be read from
  * @val: Pointer to store read value, in native register size for device
  * @val_count: Number of registers to read
@@ -2173,6 +2173,10 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
        int i, ret;
        bool bypass;
 
+       if (WARN_ONCE(num_regs <= 0, "invalid registers number (%d)\n",
+           num_regs))
+               return 0;
+
        map->lock(map->lock_arg);
 
        bypass = map->cache_bypass;
index 14a9d1912318b99fe764108420b143159c2bca32..9220f8e833d08228297373d116c308176c8d44a8 100644 (file)
@@ -100,11 +100,8 @@ enum {
 
 struct buf {
        ulong nframesout;
-       ulong resid;
-       ulong bv_resid;
-       sector_t sector;
        struct bio *bio;
-       struct bio_vec *bv;
+       struct bvec_iter iter;
        struct request *rq;
 };
 
@@ -120,13 +117,10 @@ struct frame {
        ulong waited;
        ulong waited_total;
        struct aoetgt *t;               /* parent target I belong to */
-       sector_t lba;
        struct sk_buff *skb;            /* command skb freed on module exit */
        struct sk_buff *r_skb;          /* response skb for async processing */
        struct buf *buf;
-       struct bio_vec *bv;
-       ulong bcnt;
-       ulong bv_off;
+       struct bvec_iter iter;
        char flags;
 };
 
index d2515435e23f2f87215558ec703f5a625ab8ac80..8184451b57c04999bd23c286080e14ca7f069031 100644 (file)
@@ -196,8 +196,7 @@ aoe_freetframe(struct frame *f)
 
        t = f->t;
        f->buf = NULL;
-       f->lba = 0;
-       f->bv = NULL;
+       memset(&f->iter, 0, sizeof(f->iter));
        f->r_skb = NULL;
        f->flags = 0;
        list_add(&f->head, &t->ffree);
@@ -295,21 +294,14 @@ newframe(struct aoedev *d)
 }
 
 static void
-skb_fillup(struct sk_buff *skb, struct bio_vec *bv, ulong off, ulong cnt)
+skb_fillup(struct sk_buff *skb, struct bio *bio, struct bvec_iter iter)
 {
        int frag = 0;
-       ulong fcnt;
-loop:
-       fcnt = bv->bv_len - (off - bv->bv_offset);
-       if (fcnt > cnt)
-               fcnt = cnt;
-       skb_fill_page_desc(skb, frag++, bv->bv_page, off, fcnt);
-       cnt -= fcnt;
-       if (cnt <= 0)
-               return;
-       bv++;
-       off = bv->bv_offset;
-       goto loop;
+       struct bio_vec bv;
+
+       __bio_for_each_segment(bv, bio, iter, iter)
+               skb_fill_page_desc(skb, frag++, bv.bv_page,
+                                  bv.bv_offset, bv.bv_len);
 }
 
 static void
@@ -346,12 +338,10 @@ ata_rw_frameinit(struct frame *f)
        t->nout++;
        f->waited = 0;
        f->waited_total = 0;
-       if (f->buf)
-               f->lba = f->buf->sector;
 
        /* set up ata header */
-       ah->scnt = f->bcnt >> 9;
-       put_lba(ah, f->lba);
+       ah->scnt = f->iter.bi_size >> 9;
+       put_lba(ah, f->iter.bi_sector);
        if (t->d->flags & DEVFL_EXT) {
                ah->aflags |= AOEAFL_EXT;
        } else {
@@ -360,11 +350,11 @@ ata_rw_frameinit(struct frame *f)
                ah->lba3 |= 0xe0;       /* LBA bit + obsolete 0xa0 */
        }
        if (f->buf && bio_data_dir(f->buf->bio) == WRITE) {
-               skb_fillup(skb, f->bv, f->bv_off, f->bcnt);
+               skb_fillup(skb, f->buf->bio, f->iter);
                ah->aflags |= AOEAFL_WRITE;
-               skb->len += f->bcnt;
-               skb->data_len = f->bcnt;
-               skb->truesize += f->bcnt;
+               skb->len += f->iter.bi_size;
+               skb->data_len = f->iter.bi_size;
+               skb->truesize += f->iter.bi_size;
                t->wpkts++;
        } else {
                t->rpkts++;
@@ -382,7 +372,6 @@ aoecmd_ata_rw(struct aoedev *d)
        struct buf *buf;
        struct sk_buff *skb;
        struct sk_buff_head queue;
-       ulong bcnt, fbcnt;
 
        buf = nextbuf(d);
        if (buf == NULL)
@@ -390,39 +379,22 @@ aoecmd_ata_rw(struct aoedev *d)
        f = newframe(d);
        if (f == NULL)
                return 0;
-       bcnt = d->maxbcnt;
-       if (bcnt == 0)
-               bcnt = DEFAULTBCNT;
-       if (bcnt > buf->resid)
-               bcnt = buf->resid;
-       fbcnt = bcnt;
-       f->bv = buf->bv;
-       f->bv_off = f->bv->bv_offset + (f->bv->bv_len - buf->bv_resid);
-       do {
-               if (fbcnt < buf->bv_resid) {
-                       buf->bv_resid -= fbcnt;
-                       buf->resid -= fbcnt;
-                       break;
-               }
-               fbcnt -= buf->bv_resid;
-               buf->resid -= buf->bv_resid;
-               if (buf->resid == 0) {
-                       d->ip.buf = NULL;
-                       break;
-               }
-               buf->bv++;
-               buf->bv_resid = buf->bv->bv_len;
-               WARN_ON(buf->bv_resid == 0);
-       } while (fbcnt);
 
        /* initialize the headers & frame */
        f->buf = buf;
-       f->bcnt = bcnt;
-       ata_rw_frameinit(f);
+       f->iter = buf->iter;
+       f->iter.bi_size = min_t(unsigned long,
+                               d->maxbcnt ?: DEFAULTBCNT,
+                               f->iter.bi_size);
+       bio_advance_iter(buf->bio, &buf->iter, f->iter.bi_size);
+
+       if (!buf->iter.bi_size)
+               d->ip.buf = NULL;
 
        /* mark all tracking fields and load out */
        buf->nframesout += 1;
-       buf->sector += bcnt >> 9;
+
+       ata_rw_frameinit(f);
 
        skb = skb_clone(f->skb, GFP_ATOMIC);
        if (skb) {
@@ -613,10 +585,7 @@ reassign_frame(struct frame *f)
        skb = nf->skb;
        nf->skb = f->skb;
        nf->buf = f->buf;
-       nf->bcnt = f->bcnt;
-       nf->lba = f->lba;
-       nf->bv = f->bv;
-       nf->bv_off = f->bv_off;
+       nf->iter = f->iter;
        nf->waited = 0;
        nf->waited_total = f->waited_total;
        nf->sent = f->sent;
@@ -648,19 +617,19 @@ probe(struct aoetgt *t)
        }
        f->flags |= FFL_PROBE;
        ifrotate(t);
-       f->bcnt = t->d->maxbcnt ? t->d->maxbcnt : DEFAULTBCNT;
+       f->iter.bi_size = t->d->maxbcnt ? t->d->maxbcnt : DEFAULTBCNT;
        ata_rw_frameinit(f);
        skb = f->skb;
-       for (frag = 0, n = f->bcnt; n > 0; ++frag, n -= m) {
+       for (frag = 0, n = f->iter.bi_size; n > 0; ++frag, n -= m) {
                if (n < PAGE_SIZE)
                        m = n;
                else
                        m = PAGE_SIZE;
                skb_fill_page_desc(skb, frag, empty_page, 0, m);
        }
-       skb->len += f->bcnt;
-       skb->data_len = f->bcnt;
-       skb->truesize += f->bcnt;
+       skb->len += f->iter.bi_size;
+       skb->data_len = f->iter.bi_size;
+       skb->truesize += f->iter.bi_size;
 
        skb = skb_clone(f->skb, GFP_ATOMIC);
        if (skb) {
@@ -897,15 +866,15 @@ rqbiocnt(struct request *r)
 static void
 bio_pageinc(struct bio *bio)
 {
-       struct bio_vec *bv;
+       struct bio_vec bv;
        struct page *page;
-       int i;
+       struct bvec_iter iter;
 
-       bio_for_each_segment(bv, bio, i) {
+       bio_for_each_segment(bv, bio, iter) {
                /* Non-zero page count for non-head members of
                 * compound pages is no longer allowed by the kernel.
                 */
-               page = compound_trans_head(bv->bv_page);
+               page = compound_trans_head(bv.bv_page);
                atomic_inc(&page->_count);
        }
 }
@@ -913,12 +882,12 @@ bio_pageinc(struct bio *bio)
 static void
 bio_pagedec(struct bio *bio)
 {
-       struct bio_vec *bv;
        struct page *page;
-       int i;
+       struct bio_vec bv;
+       struct bvec_iter iter;
 
-       bio_for_each_segment(bv, bio, i) {
-               page = compound_trans_head(bv->bv_page);
+       bio_for_each_segment(bv, bio, iter) {
+               page = compound_trans_head(bv.bv_page);
                atomic_dec(&page->_count);
        }
 }
@@ -929,12 +898,8 @@ bufinit(struct buf *buf, struct request *rq, struct bio *bio)
        memset(buf, 0, sizeof(*buf));
        buf->rq = rq;
        buf->bio = bio;
-       buf->resid = bio->bi_size;
-       buf->sector = bio->bi_sector;
+       buf->iter = bio->bi_iter;
        bio_pageinc(bio);
-       buf->bv = bio_iovec(bio);
-       buf->bv_resid = buf->bv->bv_len;
-       WARN_ON(buf->bv_resid == 0);
 }
 
 static struct buf *
@@ -1119,24 +1084,18 @@ gettgt(struct aoedev *d, char *addr)
 }
 
 static void
-bvcpy(struct bio_vec *bv, ulong off, struct sk_buff *skb, long cnt)
+bvcpy(struct sk_buff *skb, struct bio *bio, struct bvec_iter iter, long cnt)
 {
-       ulong fcnt;
-       char *p;
        int soff = 0;
-loop:
-       fcnt = bv->bv_len - (off - bv->bv_offset);
-       if (fcnt > cnt)
-               fcnt = cnt;
-       p = page_address(bv->bv_page) + off;
-       skb_copy_bits(skb, soff, p, fcnt);
-       soff += fcnt;
-       cnt -= fcnt;
-       if (cnt <= 0)
-               return;
-       bv++;
-       off = bv->bv_offset;
-       goto loop;
+       struct bio_vec bv;
+
+       iter.bi_size = cnt;
+
+       __bio_for_each_segment(bv, bio, iter, iter) {
+               char *p = page_address(bv.bv_page) + bv.bv_offset;
+               skb_copy_bits(skb, soff, p, bv.bv_len);
+               soff += bv.bv_len;
+       }
 }
 
 void
@@ -1152,7 +1111,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail)
        do {
                bio = rq->bio;
                bok = !fastfail && test_bit(BIO_UPTODATE, &bio->bi_flags);
-       } while (__blk_end_request(rq, bok ? 0 : -EIO, bio->bi_size));
+       } while (__blk_end_request(rq, bok ? 0 : -EIO, bio->bi_iter.bi_size));
 
        /* cf. http://lkml.org/lkml/2006/10/31/28 */
        if (!fastfail)
@@ -1229,7 +1188,15 @@ noskb:           if (buf)
                        clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
                        break;
                }
-               bvcpy(f->bv, f->bv_off, skb, n);
+               if (n > f->iter.bi_size) {
+                       pr_err_ratelimited("%s e%ld.%d.  bytes=%ld need=%u\n",
+                               "aoe: too-large data size in read from",
+                               (long) d->aoemajor, d->aoeminor,
+                               n, f->iter.bi_size);
+                       clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
+                       break;
+               }
+               bvcpy(skb, f->buf->bio, f->iter, n);
        case ATA_CMD_PIO_WRITE:
        case ATA_CMD_PIO_WRITE_EXT:
                spin_lock_irq(&d->lock);
@@ -1272,7 +1239,7 @@ out:
 
        aoe_freetframe(f);
 
-       if (buf && --buf->nframesout == 0 && buf->resid == 0)
+       if (buf && --buf->nframesout == 0 && buf->iter.bi_size == 0)
                aoe_end_buf(d, buf);
 
        spin_unlock_irq(&d->lock);
@@ -1727,7 +1694,7 @@ aoe_failbuf(struct aoedev *d, struct buf *buf)
 {
        if (buf == NULL)
                return;
-       buf->resid = 0;
+       buf->iter.bi_size = 0;
        clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
        if (buf->nframesout == 0)
                aoe_end_buf(d, buf);
index d91f1a56e8617f56c019bfb6389bb79f71fa8ad2..e73b85cf0756876adbf4ad9b8220fc466bcdb412 100644 (file)
@@ -328,18 +328,18 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
        struct block_device *bdev = bio->bi_bdev;
        struct brd_device *brd = bdev->bd_disk->private_data;
        int rw;
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
        sector_t sector;
-       int i;
+       struct bvec_iter iter;
        int err = -EIO;
 
-       sector = bio->bi_sector;
+       sector = bio->bi_iter.bi_sector;
        if (bio_end_sector(bio) > get_capacity(bdev->bd_disk))
                goto out;
 
        if (unlikely(bio->bi_rw & REQ_DISCARD)) {
                err = 0;
-               discard_from_brd(brd, sector, bio->bi_size);
+               discard_from_brd(brd, sector, bio->bi_iter.bi_size);
                goto out;
        }
 
@@ -347,10 +347,10 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
        if (rw == READA)
                rw = READ;
 
-       bio_for_each_segment(bvec, bio, i) {
-               unsigned int len = bvec->bv_len;
-               err = brd_do_bvec(brd, bvec->bv_page, len,
-                                       bvec->bv_offset, rw, sector);
+       bio_for_each_segment(bvec, bio, iter) {
+               unsigned int len = bvec.bv_len;
+               err = brd_do_bvec(brd, bvec.bv_page, len,
+                                       bvec.bv_offset, rw, sector);
                if (err)
                        break;
                sector += len >> SECTOR_SHIFT;
index 28c73ca320a8f7f9b1741492785fa2f18e042d8c..a9b13f2cc420b055b8089fde687d601a23b8e635 100644 (file)
@@ -159,7 +159,7 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
 
        bio = bio_alloc_drbd(GFP_NOIO);
        bio->bi_bdev = bdev->md_bdev;
-       bio->bi_sector = sector;
+       bio->bi_iter.bi_sector = sector;
        err = -EIO;
        if (bio_add_page(bio, page, size, 0) != size)
                goto out;
index b12c11ec4bd21e405fe75276d656e3519c8ad873..597f111df67b3597987eb816f8ff2ca2ec17c285 100644 (file)
@@ -1028,7 +1028,7 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must
        } else
                page = b->bm_pages[page_nr];
        bio->bi_bdev = mdev->ldev->md_bdev;
-       bio->bi_sector = on_disk_sector;
+       bio->bi_iter.bi_sector = on_disk_sector;
        /* bio_add_page of a single page to an empty bio will always succeed,
         * according to api.  Do we want to assert that? */
        bio_add_page(bio, page, len, 0);
index 9e3818b1bc8321e5883a1ef1b3dfe9542e7ea619..929468e1512a687d44bb310b8e3cc94a6b15161d 100644 (file)
@@ -1537,15 +1537,17 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
 
 static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
 {
-       struct bio_vec *bvec;
-       int i;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
+
        /* hint all but last page with MSG_MORE */
-       bio_for_each_segment(bvec, bio, i) {
+       bio_for_each_segment(bvec, bio, iter) {
                int err;
 
-               err = _drbd_no_send_page(mdev, bvec->bv_page,
-                                        bvec->bv_offset, bvec->bv_len,
-                                        i == bio->bi_vcnt - 1 ? 0 : MSG_MORE);
+               err = _drbd_no_send_page(mdev, bvec.bv_page,
+                                        bvec.bv_offset, bvec.bv_len,
+                                        bio_iter_last(bvec, iter)
+                                        ? 0 : MSG_MORE);
                if (err)
                        return err;
        }
@@ -1554,15 +1556,16 @@ static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
 
 static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
 {
-       struct bio_vec *bvec;
-       int i;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
+
        /* hint all but last page with MSG_MORE */
-       bio_for_each_segment(bvec, bio, i) {
+       bio_for_each_segment(bvec, bio, iter) {
                int err;
 
-               err = _drbd_send_page(mdev, bvec->bv_page,
-                                     bvec->bv_offset, bvec->bv_len,
-                                     i == bio->bi_vcnt - 1 ? 0 : MSG_MORE);
+               err = _drbd_send_page(mdev, bvec.bv_page,
+                                     bvec.bv_offset, bvec.bv_len,
+                                     bio_iter_last(bvec, iter) ? 0 : MSG_MORE);
                if (err)
                        return err;
        }
index 6fa6673b36b396765b58142e8e8abcdc4beaae05..d073305ffd5e76e17a7d0804ad92be1ad82bba67 100644 (file)
@@ -1333,7 +1333,7 @@ next_bio:
                goto fail;
        }
        /* > peer_req->i.sector, unless this is the first bio */
-       bio->bi_sector = sector;
+       bio->bi_iter.bi_sector = sector;
        bio->bi_bdev = mdev->ldev->backing_bdev;
        bio->bi_rw = rw;
        bio->bi_private = peer_req;
@@ -1353,7 +1353,7 @@ next_bio:
                                dev_err(DEV,
                                        "bio_add_page failed for len=%u, "
                                        "bi_vcnt=0 (bi_sector=%llu)\n",
-                                       len, (unsigned long long)bio->bi_sector);
+                                       len, (uint64_t)bio->bi_iter.bi_sector);
                                err = -ENOSPC;
                                goto fail;
                        }
@@ -1595,9 +1595,10 @@ static int drbd_drain_block(struct drbd_conf *mdev, int data_size)
 static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
                           sector_t sector, int data_size)
 {
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
        struct bio *bio;
-       int dgs, err, i, expect;
+       int dgs, err, expect;
        void *dig_in = mdev->tconn->int_dig_in;
        void *dig_vv = mdev->tconn->int_dig_vv;
 
@@ -1615,13 +1616,13 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
        mdev->recv_cnt += data_size>>9;
 
        bio = req->master_bio;
-       D_ASSERT(sector == bio->bi_sector);
+       D_ASSERT(sector == bio->bi_iter.bi_sector);
 
-       bio_for_each_segment(bvec, bio, i) {
-               void *mapped = kmap(bvec->bv_page) + bvec->bv_offset;
-               expect = min_t(int, data_size, bvec->bv_len);
+       bio_for_each_segment(bvec, bio, iter) {
+               void *mapped = kmap(bvec.bv_page) + bvec.bv_offset;
+               expect = min_t(int, data_size, bvec.bv_len);
                err = drbd_recv_all_warn(mdev->tconn, mapped, expect);
-               kunmap(bvec->bv_page);
+               kunmap(bvec.bv_page);
                if (err)
                        return err;
                data_size -= expect;
index fec7bef44994cf8b76e595f69b5e34b42cdaf230..104a040f24de74141274b364ee625aa49eefbb94 100644 (file)
@@ -77,8 +77,8 @@ static struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
        req->epoch       = 0;
 
        drbd_clear_interval(&req->i);
-       req->i.sector     = bio_src->bi_sector;
-       req->i.size      = bio_src->bi_size;
+       req->i.sector     = bio_src->bi_iter.bi_sector;
+       req->i.size      = bio_src->bi_iter.bi_size;
        req->i.local = true;
        req->i.waiting = false;
 
@@ -1280,7 +1280,7 @@ void drbd_make_request(struct request_queue *q, struct bio *bio)
        /*
         * what we "blindly" assume:
         */
-       D_ASSERT(IS_ALIGNED(bio->bi_size, 512));
+       D_ASSERT(IS_ALIGNED(bio->bi_iter.bi_size, 512));
 
        inc_ap_bio(mdev);
        __drbd_make_request(mdev, bio, start_time);
index 978cb1addc98845fb8ca49838cfb5ec2478170f7..28e15d91197af1b234e43136740709adc090bcde 100644 (file)
@@ -269,7 +269,7 @@ static inline void drbd_req_make_private_bio(struct drbd_request *req, struct bi
 
 /* Short lived temporary struct on the stack.
  * We could squirrel the error to be returned into
- * bio->bi_size, or similar. But that would be too ugly. */
+ * bio->bi_iter.bi_size, or similar. But that would be too ugly. */
 struct bio_and_error {
        struct bio *bio;
        int error;
index 891c0ecaa292c84998f7357b82e3a80cdc0f6484..84d3175d493aaef91edabd97297238a717f6973c 100644 (file)
@@ -313,8 +313,8 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
 {
        struct hash_desc desc;
        struct scatterlist sg;
-       struct bio_vec *bvec;
-       int i;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
 
        desc.tfm = tfm;
        desc.flags = 0;
@@ -322,8 +322,8 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
        sg_init_table(&sg, 1);
        crypto_hash_init(&desc);
 
-       bio_for_each_segment(bvec, bio, i) {
-               sg_set_page(&sg, bvec->bv_page, bvec->bv_len, bvec->bv_offset);
+       bio_for_each_segment(bvec, bio, iter) {
+               sg_set_page(&sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset);
                crypto_hash_update(&desc, &sg, sg.length);
        }
        crypto_hash_final(&desc, digest);
index 000abe2f105c60f06d5fac31a2a4889cddd22b15..6b29c4422828a4dc5442bf19b1a2c719d5d2377c 100644 (file)
@@ -2351,7 +2351,7 @@ static void rw_interrupt(void)
 /* Compute maximal contiguous buffer size. */
 static int buffer_chain_size(void)
 {
-       struct bio_vec *bv;
+       struct bio_vec bv;
        int size;
        struct req_iterator iter;
        char *base;
@@ -2360,10 +2360,10 @@ static int buffer_chain_size(void)
        size = 0;
 
        rq_for_each_segment(bv, current_req, iter) {
-               if (page_address(bv->bv_page) + bv->bv_offset != base + size)
+               if (page_address(bv.bv_page) + bv.bv_offset != base + size)
                        break;
 
-               size += bv->bv_len;
+               size += bv.bv_len;
        }
 
        return size >> 9;
@@ -2389,7 +2389,7 @@ static int transfer_size(int ssize, int max_sector, int max_size)
 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
 {
        int remaining;          /* number of transferred 512-byte sectors */
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *buffer;
        char *dma_buffer;
        int size;
@@ -2427,10 +2427,10 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
                if (!remaining)
                        break;
 
-               size = bv->bv_len;
+               size = bv.bv_len;
                SUPBOUND(size, remaining);
 
-               buffer = page_address(bv->bv_page) + bv->bv_offset;
+               buffer = page_address(bv.bv_page) + bv.bv_offset;
                if (dma_buffer + size >
                    floppy_track_buffer + (max_buffer_sectors << 10) ||
                    dma_buffer < floppy_track_buffer) {
@@ -3775,9 +3775,9 @@ static int __floppy_read_block_0(struct block_device *bdev)
        bio_vec.bv_len = size;
        bio_vec.bv_offset = 0;
        bio.bi_vcnt = 1;
-       bio.bi_size = size;
+       bio.bi_iter.bi_size = size;
        bio.bi_bdev = bdev;
-       bio.bi_sector = 0;
+       bio.bi_iter.bi_sector = 0;
        bio.bi_flags = (1 << BIO_QUIET);
        init_completion(&complete);
        bio.bi_private = &complete;
index c8dac730524408f63e78cb9acdae8294aaf8dafa..33fde3a3975954c793d0d2e9feb846e5e6a2bdc2 100644 (file)
@@ -288,9 +288,10 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
 {
        int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t,
                        struct page *page);
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
        struct page *page = NULL;
-       int i, ret = 0;
+       int ret = 0;
 
        if (lo->transfer != transfer_none) {
                page = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
@@ -302,11 +303,11 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
                do_lo_send = do_lo_send_direct_write;
        }
 
-       bio_for_each_segment(bvec, bio, i) {
-               ret = do_lo_send(lo, bvec, pos, page);
+       bio_for_each_segment(bvec, bio, iter) {
+               ret = do_lo_send(lo, &bvec, pos, page);
                if (ret < 0)
                        break;
-               pos += bvec->bv_len;
+               pos += bvec.bv_len;
        }
        if (page) {
                kunmap(page);
@@ -392,20 +393,20 @@ do_lo_receive(struct loop_device *lo,
 static int
 lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
 {
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
        ssize_t s;
-       int i;
 
-       bio_for_each_segment(bvec, bio, i) {
-               s = do_lo_receive(lo, bvec, bsize, pos);
+       bio_for_each_segment(bvec, bio, iter) {
+               s = do_lo_receive(lo, &bvec, bsize, pos);
                if (s < 0)
                        return s;
 
-               if (s != bvec->bv_len) {
+               if (s != bvec.bv_len) {
                        zero_fill_bio(bio);
                        break;
                }
-               pos += bvec->bv_len;
+               pos += bvec.bv_len;
        }
        return 0;
 }
@@ -415,7 +416,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
        loff_t pos;
        int ret;
 
-       pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
+       pos = ((loff_t) bio->bi_iter.bi_sector << 9) + lo->lo_offset;
 
        if (bio_rw(bio) == WRITE) {
                struct file *file = lo->lo_backing_file;
@@ -444,7 +445,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
                                goto out;
                        }
                        ret = file->f_op->fallocate(file, mode, pos,
-                                                   bio->bi_size);
+                                                   bio->bi_iter.bi_size);
                        if (unlikely(ret && ret != -EINVAL &&
                                     ret != -EOPNOTSUPP))
                                ret = -EIO;
index 050c71267f146340281992e341ab86c93d79c33d..52b2f2a714708a756b4adcee140e8ae2a91f5006 100644 (file)
@@ -3962,8 +3962,9 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
 {
        struct driver_data *dd = queue->queuedata;
        struct scatterlist *sg;
-       struct bio_vec *bvec;
-       int i, nents = 0;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
+       int nents = 0;
        int tag = 0, unaligned = 0;
 
        if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) {
@@ -3993,7 +3994,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
        }
 
        if (unlikely(bio->bi_rw & REQ_DISCARD)) {
-               bio_endio(bio, mtip_send_trim(dd, bio->bi_sector,
+               bio_endio(bio, mtip_send_trim(dd, bio->bi_iter.bi_sector,
                                                bio_sectors(bio)));
                return;
        }
@@ -4006,7 +4007,8 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
 
        if (bio_data_dir(bio) == WRITE && bio_sectors(bio) <= 64 &&
                                                        dd->unal_qdepth) {
-               if (bio->bi_sector % 8 != 0) /* Unaligned on 4k boundaries */
+               if (bio->bi_iter.bi_sector % 8 != 0)
+                       /* Unaligned on 4k boundaries */
                        unaligned = 1;
                else if (bio_sectors(bio) % 8 != 0) /* Aligned but not 4k/8k */
                        unaligned = 1;
@@ -4025,17 +4027,17 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
                }
 
                /* Create the scatter list for this bio. */
-               bio_for_each_segment(bvec, bio, i) {
+               bio_for_each_segment(bvec, bio, iter) {
                        sg_set_page(&sg[nents],
-                                       bvec->bv_page,
-                                       bvec->bv_len,
-                                       bvec->bv_offset);
+                                       bvec.bv_page,
+                                       bvec.bv_len,
+                                       bvec.bv_offset);
                        nents++;
                }
 
                /* Issue the read/write. */
                mtip_hw_submit_io(dd,
-                               bio->bi_sector,
+                               bio->bi_iter.bi_sector,
                                bio_sectors(bio),
                                nents,
                                tag,
index 2dc3b5153f0d82b42cfab720464e17bd963223f8..55298db36b2d61a113f25c22905fffb0f22ddd32 100644 (file)
@@ -271,18 +271,18 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
 
        if (nbd_cmd(req) == NBD_CMD_WRITE) {
                struct req_iterator iter;
-               struct bio_vec *bvec;
+               struct bio_vec bvec;
                /*
                 * we are really probing at internals to determine
                 * whether to set MSG_MORE or not...
                 */
                rq_for_each_segment(bvec, req, iter) {
                        flags = 0;
-                       if (!rq_iter_last(req, iter))
+                       if (!rq_iter_last(bvec, iter))
                                flags = MSG_MORE;
                        dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n",
-                                       nbd->disk->disk_name, req, bvec->bv_len);
-                       result = sock_send_bvec(nbd, bvec, flags);
+                                       nbd->disk->disk_name, req, bvec.bv_len);
+                       result = sock_send_bvec(nbd, &bvec, flags);
                        if (result <= 0) {
                                dev_err(disk_to_dev(nbd->disk),
                                        "Send data failed (result %d)\n",
@@ -378,10 +378,10 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
                        nbd->disk->disk_name, req);
        if (nbd_cmd(req) == NBD_CMD_READ) {
                struct req_iterator iter;
-               struct bio_vec *bvec;
+               struct bio_vec bvec;
 
                rq_for_each_segment(bvec, req, iter) {
-                       result = sock_recv_bvec(nbd, bvec);
+                       result = sock_recv_bvec(nbd, &bvec);
                        if (result <= 0) {
                                dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n",
                                        result);
@@ -389,7 +389,7 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
                                return req;
                        }
                        dprintk(DBG_RX, "%s: request %p: got %d bytes data\n",
-                               nbd->disk->disk_name, req, bvec->bv_len);
+                               nbd->disk->disk_name, req, bvec.bv_len);
                }
        }
        return req;
index 26d03fa0bf26696d9e004b3983a580d409d3d006..1f14ac4039450e84137b4eab0dacf043aa46d16e 100644 (file)
@@ -441,104 +441,19 @@ int nvme_setup_prps(struct nvme_dev *dev, struct nvme_common_command *cmd,
        return total_len;
 }
 
-struct nvme_bio_pair {
-       struct bio b1, b2, *parent;
-       struct bio_vec *bv1, *bv2;
-       int err;
-       atomic_t cnt;
-};
-
-static void nvme_bio_pair_endio(struct bio *bio, int err)
-{
-       struct nvme_bio_pair *bp = bio->bi_private;
-
-       if (err)
-               bp->err = err;
-
-       if (atomic_dec_and_test(&bp->cnt)) {
-               bio_endio(bp->parent, bp->err);
-               kfree(bp->bv1);
-               kfree(bp->bv2);
-               kfree(bp);
-       }
-}
-
-static struct nvme_bio_pair *nvme_bio_split(struct bio *bio, int idx,
-                                                       int len, int offset)
-{
-       struct nvme_bio_pair *bp;
-
-       BUG_ON(len > bio->bi_size);
-       BUG_ON(idx > bio->bi_vcnt);
-
-       bp = kmalloc(sizeof(*bp), GFP_ATOMIC);
-       if (!bp)
-               return NULL;
-       bp->err = 0;
-
-       bp->b1 = *bio;
-       bp->b2 = *bio;
-
-       bp->b1.bi_size = len;
-       bp->b2.bi_size -= len;
-       bp->b1.bi_vcnt = idx;
-       bp->b2.bi_idx = idx;
-       bp->b2.bi_sector += len >> 9;
-
-       if (offset) {
-               bp->bv1 = kmalloc(bio->bi_max_vecs * sizeof(struct bio_vec),
-                                                               GFP_ATOMIC);
-               if (!bp->bv1)
-                       goto split_fail_1;
-
-               bp->bv2 = kmalloc(bio->bi_max_vecs * sizeof(struct bio_vec),
-                                                               GFP_ATOMIC);
-               if (!bp->bv2)
-                       goto split_fail_2;
-
-               memcpy(bp->bv1, bio->bi_io_vec,
-                       bio->bi_max_vecs * sizeof(struct bio_vec));
-               memcpy(bp->bv2, bio->bi_io_vec,
-                       bio->bi_max_vecs * sizeof(struct bio_vec));
-
-               bp->b1.bi_io_vec = bp->bv1;
-               bp->b2.bi_io_vec = bp->bv2;
-               bp->b2.bi_io_vec[idx].bv_offset += offset;
-               bp->b2.bi_io_vec[idx].bv_len -= offset;
-               bp->b1.bi_io_vec[idx].bv_len = offset;
-               bp->b1.bi_vcnt++;
-       } else
-               bp->bv1 = bp->bv2 = NULL;
-
-       bp->b1.bi_private = bp;
-       bp->b2.bi_private = bp;
-
-       bp->b1.bi_end_io = nvme_bio_pair_endio;
-       bp->b2.bi_end_io = nvme_bio_pair_endio;
-
-       bp->parent = bio;
-       atomic_set(&bp->cnt, 2);
-
-       return bp;
-
- split_fail_2:
-       kfree(bp->bv1);
- split_fail_1:
-       kfree(bp);
-       return NULL;
-}
-
 static int nvme_split_and_submit(struct bio *bio, struct nvme_queue *nvmeq,
-                                               int idx, int len, int offset)
+                                int len)
 {
-       struct nvme_bio_pair *bp = nvme_bio_split(bio, idx, len, offset);
-       if (!bp)
+       struct bio *split = bio_split(bio, len >> 9, GFP_ATOMIC, NULL);
+       if (!split)
                return -ENOMEM;
 
+       bio_chain(split, bio);
+
        if (bio_list_empty(&nvmeq->sq_cong))
                add_wait_queue(&nvmeq->sq_full, &nvmeq->sq_cong_wait);
-       bio_list_add(&nvmeq->sq_cong, &bp->b1);
-       bio_list_add(&nvmeq->sq_cong, &bp->b2);
+       bio_list_add(&nvmeq->sq_cong, split);
+       bio_list_add(&nvmeq->sq_cong, bio);
 
        return 0;
 }
@@ -550,41 +465,44 @@ static int nvme_split_and_submit(struct bio *bio, struct nvme_queue *nvmeq,
 static int nvme_map_bio(struct nvme_queue *nvmeq, struct nvme_iod *iod,
                struct bio *bio, enum dma_data_direction dma_dir, int psegs)
 {
-       struct bio_vec *bvec, *bvprv = NULL;
+       struct bio_vec bvec, bvprv;
+       struct bvec_iter iter;
        struct scatterlist *sg = NULL;
-       int i, length = 0, nsegs = 0, split_len = bio->bi_size;
+       int length = 0, nsegs = 0, split_len = bio->bi_iter.bi_size;
+       int first = 1;
 
        if (nvmeq->dev->stripe_size)
                split_len = nvmeq->dev->stripe_size -
-                       ((bio->bi_sector << 9) & (nvmeq->dev->stripe_size - 1));
+                       ((bio->bi_iter.bi_sector << 9) &
+                        (nvmeq->dev->stripe_size - 1));
 
        sg_init_table(iod->sg, psegs);
-       bio_for_each_segment(bvec, bio, i) {
-               if (bvprv && BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) {
-                       sg->length += bvec->bv_len;
+       bio_for_each_segment(bvec, bio, iter) {
+               if (!first && BIOVEC_PHYS_MERGEABLE(&bvprv, &bvec)) {
+                       sg->length += bvec.bv_len;
                } else {
-                       if (bvprv && BIOVEC_NOT_VIRT_MERGEABLE(bvprv, bvec))
-                               return nvme_split_and_submit(bio, nvmeq, i,
-                                                               length, 0);
+                       if (!first && BIOVEC_NOT_VIRT_MERGEABLE(&bvprv, &bvec))
+                               return nvme_split_and_submit(bio, nvmeq,
+                                                            length);
 
                        sg = sg ? sg + 1 : iod->sg;
-                       sg_set_page(sg, bvec->bv_page, bvec->bv_len,
-                                                       bvec->bv_offset);
+                       sg_set_page(sg, bvec.bv_page,
+                                   bvec.bv_len, bvec.bv_offset);
                        nsegs++;
                }
 
-               if (split_len - length < bvec->bv_len)
-                       return nvme_split_and_submit(bio, nvmeq, i, split_len,
-                                                       split_len - length);
-               length += bvec->bv_len;
+               if (split_len - length < bvec.bv_len)
+                       return nvme_split_and_submit(bio, nvmeq, split_len);
+               length += bvec.bv_len;
                bvprv = bvec;
+               first = 0;
        }
        iod->nents = nsegs;
        sg_mark_end(sg);
        if (dma_map_sg(nvmeq->q_dmadev, iod->sg, iod->nents, dma_dir) == 0)
                return -ENOMEM;
 
-       BUG_ON(length != bio->bi_size);
+       BUG_ON(length != bio->bi_iter.bi_size);
        return length;
 }
 
@@ -608,8 +526,8 @@ static int nvme_submit_discard(struct nvme_queue *nvmeq, struct nvme_ns *ns,
        iod->npages = 0;
 
        range->cattr = cpu_to_le32(0);
-       range->nlb = cpu_to_le32(bio->bi_size >> ns->lba_shift);
-       range->slba = cpu_to_le64(nvme_block_nr(ns, bio->bi_sector));
+       range->nlb = cpu_to_le32(bio->bi_iter.bi_size >> ns->lba_shift);
+       range->slba = cpu_to_le64(nvme_block_nr(ns, bio->bi_iter.bi_sector));
 
        memset(cmnd, 0, sizeof(*cmnd));
        cmnd->dsm.opcode = nvme_cmd_dsm;
@@ -674,7 +592,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns,
        }
 
        result = -ENOMEM;
-       iod = nvme_alloc_iod(psegs, bio->bi_size, GFP_ATOMIC);
+       iod = nvme_alloc_iod(psegs, bio->bi_iter.bi_size, GFP_ATOMIC);
        if (!iod)
                goto nomem;
        iod->private = bio;
@@ -723,7 +641,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns,
        cmnd->rw.nsid = cpu_to_le32(ns->ns_id);
        length = nvme_setup_prps(nvmeq->dev, &cmnd->common, iod, length,
                                                                GFP_ATOMIC);
-       cmnd->rw.slba = cpu_to_le64(nvme_block_nr(ns, bio->bi_sector));
+       cmnd->rw.slba = cpu_to_le64(nvme_block_nr(ns, bio->bi_iter.bi_sector));
        cmnd->rw.length = cpu_to_le16((length >> ns->lba_shift) - 1);
        cmnd->rw.control = cpu_to_le16(control);
        cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt);
index ff8668c5efb10eebc1a02736d306cce1f43ad7ff..3dda09a5ec4172bc7e57f6e18dff272ecd8deaba 100644 (file)
@@ -651,7 +651,7 @@ static struct pkt_rb_node *pkt_rbtree_find(struct pktcdvd_device *pd, sector_t s
 
        for (;;) {
                tmp = rb_entry(n, struct pkt_rb_node, rb_node);
-               if (s <= tmp->bio->bi_sector)
+               if (s <= tmp->bio->bi_iter.bi_sector)
                        next = n->rb_left;
                else
                        next = n->rb_right;
@@ -660,12 +660,12 @@ static struct pkt_rb_node *pkt_rbtree_find(struct pktcdvd_device *pd, sector_t s
                n = next;
        }
 
-       if (s > tmp->bio->bi_sector) {
+       if (s > tmp->bio->bi_iter.bi_sector) {
                tmp = pkt_rbtree_next(tmp);
                if (!tmp)
                        return NULL;
        }
-       BUG_ON(s > tmp->bio->bi_sector);
+       BUG_ON(s > tmp->bio->bi_iter.bi_sector);
        return tmp;
 }
 
@@ -676,13 +676,13 @@ static void pkt_rbtree_insert(struct pktcdvd_device *pd, struct pkt_rb_node *nod
 {
        struct rb_node **p = &pd->bio_queue.rb_node;
        struct rb_node *parent = NULL;
-       sector_t s = node->bio->bi_sector;
+       sector_t s = node->bio->bi_iter.bi_sector;
        struct pkt_rb_node *tmp;
 
        while (*p) {
                parent = *p;
                tmp = rb_entry(parent, struct pkt_rb_node, rb_node);
-               if (s < tmp->bio->bi_sector)
+               if (s < tmp->bio->bi_iter.bi_sector)
                        p = &(*p)->rb_left;
                else
                        p = &(*p)->rb_right;
@@ -857,7 +857,8 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
                        spin_lock(&pd->iosched.lock);
                        bio = bio_list_peek(&pd->iosched.write_queue);
                        spin_unlock(&pd->iosched.lock);
-                       if (bio && (bio->bi_sector == pd->iosched.last_write))
+                       if (bio && (bio->bi_iter.bi_sector ==
+                                   pd->iosched.last_write))
                                need_write_seek = 0;
                        if (need_write_seek && reads_queued) {
                                if (atomic_read(&pd->cdrw.pending_bios) > 0) {
@@ -888,7 +889,8 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
                        continue;
 
                if (bio_data_dir(bio) == READ)
-                       pd->iosched.successive_reads += bio->bi_size >> 10;
+                       pd->iosched.successive_reads +=
+                               bio->bi_iter.bi_size >> 10;
                else {
                        pd->iosched.successive_reads = 0;
                        pd->iosched.last_write = bio_end_sector(bio);
@@ -978,7 +980,7 @@ static void pkt_end_io_read(struct bio *bio, int err)
 
        pkt_dbg(2, pd, "bio=%p sec0=%llx sec=%llx err=%d\n",
                bio, (unsigned long long)pkt->sector,
-               (unsigned long long)bio->bi_sector, err);
+               (unsigned long long)bio->bi_iter.bi_sector, err);
 
        if (err)
                atomic_inc(&pkt->io_errors);
@@ -1026,8 +1028,9 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
        memset(written, 0, sizeof(written));
        spin_lock(&pkt->lock);
        bio_list_for_each(bio, &pkt->orig_bios) {
-               int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9);
-               int num_frames = bio->bi_size / CD_FRAMESIZE;
+               int first_frame = (bio->bi_iter.bi_sector - pkt->sector) /
+                       (CD_FRAMESIZE >> 9);
+               int num_frames = bio->bi_iter.bi_size / CD_FRAMESIZE;
                pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9);
                BUG_ON(first_frame < 0);
                BUG_ON(first_frame + num_frames > pkt->frames);
@@ -1053,7 +1056,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
 
                bio = pkt->r_bios[f];
                bio_reset(bio);
-               bio->bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
+               bio->bi_iter.bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
                bio->bi_bdev = pd->bdev;
                bio->bi_end_io = pkt_end_io_read;
                bio->bi_private = pkt;
@@ -1150,8 +1153,8 @@ static int pkt_start_recovery(struct packet_data *pkt)
        bio_reset(pkt->bio);
        pkt->bio->bi_bdev = pd->bdev;
        pkt->bio->bi_rw = REQ_WRITE;
-       pkt->bio->bi_sector = new_sector;
-       pkt->bio->bi_size = pkt->frames * CD_FRAMESIZE;
+       pkt->bio->bi_iter.bi_sector = new_sector;
+       pkt->bio->bi_iter.bi_size = pkt->frames * CD_FRAMESIZE;
        pkt->bio->bi_vcnt = pkt->frames;
 
        pkt->bio->bi_end_io = pkt_end_io_packet_write;
@@ -1213,7 +1216,7 @@ static int pkt_handle_queue(struct pktcdvd_device *pd)
        node = first_node;
        while (node) {
                bio = node->bio;
-               zone = get_zone(bio->bi_sector, pd);
+               zone = get_zone(bio->bi_iter.bi_sector, pd);
                list_for_each_entry(p, &pd->cdrw.pkt_active_list, list) {
                        if (p->sector == zone) {
                                bio = NULL;
@@ -1252,14 +1255,14 @@ try_next_bio:
        pkt_dbg(2, pd, "looking for zone %llx\n", (unsigned long long)zone);
        while ((node = pkt_rbtree_find(pd, zone)) != NULL) {
                bio = node->bio;
-               pkt_dbg(2, pd, "found zone=%llx\n",
-                       (unsigned long long)get_zone(bio->bi_sector, pd));
-               if (get_zone(bio->bi_sector, pd) != zone)
+               pkt_dbg(2, pd, "found zone=%llx\n", (unsigned long long)
+                       get_zone(bio->bi_iter.bi_sector, pd));
+               if (get_zone(bio->bi_iter.bi_sector, pd) != zone)
                        break;
                pkt_rbtree_erase(pd, node);
                spin_lock(&pkt->lock);
                bio_list_add(&pkt->orig_bios, bio);
-               pkt->write_size += bio->bi_size / CD_FRAMESIZE;
+               pkt->write_size += bio->bi_iter.bi_size / CD_FRAMESIZE;
                spin_unlock(&pkt->lock);
        }
        /* check write congestion marks, and if bio_queue_size is
@@ -1293,7 +1296,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
        struct bio_vec *bvec = pkt->w_bio->bi_io_vec;
 
        bio_reset(pkt->w_bio);
-       pkt->w_bio->bi_sector = pkt->sector;
+       pkt->w_bio->bi_iter.bi_sector = pkt->sector;
        pkt->w_bio->bi_bdev = pd->bdev;
        pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
        pkt->w_bio->bi_private = pkt;
@@ -2335,75 +2338,29 @@ static void pkt_end_io_read_cloned(struct bio *bio, int err)
        pkt_bio_finished(pd);
 }
 
-static void pkt_make_request(struct request_queue *q, struct bio *bio)
+static void pkt_make_request_read(struct pktcdvd_device *pd, struct bio *bio)
 {
-       struct pktcdvd_device *pd;
-       char b[BDEVNAME_SIZE];
+       struct bio *cloned_bio = bio_clone(bio, GFP_NOIO);
+       struct packet_stacked_data *psd = mempool_alloc(psd_pool, GFP_NOIO);
+
+       psd->pd = pd;
+       psd->bio = bio;
+       cloned_bio->bi_bdev = pd->bdev;
+       cloned_bio->bi_private = psd;
+       cloned_bio->bi_end_io = pkt_end_io_read_cloned;
+       pd->stats.secs_r += bio_sectors(bio);
+       pkt_queue_bio(pd, cloned_bio);
+}
+
+static void pkt_make_request_write(struct request_queue *q, struct bio *bio)
+{
+       struct pktcdvd_device *pd = q->queuedata;
        sector_t zone;
        struct packet_data *pkt;
        int was_empty, blocked_bio;
        struct pkt_rb_node *node;
 
-       pd = q->queuedata;
-       if (!pd) {
-               pr_err("%s incorrect request queue\n",
-                      bdevname(bio->bi_bdev, b));
-               goto end_io;
-       }
-
-       /*
-        * Clone READ bios so we can have our own bi_end_io callback.
-        */
-       if (bio_data_dir(bio) == READ) {
-               struct bio *cloned_bio = bio_clone(bio, GFP_NOIO);
-               struct packet_stacked_data *psd = mempool_alloc(psd_pool, GFP_NOIO);
-
-               psd->pd = pd;
-               psd->bio = bio;
-               cloned_bio->bi_bdev = pd->bdev;
-               cloned_bio->bi_private = psd;
-               cloned_bio->bi_end_io = pkt_end_io_read_cloned;
-               pd->stats.secs_r += bio_sectors(bio);
-               pkt_queue_bio(pd, cloned_bio);
-               return;
-       }
-
-       if (!test_bit(PACKET_WRITABLE, &pd->flags)) {
-               pkt_notice(pd, "WRITE for ro device (%llu)\n",
-                          (unsigned long long)bio->bi_sector);
-               goto end_io;
-       }
-
-       if (!bio->bi_size || (bio->bi_size % CD_FRAMESIZE)) {
-               pkt_err(pd, "wrong bio size\n");
-               goto end_io;
-       }
-
-       blk_queue_bounce(q, &bio);
-
-       zone = get_zone(bio->bi_sector, pd);
-       pkt_dbg(2, pd, "start = %6llx stop = %6llx\n",
-               (unsigned long long)bio->bi_sector,
-               (unsigned long long)bio_end_sector(bio));
-
-       /* Check if we have to split the bio */
-       {
-               struct bio_pair *bp;
-               sector_t last_zone;
-               int first_sectors;
-
-               last_zone = get_zone(bio_end_sector(bio) - 1, pd);
-               if (last_zone != zone) {
-                       BUG_ON(last_zone != zone + pd->settings.size);
-                       first_sectors = last_zone - bio->bi_sector;
-                       bp = bio_split(bio, first_sectors);
-                       BUG_ON(!bp);
-                       pkt_make_request(q, &bp->bio1);
-                       pkt_make_request(q, &bp->bio2);
-                       bio_pair_release(bp);
-                       return;
-               }
-       }
+       zone = get_zone(bio->bi_iter.bi_sector, pd);
 
        /*
         * If we find a matching packet in state WAITING or READ_WAIT, we can
@@ -2417,7 +2374,8 @@ static void pkt_make_request(struct request_queue *q, struct bio *bio)
                        if ((pkt->state == PACKET_WAITING_STATE) ||
                            (pkt->state == PACKET_READ_WAIT_STATE)) {
                                bio_list_add(&pkt->orig_bios, bio);
-                               pkt->write_size += bio->bi_size / CD_FRAMESIZE;
+                               pkt->write_size +=
+                                       bio->bi_iter.bi_size / CD_FRAMESIZE;
                                if ((pkt->write_size >= pkt->frames) &&
                                    (pkt->state == PACKET_WAITING_STATE)) {
                                        atomic_inc(&pkt->run_sm);
@@ -2476,6 +2434,64 @@ static void pkt_make_request(struct request_queue *q, struct bio *bio)
                 */
                wake_up(&pd->wqueue);
        }
+}
+
+static void pkt_make_request(struct request_queue *q, struct bio *bio)
+{
+       struct pktcdvd_device *pd;
+       char b[BDEVNAME_SIZE];
+       struct bio *split;
+
+       pd = q->queuedata;
+       if (!pd) {
+               pr_err("%s incorrect request queue\n",
+                      bdevname(bio->bi_bdev, b));
+               goto end_io;
+       }
+
+       pkt_dbg(2, pd, "start = %6llx stop = %6llx\n",
+               (unsigned long long)bio->bi_iter.bi_sector,
+               (unsigned long long)bio_end_sector(bio));
+
+       /*
+        * Clone READ bios so we can have our own bi_end_io callback.
+        */
+       if (bio_data_dir(bio) == READ) {
+               pkt_make_request_read(pd, bio);
+               return;
+       }
+
+       if (!test_bit(PACKET_WRITABLE, &pd->flags)) {
+               pkt_notice(pd, "WRITE for ro device (%llu)\n",
+                          (unsigned long long)bio->bi_iter.bi_sector);
+               goto end_io;
+       }
+
+       if (!bio->bi_iter.bi_size || (bio->bi_iter.bi_size % CD_FRAMESIZE)) {
+               pkt_err(pd, "wrong bio size\n");
+               goto end_io;
+       }
+
+       blk_queue_bounce(q, &bio);
+
+       do {
+               sector_t zone = get_zone(bio->bi_iter.bi_sector, pd);
+               sector_t last_zone = get_zone(bio_end_sector(bio) - 1, pd);
+
+               if (last_zone != zone) {
+                       BUG_ON(last_zone != zone + pd->settings.size);
+
+                       split = bio_split(bio, last_zone -
+                                         bio->bi_iter.bi_sector,
+                                         GFP_NOIO, fs_bio_set);
+                       bio_chain(split, bio);
+               } else {
+                       split = bio;
+               }
+
+               pkt_make_request_write(q, split);
+       } while (split != bio);
+
        return;
 end_io:
        bio_io_error(bio);
index d754a88d75858ef46f8553ac54b0163ff7b60d8a..c120d70d3fb3b31fdfb584859a8cdd5bf0849dab 100644 (file)
@@ -94,26 +94,25 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev,
 {
        unsigned int offset = 0;
        struct req_iterator iter;
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
        unsigned int i = 0;
        size_t size;
        void *buf;
 
        rq_for_each_segment(bvec, req, iter) {
                unsigned long flags;
-               dev_dbg(&dev->sbd.core,
-                       "%s:%u: bio %u: %u segs %u sectors from %lu\n",
-                       __func__, __LINE__, i, bio_segments(iter.bio),
-                       bio_sectors(iter.bio), iter.bio->bi_sector);
+               dev_dbg(&dev->sbd.core, "%s:%u: bio %u: %u sectors from %lu\n",
+                       __func__, __LINE__, i, bio_sectors(iter.bio),
+                       iter.bio->bi_iter.bi_sector);
 
-               size = bvec->bv_len;
-               buf = bvec_kmap_irq(bvec, &flags);
+               size = bvec.bv_len;
+               buf = bvec_kmap_irq(&bvec, &flags);
                if (gather)
                        memcpy(dev->bounce_buf+offset, buf, size);
                else
                        memcpy(buf, dev->bounce_buf+offset, size);
                offset += size;
-               flush_kernel_dcache_page(bvec->bv_page);
+               flush_kernel_dcache_page(bvec.bv_page);
                bvec_kunmap_irq(buf, &flags);
                i++;
        }
@@ -130,7 +129,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
 
 #ifdef DEBUG
        unsigned int n = 0;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        struct req_iterator iter;
 
        rq_for_each_segment(bv, req, iter)
index 06a2e53e5f37299191b1d9c7fe5e2caf036461a6..ef45cfb98fd2f12278d9f9caa6d044c1336e7baa 100644 (file)
@@ -553,16 +553,16 @@ static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev,
        struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
        int write = bio_data_dir(bio) == WRITE;
        const char *op = write ? "write" : "read";
-       loff_t offset = bio->bi_sector << 9;
+       loff_t offset = bio->bi_iter.bi_sector << 9;
        int error = 0;
-       struct bio_vec *bvec;
-       unsigned int i;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
        struct bio *next;
 
-       bio_for_each_segment(bvec, bio, i) {
+       bio_for_each_segment(bvec, bio, iter) {
                /* PS3 is ppc64, so we don't handle highmem */
-               char *ptr = page_address(bvec->bv_page) + bvec->bv_offset;
-               size_t len = bvec->bv_len, retlen;
+               char *ptr = page_address(bvec.bv_page) + bvec.bv_offset;
+               size_t len = bvec.bv_len, retlen;
 
                dev_dbg(&dev->core, "    %s %zu bytes at offset %llu\n", op,
                        len, offset);
index cb1db2979d3d7b5417a8a4b131e09c5c5f6767c0..3624368b910dd30fe841cb42e2f13a8ec5109bc8 100644 (file)
@@ -1109,23 +1109,23 @@ static void bio_chain_put(struct bio *chain)
  */
 static void zero_bio_chain(struct bio *chain, int start_ofs)
 {
-       struct bio_vec *bv;
+       struct bio_vec bv;
+       struct bvec_iter iter;
        unsigned long flags;
        void *buf;
-       int i;
        int pos = 0;
 
        while (chain) {
-               bio_for_each_segment(bv, chain, i) {
-                       if (pos + bv->bv_len > start_ofs) {
+               bio_for_each_segment(bv, chain, iter) {
+                       if (pos + bv.bv_len > start_ofs) {
                                int remainder = max(start_ofs - pos, 0);
-                               buf = bvec_kmap_irq(bv, &flags);
+                               buf = bvec_kmap_irq(&bv, &flags);
                                memset(buf + remainder, 0,
-                                      bv->bv_len - remainder);
-                               flush_dcache_page(bv->bv_page);
+                                      bv.bv_len - remainder);
+                               flush_dcache_page(bv.bv_page);
                                bvec_kunmap_irq(buf, &flags);
                        }
-                       pos += bv->bv_len;
+                       pos += bv.bv_len;
                }
 
                chain = chain->bi_next;
@@ -1173,74 +1173,14 @@ static struct bio *bio_clone_range(struct bio *bio_src,
                                        unsigned int len,
                                        gfp_t gfpmask)
 {
-       struct bio_vec *bv;
-       unsigned int resid;
-       unsigned short idx;
-       unsigned int voff;
-       unsigned short end_idx;
-       unsigned short vcnt;
        struct bio *bio;
 
-       /* Handle the easy case for the caller */
-
-       if (!offset && len == bio_src->bi_size)
-               return bio_clone(bio_src, gfpmask);
-
-       if (WARN_ON_ONCE(!len))
-               return NULL;
-       if (WARN_ON_ONCE(len > bio_src->bi_size))
-               return NULL;
-       if (WARN_ON_ONCE(offset > bio_src->bi_size - len))
-               return NULL;
-
-       /* Find first affected segment... */
-
-       resid = offset;
-       bio_for_each_segment(bv, bio_src, idx) {
-               if (resid < bv->bv_len)
-                       break;
-               resid -= bv->bv_len;
-       }
-       voff = resid;
-
-       /* ...and the last affected segment */
-
-       resid += len;
-       __bio_for_each_segment(bv, bio_src, end_idx, idx) {
-               if (resid <= bv->bv_len)
-                       break;
-               resid -= bv->bv_len;
-       }
-       vcnt = end_idx - idx + 1;
-
-       /* Build the clone */
-
-       bio = bio_alloc(gfpmask, (unsigned int) vcnt);
+       bio = bio_clone(bio_src, gfpmask);
        if (!bio)
                return NULL;    /* ENOMEM */
 
-       bio->bi_bdev = bio_src->bi_bdev;
-       bio->bi_sector = bio_src->bi_sector + (offset >> SECTOR_SHIFT);
-       bio->bi_rw = bio_src->bi_rw;
-       bio->bi_flags |= 1 << BIO_CLONED;
-
-       /*
-        * Copy over our part of the bio_vec, then update the first
-        * and last (or only) entries.
-        */
-       memcpy(&bio->bi_io_vec[0], &bio_src->bi_io_vec[idx],
-                       vcnt * sizeof (struct bio_vec));
-       bio->bi_io_vec[0].bv_offset += voff;
-       if (vcnt > 1) {
-               bio->bi_io_vec[0].bv_len -= voff;
-               bio->bi_io_vec[vcnt - 1].bv_len = resid;
-       } else {
-               bio->bi_io_vec[0].bv_len = len;
-       }
-
-       bio->bi_vcnt = vcnt;
-       bio->bi_size = len;
-       bio->bi_idx = 0;
+       bio_advance(bio, offset);
+       bio->bi_iter.bi_size = len;
 
        return bio;
 }
@@ -1271,7 +1211,7 @@ static struct bio *bio_chain_clone_range(struct bio **bio_src,
 
        /* Build up a chain of clone bios up to the limit */
 
-       if (!bi || off >= bi->bi_size || !len)
+       if (!bi || off >= bi->bi_iter.bi_size || !len)
                return NULL;            /* Nothing to clone */
 
        end = &chain;
@@ -1283,7 +1223,7 @@ static struct bio *bio_chain_clone_range(struct bio **bio_src,
                        rbd_warn(NULL, "bio_chain exhausted with %u left", len);
                        goto out_err;   /* EINVAL; ran out of bio's */
                }
-               bi_size = min_t(unsigned int, bi->bi_size - off, len);
+               bi_size = min_t(unsigned int, bi->bi_iter.bi_size - off, len);
                bio = bio_clone_range(bi, off, bi_size, gfpmask);
                if (!bio)
                        goto out_err;   /* ENOMEM */
@@ -1292,7 +1232,7 @@ static struct bio *bio_chain_clone_range(struct bio **bio_src,
                end = &bio->bi_next;
 
                off += bi_size;
-               if (off == bi->bi_size) {
+               if (off == bi->bi_iter.bi_size) {
                        bi = bi->bi_next;
                        off = 0;
                }
@@ -2186,7 +2126,8 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
 
        if (type == OBJ_REQUEST_BIO) {
                bio_list = data_desc;
-               rbd_assert(img_offset == bio_list->bi_sector << SECTOR_SHIFT);
+               rbd_assert(img_offset ==
+                          bio_list->bi_iter.bi_sector << SECTOR_SHIFT);
        } else {
                rbd_assert(type == OBJ_REQUEST_PAGES);
                pages = data_desc;
index 2284f5d3a54ad00dd05c512b30b7bfed30411482..2839d37e5af77922051cb1d48561602ea3a3c2b7 100644 (file)
@@ -174,7 +174,7 @@ static void rsxx_make_request(struct request_queue *q, struct bio *bio)
        if (!card)
                goto req_err;
 
-       if (bio->bi_sector + (bio->bi_size >> 9) > get_capacity(card->gendisk))
+       if (bio_end_sector(bio) > get_capacity(card->gendisk))
                goto req_err;
 
        if (unlikely(card->halt)) {
@@ -187,7 +187,7 @@ static void rsxx_make_request(struct request_queue *q, struct bio *bio)
                goto req_err;
        }
 
-       if (bio->bi_size == 0) {
+       if (bio->bi_iter.bi_size == 0) {
                dev_err(CARD_TO_DEV(card), "size zero BIO!\n");
                goto req_err;
        }
@@ -208,7 +208,7 @@ static void rsxx_make_request(struct request_queue *q, struct bio *bio)
 
        dev_dbg(CARD_TO_DEV(card), "BIO[%c]: meta: %p addr8: x%llx size: %d\n",
                 bio_data_dir(bio) ? 'W' : 'R', bio_meta,
-                (u64)bio->bi_sector << 9, bio->bi_size);
+                (u64)bio->bi_iter.bi_sector << 9, bio->bi_iter.bi_size);
 
        st = rsxx_dma_queue_bio(card, bio, &bio_meta->pending_dmas,
                                    bio_dma_done_cb, bio_meta);
index fc88ba3e1bd27835ecf170d5ba321cf8313a6cea..cf8cd293abb51d338cd6d0ae7762070c80be99a2 100644 (file)
@@ -684,7 +684,8 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
                           void *cb_data)
 {
        struct list_head dma_list[RSXX_MAX_TARGETS];
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
        unsigned long long addr8;
        unsigned int laddr;
        unsigned int bv_len;
@@ -696,7 +697,7 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
        int st;
        int i;
 
-       addr8 = bio->bi_sector << 9; /* sectors are 512 bytes */
+       addr8 = bio->bi_iter.bi_sector << 9; /* sectors are 512 bytes */
        atomic_set(n_dmas, 0);
 
        for (i = 0; i < card->n_targets; i++) {
@@ -705,7 +706,7 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
        }
 
        if (bio->bi_rw & REQ_DISCARD) {
-               bv_len = bio->bi_size;
+               bv_len = bio->bi_iter.bi_size;
 
                while (bv_len > 0) {
                        tgt   = rsxx_get_dma_tgt(card, addr8);
@@ -722,9 +723,9 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
                        bv_len -= RSXX_HW_BLK_SIZE;
                }
        } else {
-               bio_for_each_segment(bvec, bio, i) {
-                       bv_len = bvec->bv_len;
-                       bv_off = bvec->bv_offset;
+               bio_for_each_segment(bvec, bio, iter) {
+                       bv_len = bvec.bv_len;
+                       bv_off = bvec.bv_offset;
 
                        while (bv_len > 0) {
                                tgt   = rsxx_get_dma_tgt(card, addr8);
@@ -736,7 +737,7 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
                                st = rsxx_queue_dma(card, &dma_list[tgt],
                                                        bio_data_dir(bio),
                                                        dma_off, dma_len,
-                                                       laddr, bvec->bv_page,
+                                                       laddr, bvec.bv_page,
                                                        bv_off, cb, cb_data);
                                if (st)
                                        goto bvec_err;
index ad70868f8a967b40bc866bc5430387b55f4601ac..4cf81b5bf0f7fba42a243a7e717ead98b2144759 100644 (file)
@@ -108,8 +108,7 @@ struct cardinfo {
                                    * have been written
                                    */
        struct bio      *bio, *currentbio, **biotail;
-       int             current_idx;
-       sector_t        current_sector;
+       struct bvec_iter current_iter;
 
        struct request_queue *queue;
 
@@ -118,7 +117,7 @@ struct cardinfo {
                struct mm_dma_desc      *desc;
                int                     cnt, headcnt;
                struct bio              *bio, **biotail;
-               int                     idx;
+               struct bvec_iter        iter;
        } mm_pages[2];
 #define DESC_PER_PAGE ((PAGE_SIZE*2)/sizeof(struct mm_dma_desc))
 
@@ -344,16 +343,13 @@ static int add_bio(struct cardinfo *card)
        dma_addr_t dma_handle;
        int offset;
        struct bio *bio;
-       struct bio_vec *vec;
-       int idx;
+       struct bio_vec vec;
        int rw;
-       int len;
 
        bio = card->currentbio;
        if (!bio && card->bio) {
                card->currentbio = card->bio;
-               card->current_idx = card->bio->bi_idx;
-               card->current_sector = card->bio->bi_sector;
+               card->current_iter = card->bio->bi_iter;
                card->bio = card->bio->bi_next;
                if (card->bio == NULL)
                        card->biotail = &card->bio;
@@ -362,18 +358,17 @@ static int add_bio(struct cardinfo *card)
        }
        if (!bio)
                return 0;
-       idx = card->current_idx;
 
        rw = bio_rw(bio);
        if (card->mm_pages[card->Ready].cnt >= DESC_PER_PAGE)
                return 0;
 
-       vec = bio_iovec_idx(bio, idx);
-       len = vec->bv_len;
+       vec = bio_iter_iovec(bio, card->current_iter);
+
        dma_handle = pci_map_page(card->dev,
-                                 vec->bv_page,
-                                 vec->bv_offset,
-                                 len,
+                                 vec.bv_page,
+                                 vec.bv_offset,
+                                 vec.bv_len,
                                  (rw == READ) ?
                                  PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
 
@@ -381,7 +376,7 @@ static int add_bio(struct cardinfo *card)
        desc = &p->desc[p->cnt];
        p->cnt++;
        if (p->bio == NULL)
-               p->idx = idx;
+               p->iter = card->current_iter;
        if ((p->biotail) != &bio->bi_next) {
                *(p->biotail) = bio;
                p->biotail = &(bio->bi_next);
@@ -391,8 +386,8 @@ static int add_bio(struct cardinfo *card)
        desc->data_dma_handle = dma_handle;
 
        desc->pci_addr = cpu_to_le64((u64)desc->data_dma_handle);
-       desc->local_addr = cpu_to_le64(card->current_sector << 9);
-       desc->transfer_size = cpu_to_le32(len);
+       desc->local_addr = cpu_to_le64(card->current_iter.bi_sector << 9);
+       desc->transfer_size = cpu_to_le32(vec.bv_len);
        offset = (((char *)&desc->sem_control_bits) - ((char *)p->desc));
        desc->sem_addr = cpu_to_le64((u64)(p->page_dma+offset));
        desc->zero1 = desc->zero2 = 0;
@@ -407,10 +402,9 @@ static int add_bio(struct cardinfo *card)
                desc->control_bits |= cpu_to_le32(DMASCR_TRANSFER_READ);
        desc->sem_control_bits = desc->control_bits;
 
-       card->current_sector += (len >> 9);
-       idx++;
-       card->current_idx = idx;
-       if (idx >= bio->bi_vcnt)
+
+       bio_advance_iter(bio, &card->current_iter, vec.bv_len);
+       if (!card->current_iter.bi_size)
                card->currentbio = NULL;
 
        return 1;
@@ -439,23 +433,25 @@ static void process_page(unsigned long data)
                struct mm_dma_desc *desc = &page->desc[page->headcnt];
                int control = le32_to_cpu(desc->sem_control_bits);
                int last = 0;
-               int idx;
+               struct bio_vec vec;
 
                if (!(control & DMASCR_DMA_COMPLETE)) {
                        control = dma_status;
                        last = 1;
                }
+
                page->headcnt++;
-               idx = page->idx;
-               page->idx++;
-               if (page->idx >= bio->bi_vcnt) {
+               vec = bio_iter_iovec(bio, page->iter);
+               bio_advance_iter(bio, &page->iter, vec.bv_len);
+
+               if (!page->iter.bi_size) {
                        page->bio = bio->bi_next;
                        if (page->bio)
-                               page->idx = page->bio->bi_idx;
+                               page->iter = page->bio->bi_iter;
                }
 
                pci_unmap_page(card->dev, desc->data_dma_handle,
-                              bio_iovec_idx(bio, idx)->bv_len,
+                              vec.bv_len,
                                 (control & DMASCR_TRANSFER_READ) ?
                                PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
                if (control & DMASCR_HARD_ERROR) {
@@ -532,7 +528,8 @@ static void mm_make_request(struct request_queue *q, struct bio *bio)
 {
        struct cardinfo *card = q->queuedata;
        pr_debug("mm_make_request %llu %u\n",
-                (unsigned long long)bio->bi_sector, bio->bi_size);
+                (unsigned long long)bio->bi_iter.bi_sector,
+                bio->bi_iter.bi_size);
 
        spin_lock_irq(&card->lock);
        *card->biotail = bio;
index 6620b73d04906191132d771dade31f9e00043e07..4b97b86da9265b4ca5dcb3a7ab562dbf1eb5bac0 100644 (file)
@@ -1257,7 +1257,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
                        bio->bi_bdev    = preq.bdev;
                        bio->bi_private = pending_req;
                        bio->bi_end_io  = end_block_io_op;
-                       bio->bi_sector  = preq.sector_number;
+                       bio->bi_iter.bi_sector  = preq.sector_number;
                }
 
                preq.sector_number += seg[i].nsec;
index 432db1b59b003a837679cd187c4743f98ca9b152..80e86307dd4b043e295e4b2adff3f09789621cd6 100644 (file)
@@ -1547,7 +1547,7 @@ static int blkif_recover(struct blkfront_info *info)
                        for (i = 0; i < pending; i++) {
                                offset = (i * segs * PAGE_SIZE) >> 9;
                                size = min((unsigned int)(segs * PAGE_SIZE) >> 9,
-                                          (unsigned int)(bio->bi_size >> 9) - offset);
+                                          (unsigned int)bio_sectors(bio) - offset);
                                cloned_bio = bio_clone(bio, GFP_NOIO);
                                BUG_ON(cloned_bio == NULL);
                                bio_trim(cloned_bio, offset, size);
index 5a95baf4b104e4c2dc559534867effa53e6327a2..27de5046708a233cbc99e42a4349387f9f5157cb 100644 (file)
@@ -43,9 +43,6 @@
 #include <linux/zorro.h>
 
 
-extern int m68k_realnum_memory;
-extern struct mem_info m68k_memory[NUM_MEMINFO];
-
 #define Z2MINOR_COMBINED      (0)
 #define Z2MINOR_Z2ONLY        (1)
 #define Z2MINOR_CHIPONLY      (2)
@@ -116,8 +113,8 @@ get_z2ram( void )
        if ( test_bit( i, zorro_unused_z2ram ) )
        {
            z2_count++;
-           z2ram_map[ z2ram_size++ ] = 
-               ZTWO_VADDR( Z2RAM_START ) + ( i << Z2RAM_CHUNKSHIFT );
+           z2ram_map[z2ram_size++] = (unsigned long)ZTWO_VADDR(Z2RAM_START) +
+                                     (i << Z2RAM_CHUNKSHIFT);
            clear_bit( i, zorro_unused_z2ram );
        }
     }
index 6bfc1bb318f6399397ca8f169cc07fd98b46256d..d3fdc32b579d72afcee794d9ba68c68b1f4c367d 100644 (file)
@@ -83,6 +83,7 @@ static const struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x04CA, 0x3005) },
        { USB_DEVICE(0x04CA, 0x3006) },
        { USB_DEVICE(0x04CA, 0x3008) },
+       { USB_DEVICE(0x04CA, 0x300b) },
        { USB_DEVICE(0x13d3, 0x3362) },
        { USB_DEVICE(0x0CF3, 0xE004) },
        { USB_DEVICE(0x0CF3, 0xE005) },
@@ -96,6 +97,7 @@ static const struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x13d3, 0x3402) },
        { USB_DEVICE(0x0cf3, 0x3121) },
        { USB_DEVICE(0x0cf3, 0xe003) },
+       { USB_DEVICE(0x0489, 0xe05f) },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE02C) },
@@ -125,6 +127,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
@@ -138,6 +141,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU22 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
index f9d183387f4585b37e0642aef9e269e17c6be1a4..7399303d7d9978447ff722d823c1dcece408029a 100644 (file)
@@ -23,8 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/slab.h>
 #include <net/bluetooth/bluetooth.h>
-#include <linux/ctype.h>
-#include <linux/firmware.h>
 
 #define BTM_HEADER_LEN                 4
 #define BTM_UPLD_SIZE                  2312
@@ -43,8 +41,6 @@ struct btmrvl_thread {
 struct btmrvl_device {
        void *card;
        struct hci_dev *hcidev;
-       struct device *dev;
-       const char *cal_data;
 
        u8 dev_type;
 
@@ -90,12 +86,12 @@ struct btmrvl_private {
 
 #define MRVL_VENDOR_PKT                        0xFE
 
-/* Bluetooth commands  */
-#define BT_CMD_AUTO_SLEEP_MODE         0x23
-#define BT_CMD_HOST_SLEEP_CONFIG       0x59
-#define BT_CMD_HOST_SLEEP_ENABLE       0x5A
-#define BT_CMD_MODULE_CFG_REQ          0x5B
-#define BT_CMD_LOAD_CONFIG_DATA                0x61
+/* Vendor specific Bluetooth commands */
+#define BT_CMD_AUTO_SLEEP_MODE         0xFC23
+#define BT_CMD_HOST_SLEEP_CONFIG       0xFC59
+#define BT_CMD_HOST_SLEEP_ENABLE       0xFC5A
+#define BT_CMD_MODULE_CFG_REQ          0xFC5B
+#define BT_CMD_LOAD_CONFIG_DATA                0xFC61
 
 /* Sub-commands: Module Bringup/Shutdown Request/Response */
 #define MODULE_BRINGUP_REQ             0xF1
@@ -104,6 +100,11 @@ struct btmrvl_private {
 
 #define MODULE_SHUTDOWN_REQ            0xF2
 
+/* Vendor specific Bluetooth events */
+#define BT_EVENT_AUTO_SLEEP_MODE       0x23
+#define BT_EVENT_HOST_SLEEP_CONFIG     0x59
+#define BT_EVENT_HOST_SLEEP_ENABLE     0x5A
+#define BT_EVENT_MODULE_CFG_REQ                0x5B
 #define BT_EVENT_POWER_STATE           0x20
 
 /* Bluetooth Power States */
@@ -111,8 +112,6 @@ struct btmrvl_private {
 #define BT_PS_DISABLE                  0x03
 #define BT_PS_SLEEP                    0x01
 
-#define OGF                            0x3F
-
 /* Host Sleep states */
 #define HS_ACTIVATED                   0x01
 #define HS_DEACTIVATED                 0x00
@@ -121,7 +120,7 @@ struct btmrvl_private {
 #define PS_SLEEP                       0x01
 #define PS_AWAKE                       0x00
 
-#define BT_CMD_DATA_SIZE               32
+#define BT_CAL_HDR_LEN                 4
 #define BT_CAL_DATA_SIZE               28
 
 struct btmrvl_event {
index 5cf31c4fe6d1cf552c9846c8fe7a79857851c9b6..1e0320af00c63be9a1fdd808e8c0301dedf7ad0a 100644 (file)
@@ -19,7 +19,7 @@
  **/
 
 #include <linux/module.h>
-
+#include <linux/of.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
@@ -50,12 +50,10 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
 
        if (hdr->evt == HCI_EV_CMD_COMPLETE) {
                struct hci_ev_cmd_complete *ec;
-               u16 opcode, ocf, ogf;
+               u16 opcode;
 
                ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
                opcode = __le16_to_cpu(ec->opcode);
-               ocf = hci_opcode_ocf(opcode);
-               ogf = hci_opcode_ogf(opcode);
 
                if (priv->btmrvl_dev.sendcmdflag) {
                        priv->btmrvl_dev.sendcmdflag = false;
@@ -63,9 +61,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
                        wake_up_interruptible(&priv->adapter->cmd_wait_q);
                }
 
-               if (ogf == OGF) {
-                       BT_DBG("vendor event skipped: ogf 0x%4.4x ocf 0x%4.4x",
-                              ogf, ocf);
+               if (hci_opcode_ogf(opcode) == 0x3F) {
+                       BT_DBG("vendor event skipped: opcode=%#4.4x", opcode);
                        kfree_skb(skb);
                        return false;
                }
@@ -89,7 +86,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
        }
 
        switch (event->data[0]) {
-       case BT_CMD_AUTO_SLEEP_MODE:
+       case BT_EVENT_AUTO_SLEEP_MODE:
                if (!event->data[2]) {
                        if (event->data[1] == BT_PS_ENABLE)
                                adapter->psmode = 1;
@@ -102,7 +99,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
                }
                break;
 
-       case BT_CMD_HOST_SLEEP_CONFIG:
+       case BT_EVENT_HOST_SLEEP_CONFIG:
                if (!event->data[3])
                        BT_DBG("gpio=%x, gap=%x", event->data[1],
                                                        event->data[2]);
@@ -110,7 +107,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
                        BT_DBG("HSCFG command failed");
                break;
 
-       case BT_CMD_HOST_SLEEP_ENABLE:
+       case BT_EVENT_HOST_SLEEP_ENABLE:
                if (!event->data[1]) {
                        adapter->hs_state = HS_ACTIVATED;
                        if (adapter->psmode)
@@ -121,7 +118,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
                }
                break;
 
-       case BT_CMD_MODULE_CFG_REQ:
+       case BT_EVENT_MODULE_CFG_REQ:
                if (priv->btmrvl_dev.sendcmdflag &&
                                event->data[1] == MODULE_BRINGUP_REQ) {
                        BT_DBG("EVENT:%s",
@@ -166,7 +163,7 @@ exit:
 }
 EXPORT_SYMBOL_GPL(btmrvl_process_event);
 
-static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
+static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
                                const void *param, u8 len)
 {
        struct sk_buff *skb;
@@ -179,7 +176,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
        }
 
        hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE);
-       hdr->opcode = cpu_to_le16(hci_opcode_pack(OGF, cmd_no));
+       hdr->opcode = cpu_to_le16(opcode);
        hdr->plen = len;
 
        if (len)
@@ -417,127 +414,62 @@ static int btmrvl_open(struct hci_dev *hdev)
        return 0;
 }
 
-/*
- * This function parses provided calibration data input. It should contain
- * hex bytes separated by space or new line character. Here is an example.
- * 00 1C 01 37 FF FF FF FF 02 04 7F 01
- * CE BA 00 00 00 2D C6 C0 00 00 00 00
- * 00 F0 00 00
- */
-static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size)
+static int btmrvl_download_cal_data(struct btmrvl_private *priv,
+                                   u8 *data, int len)
 {
-       const u8 *s = src;
-       u8 *d = dst;
        int ret;
-       u8 tmp[3];
-
-       tmp[2] = '\0';
-       while ((s - src) <= len - 2) {
-               if (isspace(*s)) {
-                       s++;
-                       continue;
-               }
-
-               if (isxdigit(*s)) {
-                       if ((d - dst) >= dst_size) {
-                               BT_ERR("calibration data file too big!!!");
-                               return -EINVAL;
-                       }
-
-                       memcpy(tmp, s, 2);
-
-                       ret = kstrtou8(tmp, 16, d++);
-                       if (ret < 0)
-                               return ret;
-
-                       s += 2;
-               } else {
-                       return -EINVAL;
-               }
-       }
-       if (d == dst)
-               return -EINVAL;
-
-       return 0;
-}
-
-static int btmrvl_load_cal_data(struct btmrvl_private *priv,
-                               u8 *config_data)
-{
-       int i, ret;
-       u8 data[BT_CMD_DATA_SIZE];
 
        data[0] = 0x00;
        data[1] = 0x00;
        data[2] = 0x00;
-       data[3] = BT_CMD_DATA_SIZE - 4;
-
-       /* Swap cal-data bytes. Each four bytes are swapped. Considering 4
-        * byte SDIO header offset, mapping of input and output bytes will be
-        * {3, 2, 1, 0} -> {0+4, 1+4, 2+4, 3+4},
-        * {7, 6, 5, 4} -> {4+4, 5+4, 6+4, 7+4} */
-       for (i = 4; i < BT_CMD_DATA_SIZE; i++)
-               data[i] = config_data[(i / 4) * 8 - 1 - i];
+       data[3] = len;
 
        print_hex_dump_bytes("Calibration data: ",
-                            DUMP_PREFIX_OFFSET, data, BT_CMD_DATA_SIZE);
+                            DUMP_PREFIX_OFFSET, data, BT_CAL_HDR_LEN + len);
 
        ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data,
-                                  BT_CMD_DATA_SIZE);
+                                  BT_CAL_HDR_LEN + len);
        if (ret)
                BT_ERR("Failed to download caibration data\n");
 
        return 0;
 }
 
-static int
-btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size)
+static int btmrvl_cal_data_dt(struct btmrvl_private *priv)
 {
-       u8 cal_data[BT_CAL_DATA_SIZE];
+       struct device_node *dt_node;
+       u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
+       const char name[] = "btmrvl_caldata";
+       const char property[] = "btmrvl,caldata";
        int ret;
 
-       ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data));
+       dt_node = of_find_node_by_name(NULL, name);
+       if (!dt_node)
+               return -ENODEV;
+
+       ret = of_property_read_u8_array(dt_node, property,
+                                       cal_data + BT_CAL_HDR_LEN,
+                                       BT_CAL_DATA_SIZE);
        if (ret)
                return ret;
 
-       ret = btmrvl_load_cal_data(priv, cal_data);
+       BT_DBG("Use cal data from device tree");
+       ret = btmrvl_download_cal_data(priv, cal_data, BT_CAL_DATA_SIZE);
        if (ret) {
-               BT_ERR("Fail to load calibrate data");
+               BT_ERR("Fail to download calibrate data");
                return ret;
        }
 
        return 0;
 }
 
-static int btmrvl_cal_data_config(struct btmrvl_private *priv)
-{
-       const struct firmware *cfg;
-       int ret;
-       const char *cal_data = priv->btmrvl_dev.cal_data;
-
-       if (!cal_data)
-               return 0;
-
-       ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev);
-       if (ret < 0) {
-               BT_DBG("Failed to get %s file, skipping cal data download",
-                      cal_data);
-               return 0;
-       }
-
-       ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size);
-       release_firmware(cfg);
-       return ret;
-}
-
 static int btmrvl_setup(struct hci_dev *hdev)
 {
        struct btmrvl_private *priv = hci_get_drvdata(hdev);
 
        btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
 
-       if (btmrvl_cal_data_config(priv))
-               BT_ERR("Set cal data failed");
+       btmrvl_cal_data_dt(priv);
 
        priv->btmrvl_dev.psmode = 1;
        btmrvl_enable_ps(priv);
index fabcf5bb48afbb1c62cf5145d5a12f60eb3a05a8..1b52c9f5230d324d0476a2d7dd3f308e7fd723d8 100644 (file)
@@ -18,6 +18,7 @@
  * this warranty disclaimer.
  **/
 
+#include <linux/firmware.h>
 #include <linux/slab.h>
 
 #include <linux/mmc/sdio_ids.h>
@@ -101,7 +102,6 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
        .helper         = "mrvl/sd8688_helper.bin",
        .firmware       = "mrvl/sd8688.bin",
-       .cal_data       = NULL,
        .reg            = &btmrvl_reg_8688,
        .sd_blksz_fw_dl = 64,
 };
@@ -109,7 +109,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
        .helper         = NULL,
        .firmware       = "mrvl/sd8787_uapsta.bin",
-       .cal_data       = NULL,
        .reg            = &btmrvl_reg_87xx,
        .sd_blksz_fw_dl = 256,
 };
@@ -117,7 +116,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
        .helper         = NULL,
        .firmware       = "mrvl/sd8797_uapsta.bin",
-       .cal_data       = "mrvl/sd8797_caldata.conf",
        .reg            = &btmrvl_reg_87xx,
        .sd_blksz_fw_dl = 256,
 };
@@ -125,7 +123,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
        .helper         = NULL,
        .firmware       = "mrvl/sd8897_uapsta.bin",
-       .cal_data       = NULL,
        .reg            = &btmrvl_reg_88xx,
        .sd_blksz_fw_dl = 256,
 };
@@ -1007,7 +1004,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
                struct btmrvl_sdio_device *data = (void *) id->driver_data;
                card->helper = data->helper;
                card->firmware = data->firmware;
-               card->cal_data = data->cal_data;
                card->reg = data->reg;
                card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
        }
@@ -1036,8 +1032,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
        }
 
        card->priv = priv;
-       priv->btmrvl_dev.dev = &card->func->dev;
-       priv->btmrvl_dev.cal_data = card->cal_data;
 
        /* Initialize the interface specific function pointers */
        priv->hw_host_to_card = btmrvl_sdio_host_to_card;
@@ -1220,5 +1214,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
 MODULE_FIRMWARE("mrvl/sd8688.bin");
 MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
 MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
-MODULE_FIRMWARE("mrvl/sd8797_caldata.conf");
 MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
index 6872d9ecac074ba04792c22776b3baee3971c9de..43d35a609ca9a94795afb731d230fa88ca109bef 100644 (file)
@@ -85,7 +85,6 @@ struct btmrvl_sdio_card {
        u32 ioport;
        const char *helper;
        const char *firmware;
-       const char *cal_data;
        const struct btmrvl_sdio_card_reg *reg;
        u16 sd_blksz_fw_dl;
        u8 rx_unit;
@@ -95,7 +94,6 @@ struct btmrvl_sdio_card {
 struct btmrvl_sdio_device {
        const char *helper;
        const char *firmware;
-       const char *cal_data;
        const struct btmrvl_sdio_card_reg *reg;
        u16 sd_blksz_fw_dl;
 };
index c0ff34f2d2df577efffe902562f9578690ea4e39..bfbcc5a772a61ecb1619d6bbb988eb22bb9f0fef 100644 (file)
@@ -150,6 +150,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
@@ -163,6 +164,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -223,6 +225,7 @@ static const struct usb_device_id blacklist_table[] = {
 
        /* Intel Bluetooth device */
        { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
+       { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
 
        { }     /* Terminating entry */
 };
@@ -1435,8 +1438,10 @@ static int btusb_probe(struct usb_interface *intf,
        if (id->driver_info & BTUSB_BCM92035)
                hdev->setup = btusb_setup_bcm92035;
 
-       if (id->driver_info & BTUSB_INTEL)
+       if (id->driver_info & BTUSB_INTEL) {
+               usb_enable_autosuspend(data->udev);
                hdev->setup = btusb_setup_intel;
+       }
 
        /* Interface numbers are hardcoded in the specification */
        data->isoc = usb_ifnum_to_if(data->udev, 1);
index 2394e9753ef56b47e93d91bd7499eeb657c51383..725c46162bbd1cb0ad05624502ad16030e5991ca 100644 (file)
@@ -588,12 +588,6 @@ static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = {
        .show_cpu_target     = mvebu_sdram_debug_show_orion,
 };
 
-/*
- * The driver doesn't yet have a DT binding because the details of
- * this DT binding still need to be sorted out. However, as a
- * preparation, we already use of_device_id to match a SoC description
- * string against the SoC specific details of this driver.
- */
 static const struct of_device_id of_mvebu_mbus_ids[] = {
        { .compatible = "marvell,armada370-mbus",
          .data = &armada_370_xp_mbus_data, },
@@ -734,11 +728,11 @@ int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
 {
        const struct of_device_id *of_id;
 
-       for (of_id = of_mvebu_mbus_ids; of_id->compatible; of_id++)
+       for (of_id = of_mvebu_mbus_ids; of_id->compatible[0]; of_id++)
                if (!strcmp(of_id->compatible, soc))
                        break;
 
-       if (!of_id->compatible) {
+       if (!of_id->compatible[0]) {
                pr_err("could not find a matching SoC family\n");
                return -ENODEV;
        }
index 7ff1d0d208a7c3f89f6827fd3e9ba8815dad202d..2d68054f97954402095051600529754b0f4b3e56 100644 (file)
@@ -50,7 +50,7 @@ obj-$(CONFIG_GPIO_TB0219)     += tb0219.o
 obj-$(CONFIG_TELCLOCK)         += tlclk.o
 
 obj-$(CONFIG_MWAVE)            += mwave/
-obj-$(CONFIG_AGP)              += agp/
+obj-y                          += agp/
 obj-$(CONFIG_PCMCIA)           += pcmcia/
 
 obj-$(CONFIG_HANGCHECK_TIMER)  += hangcheck-timer.o
index d8b1b576556cf8eba8c2fa398c6c9bc8d6960803..c528f96ee204fb3f480e29d96992e1e0c1870272 100644 (file)
@@ -68,6 +68,7 @@ config AGP_AMD64
 config AGP_INTEL
        tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support"
        depends on AGP && X86
+       select INTEL_GTT
        help
          This option gives you AGP support for the GLX component of X
          on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875,
@@ -155,3 +156,7 @@ config AGP_SGI_TIOCA
           This option gives you AGP GART support for the SGI TIO chipset
           for IA64 processors.
 
+config INTEL_GTT
+       tristate
+       depends on X86 && PCI
+
index 8eb56e273e75719f51d617fe3a2ed5c4b9cc06f2..604489bcdbf9b6c70b51e89f093accfdb34f4d25 100644 (file)
@@ -13,7 +13,7 @@ obj-$(CONFIG_AGP_HP_ZX1)      += hp-agp.o
 obj-$(CONFIG_AGP_PARISC)       += parisc-agp.o
 obj-$(CONFIG_AGP_I460)         += i460-agp.o
 obj-$(CONFIG_AGP_INTEL)                += intel-agp.o
-obj-$(CONFIG_AGP_INTEL)                += intel-gtt.o
+obj-$(CONFIG_INTEL_GTT)                += intel-gtt.o
 obj-$(CONFIG_AGP_NVIDIA)       += nvidia-agp.o
 obj-$(CONFIG_AGP_SGI_TIOCA)    += sgi-agp.o
 obj-$(CONFIG_AGP_SIS)          += sis-agp.o
index a426ee1f57a6fd71b30fbd80429cac7c97aa1b4c..9ef0a48a5b28196600a780e4f76ec33ab4120c5e 100644 (file)
@@ -14,9 +14,6 @@
 #include "intel-agp.h"
 #include <drm/intel-gtt.h>
 
-int intel_agp_enabled;
-EXPORT_SYMBOL(intel_agp_enabled);
-
 static int intel_fetch_size(void)
 {
        int i;
@@ -814,8 +811,6 @@ static int agp_intel_probe(struct pci_dev *pdev,
 found_gmch:
        pci_set_drvdata(pdev, bridge);
        err = agp_add_bridge(bridge);
-       if (!err)
-               intel_agp_enabled = 1;
        return err;
 }
 
index b8e2014cb9cb0681d8fa1a21d7930b13e1e2a261..078968d8d07d933b974c8183b6cbd1f9a7163011 100644 (file)
@@ -94,6 +94,7 @@ static struct _intel_private {
 #define IS_IRONLAKE    intel_private.driver->is_ironlake
 #define HAS_PGTBL_EN   intel_private.driver->has_pgtbl_enable
 
+#if IS_ENABLED(CONFIG_AGP_INTEL)
 static int intel_gtt_map_memory(struct page **pages,
                                unsigned int num_entries,
                                struct sg_table *st)
@@ -168,6 +169,7 @@ static void i8xx_destroy_pages(struct page *page)
        __free_pages(page, 2);
        atomic_dec(&agp_bridge->current_memory_agp);
 }
+#endif
 
 #define I810_GTT_ORDER 4
 static int i810_setup(void)
@@ -209,6 +211,7 @@ static void i810_cleanup(void)
        free_gatt_pages(intel_private.i81x_gtt_table, I810_GTT_ORDER);
 }
 
+#if IS_ENABLED(CONFIG_AGP_INTEL)
 static int i810_insert_dcache_entries(struct agp_memory *mem, off_t pg_start,
                                      int type)
 {
@@ -289,6 +292,7 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
        }
        kfree(curr);
 }
+#endif
 
 static int intel_gtt_setup_scratch_page(void)
 {
@@ -647,7 +651,9 @@ static int intel_gtt_init(void)
                return -ENOMEM;
        }
 
+#if IS_ENABLED(CONFIG_AGP_INTEL)
        global_cache_flush();   /* FIXME: ? */
+#endif
 
        intel_private.stolen_size = intel_gtt_stolen_size();
 
@@ -671,6 +677,7 @@ static int intel_gtt_init(void)
        return 0;
 }
 
+#if IS_ENABLED(CONFIG_AGP_INTEL)
 static int intel_fake_agp_fetch_size(void)
 {
        int num_sizes = ARRAY_SIZE(intel_fake_agp_sizes);
@@ -689,6 +696,7 @@ static int intel_fake_agp_fetch_size(void)
 
        return 0;
 }
+#endif
 
 static void i830_cleanup(void)
 {
@@ -801,6 +809,7 @@ static int i830_setup(void)
        return 0;
 }
 
+#if IS_ENABLED(CONFIG_AGP_INTEL)
 static int intel_fake_agp_create_gatt_table(struct agp_bridge_data *bridge)
 {
        agp_bridge->gatt_table_real = NULL;
@@ -825,6 +834,7 @@ static int intel_fake_agp_configure(void)
 
        return 0;
 }
+#endif
 
 static bool i830_check_flags(unsigned int flags)
 {
@@ -863,6 +873,7 @@ void intel_gtt_insert_sg_entries(struct sg_table *st,
 }
 EXPORT_SYMBOL(intel_gtt_insert_sg_entries);
 
+#if IS_ENABLED(CONFIG_AGP_INTEL)
 static void intel_gtt_insert_pages(unsigned int first_entry,
                                   unsigned int num_entries,
                                   struct page **pages,
@@ -928,6 +939,7 @@ out_err:
        mem->is_flushed = true;
        return ret;
 }
+#endif
 
 void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
 {
@@ -941,6 +953,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
 }
 EXPORT_SYMBOL(intel_gtt_clear_range);
 
+#if IS_ENABLED(CONFIG_AGP_INTEL)
 static int intel_fake_agp_remove_entries(struct agp_memory *mem,
                                         off_t pg_start, int type)
 {
@@ -982,6 +995,7 @@ static struct agp_memory *intel_fake_agp_alloc_by_type(size_t pg_count,
        /* always return NULL for other allocation types for now */
        return NULL;
 }
+#endif
 
 static int intel_alloc_chipset_flush_resource(void)
 {
@@ -1138,6 +1152,7 @@ static int i9xx_setup(void)
        return 0;
 }
 
+#if IS_ENABLED(CONFIG_AGP_INTEL)
 static const struct agp_bridge_driver intel_fake_agp_driver = {
        .owner                  = THIS_MODULE,
        .size_type              = FIXED_APER_SIZE,
@@ -1159,6 +1174,7 @@ static const struct agp_bridge_driver intel_fake_agp_driver = {
        .agp_destroy_page       = agp_generic_destroy_page,
        .agp_destroy_pages      = agp_generic_destroy_pages,
 };
+#endif
 
 static const struct intel_gtt_driver i81x_gtt_driver = {
        .gen = 1,
@@ -1376,11 +1392,13 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
 
        intel_private.refcount++;
 
+#if IS_ENABLED(CONFIG_AGP_INTEL)
        if (bridge) {
                bridge->driver = &intel_fake_agp_driver;
                bridge->dev_private_data = &intel_private;
                bridge->dev = bridge_pdev;
        }
+#endif
 
        intel_private.bridge_dev = pci_dev_get(bridge_pdev);
 
index 5d9c31dfc905eac973f167d4f77d1c8b628de0b0..d5d4cd82b9f7dac435af267806ff541777f3ebdb 100644 (file)
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/io.h>
-
+#include <linux/acpi.h>
+#include <linux/hpet.h>
 #include <asm/current.h>
 #include <asm/irq.h>
 #include <asm/div64.h>
 
-#include <linux/acpi.h>
-#include <acpi/acpi_bus.h>
-#include <linux/hpet.h>
-
 /*
  * The High Precision Event Timer driver.
  * This driver is closely modelled after the rtc.c driver.
index c206de2951f20f086c099ab69e8a1a48286465be..2f2b08457c673547568187f04863a01947163385 100644 (file)
@@ -165,6 +165,19 @@ config HW_RANDOM_OMAP
 
          If unsure, say Y.
 
+config HW_RANDOM_OMAP3_ROM
+       tristate "OMAP3 ROM Random Number Generator support"
+       depends on HW_RANDOM && ARCH_OMAP3
+       default HW_RANDOM
+       ---help---
+         This driver provides kernel-side support for the Random Number
+         Generator hardware found on OMAP34xx processors.
+
+         To compile this driver as a module, choose M here: the
+         module will be called omap3-rom-rng.
+
+         If unsure, say Y.
+
 config HW_RANDOM_OCTEON
        tristate "Octeon Random Number Generator support"
        depends on HW_RANDOM && CAVIUM_OCTEON_SOC
@@ -327,3 +340,15 @@ config HW_RANDOM_TPM
          module will be called tpm-rng.
 
          If unsure, say Y.
+
+config HW_RANDOM_MSM
+       tristate "Qualcomm MSM Random Number Generator support"
+       depends on HW_RANDOM && ARCH_MSM
+       ---help---
+         This driver provides kernel-side support for the Random Number
+         Generator hardware found on Qualcomm MSM SoCs.
+
+         To compile this driver as a module, choose M here. the
+         module will be called msm-rng.
+
+         If unsure, say Y.
index d7d2435ff7fa8d38cd129d327c59ded717e3682a..3ae7755a52e706bd8356e8ae5bc660fe8a693767 100644 (file)
@@ -15,6 +15,7 @@ n2-rng-y := n2-drv.o n2-asm.o
 obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
 obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
 obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
+obj-$(CONFIG_HW_RANDOM_OMAP3_ROM) += omap3-rom-rng.o
 obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
 obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
 obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
@@ -28,3 +29,4 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
 obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
 obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
 obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
+obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o
diff --git a/drivers/char/hw_random/msm-rng.c b/drivers/char/hw_random/msm-rng.c
new file mode 100644 (file)
index 0000000..148521e
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ *
+ */
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+/* Device specific register offsets */
+#define PRNG_DATA_OUT          0x0000
+#define PRNG_STATUS            0x0004
+#define PRNG_LFSR_CFG          0x0100
+#define PRNG_CONFIG            0x0104
+
+/* Device specific register masks and config values */
+#define PRNG_LFSR_CFG_MASK     0x0000ffff
+#define PRNG_LFSR_CFG_CLOCKS   0x0000dddd
+#define PRNG_CONFIG_HW_ENABLE  BIT(1)
+#define PRNG_STATUS_DATA_AVAIL BIT(0)
+
+#define MAX_HW_FIFO_DEPTH      16
+#define MAX_HW_FIFO_SIZE       (MAX_HW_FIFO_DEPTH * 4)
+#define WORD_SZ                        4
+
+struct msm_rng {
+       void __iomem *base;
+       struct clk *clk;
+       struct hwrng hwrng;
+};
+
+#define to_msm_rng(p)  container_of(p, struct msm_rng, hwrng)
+
+static int msm_rng_enable(struct hwrng *hwrng, int enable)
+{
+       struct msm_rng *rng = to_msm_rng(hwrng);
+       u32 val;
+       int ret;
+
+       ret = clk_prepare_enable(rng->clk);
+       if (ret)
+               return ret;
+
+       if (enable) {
+               /* Enable PRNG only if it is not already enabled */
+               val = readl_relaxed(rng->base + PRNG_CONFIG);
+               if (val & PRNG_CONFIG_HW_ENABLE)
+                       goto already_enabled;
+
+               val = readl_relaxed(rng->base + PRNG_LFSR_CFG);
+               val &= ~PRNG_LFSR_CFG_MASK;
+               val |= PRNG_LFSR_CFG_CLOCKS;
+               writel(val, rng->base + PRNG_LFSR_CFG);
+
+               val = readl_relaxed(rng->base + PRNG_CONFIG);
+               val |= PRNG_CONFIG_HW_ENABLE;
+               writel(val, rng->base + PRNG_CONFIG);
+       } else {
+               val = readl_relaxed(rng->base + PRNG_CONFIG);
+               val &= ~PRNG_CONFIG_HW_ENABLE;
+               writel(val, rng->base + PRNG_CONFIG);
+       }
+
+already_enabled:
+       clk_disable_unprepare(rng->clk);
+       return 0;
+}
+
+static int msm_rng_read(struct hwrng *hwrng, void *data, size_t max, bool wait)
+{
+       struct msm_rng *rng = to_msm_rng(hwrng);
+       size_t currsize = 0;
+       u32 *retdata = data;
+       size_t maxsize;
+       int ret;
+       u32 val;
+
+       /* calculate max size bytes to transfer back to caller */
+       maxsize = min_t(size_t, MAX_HW_FIFO_SIZE, max);
+
+       /* no room for word data */
+       if (maxsize < WORD_SZ)
+               return 0;
+
+       ret = clk_prepare_enable(rng->clk);
+       if (ret)
+               return ret;
+
+       /* read random data from hardware */
+       do {
+               val = readl_relaxed(rng->base + PRNG_STATUS);
+               if (!(val & PRNG_STATUS_DATA_AVAIL))
+                       break;
+
+               val = readl_relaxed(rng->base + PRNG_DATA_OUT);
+               if (!val)
+                       break;
+
+               *retdata++ = val;
+               currsize += WORD_SZ;
+
+               /* make sure we stay on 32bit boundary */
+               if ((maxsize - currsize) < WORD_SZ)
+                       break;
+       } while (currsize < maxsize);
+
+       clk_disable_unprepare(rng->clk);
+
+       return currsize;
+}
+
+static int msm_rng_init(struct hwrng *hwrng)
+{
+       return msm_rng_enable(hwrng, 1);
+}
+
+static void msm_rng_cleanup(struct hwrng *hwrng)
+{
+       msm_rng_enable(hwrng, 0);
+}
+
+static int msm_rng_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       struct msm_rng *rng;
+       int ret;
+
+       rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+       if (!rng)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, rng);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rng->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(rng->base))
+               return PTR_ERR(rng->base);
+
+       rng->clk = devm_clk_get(&pdev->dev, "core");
+       if (IS_ERR(rng->clk))
+               return PTR_ERR(rng->clk);
+
+       rng->hwrng.name = KBUILD_MODNAME,
+       rng->hwrng.init = msm_rng_init,
+       rng->hwrng.cleanup = msm_rng_cleanup,
+       rng->hwrng.read = msm_rng_read,
+
+       ret = hwrng_register(&rng->hwrng);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register hwrng\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int msm_rng_remove(struct platform_device *pdev)
+{
+       struct msm_rng *rng = platform_get_drvdata(pdev);
+
+       hwrng_unregister(&rng->hwrng);
+       return 0;
+}
+
+static const struct of_device_id msm_rng_of_match[] = {
+       { .compatible = "qcom,prng", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, msm_rng_of_match);
+
+static struct platform_driver msm_rng_driver = {
+       .probe = msm_rng_probe,
+       .remove = msm_rng_remove,
+       .driver = {
+               .name = KBUILD_MODNAME,
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(msm_rng_of_match),
+       }
+};
+module_platform_driver(msm_rng_driver);
+
+MODULE_ALIAS("platform:" KBUILD_MODNAME);
+MODULE_AUTHOR("The Linux Foundation");
+MODULE_DESCRIPTION("Qualcomm MSM random number generator driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c
new file mode 100644 (file)
index 0000000..c853e9e
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * omap3-rom-rng.c - RNG driver for TI OMAP3 CPU family
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Juha Yrjola <juha.yrjola@solidboot.com>
+ *
+ * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <linux/hw_random.h>
+#include <linux/timer.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#define RNG_RESET                      0x01
+#define RNG_GEN_PRNG_HW_INIT           0x02
+#define RNG_GEN_HW                     0x08
+
+/* param1: ptr, param2: count, param3: flag */
+static u32 (*omap3_rom_rng_call)(u32, u32, u32);
+
+static struct timer_list idle_timer;
+static int rng_idle;
+static struct clk *rng_clk;
+
+static void omap3_rom_rng_idle(unsigned long data)
+{
+       int r;
+
+       r = omap3_rom_rng_call(0, 0, RNG_RESET);
+       if (r != 0) {
+               pr_err("reset failed: %d\n", r);
+               return;
+       }
+       clk_disable_unprepare(rng_clk);
+       rng_idle = 1;
+}
+
+static int omap3_rom_rng_get_random(void *buf, unsigned int count)
+{
+       u32 r;
+       u32 ptr;
+
+       del_timer_sync(&idle_timer);
+       if (rng_idle) {
+               clk_prepare_enable(rng_clk);
+               r = omap3_rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT);
+               if (r != 0) {
+                       clk_disable_unprepare(rng_clk);
+                       pr_err("HW init failed: %d\n", r);
+                       return -EIO;
+               }
+               rng_idle = 0;
+       }
+
+       ptr = virt_to_phys(buf);
+       r = omap3_rom_rng_call(ptr, count, RNG_GEN_HW);
+       mod_timer(&idle_timer, jiffies + msecs_to_jiffies(500));
+       if (r != 0)
+               return -EINVAL;
+       return 0;
+}
+
+static int omap3_rom_rng_data_present(struct hwrng *rng, int wait)
+{
+       return 1;
+}
+
+static int omap3_rom_rng_data_read(struct hwrng *rng, u32 *data)
+{
+       int r;
+
+       r = omap3_rom_rng_get_random(data, 4);
+       if (r < 0)
+               return r;
+       return 4;
+}
+
+static struct hwrng omap3_rom_rng_ops = {
+       .name           = "omap3-rom",
+       .data_present   = omap3_rom_rng_data_present,
+       .data_read      = omap3_rom_rng_data_read,
+};
+
+static int omap3_rom_rng_probe(struct platform_device *pdev)
+{
+       pr_info("initializing\n");
+
+       omap3_rom_rng_call = pdev->dev.platform_data;
+       if (!omap3_rom_rng_call) {
+               pr_err("omap3_rom_rng_call is NULL\n");
+               return -EINVAL;
+       }
+
+       setup_timer(&idle_timer, omap3_rom_rng_idle, 0);
+       rng_clk = clk_get(&pdev->dev, "ick");
+       if (IS_ERR(rng_clk)) {
+               pr_err("unable to get RNG clock\n");
+               return PTR_ERR(rng_clk);
+       }
+
+       /* Leave the RNG in reset state. */
+       clk_prepare_enable(rng_clk);
+       omap3_rom_rng_idle(0);
+
+       return hwrng_register(&omap3_rom_rng_ops);
+}
+
+static int omap3_rom_rng_remove(struct platform_device *pdev)
+{
+       hwrng_unregister(&omap3_rom_rng_ops);
+       clk_disable_unprepare(rng_clk);
+       clk_put(rng_clk);
+       return 0;
+}
+
+static struct platform_driver omap3_rom_rng_driver = {
+       .driver = {
+               .name           = "omap3-rom-rng",
+               .owner          = THIS_MODULE,
+       },
+       .probe          = omap3_rom_rng_probe,
+       .remove         = omap3_rom_rng_remove,
+};
+
+module_platform_driver(omap3_rom_rng_driver);
+
+MODULE_ALIAS("platform:omap3-rom-rng");
+MODULE_AUTHOR("Juha Yrjola");
+MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
+MODULE_LICENSE("GPL");
index b761459a3436c25d31321f5bb46037f7faaf9292..ab7ffdec0ec3545a7ec6f940b32cff396d153183 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/hw_random.h>
 #include <asm/vio.h>
 
-#define MODULE_NAME "pseries-rng"
 
 static int pseries_rng_data_read(struct hwrng *rng, u32 *data)
 {
@@ -55,7 +54,7 @@ static unsigned long pseries_rng_get_desired_dma(struct vio_dev *vdev)
 };
 
 static struct hwrng pseries_rng = {
-       .name           = MODULE_NAME,
+       .name           = KBUILD_MODNAME,
        .data_read      = pseries_rng_data_read,
 };
 
@@ -78,7 +77,7 @@ static struct vio_device_id pseries_rng_driver_ids[] = {
 MODULE_DEVICE_TABLE(vio, pseries_rng_driver_ids);
 
 static struct vio_driver pseries_rng_driver = {
-       .name = MODULE_NAME,
+       .name = KBUILD_MODNAME,
        .probe = pseries_rng_probe,
        .remove = pseries_rng_remove,
        .get_desired_dma = pseries_rng_get_desired_dma,
index e737772ad69a8103312e596cd0e24ce00d759e22..de5a6dcfb3e242ec4aa5b6742c73c7700e32d551 100644 (file)
@@ -221,7 +221,7 @@ static void __exit mod_exit(void)
 module_init(mod_init);
 module_exit(mod_exit);
 
-static struct x86_cpu_id via_rng_cpu_id[] = {
+static struct x86_cpu_id __maybe_unused via_rng_cpu_id[] = {
        X86_FEATURE_MATCH(X86_FEATURE_XSTORE),
        {}
 };
index 64420b3396a294ccd56c2b6e727b1aaa0459a34b..b9a57fa4b710301d3844cf9ea9b659830b871d0f 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/security.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <acpi/acpi.h>
+#include <linux/acpi.h>
 
 #include "tpm.h"
 #include "tpm_eventlog.h"
index 8e562dc656016cd9c4dbeaaa3dac0a96a02d0f26..dd60ef336f8d8bf4fba5c6bb9ab473724d578a61 100644 (file)
@@ -1,5 +1,4 @@
 #include <linux/acpi.h>
-#include <acpi/acpi_drivers.h>
 #include "tpm.h"
 
 static const u8 tpm_ppi_uuid[] = {
index 0b0f3e729cf7ca5ec18c322a6322ab2001a55a70..c339b829d3e33fe60af81cbfb0317cecdb12add5 100644 (file)
@@ -4,15 +4,20 @@ config MVEBU_CLK_COMMON
 config MVEBU_CLK_CPU
        bool
 
+config MVEBU_CLK_COREDIV
+       bool
+
 config ARMADA_370_CLK
        bool
        select MVEBU_CLK_COMMON
        select MVEBU_CLK_CPU
+       select MVEBU_CLK_COREDIV
 
 config ARMADA_XP_CLK
        bool
        select MVEBU_CLK_COMMON
        select MVEBU_CLK_CPU
+       select MVEBU_CLK_COREDIV
 
 config DOVE_CLK
        bool
index 1c7e70c63fb26b80145b5e506015874b5da16b64..21bbfb4a9f42e9edcda25a0705ff1f9f701ac8bd 100644 (file)
@@ -1,5 +1,6 @@
 obj-$(CONFIG_MVEBU_CLK_COMMON) += common.o
 obj-$(CONFIG_MVEBU_CLK_CPU)    += clk-cpu.o
+obj-$(CONFIG_MVEBU_CLK_COREDIV)        += clk-corediv.o
 
 obj-$(CONFIG_ARMADA_370_CLK)   += armada-370.o
 obj-$(CONFIG_ARMADA_XP_CLK)    += armada-xp.o
diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c
new file mode 100644 (file)
index 0000000..7162615
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * MVEBU Core divider clock
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "common.h"
+
+#define CORE_CLK_DIV_RATIO_MASK                0xff
+#define CORE_CLK_DIV_RATIO_RELOAD      BIT(8)
+#define CORE_CLK_DIV_ENABLE_OFFSET     24
+#define CORE_CLK_DIV_RATIO_OFFSET      0x8
+
+struct clk_corediv_desc {
+       unsigned int mask;
+       unsigned int offset;
+       unsigned int fieldbit;
+};
+
+struct clk_corediv {
+       struct clk_hw hw;
+       void __iomem *reg;
+       struct clk_corediv_desc desc;
+       spinlock_t lock;
+};
+
+static struct clk_onecell_data clk_data;
+
+static const struct clk_corediv_desc mvebu_corediv_desc[] __initconst = {
+       { .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */
+};
+
+#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw)
+
+static int clk_corediv_is_enabled(struct clk_hw *hwclk)
+{
+       struct clk_corediv *corediv = to_corediv_clk(hwclk);
+       struct clk_corediv_desc *desc = &corediv->desc;
+       u32 enable_mask = BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET;
+
+       return !!(readl(corediv->reg) & enable_mask);
+}
+
+static int clk_corediv_enable(struct clk_hw *hwclk)
+{
+       struct clk_corediv *corediv = to_corediv_clk(hwclk);
+       struct clk_corediv_desc *desc = &corediv->desc;
+       unsigned long flags = 0;
+       u32 reg;
+
+       spin_lock_irqsave(&corediv->lock, flags);
+
+       reg = readl(corediv->reg);
+       reg |= (BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
+       writel(reg, corediv->reg);
+
+       spin_unlock_irqrestore(&corediv->lock, flags);
+
+       return 0;
+}
+
+static void clk_corediv_disable(struct clk_hw *hwclk)
+{
+       struct clk_corediv *corediv = to_corediv_clk(hwclk);
+       struct clk_corediv_desc *desc = &corediv->desc;
+       unsigned long flags = 0;
+       u32 reg;
+
+       spin_lock_irqsave(&corediv->lock, flags);
+
+       reg = readl(corediv->reg);
+       reg &= ~(BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
+       writel(reg, corediv->reg);
+
+       spin_unlock_irqrestore(&corediv->lock, flags);
+}
+
+static unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk,
+                                        unsigned long parent_rate)
+{
+       struct clk_corediv *corediv = to_corediv_clk(hwclk);
+       struct clk_corediv_desc *desc = &corediv->desc;
+       u32 reg, div;
+
+       reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+       div = (reg >> desc->offset) & desc->mask;
+       return parent_rate / div;
+}
+
+static long clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long rate,
+                              unsigned long *parent_rate)
+{
+       /* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */
+       u32 div;
+
+       div = *parent_rate / rate;
+       if (div < 4)
+               div = 4;
+       else if (div > 6)
+               div = 8;
+
+       return *parent_rate / div;
+}
+
+static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
+                           unsigned long parent_rate)
+{
+       struct clk_corediv *corediv = to_corediv_clk(hwclk);
+       struct clk_corediv_desc *desc = &corediv->desc;
+       unsigned long flags = 0;
+       u32 reg, div;
+
+       div = parent_rate / rate;
+
+       spin_lock_irqsave(&corediv->lock, flags);
+
+       /* Write new divider to the divider ratio register */
+       reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+       reg &= ~(desc->mask << desc->offset);
+       reg |= (div & desc->mask) << desc->offset;
+       writel(reg, corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+
+       /* Set reload-force for this clock */
+       reg = readl(corediv->reg) | BIT(desc->fieldbit);
+       writel(reg, corediv->reg);
+
+       /* Now trigger the clock update */
+       reg = readl(corediv->reg) | CORE_CLK_DIV_RATIO_RELOAD;
+       writel(reg, corediv->reg);
+
+       /*
+        * Wait for clocks to settle down, and then clear all the
+        * ratios request and the reload request.
+        */
+       udelay(1000);
+       reg &= ~(CORE_CLK_DIV_RATIO_MASK | CORE_CLK_DIV_RATIO_RELOAD);
+       writel(reg, corediv->reg);
+       udelay(1000);
+
+       spin_unlock_irqrestore(&corediv->lock, flags);
+
+       return 0;
+}
+
+static const struct clk_ops corediv_ops = {
+       .enable = clk_corediv_enable,
+       .disable = clk_corediv_disable,
+       .is_enabled = clk_corediv_is_enabled,
+       .recalc_rate = clk_corediv_recalc_rate,
+       .round_rate = clk_corediv_round_rate,
+       .set_rate = clk_corediv_set_rate,
+};
+
+static void __init mvebu_corediv_clk_init(struct device_node *node)
+{
+       struct clk_init_data init;
+       struct clk_corediv *corediv;
+       struct clk **clks;
+       void __iomem *base;
+       const char *parent_name;
+       const char *clk_name;
+       int i;
+
+       base = of_iomap(node, 0);
+       if (WARN_ON(!base))
+               return;
+
+       parent_name = of_clk_get_parent_name(node, 0);
+
+       clk_data.clk_num = ARRAY_SIZE(mvebu_corediv_desc);
+
+       /* clks holds the clock array */
+       clks = kcalloc(clk_data.clk_num, sizeof(struct clk *),
+                               GFP_KERNEL);
+       if (WARN_ON(!clks))
+               goto err_unmap;
+       /* corediv holds the clock specific array */
+       corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),
+                               GFP_KERNEL);
+       if (WARN_ON(!corediv))
+               goto err_free_clks;
+
+       spin_lock_init(&corediv->lock);
+
+       for (i = 0; i < clk_data.clk_num; i++) {
+               of_property_read_string_index(node, "clock-output-names",
+                                             i, &clk_name);
+               init.num_parents = 1;
+               init.parent_names = &parent_name;
+               init.name = clk_name;
+               init.ops = &corediv_ops;
+               init.flags = 0;
+
+               corediv[i].desc = mvebu_corediv_desc[i];
+               corediv[i].reg = base;
+               corediv[i].hw.init = &init;
+
+               clks[i] = clk_register(NULL, &corediv[i].hw);
+               WARN_ON(IS_ERR(clks[i]));
+       }
+
+       clk_data.clks = clks;
+       of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
+       return;
+
+err_free_clks:
+       kfree(clks);
+err_unmap:
+       iounmap(base);
+}
+CLK_OF_DECLARE(mvebu_corediv_clk, "marvell,armada-370-corediv-clock",
+              mvebu_corediv_clk_init);
index 1466865b0743bf2110b74a6832acbef832743b77..8ebf757d29e2d0885791442bfbac5efd586db22b 100644 (file)
@@ -101,7 +101,7 @@ static const struct clk_ops cpu_ops = {
        .set_rate = clk_cpu_set_rate,
 };
 
-void __init of_cpu_clk_setup(struct device_node *node)
+static void __init of_cpu_clk_setup(struct device_node *node)
 {
        struct cpu_clk *cpuclk;
        void __iomem *clock_complex_base = of_iomap(node, 0);
index bdb953e15d2a88d201c3997ca86e80f15a00e5cf..5c07a56962dbcffc038b81eb09305e61ee1d83e6 100644 (file)
@@ -87,6 +87,7 @@ config ARM_ARCH_TIMER
 config ARM_ARCH_TIMER_EVTSTREAM
        bool "Support for ARM architected timer event stream generation"
        default y if ARM_ARCH_TIMER
+       depends on ARM_ARCH_TIMER
        help
          This option enables support for event stream generation based on
          the ARM architected timer. It is used for waking up CPUs executing
index 4aac9ee0d0c054a7ba953b17ac3272946af7b47d..3cf12834681e8335fa7f49dd032eb3cb57ad128a 100644 (file)
@@ -313,8 +313,20 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev)
                goto err1;
        }
 
-       return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev),
-                               cfg->clockevent_rating);
+       ret = clk_prepare(p->clk);
+       if (ret < 0)
+               goto err2;
+
+       ret = sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev),
+                              cfg->clockevent_rating);
+       if (ret < 0)
+               goto err3;
+
+       return 0;
+ err3:
+       clk_unprepare(p->clk);
+ err2:
+       clk_put(p->clk);
  err1:
        iounmap(p->mapbase);
  err0:
index 78b8dae49628cce42fb45ebdff2b32ece5045a52..63557cda0a7d599e352c402f2db23b348481e365 100644 (file)
@@ -472,12 +472,26 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
                ret = PTR_ERR(p->clk);
                goto err1;
        }
+
+       ret = clk_prepare(p->clk);
+       if (ret < 0)
+               goto err2;
+
        p->cs_enabled = false;
        p->enable_count = 0;
 
-       return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev),
-                              cfg->clockevent_rating,
-                              cfg->clocksource_rating);
+       ret = sh_tmu_register(p, (char *)dev_name(&p->pdev->dev),
+                             cfg->clockevent_rating,
+                             cfg->clocksource_rating);
+       if (ret < 0)
+               goto err3;
+
+       return 0;
+
+ err3:
+       clk_unprepare(p->clk);
+ err2:
+       clk_put(p->clk);
  err1:
        iounmap(p->mapbase);
  err0:
index d4585ce2346cf187a0c5511fafdd7ac08204f1bb..0faf756f6197d216fbb8ddf6d276fdf7f86d3b7f 100644 (file)
@@ -44,7 +44,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
        int ret;
 
        freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
-       if (freq_Hz < 0)
+       if (freq_Hz <= 0)
                freq_Hz = freq_table[index].frequency * 1000;
 
        freq_exact = freq_Hz;
index 02d534da22dda0bb22277c4f80f7c1d27f24cd65..606224a8abc2db9bf7486c5382b7f7bc7c488c53 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/suspend.h>
 #include <linux/syscore_ops.h>
 #include <linux/tick.h>
 #include <trace/events/power.h>
@@ -47,6 +48,9 @@ static LIST_HEAD(cpufreq_policy_list);
 static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
 #endif
 
+/* Flag to suspend/resume CPUFreq governors */
+static bool cpufreq_suspended;
+
 static inline bool has_target(void)
 {
        return cpufreq_driver->target_index || cpufreq_driver->target;
@@ -1462,6 +1466,41 @@ static struct subsys_interface cpufreq_interface = {
        .remove_dev     = cpufreq_remove_dev,
 };
 
+void cpufreq_suspend(void)
+{
+       struct cpufreq_policy *policy;
+
+       if (!has_target())
+               return;
+
+       pr_debug("%s: Suspending Governors\n", __func__);
+
+       list_for_each_entry(policy, &cpufreq_policy_list, policy_list)
+               if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP))
+                       pr_err("%s: Failed to stop governor for policy: %p\n",
+                               __func__, policy);
+
+       cpufreq_suspended = true;
+}
+
+void cpufreq_resume(void)
+{
+       struct cpufreq_policy *policy;
+
+       if (!has_target())
+               return;
+
+       pr_debug("%s: Resuming Governors\n", __func__);
+
+       cpufreq_suspended = false;
+
+       list_for_each_entry(policy, &cpufreq_policy_list, policy_list)
+               if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
+                   || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))
+                       pr_err("%s: Failed to start governor for policy: %p\n",
+                               __func__, policy);
+}
+
 /**
  * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
  *
@@ -1764,6 +1803,10 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
        struct cpufreq_governor *gov = NULL;
 #endif
 
+       /* Don't start any governor operations if we are entering suspend */
+       if (cpufreq_suspended)
+               return 0;
+
        if (policy->governor->max_transition_latency &&
            policy->cpuinfo.transition_latency >
            policy->governor->max_transition_latency) {
index f2c75065ce198694428d631baef388ad8e9aa6c6..dfd1643b0b2ff86f229b8e8726fee437c3e1e618 100644 (file)
@@ -157,4 +157,3 @@ err_moutcore:
        pr_debug("%s: failed initialization\n", __func__);
        return -EINVAL;
 }
-EXPORT_SYMBOL(exynos4210_cpufreq_init);
index 8683304ce62cc4dba0c947e2be6049e1b94ffcaf..efad5e657f6f95d9729b33469b2a3f018eaa798c 100644 (file)
@@ -211,4 +211,3 @@ err_moutcore:
        pr_debug("%s: failed initialization\n", __func__);
        return -EINVAL;
 }
-EXPORT_SYMBOL(exynos4x12_cpufreq_init);
index 9fae466d7746a5fed781edb17f4838b6931ed8f0..8feda86fe42c5b5b86c5ac53b02c4d47216fd101 100644 (file)
@@ -236,4 +236,3 @@ err_moutcore:
        pr_err("%s: failed initialization\n", __func__);
        return -EINVAL;
 }
-EXPORT_SYMBOL(exynos5250_cpufreq_init);
index d02ccd19c9c4f20e4b5a3cfdcf1035b0c15c97fd..45ea4c094542d677bf2edd83f642b0173ed90541 100644 (file)
@@ -138,7 +138,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
        }
 
        newfreq = clk_round_rate(srcclk, newfreq * mult);
-       if (newfreq < 0) {
+       if (newfreq <= 0) {
                pr_err("clk_round_rate failed for cpu src clock\n");
                return newfreq;
        }
index f42df7ec03c53a00838839861567de2e0d8060fa..b7309c37033d57b64d37ca3b93354f0b2848102d 100644 (file)
@@ -142,10 +142,8 @@ static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
 
        mutex_lock(&tegra_cpu_lock);
 
-       if (is_suspended) {
-               ret = -EBUSY;
+       if (is_suspended)
                goto out;
-       }
 
        freq = freq_table[index].frequency;
 
index ca89f6b84b068c1ecc770eededee50bf8c1d55aa..e7555ff4cafdb4b0444a09f2de4b2b153f9e78e9 100644 (file)
@@ -4,16 +4,29 @@ config CRYPTO_DEV_FSL_CAAM
        help
          Enables the driver module for Freescale's Cryptographic Accelerator
          and Assurance Module (CAAM), also known as the SEC version 4 (SEC4).
-         This module adds a job ring operation interface, and configures h/w
+         This module creates job ring devices, and configures h/w
          to operate as a DPAA component automatically, depending
          on h/w feature availability.
 
          To compile this driver as a module, choose M here: the module
          will be called caam.
 
+config CRYPTO_DEV_FSL_CAAM_JR
+       tristate "Freescale CAAM Job Ring driver backend"
+       depends on CRYPTO_DEV_FSL_CAAM
+       default y
+       help
+         Enables the driver module for Job Rings which are part of
+         Freescale's Cryptographic Accelerator
+         and Assurance Module (CAAM). This module adds a job ring operation
+         interface.
+
+         To compile this driver as a module, choose M here: the module
+         will be called caam_jr.
+
 config CRYPTO_DEV_FSL_CAAM_RINGSIZE
        int "Job Ring size"
-       depends on CRYPTO_DEV_FSL_CAAM
+       depends on CRYPTO_DEV_FSL_CAAM_JR
        range 2 9
        default "9"
        help
@@ -31,7 +44,7 @@ config CRYPTO_DEV_FSL_CAAM_RINGSIZE
 
 config CRYPTO_DEV_FSL_CAAM_INTC
        bool "Job Ring interrupt coalescing"
-       depends on CRYPTO_DEV_FSL_CAAM
+       depends on CRYPTO_DEV_FSL_CAAM_JR
        default n
        help
          Enable the Job Ring's interrupt coalescing feature.
@@ -62,7 +75,7 @@ config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD
 
 config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
        tristate "Register algorithm implementations with the Crypto API"
-       depends on CRYPTO_DEV_FSL_CAAM
+       depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
        default y
        select CRYPTO_ALGAPI
        select CRYPTO_AUTHENC
@@ -76,7 +89,7 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
 
 config CRYPTO_DEV_FSL_CAAM_AHASH_API
        tristate "Register hash algorithm implementations with Crypto API"
-       depends on CRYPTO_DEV_FSL_CAAM
+       depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
        default y
        select CRYPTO_HASH
        help
@@ -88,7 +101,7 @@ config CRYPTO_DEV_FSL_CAAM_AHASH_API
 
 config CRYPTO_DEV_FSL_CAAM_RNG_API
        tristate "Register caam device for hwrng API"
-       depends on CRYPTO_DEV_FSL_CAAM
+       depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
        default y
        select CRYPTO_RNG
        select HW_RANDOM
index d56bd0ec65d877ca9f2989ad77173214cc537868..550758a333e7c8e920a422da0cc20fc8807476d1 100644 (file)
@@ -6,8 +6,10 @@ ifeq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG), y)
 endif
 
 obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
 obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
 obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
 obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
 
-caam-objs := ctrl.o jr.o error.o key_gen.o
+caam-objs := ctrl.o
+caam_jr-objs := jr.o key_gen.o error.o
index 7c63b72ecd750f381fef66e8baccc7955351b1b3..4cf5dec826e1e283aa8b5991cd1a4b80a0dbdba6 100644 (file)
@@ -86,6 +86,7 @@
 #else
 #define debug(format, arg...)
 #endif
+static struct list_head alg_list;
 
 /* Set DK bit in class 1 operation if shared */
 static inline void append_dec_op1(u32 *desc, u32 type)
@@ -817,7 +818,7 @@ static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
                       ivsize, 1);
        print_hex_dump(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
                       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->dst),
-                      req->cryptlen, 1);
+                      req->cryptlen - ctx->authsize, 1);
 #endif
 
        if (err) {
@@ -971,12 +972,9 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr,
                                 (edesc->src_nents ? : 1);
                in_options = LDST_SGF;
        }
-       if (encrypt)
-               append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize +
-                                 req->cryptlen - authsize, in_options);
-       else
-               append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize +
-                                 req->cryptlen, in_options);
+
+       append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen,
+                         in_options);
 
        if (likely(req->src == req->dst)) {
                if (all_contig) {
@@ -997,7 +995,8 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr,
                }
        }
        if (encrypt)
-               append_seq_out_ptr(desc, dst_dma, req->cryptlen, out_options);
+               append_seq_out_ptr(desc, dst_dma, req->cryptlen + authsize,
+                                  out_options);
        else
                append_seq_out_ptr(desc, dst_dma, req->cryptlen - authsize,
                                   out_options);
@@ -1047,8 +1046,8 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr,
                sec4_sg_index += edesc->assoc_nents + 1 + edesc->src_nents;
                in_options = LDST_SGF;
        }
-       append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize +
-                         req->cryptlen - authsize, in_options);
+       append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen,
+                         in_options);
 
        if (contig & GIV_DST_CONTIG) {
                dst_dma = edesc->iv_dma;
@@ -1065,7 +1064,8 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr,
                }
        }
 
-       append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen, out_options);
+       append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen + authsize,
+                          out_options);
 }
 
 /*
@@ -1129,7 +1129,8 @@ static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr,
  * allocate and map the aead extended descriptor
  */
 static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
-                                          int desc_bytes, bool *all_contig_ptr)
+                                          int desc_bytes, bool *all_contig_ptr,
+                                          bool encrypt)
 {
        struct crypto_aead *aead = crypto_aead_reqtfm(req);
        struct caam_ctx *ctx = crypto_aead_ctx(aead);
@@ -1144,12 +1145,22 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
        bool assoc_chained = false, src_chained = false, dst_chained = false;
        int ivsize = crypto_aead_ivsize(aead);
        int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
+       unsigned int authsize = ctx->authsize;
 
        assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained);
-       src_nents = sg_count(req->src, req->cryptlen, &src_chained);
 
-       if (unlikely(req->dst != req->src))
-               dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
+       if (unlikely(req->dst != req->src)) {
+               src_nents = sg_count(req->src, req->cryptlen, &src_chained);
+               dst_nents = sg_count(req->dst,
+                                    req->cryptlen +
+                                       (encrypt ? authsize : (-authsize)),
+                                    &dst_chained);
+       } else {
+               src_nents = sg_count(req->src,
+                                    req->cryptlen +
+                                       (encrypt ? authsize : 0),
+                                    &src_chained);
+       }
 
        sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
                                 DMA_TO_DEVICE, assoc_chained);
@@ -1233,11 +1244,9 @@ static int aead_encrypt(struct aead_request *req)
        u32 *desc;
        int ret = 0;
 
-       req->cryptlen += ctx->authsize;
-
        /* allocate extended descriptor */
        edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
-                                CAAM_CMD_SZ, &all_contig);
+                                CAAM_CMD_SZ, &all_contig, true);
        if (IS_ERR(edesc))
                return PTR_ERR(edesc);
 
@@ -1274,7 +1283,7 @@ static int aead_decrypt(struct aead_request *req)
 
        /* allocate extended descriptor */
        edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
-                                CAAM_CMD_SZ, &all_contig);
+                                CAAM_CMD_SZ, &all_contig, false);
        if (IS_ERR(edesc))
                return PTR_ERR(edesc);
 
@@ -1331,7 +1340,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
        src_nents = sg_count(req->src, req->cryptlen, &src_chained);
 
        if (unlikely(req->dst != req->src))
-               dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
+               dst_nents = sg_count(req->dst, req->cryptlen + ctx->authsize,
+                                    &dst_chained);
 
        sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
                                 DMA_TO_DEVICE, assoc_chained);
@@ -1425,8 +1435,6 @@ static int aead_givencrypt(struct aead_givcrypt_request *areq)
        u32 *desc;
        int ret = 0;
 
-       req->cryptlen += ctx->authsize;
-
        /* allocate extended descriptor */
        edesc = aead_giv_edesc_alloc(areq, DESC_JOB_IO_LEN *
                                     CAAM_CMD_SZ, &contig);
@@ -2057,7 +2065,6 @@ static struct caam_alg_template driver_algs[] = {
 
 struct caam_crypto_alg {
        struct list_head entry;
-       struct device *ctrldev;
        int class1_alg_type;
        int class2_alg_type;
        int alg_op;
@@ -2070,14 +2077,12 @@ static int caam_cra_init(struct crypto_tfm *tfm)
        struct caam_crypto_alg *caam_alg =
                 container_of(alg, struct caam_crypto_alg, crypto_alg);
        struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
-       struct caam_drv_private *priv = dev_get_drvdata(caam_alg->ctrldev);
-       int tgt_jr = atomic_inc_return(&priv->tfm_count);
 
-       /*
-        * distribute tfms across job rings to ensure in-order
-        * crypto request processing per tfm
-        */
-       ctx->jrdev = priv->jrdev[(tgt_jr / 2) % priv->total_jobrs];
+       ctx->jrdev = caam_jr_alloc();
+       if (IS_ERR(ctx->jrdev)) {
+               pr_err("Job Ring Device allocation for transform failed\n");
+               return PTR_ERR(ctx->jrdev);
+       }
 
        /* copy descriptor header template value */
        ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type;
@@ -2104,44 +2109,26 @@ static void caam_cra_exit(struct crypto_tfm *tfm)
                dma_unmap_single(ctx->jrdev, ctx->sh_desc_givenc_dma,
                                 desc_bytes(ctx->sh_desc_givenc),
                                 DMA_TO_DEVICE);
+
+       caam_jr_free(ctx->jrdev);
 }
 
 static void __exit caam_algapi_exit(void)
 {
 
-       struct device_node *dev_node;
-       struct platform_device *pdev;
-       struct device *ctrldev;
-       struct caam_drv_private *priv;
        struct caam_crypto_alg *t_alg, *n;
 
-       dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
-       if (!dev_node) {
-               dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
-               if (!dev_node)
-                       return;
-       }
-
-       pdev = of_find_device_by_node(dev_node);
-       if (!pdev)
-               return;
-
-       ctrldev = &pdev->dev;
-       of_node_put(dev_node);
-       priv = dev_get_drvdata(ctrldev);
-
-       if (!priv->alg_list.next)
+       if (!alg_list.next)
                return;
 
-       list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
+       list_for_each_entry_safe(t_alg, n, &alg_list, entry) {
                crypto_unregister_alg(&t_alg->crypto_alg);
                list_del(&t_alg->entry);
                kfree(t_alg);
        }
 }
 
-static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev,
-                                             struct caam_alg_template
+static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
                                              *template)
 {
        struct caam_crypto_alg *t_alg;
@@ -2149,7 +2136,7 @@ static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev,
 
        t_alg = kzalloc(sizeof(struct caam_crypto_alg), GFP_KERNEL);
        if (!t_alg) {
-               dev_err(ctrldev, "failed to allocate t_alg\n");
+               pr_err("failed to allocate t_alg\n");
                return ERR_PTR(-ENOMEM);
        }
 
@@ -2181,62 +2168,39 @@ static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev,
        t_alg->class1_alg_type = template->class1_alg_type;
        t_alg->class2_alg_type = template->class2_alg_type;
        t_alg->alg_op = template->alg_op;
-       t_alg->ctrldev = ctrldev;
 
        return t_alg;
 }
 
 static int __init caam_algapi_init(void)
 {
-       struct device_node *dev_node;
-       struct platform_device *pdev;
-       struct device *ctrldev;
-       struct caam_drv_private *priv;
        int i = 0, err = 0;
 
-       dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
-       if (!dev_node) {
-               dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
-               if (!dev_node)
-                       return -ENODEV;
-       }
-
-       pdev = of_find_device_by_node(dev_node);
-       if (!pdev)
-               return -ENODEV;
-
-       ctrldev = &pdev->dev;
-       priv = dev_get_drvdata(ctrldev);
-       of_node_put(dev_node);
-
-       INIT_LIST_HEAD(&priv->alg_list);
-
-       atomic_set(&priv->tfm_count, -1);
+       INIT_LIST_HEAD(&alg_list);
 
        /* register crypto algorithms the device supports */
        for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
                /* TODO: check if h/w supports alg */
                struct caam_crypto_alg *t_alg;
 
-               t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]);
+               t_alg = caam_alg_alloc(&driver_algs[i]);
                if (IS_ERR(t_alg)) {
                        err = PTR_ERR(t_alg);
-                       dev_warn(ctrldev, "%s alg allocation failed\n",
-                                driver_algs[i].driver_name);
+                       pr_warn("%s alg allocation failed\n",
+                               driver_algs[i].driver_name);
                        continue;
                }
 
                err = crypto_register_alg(&t_alg->crypto_alg);
                if (err) {
-                       dev_warn(ctrldev, "%s alg registration failed\n",
+                       pr_warn("%s alg registration failed\n",
                                t_alg->crypto_alg.cra_driver_name);
                        kfree(t_alg);
                } else
-                       list_add_tail(&t_alg->entry, &priv->alg_list);
+                       list_add_tail(&t_alg->entry, &alg_list);
        }
-       if (!list_empty(&priv->alg_list))
-               dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n",
-                        (char *)of_get_property(dev_node, "compatible", NULL));
+       if (!list_empty(&alg_list))
+               pr_info("caam algorithms registered in /proc/crypto\n");
 
        return err;
 }
index e732bd962e98cc715db6463c7587dbb2511707e3..0378328f47a775b368b795cd3d7adc9b678fd31b 100644 (file)
@@ -94,6 +94,9 @@
 #define debug(format, arg...)
 #endif
 
+
+static struct list_head hash_list;
+
 /* ahash per-session context */
 struct caam_hash_ctx {
        struct device *jrdev;
@@ -1653,7 +1656,6 @@ static struct caam_hash_template driver_hash[] = {
 
 struct caam_hash_alg {
        struct list_head entry;
-       struct device *ctrldev;
        int alg_type;
        int alg_op;
        struct ahash_alg ahash_alg;
@@ -1670,7 +1672,6 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm)
        struct caam_hash_alg *caam_hash =
                 container_of(alg, struct caam_hash_alg, ahash_alg);
        struct caam_hash_ctx *ctx = crypto_tfm_ctx(tfm);
-       struct caam_drv_private *priv = dev_get_drvdata(caam_hash->ctrldev);
        /* Sizes for MDHA running digests: MD5, SHA1, 224, 256, 384, 512 */
        static const u8 runninglen[] = { HASH_MSG_LEN + MD5_DIGEST_SIZE,
                                         HASH_MSG_LEN + SHA1_DIGEST_SIZE,
@@ -1678,15 +1679,17 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm)
                                         HASH_MSG_LEN + SHA256_DIGEST_SIZE,
                                         HASH_MSG_LEN + 64,
                                         HASH_MSG_LEN + SHA512_DIGEST_SIZE };
-       int tgt_jr = atomic_inc_return(&priv->tfm_count);
        int ret = 0;
 
        /*
-        * distribute tfms across job rings to ensure in-order
+        * Get a Job ring from Job Ring driver to ensure in-order
         * crypto request processing per tfm
         */
-       ctx->jrdev = priv->jrdev[tgt_jr % priv->total_jobrs];
-
+       ctx->jrdev = caam_jr_alloc();
+       if (IS_ERR(ctx->jrdev)) {
+               pr_err("Job Ring Device allocation for transform failed\n");
+               return PTR_ERR(ctx->jrdev);
+       }
        /* copy descriptor header template value */
        ctx->alg_type = OP_TYPE_CLASS2_ALG | caam_hash->alg_type;
        ctx->alg_op = OP_TYPE_CLASS2_ALG | caam_hash->alg_op;
@@ -1729,35 +1732,18 @@ static void caam_hash_cra_exit(struct crypto_tfm *tfm)
            !dma_mapping_error(ctx->jrdev, ctx->sh_desc_finup_dma))
                dma_unmap_single(ctx->jrdev, ctx->sh_desc_finup_dma,
                                 desc_bytes(ctx->sh_desc_finup), DMA_TO_DEVICE);
+
+       caam_jr_free(ctx->jrdev);
 }
 
 static void __exit caam_algapi_hash_exit(void)
 {
-       struct device_node *dev_node;
-       struct platform_device *pdev;
-       struct device *ctrldev;
-       struct caam_drv_private *priv;
        struct caam_hash_alg *t_alg, *n;
 
-       dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
-       if (!dev_node) {
-               dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
-               if (!dev_node)
-                       return;
-       }
-
-       pdev = of_find_device_by_node(dev_node);
-       if (!pdev)
+       if (!hash_list.next)
                return;
 
-       ctrldev = &pdev->dev;
-       of_node_put(dev_node);
-       priv = dev_get_drvdata(ctrldev);
-
-       if (!priv->hash_list.next)
-               return;
-
-       list_for_each_entry_safe(t_alg, n, &priv->hash_list, entry) {
+       list_for_each_entry_safe(t_alg, n, &hash_list, entry) {
                crypto_unregister_ahash(&t_alg->ahash_alg);
                list_del(&t_alg->entry);
                kfree(t_alg);
@@ -1765,7 +1751,7 @@ static void __exit caam_algapi_hash_exit(void)
 }
 
 static struct caam_hash_alg *
-caam_hash_alloc(struct device *ctrldev, struct caam_hash_template *template,
+caam_hash_alloc(struct caam_hash_template *template,
                bool keyed)
 {
        struct caam_hash_alg *t_alg;
@@ -1774,7 +1760,7 @@ caam_hash_alloc(struct device *ctrldev, struct caam_hash_template *template,
 
        t_alg = kzalloc(sizeof(struct caam_hash_alg), GFP_KERNEL);
        if (!t_alg) {
-               dev_err(ctrldev, "failed to allocate t_alg\n");
+               pr_err("failed to allocate t_alg\n");
                return ERR_PTR(-ENOMEM);
        }
 
@@ -1805,37 +1791,15 @@ caam_hash_alloc(struct device *ctrldev, struct caam_hash_template *template,
 
        t_alg->alg_type = template->alg_type;
        t_alg->alg_op = template->alg_op;
-       t_alg->ctrldev = ctrldev;
 
        return t_alg;
 }
 
 static int __init caam_algapi_hash_init(void)
 {
-       struct device_node *dev_node;
-       struct platform_device *pdev;
-       struct device *ctrldev;
-       struct caam_drv_private *priv;
        int i = 0, err = 0;
 
-       dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
-       if (!dev_node) {
-               dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
-               if (!dev_node)
-                       return -ENODEV;
-       }
-
-       pdev = of_find_device_by_node(dev_node);
-       if (!pdev)
-               return -ENODEV;
-
-       ctrldev = &pdev->dev;
-       priv = dev_get_drvdata(ctrldev);
-       of_node_put(dev_node);
-
-       INIT_LIST_HEAD(&priv->hash_list);
-
-       atomic_set(&priv->tfm_count, -1);
+       INIT_LIST_HEAD(&hash_list);
 
        /* register crypto algorithms the device supports */
        for (i = 0; i < ARRAY_SIZE(driver_hash); i++) {
@@ -1843,38 +1807,38 @@ static int __init caam_algapi_hash_init(void)
                struct caam_hash_alg *t_alg;
 
                /* register hmac version */
-               t_alg = caam_hash_alloc(ctrldev, &driver_hash[i], true);
+               t_alg = caam_hash_alloc(&driver_hash[i], true);
                if (IS_ERR(t_alg)) {
                        err = PTR_ERR(t_alg);
-                       dev_warn(ctrldev, "%s alg allocation failed\n",
-                                driver_hash[i].driver_name);
+                       pr_warn("%s alg allocation failed\n",
+                               driver_hash[i].driver_name);
                        continue;
                }
 
                err = crypto_register_ahash(&t_alg->ahash_alg);
                if (err) {
-                       dev_warn(ctrldev, "%s alg registration failed\n",
+                       pr_warn("%s alg registration failed\n",
                                t_alg->ahash_alg.halg.base.cra_driver_name);
                        kfree(t_alg);
                } else
-                       list_add_tail(&t_alg->entry, &priv->hash_list);
+                       list_add_tail(&t_alg->entry, &hash_list);
 
                /* register unkeyed version */
-               t_alg = caam_hash_alloc(ctrldev, &driver_hash[i], false);
+               t_alg = caam_hash_alloc(&driver_hash[i], false);
                if (IS_ERR(t_alg)) {
                        err = PTR_ERR(t_alg);
-                       dev_warn(ctrldev, "%s alg allocation failed\n",
-                                driver_hash[i].driver_name);
+                       pr_warn("%s alg allocation failed\n",
+                               driver_hash[i].driver_name);
                        continue;
                }
 
                err = crypto_register_ahash(&t_alg->ahash_alg);
                if (err) {
-                       dev_warn(ctrldev, "%s alg registration failed\n",
+                       pr_warn("%s alg registration failed\n",
                                t_alg->ahash_alg.halg.base.cra_driver_name);
                        kfree(t_alg);
                } else
-                       list_add_tail(&t_alg->entry, &priv->hash_list);
+                       list_add_tail(&t_alg->entry, &hash_list);
        }
 
        return err;
index d1939a9539c06a4204a26b65d3d743d46c2346d3..28486b19fc36b3e837d774ace08a3aa041b8d1e7 100644 (file)
@@ -273,34 +273,23 @@ static struct hwrng caam_rng = {
 
 static void __exit caam_rng_exit(void)
 {
+       caam_jr_free(rng_ctx.jrdev);
        hwrng_unregister(&caam_rng);
 }
 
 static int __init caam_rng_init(void)
 {
-       struct device_node *dev_node;
-       struct platform_device *pdev;
-       struct device *ctrldev;
-       struct caam_drv_private *priv;
-
-       dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
-       if (!dev_node) {
-               dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
-               if (!dev_node)
-                       return -ENODEV;
-       }
-
-       pdev = of_find_device_by_node(dev_node);
-       if (!pdev)
-               return -ENODEV;
+       struct device *dev;
 
-       ctrldev = &pdev->dev;
-       priv = dev_get_drvdata(ctrldev);
-       of_node_put(dev_node);
+       dev = caam_jr_alloc();
+       if (IS_ERR(dev)) {
+               pr_err("Job Ring Device allocation for transform failed\n");
+               return PTR_ERR(dev);
+       }
 
-       caam_init_rng(&rng_ctx, priv->jrdev[0]);
+       caam_init_rng(&rng_ctx, dev);
 
-       dev_info(priv->jrdev[0], "registering rng-caam\n");
+       dev_info(dev, "registering rng-caam\n");
        return hwrng_register(&caam_rng);
 }
 
index bc6d820812b6a73e83c6596caa48ae7d475c315a..63fb1af2c43187fe398663869b5877fa16bf8834 100644 (file)
 #include "error.h"
 #include "ctrl.h"
 
-static int caam_remove(struct platform_device *pdev)
-{
-       struct device *ctrldev;
-       struct caam_drv_private *ctrlpriv;
-       struct caam_drv_private_jr *jrpriv;
-       struct caam_full __iomem *topregs;
-       int ring, ret = 0;
-
-       ctrldev = &pdev->dev;
-       ctrlpriv = dev_get_drvdata(ctrldev);
-       topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
-
-       /* shut down JobRs */
-       for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
-               ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
-               jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
-               irq_dispose_mapping(jrpriv->irq);
-       }
-
-       /* Shut down debug views */
-#ifdef CONFIG_DEBUG_FS
-       debugfs_remove_recursive(ctrlpriv->dfs_root);
-#endif
-
-       /* Unmap controller region */
-       iounmap(&topregs->ctrl);
-
-       kfree(ctrlpriv->jrdev);
-       kfree(ctrlpriv);
-
-       return ret;
-}
-
 /*
  * Descriptor to instantiate RNG State Handle 0 in normal mode and
  * load the JDKEK, TDKEK and TDSK registers
  */
-static void build_instantiation_desc(u32 *desc)
+static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
 {
-       u32 *jump_cmd;
+       u32 *jump_cmd, op_flags;
 
        init_job_desc(desc, 0);
 
+       op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+                       (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT;
+
        /* INIT RNG in non-test mode */
-       append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
-                        OP_ALG_AS_INIT);
+       append_operation(desc, op_flags);
+
+       if (!handle && do_sk) {
+               /*
+                * For SH0, Secure Keys must be generated as well
+                */
+
+               /* wait for done */
+               jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
+               set_jump_tgt_here(desc, jump_cmd);
+
+               /*
+                * load 1 to clear written reg:
+                * resets the done interrrupt and returns the RNG to idle.
+                */
+               append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+
+               /* Initialize State Handle  */
+               append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+                                OP_ALG_AAI_RNG4_SK);
+       }
 
-       /* wait for done */
-       jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
-       set_jump_tgt_here(desc, jump_cmd);
+       append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
+}
 
-       /*
-        * load 1 to clear written reg:
-        * resets the done interrupt and returns the RNG to idle.
-        */
-       append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+/* Descriptor for deinstantiation of State Handle 0 of the RNG block. */
+static void build_deinstantiation_desc(u32 *desc, int handle)
+{
+       init_job_desc(desc, 0);
 
-       /* generate secure keys (non-test) */
+       /* Uninstantiate State Handle 0 */
        append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
-                        OP_ALG_RNG4_SK);
+                        (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL);
+
+       append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
 }
 
-static int instantiate_rng(struct device *ctrldev)
+/*
+ * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of
+ *                       the software (no JR/QI used).
+ * @ctrldev - pointer to device
+ * @status - descriptor status, after being run
+ *
+ * Return: - 0 if no error occurred
+ *        - -ENODEV if the DECO couldn't be acquired
+ *        - -EAGAIN if an error occurred while executing the descriptor
+ */
+static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
+                                       u32 *status)
 {
        struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
        struct caam_full __iomem *topregs;
        unsigned int timeout = 100000;
-       u32 *desc;
-       int i, ret = 0;
-
-       desc = kmalloc(CAAM_CMD_SZ * 6, GFP_KERNEL | GFP_DMA);
-       if (!desc) {
-               dev_err(ctrldev, "can't allocate RNG init descriptor memory\n");
-               return -ENOMEM;
-       }
-       build_instantiation_desc(desc);
+       u32 deco_dbg_reg, flags;
+       int i;
 
        /* Set the bit to request direct access to DECO0 */
        topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
@@ -103,36 +96,219 @@ static int instantiate_rng(struct device *ctrldev)
 
        if (!timeout) {
                dev_err(ctrldev, "failed to acquire DECO 0\n");
-               ret = -EIO;
-               goto out;
+               clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
+               return -ENODEV;
        }
 
        for (i = 0; i < desc_len(desc); i++)
-               topregs->deco.descbuf[i] = *(desc + i);
+               wr_reg32(&topregs->deco.descbuf[i], *(desc + i));
+
+       flags = DECO_JQCR_WHL;
+       /*
+        * If the descriptor length is longer than 4 words, then the
+        * FOUR bit in JRCTRL register must be set.
+        */
+       if (desc_len(desc) >= 4)
+               flags |= DECO_JQCR_FOUR;
 
-       wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR);
+       /* Instruct the DECO to execute it */
+       wr_reg32(&topregs->deco.jr_ctl_hi, flags);
 
        timeout = 10000000;
-       while ((rd_reg32(&topregs->deco.desc_dbg) & DECO_DBG_VALID) &&
-                                                                --timeout)
+       do {
+               deco_dbg_reg = rd_reg32(&topregs->deco.desc_dbg);
+               /*
+                * If an error occured in the descriptor, then
+                * the DECO status field will be set to 0x0D
+                */
+               if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) ==
+                   DESC_DBG_DECO_STAT_HOST_ERR)
+                       break;
                cpu_relax();
+       } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
 
-       if (!timeout) {
-               dev_err(ctrldev, "failed to instantiate RNG\n");
-               ret = -EIO;
-       }
+       *status = rd_reg32(&topregs->deco.op_status_hi) &
+                 DECO_OP_STATUS_HI_ERR_MASK;
 
+       /* Mark the DECO as free */
        clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
-out:
+
+       if (!timeout)
+               return -EAGAIN;
+
+       return 0;
+}
+
+/*
+ * instantiate_rng - builds and executes a descriptor on DECO0,
+ *                  which initializes the RNG block.
+ * @ctrldev - pointer to device
+ * @state_handle_mask - bitmask containing the instantiation status
+ *                     for the RNG4 state handles which exist in
+ *                     the RNG4 block: 1 if it's been instantiated
+ *                     by an external entry, 0 otherwise.
+ * @gen_sk  - generate data to be loaded into the JDKEK, TDKEK and TDSK;
+ *           Caution: this can be done only once; if the keys need to be
+ *           regenerated, a POR is required
+ *
+ * Return: - 0 if no error occurred
+ *        - -ENOMEM if there isn't enough memory to allocate the descriptor
+ *        - -ENODEV if DECO0 couldn't be acquired
+ *        - -EAGAIN if an error occurred when executing the descriptor
+ *           f.i. there was a RNG hardware error due to not "good enough"
+ *           entropy being aquired.
+ */
+static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
+                          int gen_sk)
+{
+       struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
+       struct caam_full __iomem *topregs;
+       struct rng4tst __iomem *r4tst;
+       u32 *desc, status, rdsta_val;
+       int ret = 0, sh_idx;
+
+       topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+       r4tst = &topregs->ctrl.r4tst[0];
+
+       desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
+       if (!desc)
+               return -ENOMEM;
+
+       for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+               /*
+                * If the corresponding bit is set, this state handle
+                * was initialized by somebody else, so it's left alone.
+                */
+               if ((1 << sh_idx) & state_handle_mask)
+                       continue;
+
+               /* Create the descriptor for instantiating RNG State Handle */
+               build_instantiation_desc(desc, sh_idx, gen_sk);
+
+               /* Try to run it through DECO0 */
+               ret = run_descriptor_deco0(ctrldev, desc, &status);
+
+               /*
+                * If ret is not 0, or descriptor status is not 0, then
+                * something went wrong. No need to try the next state
+                * handle (if available), bail out here.
+                * Also, if for some reason, the State Handle didn't get
+                * instantiated although the descriptor has finished
+                * without any error (HW optimizations for later
+                * CAAM eras), then try again.
+                */
+               rdsta_val =
+                       rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IFMASK;
+               if (status || !(rdsta_val & (1 << sh_idx)))
+                       ret = -EAGAIN;
+               if (ret)
+                       break;
+
+               dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
+               /* Clear the contents before recreating the descriptor */
+               memset(desc, 0x00, CAAM_CMD_SZ * 7);
+       }
+
        kfree(desc);
+
        return ret;
 }
 
 /*
- * By default, the TRNG runs for 200 clocks per sample;
- * 1600 clocks per sample generates better entropy.
+ * deinstantiate_rng - builds and executes a descriptor on DECO0,
+ *                    which deinitializes the RNG block.
+ * @ctrldev - pointer to device
+ * @state_handle_mask - bitmask containing the instantiation status
+ *                     for the RNG4 state handles which exist in
+ *                     the RNG4 block: 1 if it's been instantiated
+ *
+ * Return: - 0 if no error occurred
+ *        - -ENOMEM if there isn't enough memory to allocate the descriptor
+ *        - -ENODEV if DECO0 couldn't be acquired
+ *        - -EAGAIN if an error occurred when executing the descriptor
  */
-static void kick_trng(struct platform_device *pdev)
+static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask)
+{
+       u32 *desc, status;
+       int sh_idx, ret = 0;
+
+       desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL);
+       if (!desc)
+               return -ENOMEM;
+
+       for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+               /*
+                * If the corresponding bit is set, then it means the state
+                * handle was initialized by us, and thus it needs to be
+                * deintialized as well
+                */
+               if ((1 << sh_idx) & state_handle_mask) {
+                       /*
+                        * Create the descriptor for deinstantating this state
+                        * handle
+                        */
+                       build_deinstantiation_desc(desc, sh_idx);
+
+                       /* Try to run it through DECO0 */
+                       ret = run_descriptor_deco0(ctrldev, desc, &status);
+
+                       if (ret || status) {
+                               dev_err(ctrldev,
+                                       "Failed to deinstantiate RNG4 SH%d\n",
+                                       sh_idx);
+                               break;
+                       }
+                       dev_info(ctrldev, "Deinstantiated RNG4 SH%d\n", sh_idx);
+               }
+       }
+
+       kfree(desc);
+
+       return ret;
+}
+
+static int caam_remove(struct platform_device *pdev)
+{
+       struct device *ctrldev;
+       struct caam_drv_private *ctrlpriv;
+       struct caam_full __iomem *topregs;
+       int ring, ret = 0;
+
+       ctrldev = &pdev->dev;
+       ctrlpriv = dev_get_drvdata(ctrldev);
+       topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+
+       /* Remove platform devices for JobRs */
+       for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
+               if (ctrlpriv->jrpdev[ring])
+                       of_device_unregister(ctrlpriv->jrpdev[ring]);
+       }
+
+       /* De-initialize RNG state handles initialized by this driver. */
+       if (ctrlpriv->rng4_sh_init)
+               deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init);
+
+       /* Shut down debug views */
+#ifdef CONFIG_DEBUG_FS
+       debugfs_remove_recursive(ctrlpriv->dfs_root);
+#endif
+
+       /* Unmap controller region */
+       iounmap(&topregs->ctrl);
+
+       kfree(ctrlpriv->jrpdev);
+       kfree(ctrlpriv);
+
+       return ret;
+}
+
+/*
+ * kick_trng - sets the various parameters for enabling the initialization
+ *            of the RNG4 block in CAAM
+ * @pdev - pointer to the platform device
+ * @ent_delay - Defines the length (in system clocks) of each entropy sample.
+ */
+static void kick_trng(struct platform_device *pdev, int ent_delay)
 {
        struct device *ctrldev = &pdev->dev;
        struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
@@ -145,14 +321,31 @@ static void kick_trng(struct platform_device *pdev)
 
        /* put RNG4 into program mode */
        setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
-       /* 1600 clocks per sample */
+
+       /*
+        * Performance-wise, it does not make sense to
+        * set the delay to a value that is lower
+        * than the last one that worked (i.e. the state handles
+        * were instantiated properly. Thus, instead of wasting
+        * time trying to set the values controlling the sample
+        * frequency, the function simply returns.
+        */
+       val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
+             >> RTSDCTL_ENT_DLY_SHIFT;
+       if (ent_delay <= val) {
+               /* put RNG4 into run mode */
+               clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
+               return;
+       }
+
        val = rd_reg32(&r4tst->rtsdctl);
-       val = (val & ~RTSDCTL_ENT_DLY_MASK) | (1600 << RTSDCTL_ENT_DLY_SHIFT);
+       val = (val & ~RTSDCTL_ENT_DLY_MASK) |
+             (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
        wr_reg32(&r4tst->rtsdctl, val);
-       /* min. freq. count */
-       wr_reg32(&r4tst->rtfrqmin, 400);
-       /* max. freq. count */
-       wr_reg32(&r4tst->rtfrqmax, 6400);
+       /* min. freq. count, equal to 1/4 of the entropy sample length */
+       wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
+       /* max. freq. count, equal to 8 times the entropy sample length */
+       wr_reg32(&r4tst->rtfrqmax, ent_delay << 3);
        /* put RNG4 into run mode */
        clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
 }
@@ -193,7 +386,7 @@ EXPORT_SYMBOL(caam_get_era);
 /* Probe routine for CAAM top (controller) level */
 static int caam_probe(struct platform_device *pdev)
 {
-       int ret, ring, rspec;
+       int ret, ring, rspec, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
        u64 caam_id;
        struct device *dev;
        struct device_node *nprop, *np;
@@ -258,8 +451,9 @@ static int caam_probe(struct platform_device *pdev)
                        rspec++;
        }
 
-       ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL);
-       if (ctrlpriv->jrdev == NULL) {
+       ctrlpriv->jrpdev = kzalloc(sizeof(struct platform_device *) * rspec,
+                                                               GFP_KERNEL);
+       if (ctrlpriv->jrpdev == NULL) {
                iounmap(&topregs->ctrl);
                return -ENOMEM;
        }
@@ -267,13 +461,24 @@ static int caam_probe(struct platform_device *pdev)
        ring = 0;
        ctrlpriv->total_jobrs = 0;
        for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") {
-               caam_jr_probe(pdev, np, ring);
+               ctrlpriv->jrpdev[ring] =
+                               of_platform_device_create(np, NULL, dev);
+               if (!ctrlpriv->jrpdev[ring]) {
+                       pr_warn("JR%d Platform device creation error\n", ring);
+                       continue;
+               }
                ctrlpriv->total_jobrs++;
                ring++;
        }
        if (!ring) {
                for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") {
-                       caam_jr_probe(pdev, np, ring);
+                       ctrlpriv->jrpdev[ring] =
+                               of_platform_device_create(np, NULL, dev);
+                       if (!ctrlpriv->jrpdev[ring]) {
+                               pr_warn("JR%d Platform device creation error\n",
+                                       ring);
+                               continue;
+                       }
                        ctrlpriv->total_jobrs++;
                        ring++;
                }
@@ -299,16 +504,55 @@ static int caam_probe(struct platform_device *pdev)
 
        /*
         * If SEC has RNG version >= 4 and RNG state handle has not been
-        * already instantiated ,do RNG instantiation
+        * already instantiateddo RNG instantiation
         */
-       if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 &&
-           !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) {
-               kick_trng(pdev);
-               ret = instantiate_rng(dev);
+       if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4) {
+               ctrlpriv->rng4_sh_init =
+                       rd_reg32(&topregs->ctrl.r4tst[0].rdsta);
+               /*
+                * If the secure keys (TDKEK, JDKEK, TDSK), were already
+                * generated, signal this to the function that is instantiating
+                * the state handles. An error would occur if RNG4 attempts
+                * to regenerate these keys before the next POR.
+                */
+               gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
+               ctrlpriv->rng4_sh_init &= RDSTA_IFMASK;
+               do {
+                       int inst_handles =
+                               rd_reg32(&topregs->ctrl.r4tst[0].rdsta) &
+                                                               RDSTA_IFMASK;
+                       /*
+                        * If either SH were instantiated by somebody else
+                        * (e.g. u-boot) then it is assumed that the entropy
+                        * parameters are properly set and thus the function
+                        * setting these (kick_trng(...)) is skipped.
+                        * Also, if a handle was instantiated, do not change
+                        * the TRNG parameters.
+                        */
+                       if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
+                               kick_trng(pdev, ent_delay);
+                               ent_delay += 400;
+                       }
+                       /*
+                        * if instantiate_rng(...) fails, the loop will rerun
+                        * and the kick_trng(...) function will modfiy the
+                        * upper and lower limits of the entropy sampling
+                        * interval, leading to a sucessful initialization of
+                        * the RNG.
+                        */
+                       ret = instantiate_rng(dev, inst_handles,
+                                             gen_sk);
+               } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
                if (ret) {
+                       dev_err(dev, "failed to instantiate RNG");
                        caam_remove(pdev);
                        return ret;
                }
+               /*
+                * Set handles init'ed by this module as the complement of the
+                * already initialized ones
+                */
+               ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK;
 
                /* Enable RDB bit so that RNG works faster */
                setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE);
index 53b296f78b0d2a588fe1cc3bb4bde067c05a0eda..7e4500f18df6f06de602a3d44ff6d88c4ca70ec5 100644 (file)
@@ -1155,8 +1155,15 @@ struct sec4_sg_entry {
 
 /* randomizer AAI set */
 #define OP_ALG_AAI_RNG         (0x00 << OP_ALG_AAI_SHIFT)
-#define OP_ALG_AAI_RNG_NOZERO  (0x10 << OP_ALG_AAI_SHIFT)
-#define OP_ALG_AAI_RNG_ODD     (0x20 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_NZB     (0x10 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_OBP     (0x20 << OP_ALG_AAI_SHIFT)
+
+/* RNG4 AAI set */
+#define OP_ALG_AAI_RNG4_SH_0   (0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SH_1   (0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_PS     (0x40 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_AI     (0x80 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SK     (0x100 << OP_ALG_AAI_SHIFT)
 
 /* hmac/smac AAI set */
 #define OP_ALG_AAI_HASH                (0x00 << OP_ALG_AAI_SHIFT)
@@ -1178,12 +1185,6 @@ struct sec4_sg_entry {
 #define OP_ALG_AAI_GSM         (0x10 << OP_ALG_AAI_SHIFT)
 #define OP_ALG_AAI_EDGE                (0x20 << OP_ALG_AAI_SHIFT)
 
-/* RNG4 set */
-#define OP_ALG_RNG4_SHIFT      4
-#define OP_ALG_RNG4_MASK       (0x1f3 << OP_ALG_RNG4_SHIFT)
-
-#define OP_ALG_RNG4_SK         (0x100 << OP_ALG_RNG4_SHIFT)
-
 #define OP_ALG_AS_SHIFT                2
 #define OP_ALG_AS_MASK         (0x3 << OP_ALG_AS_SHIFT)
 #define OP_ALG_AS_UPDATE       (0 << OP_ALG_AS_SHIFT)
index 34c4b9f7fbfae414a1578e37da245fd9119ac8fd..6d85fcc5bd0a48977467eaa058609ff882fff26e 100644 (file)
@@ -37,13 +37,16 @@ struct caam_jrentry_info {
 
 /* Private sub-storage for a single JobR */
 struct caam_drv_private_jr {
-       struct device *parentdev;       /* points back to controller dev */
-       struct platform_device *jr_pdev;/* points to platform device for JR */
+       struct list_head        list_node;      /* Job Ring device list */
+       struct device           *dev;
        int ridx;
        struct caam_job_ring __iomem *rregs;    /* JobR's register space */
        struct tasklet_struct irqtask;
        int irq;                        /* One per queue */
 
+       /* Number of scatterlist crypt transforms active on the JobR */
+       atomic_t tfm_count ____cacheline_aligned;
+
        /* Job ring info */
        int ringsize;   /* Size of rings (assume input = output) */
        struct caam_jrentry_info *entinfo;      /* Alloc'ed 1 per ring entry */
@@ -63,7 +66,7 @@ struct caam_drv_private_jr {
 struct caam_drv_private {
 
        struct device *dev;
-       struct device **jrdev; /* Alloc'ed array per sub-device */
+       struct platform_device **jrpdev; /* Alloc'ed array per sub-device */
        struct platform_device *pdev;
 
        /* Physical-presence section */
@@ -80,12 +83,11 @@ struct caam_drv_private {
        u8 qi_present;          /* Nonzero if QI present in device */
        int secvio_irq;         /* Security violation interrupt number */
 
-       /* which jr allocated to scatterlist crypto */
-       atomic_t tfm_count ____cacheline_aligned;
-       /* list of registered crypto algorithms (mk generic context handle?) */
-       struct list_head alg_list;
-       /* list of registered hash algorithms (mk generic context handle?) */
-       struct list_head hash_list;
+#define        RNG4_MAX_HANDLES 2
+       /* RNG4 block */
+       u32 rng4_sh_init;       /* This bitmap shows which of the State
+                                  Handles of the RNG4 block are initialized
+                                  by this driver */
 
        /*
         * debugfs entries for developer view into driver/device
index bdb786d5a5e5b0216b968a833592d8aef7c96d8d..1d80bd3636c5b1f2cf4dc078d4934e64befc7f68 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/of_irq.h>
+#include <linux/of_address.h>
 
 #include "compat.h"
 #include "regs.h"
 #include "desc.h"
 #include "intern.h"
 
+struct jr_driver_data {
+       /* List of Physical JobR's with the Driver */
+       struct list_head        jr_list;
+       spinlock_t              jr_alloc_lock;  /* jr_list lock */
+} ____cacheline_aligned;
+
+static struct jr_driver_data driver_data;
+
+static int caam_reset_hw_jr(struct device *dev)
+{
+       struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+       unsigned int timeout = 100000;
+
+       /*
+        * mask interrupts since we are going to poll
+        * for reset completion status
+        */
+       setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+
+       /* initiate flush (required prior to reset) */
+       wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
+       while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
+               JRINT_ERR_HALT_INPROGRESS) && --timeout)
+               cpu_relax();
+
+       if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
+           JRINT_ERR_HALT_COMPLETE || timeout == 0) {
+               dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
+               return -EIO;
+       }
+
+       /* initiate reset */
+       timeout = 100000;
+       wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
+       while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
+               cpu_relax();
+
+       if (timeout == 0) {
+               dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
+               return -EIO;
+       }
+
+       /* unmask interrupts */
+       clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+
+       return 0;
+}
+
+/*
+ * Shutdown JobR independent of platform property code
+ */
+int caam_jr_shutdown(struct device *dev)
+{
+       struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+       dma_addr_t inpbusaddr, outbusaddr;
+       int ret;
+
+       ret = caam_reset_hw_jr(dev);
+
+       tasklet_kill(&jrp->irqtask);
+
+       /* Release interrupt */
+       free_irq(jrp->irq, dev);
+
+       /* Free rings */
+       inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
+       outbusaddr = rd_reg64(&jrp->rregs->outring_base);
+       dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
+                         jrp->inpring, inpbusaddr);
+       dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
+                         jrp->outring, outbusaddr);
+       kfree(jrp->entinfo);
+
+       return ret;
+}
+
+static int caam_jr_remove(struct platform_device *pdev)
+{
+       int ret;
+       struct device *jrdev;
+       struct caam_drv_private_jr *jrpriv;
+
+       jrdev = &pdev->dev;
+       jrpriv = dev_get_drvdata(jrdev);
+
+       /*
+        * Return EBUSY if job ring already allocated.
+        */
+       if (atomic_read(&jrpriv->tfm_count)) {
+               dev_err(jrdev, "Device is busy\n");
+               return -EBUSY;
+       }
+
+       /* Remove the node from Physical JobR list maintained by driver */
+       spin_lock(&driver_data.jr_alloc_lock);
+       list_del(&jrpriv->list_node);
+       spin_unlock(&driver_data.jr_alloc_lock);
+
+       /* Release ring */
+       ret = caam_jr_shutdown(jrdev);
+       if (ret)
+               dev_err(jrdev, "Failed to shut down job ring\n");
+       irq_dispose_mapping(jrpriv->irq);
+
+       return ret;
+}
+
 /* Main per-ring interrupt handler */
 static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
 {
@@ -127,6 +235,59 @@ static void caam_jr_dequeue(unsigned long devarg)
        clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
 }
 
+/**
+ * caam_jr_alloc() - Alloc a job ring for someone to use as needed.
+ *
+ * returns :  pointer to the newly allocated physical
+ *           JobR dev can be written to if successful.
+ **/
+struct device *caam_jr_alloc(void)
+{
+       struct caam_drv_private_jr *jrpriv, *min_jrpriv = NULL;
+       struct device *dev = NULL;
+       int min_tfm_cnt = INT_MAX;
+       int tfm_cnt;
+
+       spin_lock(&driver_data.jr_alloc_lock);
+
+       if (list_empty(&driver_data.jr_list)) {
+               spin_unlock(&driver_data.jr_alloc_lock);
+               return ERR_PTR(-ENODEV);
+       }
+
+       list_for_each_entry(jrpriv, &driver_data.jr_list, list_node) {
+               tfm_cnt = atomic_read(&jrpriv->tfm_count);
+               if (tfm_cnt < min_tfm_cnt) {
+                       min_tfm_cnt = tfm_cnt;
+                       min_jrpriv = jrpriv;
+               }
+               if (!min_tfm_cnt)
+                       break;
+       }
+
+       if (min_jrpriv) {
+               atomic_inc(&min_jrpriv->tfm_count);
+               dev = min_jrpriv->dev;
+       }
+       spin_unlock(&driver_data.jr_alloc_lock);
+
+       return dev;
+}
+EXPORT_SYMBOL(caam_jr_alloc);
+
+/**
+ * caam_jr_free() - Free the Job Ring
+ * @rdev     - points to the dev that identifies the Job ring to
+ *             be released.
+ **/
+void caam_jr_free(struct device *rdev)
+{
+       struct caam_drv_private_jr *jrpriv = dev_get_drvdata(rdev);
+
+       atomic_dec(&jrpriv->tfm_count);
+}
+EXPORT_SYMBOL(caam_jr_free);
+
 /**
  * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK,
  * -EBUSY if the queue is full, -EIO if it cannot map the caller's
@@ -207,46 +368,6 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
 }
 EXPORT_SYMBOL(caam_jr_enqueue);
 
-static int caam_reset_hw_jr(struct device *dev)
-{
-       struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
-       unsigned int timeout = 100000;
-
-       /*
-        * mask interrupts since we are going to poll
-        * for reset completion status
-        */
-       setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
-
-       /* initiate flush (required prior to reset) */
-       wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
-       while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
-               JRINT_ERR_HALT_INPROGRESS) && --timeout)
-               cpu_relax();
-
-       if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
-           JRINT_ERR_HALT_COMPLETE || timeout == 0) {
-               dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
-               return -EIO;
-       }
-
-       /* initiate reset */
-       timeout = 100000;
-       wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
-       while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
-               cpu_relax();
-
-       if (timeout == 0) {
-               dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
-               return -EIO;
-       }
-
-       /* unmask interrupts */
-       clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
-
-       return 0;
-}
-
 /*
  * Init JobR independent of platform property detection
  */
@@ -262,7 +383,7 @@ static int caam_jr_init(struct device *dev)
 
        /* Connect job ring interrupt handler. */
        error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED,
-                           "caam-jobr", dev);
+                           dev_name(dev), dev);
        if (error) {
                dev_err(dev, "can't connect JobR %d interrupt (%d)\n",
                        jrp->ridx, jrp->irq);
@@ -318,86 +439,43 @@ static int caam_jr_init(struct device *dev)
        return 0;
 }
 
-/*
- * Shutdown JobR independent of platform property code
- */
-int caam_jr_shutdown(struct device *dev)
-{
-       struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
-       dma_addr_t inpbusaddr, outbusaddr;
-       int ret;
-
-       ret = caam_reset_hw_jr(dev);
-
-       tasklet_kill(&jrp->irqtask);
-
-       /* Release interrupt */
-       free_irq(jrp->irq, dev);
-
-       /* Free rings */
-       inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
-       outbusaddr = rd_reg64(&jrp->rregs->outring_base);
-       dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
-                         jrp->inpring, inpbusaddr);
-       dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
-                         jrp->outring, outbusaddr);
-       kfree(jrp->entinfo);
-       of_device_unregister(jrp->jr_pdev);
-
-       return ret;
-}
 
 /*
- * Probe routine for each detected JobR subsystem. It assumes that
- * property detection was picked up externally.
+ * Probe routine for each detected JobR subsystem.
  */
-int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
-                 int ring)
+static int caam_jr_probe(struct platform_device *pdev)
 {
-       struct device *ctrldev, *jrdev;
-       struct platform_device *jr_pdev;
-       struct caam_drv_private *ctrlpriv;
+       struct device *jrdev;
+       struct device_node *nprop;
+       struct caam_job_ring __iomem *ctrl;
        struct caam_drv_private_jr *jrpriv;
-       u32 *jroffset;
+       static int total_jobrs;
        int error;
 
-       ctrldev = &pdev->dev;
-       ctrlpriv = dev_get_drvdata(ctrldev);
-
+       jrdev = &pdev->dev;
        jrpriv = kmalloc(sizeof(struct caam_drv_private_jr),
                         GFP_KERNEL);
-       if (jrpriv == NULL) {
-               dev_err(ctrldev, "can't alloc private mem for job ring %d\n",
-                       ring);
+       if (!jrpriv)
                return -ENOMEM;
-       }
-       jrpriv->parentdev = ctrldev; /* point back to parent */
-       jrpriv->ridx = ring; /* save ring identity relative to detection */
 
-       /*
-        * Derive a pointer to the detected JobRs regs
-        * Driver has already iomapped the entire space, we just
-        * need to add in the offset to this JobR. Don't know if I
-        * like this long-term, but it'll run
-        */
-       jroffset = (u32 *)of_get_property(np, "reg", NULL);
-       jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl
-                                                        + *jroffset);
+       dev_set_drvdata(jrdev, jrpriv);
 
-       /* Build a local dev for each detected queue */
-       jr_pdev = of_platform_device_create(np, NULL, ctrldev);
-       if (jr_pdev == NULL) {
-               kfree(jrpriv);
-               return -EINVAL;
+       /* save ring identity relative to detection */
+       jrpriv->ridx = total_jobrs++;
+
+       nprop = pdev->dev.of_node;
+       /* Get configuration properties from device tree */
+       /* First, get register page */
+       ctrl = of_iomap(nprop, 0);
+       if (!ctrl) {
+               dev_err(jrdev, "of_iomap() failed\n");
+               return -ENOMEM;
        }
 
-       jrpriv->jr_pdev = jr_pdev;
-       jrdev = &jr_pdev->dev;
-       dev_set_drvdata(jrdev, jrpriv);
-       ctrlpriv->jrdev[ring] = jrdev;
+       jrpriv->rregs = (struct caam_job_ring __force *)ctrl;
 
        if (sizeof(dma_addr_t) == sizeof(u64))
-               if (of_device_is_compatible(np, "fsl,sec-v5.0-job-ring"))
+               if (of_device_is_compatible(nprop, "fsl,sec-v5.0-job-ring"))
                        dma_set_mask(jrdev, DMA_BIT_MASK(40));
                else
                        dma_set_mask(jrdev, DMA_BIT_MASK(36));
@@ -405,15 +483,61 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
                dma_set_mask(jrdev, DMA_BIT_MASK(32));
 
        /* Identify the interrupt */
-       jrpriv->irq = irq_of_parse_and_map(np, 0);
+       jrpriv->irq = irq_of_parse_and_map(nprop, 0);
 
        /* Now do the platform independent part */
        error = caam_jr_init(jrdev); /* now turn on hardware */
        if (error) {
-               of_device_unregister(jr_pdev);
                kfree(jrpriv);
                return error;
        }
 
-       return error;
+       jrpriv->dev = jrdev;
+       spin_lock(&driver_data.jr_alloc_lock);
+       list_add_tail(&jrpriv->list_node, &driver_data.jr_list);
+       spin_unlock(&driver_data.jr_alloc_lock);
+
+       atomic_set(&jrpriv->tfm_count, 0);
+
+       return 0;
+}
+
+static struct of_device_id caam_jr_match[] = {
+       {
+               .compatible = "fsl,sec-v4.0-job-ring",
+       },
+       {
+               .compatible = "fsl,sec4.0-job-ring",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, caam_jr_match);
+
+static struct platform_driver caam_jr_driver = {
+       .driver = {
+               .name = "caam_jr",
+               .owner = THIS_MODULE,
+               .of_match_table = caam_jr_match,
+       },
+       .probe       = caam_jr_probe,
+       .remove      = caam_jr_remove,
+};
+
+static int __init jr_driver_init(void)
+{
+       spin_lock_init(&driver_data.jr_alloc_lock);
+       INIT_LIST_HEAD(&driver_data.jr_list);
+       return platform_driver_register(&caam_jr_driver);
+}
+
+static void __exit jr_driver_exit(void)
+{
+       platform_driver_unregister(&caam_jr_driver);
 }
+
+module_init(jr_driver_init);
+module_exit(jr_driver_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("FSL CAAM JR request backend");
+MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
index 9d8741a59037f82ea162ef2a0b894bca49b5b040..97113a6d6c58f500cd7aeb64a4d506ebfc0ca688 100644 (file)
@@ -8,12 +8,11 @@
 #define JR_H
 
 /* Prototypes for backend-level services exposed to APIs */
+struct device *caam_jr_alloc(void);
+void caam_jr_free(struct device *rdev);
 int caam_jr_enqueue(struct device *dev, u32 *desc,
                    void (*cbk)(struct device *dev, u32 *desc, u32 status,
                                void *areq),
                    void *areq);
 
-extern int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
-                        int ring);
-extern int caam_jr_shutdown(struct device *dev);
 #endif /* JR_H */
index 4455396918de84320380fcca2eca01d694971114..d50174f45b21c8e0c145d7077ec86f86cb66ff37 100644 (file)
@@ -245,7 +245,7 @@ struct rngtst {
 
 /* RNG4 TRNG test registers */
 struct rng4tst {
-#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */
+#define RTMCTL_PRGM    0x00010000      /* 1 -> program mode, 0 -> run mode */
        u32 rtmctl;             /* misc. control register */
        u32 rtscmisc;           /* statistical check misc. register */
        u32 rtpkrrng;           /* poker range register */
@@ -255,6 +255,8 @@ struct rng4tst {
        };
 #define RTSDCTL_ENT_DLY_SHIFT 16
 #define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
+#define RTSDCTL_ENT_DLY_MIN 1200
+#define RTSDCTL_ENT_DLY_MAX 12800
        u32 rtsdctl;            /* seed control register */
        union {
                u32 rtsblim;    /* PRGM=1: sparse bit limit register */
@@ -266,7 +268,11 @@ struct rng4tst {
                u32 rtfrqcnt;   /* PRGM=0: freq. count register */
        };
        u32 rsvd1[40];
+#define RDSTA_SKVT 0x80000000
+#define RDSTA_SKVN 0x40000000
 #define RDSTA_IF0 0x00000001
+#define RDSTA_IF1 0x00000002
+#define RDSTA_IFMASK (RDSTA_IF1 | RDSTA_IF0)
        u32 rdsta;
        u32 rsvd2[15];
 };
@@ -692,6 +698,7 @@ struct caam_deco {
        u32 jr_ctl_hi;  /* CxJRR - JobR Control Register      @800 */
        u32 jr_ctl_lo;
        u64 jr_descaddr;        /* CxDADR - JobR Descriptor Address */
+#define DECO_OP_STATUS_HI_ERR_MASK 0xF00000FF
        u32 op_status_hi;       /* DxOPSTA - DECO Operation Status */
        u32 op_status_lo;
        u32 rsvd24[2];
@@ -706,12 +713,13 @@ struct caam_deco {
        u32 rsvd29[48];
        u32 descbuf[64];        /* DxDESB - Descriptor buffer */
        u32 rscvd30[193];
+#define DESC_DBG_DECO_STAT_HOST_ERR    0x00D00000
+#define DESC_DBG_DECO_STAT_VALID       0x80000000
+#define DESC_DBG_DECO_STAT_MASK                0x00F00000
        u32 desc_dbg;           /* DxDDR - DECO Debug Register */
        u32 rsvd31[126];
 };
 
-/* DECO DBG Register Valid Bit*/
-#define DECO_DBG_VALID         0x80000000
 #define DECO_JQCR_WHL          0x20000000
 #define DECO_JQCR_FOUR         0x10000000
 
index e0037c8ee24386e941e5eed6189e9c2cd9747a3a..b12ff85f4241ece439e43310b115d16a08c5e2eb 100644 (file)
@@ -117,6 +117,21 @@ static int dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg,
        return nents;
 }
 
+/* Map SG page in kernel virtual address space and copy */
+static inline void sg_map_copy(u8 *dest, struct scatterlist *sg,
+                              int len, int offset)
+{
+       u8 *mapped_addr;
+
+       /*
+        * Page here can be user-space pinned using get_user_pages
+        * Same must be kmapped before use and kunmapped subsequently
+        */
+       mapped_addr = kmap_atomic(sg_page(sg));
+       memcpy(dest, mapped_addr + offset, len);
+       kunmap_atomic(mapped_addr);
+}
+
 /* Copy from len bytes of sg to dest, starting from beginning */
 static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len)
 {
@@ -124,15 +139,15 @@ static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len)
        int cpy_index = 0, next_cpy_index = current_sg->length;
 
        while (next_cpy_index < len) {
-               memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg),
-                      current_sg->length);
+               sg_map_copy(dest + cpy_index, current_sg, current_sg->length,
+                           current_sg->offset);
                current_sg = scatterwalk_sg_next(current_sg);
                cpy_index = next_cpy_index;
                next_cpy_index += current_sg->length;
        }
        if (cpy_index < len)
-               memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg),
-                      len - cpy_index);
+               sg_map_copy(dest + cpy_index, current_sg, len-cpy_index,
+                           current_sg->offset);
 }
 
 /* Copy sg data, from to_skip to end, to dest */
@@ -140,7 +155,7 @@ static inline void sg_copy_part(u8 *dest, struct scatterlist *sg,
                                      int to_skip, unsigned int end)
 {
        struct scatterlist *current_sg = sg;
-       int sg_index, cpy_index;
+       int sg_index, cpy_index, offset;
 
        sg_index = current_sg->length;
        while (sg_index <= to_skip) {
@@ -148,9 +163,10 @@ static inline void sg_copy_part(u8 *dest, struct scatterlist *sg,
                sg_index += current_sg->length;
        }
        cpy_index = sg_index - to_skip;
-       memcpy(dest, (u8 *) sg_virt(current_sg) +
-              current_sg->length - cpy_index, cpy_index);
-       current_sg = scatterwalk_sg_next(current_sg);
-       if (end - sg_index)
+       offset = current_sg->offset + current_sg->length - cpy_index;
+       sg_map_copy(dest, current_sg, cpy_index, offset);
+       if (end - sg_index) {
+               current_sg = scatterwalk_sg_next(current_sg);
                sg_copy(dest + cpy_index, current_sg, end - sg_index);
+       }
 }
index a8a7dd4b0d25c6741d47e40b53b9d3cfd7f101ad..247ab8048f5bea3f09e5537f103626fe84e3bce5 100644 (file)
@@ -733,12 +733,9 @@ static int dcp_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, dev);
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!r) {
-               dev_err(&pdev->dev, "failed to get IORESOURCE_MEM\n");
-               return -ENXIO;
-       }
-       dev->dcp_regs_base = devm_ioremap(&pdev->dev, r->start,
-                                         resource_size(r));
+       dev->dcp_regs_base = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(dev->dcp_regs_base))
+               return PTR_ERR(dev->dcp_regs_base);
 
        dcp_set(dev, DCP_CTRL_SFRST, DCP_REG_CTRL);
        udelay(10);
@@ -762,7 +759,8 @@ static int dcp_probe(struct platform_device *pdev)
                return -EIO;
        }
        dev->dcp_vmi_irq = r->start;
-       ret = request_irq(dev->dcp_vmi_irq, dcp_vmi_irq, 0, "dcp", dev);
+       ret = devm_request_irq(&pdev->dev, dev->dcp_vmi_irq, dcp_vmi_irq, 0,
+                              "dcp", dev);
        if (ret != 0) {
                dev_err(&pdev->dev, "can't request_irq (0)\n");
                return -EIO;
@@ -771,15 +769,14 @@ static int dcp_probe(struct platform_device *pdev)
        r = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
        if (!r) {
                dev_err(&pdev->dev, "can't get IRQ resource (1)\n");
-               ret = -EIO;
-               goto err_free_irq0;
+               return -EIO;
        }
        dev->dcp_irq = r->start;
-       ret = request_irq(dev->dcp_irq, dcp_irq, 0, "dcp", dev);
+       ret = devm_request_irq(&pdev->dev, dev->dcp_irq, dcp_irq, 0, "dcp",
+                              dev);
        if (ret != 0) {
                dev_err(&pdev->dev, "can't request_irq (1)\n");
-               ret = -EIO;
-               goto err_free_irq0;
+               return -EIO;
        }
 
        dev->hw_pkg[0] = dma_alloc_coherent(&pdev->dev,
@@ -788,8 +785,7 @@ static int dcp_probe(struct platform_device *pdev)
                        GFP_KERNEL);
        if (!dev->hw_pkg[0]) {
                dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
-               ret = -ENOMEM;
-               goto err_free_irq1;
+               return -ENOMEM;
        }
 
        for (i = 1; i < DCP_MAX_PKG; i++) {
@@ -848,16 +844,14 @@ err_unregister:
        for (j = 0; j < i; j++)
                crypto_unregister_alg(&algs[j]);
 err_free_key_iv:
+       tasklet_kill(&dev->done_task);
+       tasklet_kill(&dev->queue_task);
        dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
                        dev->payload_base_dma);
 err_free_hw_packet:
        dma_free_coherent(&pdev->dev, DCP_MAX_PKG *
                sizeof(struct dcp_hw_packet), dev->hw_pkg[0],
                dev->hw_phys_pkg);
-err_free_irq1:
-       free_irq(dev->dcp_irq, dev);
-err_free_irq0:
-       free_irq(dev->dcp_vmi_irq, dev);
 
        return ret;
 }
@@ -868,23 +862,20 @@ static int dcp_remove(struct platform_device *pdev)
        int j;
        dev = platform_get_drvdata(pdev);
 
-       dma_free_coherent(&pdev->dev,
-                       DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
-                       dev->hw_pkg[0], dev->hw_phys_pkg);
-
-       dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
-                       dev->payload_base_dma);
+       misc_deregister(&dev->dcp_bootstream_misc);
 
-       free_irq(dev->dcp_irq, dev);
-       free_irq(dev->dcp_vmi_irq, dev);
+       for (j = 0; j < ARRAY_SIZE(algs); j++)
+               crypto_unregister_alg(&algs[j]);
 
        tasklet_kill(&dev->done_task);
        tasklet_kill(&dev->queue_task);
 
-       for (j = 0; j < ARRAY_SIZE(algs); j++)
-               crypto_unregister_alg(&algs[j]);
+       dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
+                       dev->payload_base_dma);
 
-       misc_deregister(&dev->dcp_bootstream_misc);
+       dma_free_coherent(&pdev->dev,
+                       DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
+                       dev->hw_pkg[0], dev->hw_phys_pkg);
 
        return 0;
 }
index 214357e12dc0b5469bb3c9daae5904ef3a618845..9dd6e01eac33050b8304c5f8758440e7286606f2 100644 (file)
@@ -1149,32 +1149,24 @@ static int aead_setkey(struct crypto_aead *tfm, const u8 *key,
                        unsigned int keylen)
 {
        struct ixp_ctx *ctx = crypto_aead_ctx(tfm);
-       struct rtattr *rta = (struct rtattr *)key;
-       struct crypto_authenc_key_param *param;
+       struct crypto_authenc_keys keys;
 
-       if (!RTA_OK(rta, keylen))
-               goto badkey;
-       if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
-               goto badkey;
-       if (RTA_PAYLOAD(rta) < sizeof(*param))
+       if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
                goto badkey;
 
-       param = RTA_DATA(rta);
-       ctx->enckey_len = be32_to_cpu(param->enckeylen);
-
-       key += RTA_ALIGN(rta->rta_len);
-       keylen -= RTA_ALIGN(rta->rta_len);
+       if (keys.authkeylen > sizeof(ctx->authkey))
+               goto badkey;
 
-       if (keylen < ctx->enckey_len)
+       if (keys.enckeylen > sizeof(ctx->enckey))
                goto badkey;
 
-       ctx->authkey_len = keylen - ctx->enckey_len;
-       memcpy(ctx->enckey, key + ctx->authkey_len, ctx->enckey_len);
-       memcpy(ctx->authkey, key, ctx->authkey_len);
+       memcpy(ctx->authkey, keys.authkey, keys.authkeylen);
+       memcpy(ctx->enckey, keys.enckey, keys.enckeylen);
+       ctx->authkey_len = keys.authkeylen;
+       ctx->enckey_len = keys.enckeylen;
 
        return aead_setup(tfm, crypto_aead_authsize(tfm));
 badkey:
-       ctx->enckey_len = 0;
        crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
        return -EINVAL;
 }
index 3374a3ebe4c75f49ecacbec24740ead4e05011b8..8d1e6f8e9e9cf613519b14fa5e5126135d37e986 100644 (file)
@@ -907,7 +907,7 @@ static int mv_cra_hash_hmac_sha1_init(struct crypto_tfm *tfm)
        return mv_cra_hash_init(tfm, "sha1", COP_HMAC_SHA1, SHA1_BLOCK_SIZE);
 }
 
-irqreturn_t crypto_int(int irq, void *priv)
+static irqreturn_t crypto_int(int irq, void *priv)
 {
        u32 val;
 
@@ -928,7 +928,7 @@ irqreturn_t crypto_int(int irq, void *priv)
        return IRQ_HANDLED;
 }
 
-struct crypto_alg mv_aes_alg_ecb = {
+static struct crypto_alg mv_aes_alg_ecb = {
        .cra_name               = "ecb(aes)",
        .cra_driver_name        = "mv-ecb-aes",
        .cra_priority   = 300,
@@ -951,7 +951,7 @@ struct crypto_alg mv_aes_alg_ecb = {
        },
 };
 
-struct crypto_alg mv_aes_alg_cbc = {
+static struct crypto_alg mv_aes_alg_cbc = {
        .cra_name               = "cbc(aes)",
        .cra_driver_name        = "mv-cbc-aes",
        .cra_priority   = 300,
@@ -975,7 +975,7 @@ struct crypto_alg mv_aes_alg_cbc = {
        },
 };
 
-struct ahash_alg mv_sha1_alg = {
+static struct ahash_alg mv_sha1_alg = {
        .init = mv_hash_init,
        .update = mv_hash_update,
        .final = mv_hash_final,
@@ -999,7 +999,7 @@ struct ahash_alg mv_sha1_alg = {
                 }
 };
 
-struct ahash_alg mv_hmac_sha1_alg = {
+static struct ahash_alg mv_hmac_sha1_alg = {
        .init = mv_hash_init,
        .update = mv_hash_update,
        .final = mv_hash_final,
@@ -1084,7 +1084,7 @@ static int mv_probe(struct platform_device *pdev)
                goto err_unmap_sram;
        }
 
-       ret = request_irq(irq, crypto_int, IRQF_DISABLED, dev_name(&pdev->dev),
+       ret = request_irq(irq, crypto_int, 0, dev_name(&pdev->dev),
                        cp);
        if (ret)
                goto err_thread;
@@ -1187,7 +1187,7 @@ static struct platform_driver marvell_crypto = {
        .driver         = {
                .owner  = THIS_MODULE,
                .name   = "mv_crypto",
-               .of_match_table = of_match_ptr(mv_cesa_of_match_table),
+               .of_match_table = mv_cesa_of_match_table,
        },
 };
 MODULE_ALIAS("platform:mv_crypto");
index ce791c2f81f79e4ffda5d7d44e6a31a8a46bcb34..a9ccbf14096e3c03a9c193042baddc6d5b0e4925 100644 (file)
@@ -275,7 +275,7 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
        if (dd->flags & FLAGS_CBC)
                val |= AES_REG_CTRL_CBC;
        if (dd->flags & FLAGS_CTR) {
-               val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_32;
+               val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_128;
                mask = AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_MASK;
        }
        if (dd->flags & FLAGS_ENCRYPT)
@@ -554,7 +554,7 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
        return err;
 }
 
-int omap_aes_check_aligned(struct scatterlist *sg)
+static int omap_aes_check_aligned(struct scatterlist *sg)
 {
        while (sg) {
                if (!IS_ALIGNED(sg->offset, 4))
@@ -566,7 +566,7 @@ int omap_aes_check_aligned(struct scatterlist *sg)
        return 0;
 }
 
-int omap_aes_copy_sgs(struct omap_aes_dev *dd)
+static int omap_aes_copy_sgs(struct omap_aes_dev *dd)
 {
        void *buf_in, *buf_out;
        int pages;
index e28104b4aab08ce20a9c1bbf26aefdb45778379a..e45aaaf0db3069d5c99cef88664dfdc62a87d434 100644 (file)
@@ -2033,3 +2033,4 @@ module_platform_driver(omap_sham_driver);
 MODULE_DESCRIPTION("OMAP SHA1/MD5 hw acceleration support.");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Dmitry Kasatkin");
+MODULE_ALIAS("platform:omap-sham");
index 888f7f4a6d3fa29a36c26a1ee1119428164d9df9..a6175ba6d2389f96ea118470123fd3e7818fb279 100644 (file)
@@ -495,45 +495,29 @@ static int spacc_aead_setkey(struct crypto_aead *tfm, const u8 *key,
 {
        struct spacc_aead_ctx *ctx = crypto_aead_ctx(tfm);
        struct spacc_alg *alg = to_spacc_alg(tfm->base.__crt_alg);
-       struct rtattr *rta = (void *)key;
-       struct crypto_authenc_key_param *param;
-       unsigned int authkeylen, enckeylen;
+       struct crypto_authenc_keys keys;
        int err = -EINVAL;
 
-       if (!RTA_OK(rta, keylen))
+       if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
                goto badkey;
 
-       if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
+       if (keys.enckeylen > AES_MAX_KEY_SIZE)
                goto badkey;
 
-       if (RTA_PAYLOAD(rta) < sizeof(*param))
-               goto badkey;
-
-       param = RTA_DATA(rta);
-       enckeylen = be32_to_cpu(param->enckeylen);
-
-       key += RTA_ALIGN(rta->rta_len);
-       keylen -= RTA_ALIGN(rta->rta_len);
-
-       if (keylen < enckeylen)
-               goto badkey;
-
-       authkeylen = keylen - enckeylen;
-
-       if (enckeylen > AES_MAX_KEY_SIZE)
+       if (keys.authkeylen > sizeof(ctx->hash_ctx))
                goto badkey;
 
        if ((alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) ==
            SPA_CTRL_CIPH_ALG_AES)
-               err = spacc_aead_aes_setkey(tfm, key + authkeylen, enckeylen);
+               err = spacc_aead_aes_setkey(tfm, keys.enckey, keys.enckeylen);
        else
-               err = spacc_aead_des_setkey(tfm, key + authkeylen, enckeylen);
+               err = spacc_aead_des_setkey(tfm, keys.enckey, keys.enckeylen);
 
        if (err)
                goto badkey;
 
-       memcpy(ctx->hash_ctx, keyauthkeylen);
-       ctx->hash_key_len = authkeylen;
+       memcpy(ctx->hash_ctx, keys.authkey, keys.authkeylen);
+       ctx->hash_key_len = keys.authkeylen;
 
        return 0;
 
index d7bb8bac36e973944334409760dc56c37eb02be1..785a9ded7bdf3bda2840bc36daa88fe7f1532a9b 100644 (file)
@@ -1058,7 +1058,7 @@ static struct platform_driver sahara_driver = {
        .driver         = {
                .name   = SAHARA_NAME,
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(sahara_dt_ids),
+               .of_match_table = sahara_dt_ids,
        },
        .id_table = sahara_platform_ids,
 };
index 6cd0e603858321dd678b45ad74dda8f6746fba97..b44f4ddc565c3bb7cd32b84c08a0b286543681e5 100644 (file)
@@ -673,39 +673,20 @@ static int aead_setkey(struct crypto_aead *authenc,
                       const u8 *key, unsigned int keylen)
 {
        struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
-       struct rtattr *rta = (void *)key;
-       struct crypto_authenc_key_param *param;
-       unsigned int authkeylen;
-       unsigned int enckeylen;
-
-       if (!RTA_OK(rta, keylen))
-               goto badkey;
+       struct crypto_authenc_keys keys;
 
-       if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
+       if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
                goto badkey;
 
-       if (RTA_PAYLOAD(rta) < sizeof(*param))
+       if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
                goto badkey;
 
-       param = RTA_DATA(rta);
-       enckeylen = be32_to_cpu(param->enckeylen);
-
-       key += RTA_ALIGN(rta->rta_len);
-       keylen -= RTA_ALIGN(rta->rta_len);
+       memcpy(ctx->key, keys.authkey, keys.authkeylen);
+       memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
 
-       if (keylen < enckeylen)
-               goto badkey;
-
-       authkeylen = keylen - enckeylen;
-
-       if (keylen > TALITOS_MAX_KEY_SIZE)
-               goto badkey;
-
-       memcpy(&ctx->key, key, keylen);
-
-       ctx->keylen = keylen;
-       ctx->enckeylen = enckeylen;
-       ctx->authkeylen = authkeylen;
+       ctx->keylen = keys.authkeylen + keys.enckeylen;
+       ctx->enckeylen = keys.enckeylen;
+       ctx->authkeylen = keys.authkeylen;
 
        return 0;
 
@@ -809,7 +790,7 @@ static void ipsec_esp_unmap(struct device *dev,
 
        if (edesc->assoc_chained)
                talitos_unmap_sg_chain(dev, areq->assoc, DMA_TO_DEVICE);
-       else
+       else if (areq->assoclen)
                /* assoc_nents counts also for IV in non-contiguous cases */
                dma_unmap_sg(dev, areq->assoc,
                             edesc->assoc_nents ? edesc->assoc_nents - 1 : 1,
@@ -992,7 +973,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
                dma_sync_single_for_device(dev, edesc->dma_link_tbl,
                                           edesc->dma_len, DMA_BIDIRECTIONAL);
        } else {
-               to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->assoc));
+               if (areq->assoclen)
+                       to_talitos_ptr(&desc->ptr[1],
+                                      sg_dma_address(areq->assoc));
+               else
+                       to_talitos_ptr(&desc->ptr[1], edesc->iv_dma);
                desc->ptr[1].j_extent = 0;
        }
 
@@ -1127,7 +1112,8 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
                                                 unsigned int authsize,
                                                 unsigned int ivsize,
                                                 int icv_stashing,
-                                                u32 cryptoflags)
+                                                u32 cryptoflags,
+                                                bool encrypt)
 {
        struct talitos_edesc *edesc;
        int assoc_nents = 0, src_nents, dst_nents, alloc_len, dma_len;
@@ -1141,10 +1127,10 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
                return ERR_PTR(-EINVAL);
        }
 
-       if (iv)
+       if (ivsize)
                iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
 
-       if (assoc) {
+       if (assoclen) {
                /*
                 * Currently it is assumed that iv is provided whenever assoc
                 * is.
@@ -1160,19 +1146,17 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
                        assoc_nents = assoc_nents ? assoc_nents + 1 : 2;
        }
 
-       src_nents = sg_count(src, cryptlen + authsize, &src_chained);
-       src_nents = (src_nents == 1) ? 0 : src_nents;
-
-       if (!dst) {
-               dst_nents = 0;
-       } else {
-               if (dst == src) {
-                       dst_nents = src_nents;
-               } else {
-                       dst_nents = sg_count(dst, cryptlen + authsize,
-                                            &dst_chained);
-                       dst_nents = (dst_nents == 1) ? 0 : dst_nents;
-               }
+       if (!dst || dst == src) {
+               src_nents = sg_count(src, cryptlen + authsize, &src_chained);
+               src_nents = (src_nents == 1) ? 0 : src_nents;
+               dst_nents = dst ? src_nents : 0;
+       } else { /* dst && dst != src*/
+               src_nents = sg_count(src, cryptlen + (encrypt ? 0 : authsize),
+                                    &src_chained);
+               src_nents = (src_nents == 1) ? 0 : src_nents;
+               dst_nents = sg_count(dst, cryptlen + (encrypt ? authsize : 0),
+                                    &dst_chained);
+               dst_nents = (dst_nents == 1) ? 0 : dst_nents;
        }
 
        /*
@@ -1192,9 +1176,16 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
 
        edesc = kmalloc(alloc_len, GFP_DMA | flags);
        if (!edesc) {
-               talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE);
+               if (assoc_chained)
+                       talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE);
+               else if (assoclen)
+                       dma_unmap_sg(dev, assoc,
+                                    assoc_nents ? assoc_nents - 1 : 1,
+                                    DMA_TO_DEVICE);
+
                if (iv_dma)
                        dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
+
                dev_err(dev, "could not allocate edescriptor\n");
                return ERR_PTR(-ENOMEM);
        }
@@ -1216,7 +1207,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
 }
 
 static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
-                                             int icv_stashing)
+                                             int icv_stashing, bool encrypt)
 {
        struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
        struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
@@ -1225,7 +1216,7 @@ static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
        return talitos_edesc_alloc(ctx->dev, areq->assoc, areq->src, areq->dst,
                                   iv, areq->assoclen, areq->cryptlen,
                                   ctx->authsize, ivsize, icv_stashing,
-                                  areq->base.flags);
+                                  areq->base.flags, encrypt);
 }
 
 static int aead_encrypt(struct aead_request *req)
@@ -1235,7 +1226,7 @@ static int aead_encrypt(struct aead_request *req)
        struct talitos_edesc *edesc;
 
        /* allocate extended descriptor */
-       edesc = aead_edesc_alloc(req, req->iv, 0);
+       edesc = aead_edesc_alloc(req, req->iv, 0, true);
        if (IS_ERR(edesc))
                return PTR_ERR(edesc);
 
@@ -1258,7 +1249,7 @@ static int aead_decrypt(struct aead_request *req)
        req->cryptlen -= authsize;
 
        /* allocate extended descriptor */
-       edesc = aead_edesc_alloc(req, req->iv, 1);
+       edesc = aead_edesc_alloc(req, req->iv, 1, false);
        if (IS_ERR(edesc))
                return PTR_ERR(edesc);
 
@@ -1304,7 +1295,7 @@ static int aead_givencrypt(struct aead_givcrypt_request *req)
        struct talitos_edesc *edesc;
 
        /* allocate extended descriptor */
-       edesc = aead_edesc_alloc(areq, req->giv, 0);
+       edesc = aead_edesc_alloc(areq, req->giv, 0, true);
        if (IS_ERR(edesc))
                return PTR_ERR(edesc);
 
@@ -1460,7 +1451,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
 }
 
 static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
-                                                   areq)
+                                                   areq, bool encrypt)
 {
        struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
        struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
@@ -1468,7 +1459,7 @@ static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
 
        return talitos_edesc_alloc(ctx->dev, NULL, areq->src, areq->dst,
                                   areq->info, 0, areq->nbytes, 0, ivsize, 0,
-                                  areq->base.flags);
+                                  areq->base.flags, encrypt);
 }
 
 static int ablkcipher_encrypt(struct ablkcipher_request *areq)
@@ -1478,7 +1469,7 @@ static int ablkcipher_encrypt(struct ablkcipher_request *areq)
        struct talitos_edesc *edesc;
 
        /* allocate extended descriptor */
-       edesc = ablkcipher_edesc_alloc(areq);
+       edesc = ablkcipher_edesc_alloc(areq, true);
        if (IS_ERR(edesc))
                return PTR_ERR(edesc);
 
@@ -1495,7 +1486,7 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq)
        struct talitos_edesc *edesc;
 
        /* allocate extended descriptor */
-       edesc = ablkcipher_edesc_alloc(areq);
+       edesc = ablkcipher_edesc_alloc(areq, false);
        if (IS_ERR(edesc))
                return PTR_ERR(edesc);
 
@@ -1647,7 +1638,7 @@ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
        struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
 
        return talitos_edesc_alloc(ctx->dev, NULL, req_ctx->psrc, NULL, NULL, 0,
-                                  nbytes, 0, 0, 0, areq->base.flags);
+                                  nbytes, 0, 0, 0, areq->base.flags, false);
 }
 
 static int ahash_init(struct ahash_request *areq)
index fa05e3c329bdd44a522a922a1d12e87a54393309..060eecc5dbc31b24bf0c05301b37192da7e36dff 100644 (file)
@@ -27,6 +27,8 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
@@ -199,8 +201,6 @@ static void aes_workqueue_handler(struct work_struct *work);
 static DECLARE_WORK(aes_work, aes_workqueue_handler);
 static struct workqueue_struct *aes_wq;
 
-extern unsigned long long tegra_chip_uid(void);
-
 static inline u32 aes_readl(struct tegra_aes_dev *dd, u32 offset)
 {
        return readl(dd->io_base + offset);
@@ -713,13 +713,12 @@ static int tegra_aes_rng_reset(struct crypto_rng *tfm, u8 *seed,
        struct tegra_aes_dev *dd = aes_dev;
        struct tegra_aes_ctx *ctx = &rng_ctx;
        struct tegra_aes_slot *key_slot;
-       struct timespec ts;
        int ret = 0;
-       u64 nsec, tmp[2];
+       u8 tmp[16]; /* 16 bytes = 128 bits of entropy */
        u8 *dt;
 
        if (!ctx || !dd) {
-               dev_err(dd->dev, "ctx=0x%x, dd=0x%x\n",
+               pr_err("ctx=0x%x, dd=0x%x\n",
                        (unsigned int)ctx, (unsigned int)dd);
                return -EINVAL;
        }
@@ -778,14 +777,8 @@ static int tegra_aes_rng_reset(struct crypto_rng *tfm, u8 *seed,
        if (dd->ivlen >= (2 * DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) {
                dt = dd->iv + DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128;
        } else {
-               getnstimeofday(&ts);
-               nsec = timespec_to_ns(&ts);
-               do_div(nsec, 1000);
-               nsec ^= dd->ctr << 56;
-               dd->ctr++;
-               tmp[0] = nsec;
-               tmp[1] = tegra_chip_uid();
-               dt = (u8 *)tmp;
+               get_random_bytes(tmp, sizeof(tmp));
+               dt = tmp;
        }
        memcpy(dd->dt, dt, DEFAULT_RNG_BLK_SZ);
 
@@ -804,7 +797,7 @@ static int tegra_aes_cra_init(struct crypto_tfm *tfm)
        return 0;
 }
 
-void tegra_aes_cra_exit(struct crypto_tfm *tfm)
+static void tegra_aes_cra_exit(struct crypto_tfm *tfm)
 {
        struct tegra_aes_ctx *ctx =
                crypto_ablkcipher_ctx((struct crypto_ablkcipher *)tfm);
@@ -924,7 +917,7 @@ static int tegra_aes_probe(struct platform_device *pdev)
        }
 
        /* Initialize the vde clock */
-       dd->aes_clk = clk_get(dev, "vde");
+       dd->aes_clk = devm_clk_get(dev, "vde");
        if (IS_ERR(dd->aes_clk)) {
                dev_err(dev, "iclock intialization failed.\n");
                err = -ENODEV;
@@ -1033,8 +1026,6 @@ out:
        if (dd->buf_out)
                dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
                        dd->buf_out, dd->dma_buf_out);
-       if (!IS_ERR(dd->aes_clk))
-               clk_put(dd->aes_clk);
        if (aes_wq)
                destroy_workqueue(aes_wq);
        spin_lock(&list_lock);
@@ -1068,7 +1059,6 @@ static int tegra_aes_remove(struct platform_device *pdev)
                          dd->buf_in, dd->dma_buf_in);
        dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
                          dd->buf_out, dd->dma_buf_out);
-       clk_put(dd->aes_clk);
        aes_dev = NULL;
 
        return 0;
index 16a2aa28f85672689f66c37039a8e72230e71b02..ec4ee5c1fe9dc2115e029d0c472bd32f48cb281c 100644 (file)
@@ -1169,7 +1169,7 @@ static void pl08x_desc_free(struct virt_dma_desc *vd)
        struct pl08x_txd *txd = to_pl08x_txd(&vd->tx);
        struct pl08x_dma_chan *plchan = to_pl08x_chan(vd->tx.chan);
 
-       dma_descriptor_unmap(txd);
+       dma_descriptor_unmap(&vd->tx);
        if (!txd->done)
                pl08x_release_mux(plchan);
 
index c75679d420286c522679cdb9c344549c97e7a0c4..152247675febf42c805b57592c222fc716c8d516 100644 (file)
@@ -323,6 +323,7 @@ struct sdma_engine {
        struct clk                      *clk_ipg;
        struct clk                      *clk_ahb;
        spinlock_t                      channel_0_lock;
+       u32                             script_number;
        struct sdma_script_start_addrs  *script_addrs;
        const struct sdma_driver_data   *drvdata;
 };
@@ -724,6 +725,10 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
                per_2_emi = sdma->script_addrs->app_2_mcu_addr;
                emi_2_per = sdma->script_addrs->mcu_2_app_addr;
                break;
+       case IMX_DMATYPE_SSI_DUAL:
+               per_2_emi = sdma->script_addrs->ssish_2_mcu_addr;
+               emi_2_per = sdma->script_addrs->mcu_2_ssish_addr;
+               break;
        case IMX_DMATYPE_SSI_SP:
        case IMX_DMATYPE_MMC:
        case IMX_DMATYPE_SDHC:
@@ -1238,6 +1243,7 @@ static void sdma_issue_pending(struct dma_chan *chan)
 }
 
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1        34
+#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2        38
 
 static void sdma_add_scripts(struct sdma_engine *sdma,
                const struct sdma_script_start_addrs *addr)
@@ -1246,7 +1252,7 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
        s32 *saddr_arr = (u32 *)sdma->script_addrs;
        int i;
 
-       for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
+       for (i = 0; i < sdma->script_number; i++)
                if (addr_arr[i] > 0)
                        saddr_arr[i] = addr_arr[i];
 }
@@ -1272,6 +1278,17 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
                goto err_firmware;
        if (header->ram_code_start + header->ram_code_size > fw->size)
                goto err_firmware;
+       switch (header->version_major) {
+               case 1:
+                       sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
+                       break;
+               case 2:
+                       sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
+                       break;
+               default:
+                       dev_err(sdma->dev, "unknown firmware version\n");
+                       goto err_firmware;
+       }
 
        addr = (void *)header + header->script_addrs_start;
        ram_code = (void *)header + header->ram_code_start;
index dcb1e05149a7664c6e65a214d783080d540aaafd..3f7712c4d3fa782bd8ae985d182ed8d6ebb48d78 100644 (file)
@@ -5,6 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #define DTADR          0x0208
 #define DCMD           0x020c
 
-#define DCSR_RUN       (1 << 31)       /* Run Bit (read / write) */
-#define DCSR_NODESC    (1 << 30)       /* No-Descriptor Fetch (read / write) */
-#define DCSR_STOPIRQEN (1 << 29)       /* Stop Interrupt Enable (read / write) */
-#define DCSR_REQPEND   (1 << 8)        /* Request Pending (read-only) */
-#define DCSR_STOPSTATE (1 << 3)        /* Stop State (read-only) */
-#define DCSR_ENDINTR   (1 << 2)        /* End Interrupt (read / write) */
-#define DCSR_STARTINTR (1 << 1)        /* Start Interrupt (read / write) */
-#define DCSR_BUSERR    (1 << 0)        /* Bus Error Interrupt (read / write) */
-
-#define DCSR_EORIRQEN  (1 << 28)       /* End of Receive Interrupt Enable (R/W) */
-#define DCSR_EORJMPEN  (1 << 27)       /* Jump to next descriptor on EOR */
-#define DCSR_EORSTOPEN (1 << 26)       /* STOP on an EOR */
-#define DCSR_SETCMPST  (1 << 25)       /* Set Descriptor Compare Status */
-#define DCSR_CLRCMPST  (1 << 24)       /* Clear Descriptor Compare Status */
-#define DCSR_CMPST     (1 << 10)       /* The Descriptor Compare Status */
-#define DCSR_EORINTR   (1 << 9)        /* The end of Receive */
-
-#define DRCMR(n)       ((((n) < 64) ? 0x0100 : 0x1100) + \
-                                (((n) & 0x3f) << 2))
-#define DRCMR_MAPVLD   (1 << 7)        /* Map Valid (read / write) */
-#define DRCMR_CHLNUM   0x1f            /* mask for Channel Number (read / write) */
+#define DCSR_RUN       BIT(31) /* Run Bit (read / write) */
+#define DCSR_NODESC    BIT(30) /* No-Descriptor Fetch (read / write) */
+#define DCSR_STOPIRQEN BIT(29) /* Stop Interrupt Enable (read / write) */
+#define DCSR_REQPEND   BIT(8)  /* Request Pending (read-only) */
+#define DCSR_STOPSTATE BIT(3)  /* Stop State (read-only) */
+#define DCSR_ENDINTR   BIT(2)  /* End Interrupt (read / write) */
+#define DCSR_STARTINTR BIT(1)  /* Start Interrupt (read / write) */
+#define DCSR_BUSERR    BIT(0)  /* Bus Error Interrupt (read / write) */
+
+#define DCSR_EORIRQEN  BIT(28) /* End of Receive Interrupt Enable (R/W) */
+#define DCSR_EORJMPEN  BIT(27) /* Jump to next descriptor on EOR */
+#define DCSR_EORSTOPEN BIT(26) /* STOP on an EOR */
+#define DCSR_SETCMPST  BIT(25) /* Set Descriptor Compare Status */
+#define DCSR_CLRCMPST  BIT(24) /* Clear Descriptor Compare Status */
+#define DCSR_CMPST     BIT(10) /* The Descriptor Compare Status */
+#define DCSR_EORINTR   BIT(9)  /* The end of Receive */
+
+#define DRCMR(n)       ((((n) < 64) ? 0x0100 : 0x1100) + (((n) & 0x3f) << 2))
+#define DRCMR_MAPVLD   BIT(7)  /* Map Valid (read / write) */
+#define DRCMR_CHLNUM   0x1f    /* mask for Channel Number (read / write) */
 
 #define DDADR_DESCADDR 0xfffffff0      /* Address of next descriptor (mask) */
-#define DDADR_STOP     (1 << 0)        /* Stop (read / write) */
-
-#define DCMD_INCSRCADDR        (1 << 31)       /* Source Address Increment Setting. */
-#define DCMD_INCTRGADDR        (1 << 30)       /* Target Address Increment Setting. */
-#define DCMD_FLOWSRC   (1 << 29)       /* Flow Control by the source. */
-#define DCMD_FLOWTRG   (1 << 28)       /* Flow Control by the target. */
-#define DCMD_STARTIRQEN        (1 << 22)       /* Start Interrupt Enable */
-#define DCMD_ENDIRQEN  (1 << 21)       /* End Interrupt Enable */
-#define DCMD_ENDIAN    (1 << 18)       /* Device Endian-ness. */
+#define DDADR_STOP     BIT(0)  /* Stop (read / write) */
+
+#define DCMD_INCSRCADDR        BIT(31) /* Source Address Increment Setting. */
+#define DCMD_INCTRGADDR        BIT(30) /* Target Address Increment Setting. */
+#define DCMD_FLOWSRC   BIT(29) /* Flow Control by the source. */
+#define DCMD_FLOWTRG   BIT(28) /* Flow Control by the target. */
+#define DCMD_STARTIRQEN        BIT(22) /* Start Interrupt Enable */
+#define DCMD_ENDIRQEN  BIT(21) /* End Interrupt Enable */
+#define DCMD_ENDIAN    BIT(18) /* Device Endian-ness. */
 #define DCMD_BURST8    (1 << 16)       /* 8 byte burst */
 #define DCMD_BURST16   (2 << 16)       /* 16 byte burst */
 #define DCMD_BURST32   (3 << 16)       /* 32 byte burst */
@@ -132,10 +132,14 @@ struct mmp_pdma_device {
        spinlock_t phy_lock; /* protect alloc/free phy channels */
 };
 
-#define tx_to_mmp_pdma_desc(tx) container_of(tx, struct mmp_pdma_desc_sw, async_tx)
-#define to_mmp_pdma_desc(lh) container_of(lh, struct mmp_pdma_desc_sw, node)
-#define to_mmp_pdma_chan(dchan) container_of(dchan, struct mmp_pdma_chan, chan)
-#define to_mmp_pdma_dev(dmadev) container_of(dmadev, struct mmp_pdma_device, device)
+#define tx_to_mmp_pdma_desc(tx)                                        \
+       container_of(tx, struct mmp_pdma_desc_sw, async_tx)
+#define to_mmp_pdma_desc(lh)                                   \
+       container_of(lh, struct mmp_pdma_desc_sw, node)
+#define to_mmp_pdma_chan(dchan)                                        \
+       container_of(dchan, struct mmp_pdma_chan, chan)
+#define to_mmp_pdma_dev(dmadev)                                        \
+       container_of(dmadev, struct mmp_pdma_device, device)
 
 static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr)
 {
@@ -162,19 +166,18 @@ static void enable_chan(struct mmp_pdma_phy *phy)
        writel(dalgn, phy->base + DALGN);
 
        reg = (phy->idx << 2) + DCSR;
-       writel(readl(phy->base + reg) | DCSR_RUN,
-                                       phy->base + reg);
+       writel(readl(phy->base + reg) | DCSR_RUN, phy->base + reg);
 }
 
 static void disable_chan(struct mmp_pdma_phy *phy)
 {
        u32 reg;
 
-       if (phy) {
-               reg = (phy->idx << 2) + DCSR;
-               writel(readl(phy->base + reg) & ~DCSR_RUN,
-                                               phy->base + reg);
-       }
+       if (!phy)
+               return;
+
+       reg = (phy->idx << 2) + DCSR;
+       writel(readl(phy->base + reg) & ~DCSR_RUN, phy->base + reg);
 }
 
 static int clear_chan_irq(struct mmp_pdma_phy *phy)
@@ -183,26 +186,27 @@ static int clear_chan_irq(struct mmp_pdma_phy *phy)
        u32 dint = readl(phy->base + DINT);
        u32 reg = (phy->idx << 2) + DCSR;
 
-       if (dint & BIT(phy->idx)) {
-               /* clear irq */
-               dcsr = readl(phy->base + reg);
-               writel(dcsr, phy->base + reg);
-               if ((dcsr & DCSR_BUSERR) && (phy->vchan))
-                       dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
-               return 0;
-       }
-       return -EAGAIN;
+       if (!(dint & BIT(phy->idx)))
+               return -EAGAIN;
+
+       /* clear irq */
+       dcsr = readl(phy->base + reg);
+       writel(dcsr, phy->base + reg);
+       if ((dcsr & DCSR_BUSERR) && (phy->vchan))
+               dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
+
+       return 0;
 }
 
 static irqreturn_t mmp_pdma_chan_handler(int irq, void *dev_id)
 {
        struct mmp_pdma_phy *phy = dev_id;
 
-       if (clear_chan_irq(phy) == 0) {
-               tasklet_schedule(&phy->vchan->tasklet);
-               return IRQ_HANDLED;
-       } else
+       if (clear_chan_irq(phy) != 0)
                return IRQ_NONE;
+
+       tasklet_schedule(&phy->vchan->tasklet);
+       return IRQ_HANDLED;
 }
 
 static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
@@ -224,8 +228,8 @@ static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
 
        if (irq_num)
                return IRQ_HANDLED;
-       else
-               return IRQ_NONE;
+
+       return IRQ_NONE;
 }
 
 /* lookup free phy channel as descending priority */
@@ -245,9 +249,9 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)
         */
 
        spin_lock_irqsave(&pdev->phy_lock, flags);
-       for (prio = 0; prio <= (((pdev->dma_channels - 1) & 0xf) >> 2); prio++) {
+       for (prio = 0; prio <= ((pdev->dma_channels - 1) & 0xf) >> 2; prio++) {
                for (i = 0; i < pdev->dma_channels; i++) {
-                       if (prio != ((i & 0xf) >> 2))
+                       if (prio != (i & 0xf) >> 2)
                                continue;
                        phy = &pdev->phy[i];
                        if (!phy->vchan) {
@@ -389,14 +393,16 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
        if (chan->desc_pool)
                return 1;
 
-       chan->desc_pool =
-               dma_pool_create(dev_name(&dchan->dev->device), chan->dev,
-                                 sizeof(struct mmp_pdma_desc_sw),
-                                 __alignof__(struct mmp_pdma_desc_sw), 0);
+       chan->desc_pool = dma_pool_create(dev_name(&dchan->dev->device),
+                                         chan->dev,
+                                         sizeof(struct mmp_pdma_desc_sw),
+                                         __alignof__(struct mmp_pdma_desc_sw),
+                                         0);
        if (!chan->desc_pool) {
                dev_err(chan->dev, "unable to allocate descriptor pool\n");
                return -ENOMEM;
        }
+
        mmp_pdma_free_phy(chan);
        chan->idle = true;
        chan->dev_addr = 0;
@@ -404,7 +410,7 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
 }
 
 static void mmp_pdma_free_desc_list(struct mmp_pdma_chan *chan,
-                                 struct list_head *list)
+                                   struct list_head *list)
 {
        struct mmp_pdma_desc_sw *desc, *_desc;
 
@@ -434,8 +440,8 @@ static void mmp_pdma_free_chan_resources(struct dma_chan *dchan)
 
 static struct dma_async_tx_descriptor *
 mmp_pdma_prep_memcpy(struct dma_chan *dchan,
-       dma_addr_t dma_dst, dma_addr_t dma_src,
-       size_t len, unsigned long flags)
+                    dma_addr_t dma_dst, dma_addr_t dma_src,
+                    size_t len, unsigned long flags)
 {
        struct mmp_pdma_chan *chan;
        struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
@@ -515,8 +521,8 @@ fail:
 
 static struct dma_async_tx_descriptor *
 mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
-                        unsigned int sg_len, enum dma_transfer_direction dir,
-                        unsigned long flags, void *context)
+                      unsigned int sg_len, enum dma_transfer_direction dir,
+                      unsigned long flags, void *context)
 {
        struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
        struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new = NULL;
@@ -591,10 +597,11 @@ fail:
        return NULL;
 }
 
-static struct dma_async_tx_descriptor *mmp_pdma_prep_dma_cyclic(
-       struct dma_chan *dchan, dma_addr_t buf_addr, size_t len,
-       size_t period_len, enum dma_transfer_direction direction,
-       unsigned long flags, void *context)
+static struct dma_async_tx_descriptor *
+mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan,
+                        dma_addr_t buf_addr, size_t len, size_t period_len,
+                        enum dma_transfer_direction direction,
+                        unsigned long flags, void *context)
 {
        struct mmp_pdma_chan *chan;
        struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
@@ -636,8 +643,8 @@ static struct dma_async_tx_descriptor *mmp_pdma_prep_dma_cyclic(
                        goto fail;
                }
 
-               new->desc.dcmd = chan->dcmd | DCMD_ENDIRQEN |
-                                       (DCMD_LENGTH & period_len);
+               new->desc.dcmd = (chan->dcmd | DCMD_ENDIRQEN |
+                                 (DCMD_LENGTH & period_len));
                new->desc.dsadr = dma_src;
                new->desc.dtadr = dma_dst;
 
@@ -677,12 +684,11 @@ fail:
 }
 
 static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
-               unsigned long arg)
+                           unsigned long arg)
 {
        struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
        struct dma_slave_config *cfg = (void *)arg;
        unsigned long flags;
-       int ret = 0;
        u32 maxburst = 0, addr = 0;
        enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
 
@@ -739,11 +745,12 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
                return -ENOSYS;
        }
 
-       return ret;
+       return 0;
 }
 
 static enum dma_status mmp_pdma_tx_status(struct dma_chan *dchan,
-                       dma_cookie_t cookie, struct dma_tx_state *txstate)
+                                         dma_cookie_t cookie,
+                                         struct dma_tx_state *txstate)
 {
        return dma_cookie_status(dchan, cookie, txstate);
 }
@@ -845,15 +852,14 @@ static int mmp_pdma_remove(struct platform_device *op)
        return 0;
 }
 
-static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
-                                                       int idx, int irq)
+static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq)
 {
        struct mmp_pdma_phy *phy  = &pdev->phy[idx];
        struct mmp_pdma_chan *chan;
        int ret;
 
-       chan = devm_kzalloc(pdev->dev,
-                       sizeof(struct mmp_pdma_chan), GFP_KERNEL);
+       chan = devm_kzalloc(pdev->dev, sizeof(struct mmp_pdma_chan),
+                           GFP_KERNEL);
        if (chan == NULL)
                return -ENOMEM;
 
@@ -861,8 +867,8 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
        phy->base = pdev->base;
 
        if (irq) {
-               ret = devm_request_irq(pdev->dev, irq,
-                       mmp_pdma_chan_handler, 0, "pdma", phy);
+               ret = devm_request_irq(pdev->dev, irq, mmp_pdma_chan_handler, 0,
+                                      "pdma", phy);
                if (ret) {
                        dev_err(pdev->dev, "channel request irq fail!\n");
                        return ret;
@@ -877,8 +883,7 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
        INIT_LIST_HEAD(&chan->chain_running);
 
        /* register virt channel to dma engine */
-       list_add_tail(&chan->chan.device_node,
-                       &pdev->device.channels);
+       list_add_tail(&chan->chan.device_node, &pdev->device.channels);
 
        return 0;
 }
@@ -913,13 +918,12 @@ retry:
         * the lookup and the reservation */
        chan = dma_get_slave_channel(candidate);
 
-       if (chan) {
-               struct mmp_pdma_chan *c = to_mmp_pdma_chan(chan);
-               c->drcmr = dma_spec->args[0];
-               return chan;
-       }
+       if (!chan)
+               goto retry;
 
-       goto retry;
+       to_mmp_pdma_chan(chan)->drcmr = dma_spec->args[0];
+
+       return chan;
 }
 
 static int mmp_pdma_probe(struct platform_device *op)
@@ -934,6 +938,7 @@ static int mmp_pdma_probe(struct platform_device *op)
        pdev = devm_kzalloc(&op->dev, sizeof(*pdev), GFP_KERNEL);
        if (!pdev)
                return -ENOMEM;
+
        pdev->dev = &op->dev;
 
        spin_lock_init(&pdev->phy_lock);
@@ -945,8 +950,8 @@ static int mmp_pdma_probe(struct platform_device *op)
 
        of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev);
        if (of_id)
-               of_property_read_u32(pdev->dev->of_node,
-                               "#dma-channels", &dma_channels);
+               of_property_read_u32(pdev->dev->of_node, "#dma-channels",
+                                    &dma_channels);
        else if (pdata && pdata->dma_channels)
                dma_channels = pdata->dma_channels;
        else
@@ -958,8 +963,9 @@ static int mmp_pdma_probe(struct platform_device *op)
                        irq_num++;
        }
 
-       pdev->phy = devm_kzalloc(pdev->dev,
-               dma_channels * sizeof(struct mmp_pdma_chan), GFP_KERNEL);
+       pdev->phy = devm_kcalloc(pdev->dev,
+                                dma_channels, sizeof(struct mmp_pdma_chan),
+                                GFP_KERNEL);
        if (pdev->phy == NULL)
                return -ENOMEM;
 
@@ -968,8 +974,8 @@ static int mmp_pdma_probe(struct platform_device *op)
        if (irq_num != dma_channels) {
                /* all chan share one irq, demux inside */
                irq = platform_get_irq(op, 0);
-               ret = devm_request_irq(pdev->dev, irq,
-                       mmp_pdma_int_handler, 0, "pdma", pdev);
+               ret = devm_request_irq(pdev->dev, irq, mmp_pdma_int_handler, 0,
+                                      "pdma", pdev);
                if (ret)
                        return ret;
        }
@@ -1017,6 +1023,7 @@ static int mmp_pdma_probe(struct platform_device *op)
                }
        }
 
+       platform_set_drvdata(op, pdev);
        dev_info(pdev->device.dev, "initialized %d channels\n", dma_channels);
        return 0;
 }
@@ -1044,7 +1051,7 @@ bool mmp_pdma_filter_fn(struct dma_chan *chan, void *param)
        if (chan->device->dev->driver != &mmp_pdma_driver.driver)
                return false;
 
-       c->drcmr = *(unsigned int *) param;
+       c->drcmr = *(unsigned int *)param;
 
        return true;
 }
@@ -1052,6 +1059,6 @@ EXPORT_SYMBOL_GPL(mmp_pdma_filter_fn);
 
 module_platform_driver(mmp_pdma_driver);
 
-MODULE_DESCRIPTION("MARVELL MMP Periphera DMA Driver");
+MODULE_DESCRIPTION("MARVELL MMP Peripheral DMA Driver");
 MODULE_AUTHOR("Marvell International Ltd.");
 MODULE_LICENSE("GPL v2");
index 3ddacc14a7366611ffb089d21c70fb4ba3c896c5..61b562b2602dadd48ff596bd856745750366e291 100644 (file)
@@ -121,7 +121,7 @@ struct mmp_tdma_chan {
        int                             idx;
        enum mmp_tdma_type              type;
        int                             irq;
-       unsigned long                   reg_base;
+       void __iomem                    *reg_base;
 
        size_t                          buf_len;
        size_t                          period_len;
@@ -526,7 +526,7 @@ static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
        tdmac->chan.device = &tdev->device;
        tdmac->idx         = idx;
        tdmac->type        = type;
-       tdmac->reg_base    = (unsigned long)tdev->base + idx * 4;
+       tdmac->reg_base    = tdev->base + idx * 4;
        tdmac->status = DMA_COMPLETE;
        tdev->tdmac[tdmac->idx] = tdmac;
        tasklet_init(&tdmac->tasklet, dma_do_tasklet, (unsigned long)tdmac);
index cdf0483b8f2dfb8f746b786fd6bf84b0d5f6657b..7adaf3abffba91d4f72656513c6ad5b235508c40 100644 (file)
@@ -578,6 +578,9 @@ struct dma_pl330_dmac {
        /* DMA-Engine Device */
        struct dma_device ddma;
 
+       /* Holds info about sg limitations */
+       struct device_dma_parameters dma_parms;
+
        /* Pool of descriptors available for the DMAC's channels */
        struct list_head desc_pool;
        /* To protect desc_pool manipulation */
@@ -3023,6 +3026,9 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
                        "unable to register DMA to the generic DT DMA helpers\n");
                }
        }
+
+       adev->dev.dma_parms = &pdmac->dma_parms;
+
        /*
         * This is the limit for transfers with a buswidth of 1, larger
         * buswidths will have larger limits.
index 4cb12797863678be86af66017ec2cffb54f5dd16..085da4fe661343a83b61d4bb839f467a6a777a5b 100644 (file)
@@ -795,7 +795,7 @@ static enum dma_status s3c24xx_dma_tx_status(struct dma_chan *chan,
 
        spin_lock_irqsave(&s3cchan->vc.lock, flags);
        ret = dma_cookie_status(chan, cookie, txstate);
-       if (ret == DMA_SUCCESS) {
+       if (ret == DMA_COMPLETE) {
                spin_unlock_irqrestore(&s3cchan->vc.lock, flags);
                return ret;
        }
index ebad84591a6e22bd1f28866c3f0b1946eba3dff0..3083d901a414f000a54e0337e02973a4586399bf 100644 (file)
@@ -60,6 +60,7 @@
 #define HPB_DMAE_DSTPR_DMSTP   BIT(0)
 
 /* DMA status register (DSTSR) bits */
+#define HPB_DMAE_DSTSR_DQSTS   BIT(2)
 #define HPB_DMAE_DSTSR_DMSTS   BIT(0)
 
 /* DMA common registers */
@@ -286,6 +287,9 @@ static void hpb_dmae_halt(struct shdma_chan *schan)
 
        ch_reg_write(chan, HPB_DMAE_DCMDR_DQEND, HPB_DMAE_DCMDR);
        ch_reg_write(chan, HPB_DMAE_DSTPR_DMSTP, HPB_DMAE_DSTPR);
+
+       chan->plane_idx = 0;
+       chan->first_desc = true;
 }
 
 static const struct hpb_dmae_slave_config *
@@ -385,7 +389,10 @@ static bool hpb_dmae_channel_busy(struct shdma_chan *schan)
        struct hpb_dmae_chan *chan = to_chan(schan);
        u32 dstsr = ch_reg_read(chan, HPB_DMAE_DSTSR);
 
-       return (dstsr & HPB_DMAE_DSTSR_DMSTS) == HPB_DMAE_DSTSR_DMSTS;
+       if (chan->xfer_mode == XFER_DOUBLE)
+               return dstsr & HPB_DMAE_DSTSR_DQSTS;
+       else
+               return dstsr & HPB_DMAE_DSTSR_DMSTS;
 }
 
 static int
@@ -510,6 +517,8 @@ static int hpb_dmae_chan_probe(struct hpb_dmae_device *hpbdev, int id)
        }
 
        schan = &new_hpb_chan->shdma_chan;
+       schan->max_xfer_len = HPB_DMA_TCR_MAX;
+
        shdma_chan_probe(sdev, schan, id);
 
        if (pdev->id >= 0)
index fd46b0bd5f2ae273cec5cad4a42b621613b307da..8f9182179a7c804088d1889ac96c7f90a28d804e 100644 (file)
@@ -1,6 +1,8 @@
 /*
  * Freescale MPC85xx Memory Controller kenel module
  *
+ * Parts Copyrighted (c) 2013 by Freescale Semiconductor, Inc.
+ *
  * Author: Dave Jiang <djiang@mvista.com>
  *
  * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under
@@ -196,6 +198,42 @@ static void mpc85xx_pci_check(struct edac_pci_ctl_info *pci)
                edac_pci_handle_npe(pci, pci->ctl_name);
 }
 
+static void mpc85xx_pcie_check(struct edac_pci_ctl_info *pci)
+{
+       struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
+       u32 err_detect;
+
+       err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR);
+
+       pr_err("PCIe error(s) detected\n");
+       pr_err("PCIe ERR_DR register: 0x%08x\n", err_detect);
+       pr_err("PCIe ERR_CAP_STAT register: 0x%08x\n",
+                       in_be32(pdata->pci_vbase + MPC85XX_PCI_GAS_TIMR));
+       pr_err("PCIe ERR_CAP_R0 register: 0x%08x\n",
+                       in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R0));
+       pr_err("PCIe ERR_CAP_R1 register: 0x%08x\n",
+                       in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R1));
+       pr_err("PCIe ERR_CAP_R2 register: 0x%08x\n",
+                       in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R2));
+       pr_err("PCIe ERR_CAP_R3 register: 0x%08x\n",
+                       in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R3));
+
+       /* clear error bits */
+       out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect);
+}
+
+static int mpc85xx_pcie_find_capability(struct device_node *np)
+{
+       struct pci_controller *hose;
+
+       if (!np)
+               return -EINVAL;
+
+       hose = pci_find_hose_for_OF_device(np);
+
+       return early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
+}
+
 static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id)
 {
        struct edac_pci_ctl_info *pci = dev_id;
@@ -207,7 +245,10 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id)
        if (!err_detect)
                return IRQ_NONE;
 
-       mpc85xx_pci_check(pci);
+       if (pdata->is_pcie)
+               mpc85xx_pcie_check(pci);
+       else
+               mpc85xx_pci_check(pci);
 
        return IRQ_HANDLED;
 }
@@ -239,14 +280,22 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
        pdata = pci->pvt_info;
        pdata->name = "mpc85xx_pci_err";
        pdata->irq = NO_IRQ;
+
+       if (mpc85xx_pcie_find_capability(op->dev.of_node) > 0)
+               pdata->is_pcie = true;
+
        dev_set_drvdata(&op->dev, pci);
        pci->dev = &op->dev;
        pci->mod_name = EDAC_MOD_STR;
        pci->ctl_name = pdata->name;
        pci->dev_name = dev_name(&op->dev);
 
-       if (edac_op_state == EDAC_OPSTATE_POLL)
-               pci->edac_check = mpc85xx_pci_check;
+       if (edac_op_state == EDAC_OPSTATE_POLL) {
+               if (pdata->is_pcie)
+                       pci->edac_check = mpc85xx_pcie_check;
+               else
+                       pci->edac_check = mpc85xx_pci_check;
+       }
 
        pdata->edac_idx = edac_pci_idx++;
 
@@ -275,16 +324,26 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
                goto err;
        }
 
-       orig_pci_err_cap_dr =
-           in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR);
+       if (pdata->is_pcie) {
+               orig_pci_err_cap_dr =
+                   in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR);
+               out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR, ~0);
+               orig_pci_err_en =
+                   in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN);
+               out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, 0);
+       } else {
+               orig_pci_err_cap_dr =
+                   in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR);
 
-       /* PCI master abort is expected during config cycles */
-       out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, 0x40);
+               /* PCI master abort is expected during config cycles */
+               out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, 0x40);
 
-       orig_pci_err_en = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN);
+               orig_pci_err_en =
+                   in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN);
 
-       /* disable master abort reporting */
-       out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0x40);
+               /* disable master abort reporting */
+               out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0x40);
+       }
 
        /* clear error bits */
        out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0);
@@ -297,7 +356,8 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
        if (edac_op_state == EDAC_OPSTATE_INT) {
                pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0);
                res = devm_request_irq(&op->dev, pdata->irq,
-                                      mpc85xx_pci_isr, IRQF_DISABLED,
+                                      mpc85xx_pci_isr,
+                                      IRQF_DISABLED | IRQF_SHARED,
                                       "[EDAC] PCI err", pci);
                if (res < 0) {
                        printk(KERN_ERR
@@ -312,6 +372,22 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
                       pdata->irq);
        }
 
+       if (pdata->is_pcie) {
+               /*
+                * Enable all PCIe error interrupt & error detect except invalid
+                * PEX_CONFIG_ADDR/PEX_CONFIG_DATA access interrupt generation
+                * enable bit and invalid PEX_CONFIG_ADDR/PEX_CONFIG_DATA access
+                * detection enable bit. Because PCIe bus code to initialize and
+                * configure these PCIe devices on booting will use some invalid
+                * PEX_CONFIG_ADDR/PEX_CONFIG_DATA, edac driver prints the much
+                * notice information. So disable this detect to fix ugly print.
+                */
+               out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0
+                        & ~PEX_ERR_ICCAIE_EN_BIT);
+               out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR, 0
+                        | PEX_ERR_ICCAD_DISR_BIT);
+       }
+
        devres_remove_group(&op->dev, mpc85xx_pci_err_probe);
        edac_dbg(3, "success\n");
        printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n");
index 932016f2cf06032a78f48297899a9a9c8b3c8eb2..8c6256436227be68d90ddd5ca8ebd3667857086c 100644 (file)
 #define MPC85XX_PCI_ERR_DR             0x0000
 #define MPC85XX_PCI_ERR_CAP_DR         0x0004
 #define MPC85XX_PCI_ERR_EN             0x0008
+#define   PEX_ERR_ICCAIE_EN_BIT                0x00020000
 #define MPC85XX_PCI_ERR_ATTRIB         0x000c
 #define MPC85XX_PCI_ERR_ADDR           0x0010
+#define   PEX_ERR_ICCAD_DISR_BIT       0x00020000
 #define MPC85XX_PCI_ERR_EXT_ADDR       0x0014
 #define MPC85XX_PCI_ERR_DL             0x0018
 #define MPC85XX_PCI_ERR_DH             0x001c
 #define MPC85XX_PCI_GAS_TIMR           0x0020
 #define MPC85XX_PCI_PCIX_TIMR          0x0024
+#define MPC85XX_PCIE_ERR_CAP_R0                0x0028
+#define MPC85XX_PCIE_ERR_CAP_R1                0x002c
+#define MPC85XX_PCIE_ERR_CAP_R2                0x0030
+#define MPC85XX_PCIE_ERR_CAP_R3                0x0034
 
 struct mpc85xx_mc_pdata {
        char *name;
@@ -158,6 +164,7 @@ struct mpc85xx_l2_pdata {
 
 struct mpc85xx_pci_pdata {
        char *name;
+       bool is_pcie;
        int edac_idx;
        void __iomem *pci_vbase;
        int irq;
index 3c55ec856e39c714e7b474f081c01180b9aa9e2d..a287cece0593c327c53e8961b70a0dde8b1af2ce 100644 (file)
@@ -1082,7 +1082,7 @@ static void arizona_micd_set_level(struct arizona *arizona, int index,
 static int arizona_extcon_probe(struct platform_device *pdev)
 {
        struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
-       struct arizona_pdata *pdata;
+       struct arizona_pdata *pdata = &arizona->pdata;
        struct arizona_extcon_info *info;
        unsigned int val;
        int jack_irq_fall, jack_irq_rise;
@@ -1091,8 +1091,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
        if (!arizona->dapm || !arizona->dapm->card)
                return -EPROBE_DEFER;
 
-       pdata = dev_get_platdata(arizona->dev);
-
        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
        if (!info) {
                dev_err(&pdev->dev, "Failed to allocate memory\n");
index 15443d3b6be18049ddddbb7ec035eb05ce7dc409..76322330cbd7a10b427ff5d011b83abbd0abb0e8 100644 (file)
@@ -792,6 +792,8 @@ void extcon_dev_unregister(struct extcon_dev *edev)
                return;
        }
 
+       device_unregister(&edev->dev);
+
        if (edev->mutually_exclusive && edev->max_supported) {
                for (index = 0; edev->mutually_exclusive[index];
                                index++)
@@ -812,7 +814,6 @@ void extcon_dev_unregister(struct extcon_dev *edev)
        if (switch_class)
                class_compat_remove_link(switch_class, &edev->dev, NULL);
 #endif
-       device_unregister(&edev->dev);
        put_device(&edev->dev);
 }
 EXPORT_SYMBOL_GPL(extcon_dev_unregister);
index 281029daf98c7ea291886d46ecf05378bfa98718..b0bb056458a363b0ee457beea13a8b926a63d483 100644 (file)
@@ -1623,6 +1623,7 @@ static struct scsi_host_template scsi_driver_template = {
        .cmd_per_lun            = 1,
        .can_queue              = 1,
        .sdev_attrs             = sbp2_scsi_sysfs_attrs,
+       .no_write_same          = 1,
 };
 
 MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
index 5002d50e37817314d1fe3e449ad991ade1969f6b..743fd426f21bf29299b850833d0137348a2bca64 100644 (file)
@@ -18,14 +18,12 @@ module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
 
 static int efi_pstore_open(struct pstore_info *psi)
 {
-       efivar_entry_iter_begin();
        psi->data = NULL;
        return 0;
 }
 
 static int efi_pstore_close(struct pstore_info *psi)
 {
-       efivar_entry_iter_end();
        psi->data = NULL;
        return 0;
 }
@@ -39,6 +37,12 @@ struct pstore_read_data {
        char **buf;
 };
 
+static inline u64 generic_id(unsigned long timestamp,
+                            unsigned int part, int count)
+{
+       return (timestamp * 100 + part) * 1000 + count;
+}
+
 static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
 {
        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
@@ -57,7 +61,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
 
        if (sscanf(name, "dump-type%u-%u-%d-%lu-%c",
                   cb_data->type, &part, &cnt, &time, &data_type) == 5) {
-               *cb_data->id = part;
+               *cb_data->id = generic_id(time, part, cnt);
                *cb_data->count = cnt;
                cb_data->timespec->tv_sec = time;
                cb_data->timespec->tv_nsec = 0;
@@ -67,7 +71,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
                        *cb_data->compressed = false;
        } else if (sscanf(name, "dump-type%u-%u-%d-%lu",
                   cb_data->type, &part, &cnt, &time) == 4) {
-               *cb_data->id = part;
+               *cb_data->id = generic_id(time, part, cnt);
                *cb_data->count = cnt;
                cb_data->timespec->tv_sec = time;
                cb_data->timespec->tv_nsec = 0;
@@ -79,7 +83,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
                 * which doesn't support holding
                 * multiple logs, remains.
                 */
-               *cb_data->id = part;
+               *cb_data->id = generic_id(time, part, 0);
                *cb_data->count = 0;
                cb_data->timespec->tv_sec = time;
                cb_data->timespec->tv_nsec = 0;
@@ -91,19 +95,125 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
        __efivar_entry_get(entry, &entry->var.Attributes,
                           &entry->var.DataSize, entry->var.Data);
        size = entry->var.DataSize;
+       memcpy(*cb_data->buf, entry->var.Data,
+              (size_t)min_t(unsigned long, EFIVARS_DATA_SIZE_MAX, size));
 
-       *cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL);
-       if (*cb_data->buf == NULL)
-               return -ENOMEM;
        return size;
 }
 
+/**
+ * efi_pstore_scan_sysfs_enter
+ * @entry: scanning entry
+ * @next: next entry
+ * @head: list head
+ */
+static void efi_pstore_scan_sysfs_enter(struct efivar_entry *pos,
+                                       struct efivar_entry *next,
+                                       struct list_head *head)
+{
+       pos->scanning = true;
+       if (&next->list != head)
+               next->scanning = true;
+}
+
+/**
+ * __efi_pstore_scan_sysfs_exit
+ * @entry: deleting entry
+ * @turn_off_scanning: Check if a scanning flag should be turned off
+ */
+static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
+                                               bool turn_off_scanning)
+{
+       if (entry->deleting) {
+               list_del(&entry->list);
+               efivar_entry_iter_end();
+               efivar_unregister(entry);
+               efivar_entry_iter_begin();
+       } else if (turn_off_scanning)
+               entry->scanning = false;
+}
+
+/**
+ * efi_pstore_scan_sysfs_exit
+ * @pos: scanning entry
+ * @next: next entry
+ * @head: list head
+ * @stop: a flag checking if scanning will stop
+ */
+static void efi_pstore_scan_sysfs_exit(struct efivar_entry *pos,
+                                      struct efivar_entry *next,
+                                      struct list_head *head, bool stop)
+{
+       __efi_pstore_scan_sysfs_exit(pos, true);
+       if (stop)
+               __efi_pstore_scan_sysfs_exit(next, &next->list != head);
+}
+
+/**
+ * efi_pstore_sysfs_entry_iter
+ *
+ * @data: function-specific data to pass to callback
+ * @pos: entry to begin iterating from
+ *
+ * You MUST call efivar_enter_iter_begin() before this function, and
+ * efivar_entry_iter_end() afterwards.
+ *
+ * It is possible to begin iteration from an arbitrary entry within
+ * the list by passing @pos. @pos is updated on return to point to
+ * the next entry of the last one passed to efi_pstore_read_func().
+ * To begin iterating from the beginning of the list @pos must be %NULL.
+ */
+static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos)
+{
+       struct efivar_entry *entry, *n;
+       struct list_head *head = &efivar_sysfs_list;
+       int size = 0;
+
+       if (!*pos) {
+               list_for_each_entry_safe(entry, n, head, list) {
+                       efi_pstore_scan_sysfs_enter(entry, n, head);
+
+                       size = efi_pstore_read_func(entry, data);
+                       efi_pstore_scan_sysfs_exit(entry, n, head, size < 0);
+                       if (size)
+                               break;
+               }
+               *pos = n;
+               return size;
+       }
+
+       list_for_each_entry_safe_from((*pos), n, head, list) {
+               efi_pstore_scan_sysfs_enter((*pos), n, head);
+
+               size = efi_pstore_read_func((*pos), data);
+               efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0);
+               if (size)
+                       break;
+       }
+       *pos = n;
+       return size;
+}
+
+/**
+ * efi_pstore_read
+ *
+ * This function returns a size of NVRAM entry logged via efi_pstore_write().
+ * The meaning and behavior of efi_pstore/pstore are as below.
+ *
+ * size > 0: Got data of an entry logged via efi_pstore_write() successfully,
+ *           and pstore filesystem will continue reading subsequent entries.
+ * size == 0: Entry was not logged via efi_pstore_write(),
+ *            and efi_pstore driver will continue reading subsequent entries.
+ * size < 0: Failed to get data of entry logging via efi_pstore_write(),
+ *           and pstore will stop reading entry.
+ */
 static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
                               int *count, struct timespec *timespec,
                               char **buf, bool *compressed,
                               struct pstore_info *psi)
 {
        struct pstore_read_data data;
+       ssize_t size;
 
        data.id = id;
        data.type = type;
@@ -112,8 +222,17 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
        data.compressed = compressed;
        data.buf = buf;
 
-       return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
-                                  (struct efivar_entry **)&psi->data);
+       *data.buf = kzalloc(EFIVARS_DATA_SIZE_MAX, GFP_KERNEL);
+       if (!*data.buf)
+               return -ENOMEM;
+
+       efivar_entry_iter_begin();
+       size = efi_pstore_sysfs_entry_iter(&data,
+                                          (struct efivar_entry **)&psi->data);
+       efivar_entry_iter_end();
+       if (size <= 0)
+               kfree(*data.buf);
+       return size;
 }
 
 static int efi_pstore_write(enum pstore_type_id type,
@@ -184,9 +303,17 @@ static int efi_pstore_erase_func(struct efivar_entry *entry, void *data)
                        return 0;
        }
 
+       if (entry->scanning) {
+               /*
+                * Skip deletion because this entry will be deleted
+                * after scanning is completed.
+                */
+               entry->deleting = true;
+       } else
+               list_del(&entry->list);
+
        /* found */
        __efivar_entry_delete(entry);
-       list_del(&entry->list);
 
        return 1;
 }
@@ -199,14 +326,16 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
        char name[DUMP_NAME_LEN];
        efi_char16_t efi_name[DUMP_NAME_LEN];
        int found, i;
+       unsigned int part;
 
-       sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
-               time.tv_sec);
+       do_div(id, 1000);
+       part = do_div(id, 100);
+       sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count, time.tv_sec);
 
        for (i = 0; i < DUMP_NAME_LEN; i++)
                efi_name[i] = name[i];
 
-       edata.id = id;
+       edata.id = part;
        edata.type = type;
        edata.count = count;
        edata.time = time;
@@ -214,10 +343,12 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
 
        efivar_entry_iter_begin();
        found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
-       efivar_entry_iter_end();
 
-       if (found)
+       if (found && !entry->scanning) {
+               efivar_entry_iter_end();
                efivar_unregister(entry);
+       } else
+               efivar_entry_iter_end();
 
        return 0;
 }
index 933eb027d527d53aa8fb275b84c5d9b6e2ce3602..3dc24823919749ebb110f62b9ca5696cdaf67511 100644 (file)
@@ -383,12 +383,16 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
        else if (__efivar_entry_delete(entry))
                err = -EIO;
 
-       efivar_entry_iter_end();
-
-       if (err)
+       if (err) {
+               efivar_entry_iter_end();
                return err;
+       }
 
-       efivar_unregister(entry);
+       if (!entry->scanning) {
+               efivar_entry_iter_end();
+               efivar_unregister(entry);
+       } else
+               efivar_entry_iter_end();
 
        /* It's dead Jim.... */
        return count;
index 391c67b182d9b282681890cd04b98c0183023abc..b22659cccca42ebf85e3b54e52249b581b786409 100644 (file)
@@ -683,8 +683,16 @@ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
        if (!found)
                return NULL;
 
-       if (remove)
-               list_del(&entry->list);
+       if (remove) {
+               if (entry->scanning) {
+                       /*
+                        * The entry will be deleted
+                        * after scanning is completed.
+                        */
+                       entry->deleting = true;
+               } else
+                       list_del(&entry->list);
+       }
 
        return entry;
 }
index 72c927dc3be1b104c53e04bec683aa37c9c92343..54c18c220a60575d0ebc63f952937d816132f89c 100644 (file)
@@ -158,7 +158,7 @@ static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio)
        spin_unlock_irqrestore(&kona_gpio->lock, flags);
 
        /* return the specified bit status */
-       return !!(val & bit);
+       return !!(val & BIT(bit));
 }
 
 static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
index f7a0cc4da9502d12ef0aa602dfa249665e5a5c4a..7b37300973dbc15d1a424448d932867b4d10d06d 100644 (file)
@@ -102,7 +102,7 @@ struct msm_gpio_dev {
        DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
        DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
        struct irq_domain *domain;
-       unsigned int summary_irq;
+       int summary_irq;
        void __iomem *msm_tlmm_base;
 };
 
index 3c3321f94053ab68f0ab0e691afc1ddf2b83f0e9..db3129043e635c2bc9c7f6a7c3ffd111de5dc6f4 100644 (file)
@@ -79,7 +79,7 @@ struct mvebu_gpio_chip {
        spinlock_t         lock;
        void __iomem      *membase;
        void __iomem      *percpu_membase;
-       unsigned int       irqbase;
+       int                irqbase;
        struct irq_domain *domain;
        int                soc_variant;
 };
index f22f7f3e2e531592ffb313c253c50e75b73b3337..b4d42112d02d5c3388849eac299245f30f193ac8 100644 (file)
@@ -286,11 +286,6 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
        if (!chip->base)
                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;
@@ -320,6 +315,11 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
        irq_set_chained_handler(irq, pl061_irq_handler);
        irq_set_handler_data(irq, chip);
 
+       chip->domain = irq_domain_add_simple(adev->dev.of_node, PL061_GPIO_NR,
+                                            irq_base, &pl061_domain_ops, chip);
+       if (!chip->domain)
+               return -ENODEV;
+
        for (i = 0; i < PL061_GPIO_NR; i++) {
                if (pdata) {
                        if (pdata->directions & (1 << i))
index d3f15ae93bd3bef20a5aa306fa02e1a7fe12b838..fe088a30567ac63325fd02be82b8e682aa2323eb 100644 (file)
@@ -381,7 +381,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)
        if (!p->irq_domain) {
                ret = -ENXIO;
                dev_err(&pdev->dev, "cannot initialize irq domain\n");
-               goto err1;
+               goto err0;
        }
 
        if (devm_request_irq(&pdev->dev, irq->start,
index 0502b9a041a50a199b40f4d3bf956bcd81dc7fdf..da071ddbad9985670843087ee3652844958b3827 100644 (file)
@@ -132,6 +132,7 @@ static int tb10x_gpio_direction_out(struct gpio_chip *chip,
        int mask = BIT(offset);
        int val = TB10X_GPIO_DIR_OUT << offset;
 
+       tb10x_gpio_set(chip, offset, value);
        tb10x_set_bits(tb10x_gpio, OFFSET_TO_REG_DDR, mask, val);
 
        return 0;
index 0c7e891c8651042a8f32e5e6ecf7344cabf6493e..b97d6a6577b961d379a977e14a3c5c693cce5049 100644 (file)
@@ -354,17 +354,18 @@ static void twl_set(struct gpio_chip *chip, unsigned offset, int value)
 static int twl_direction_out(struct gpio_chip *chip, unsigned offset, int value)
 {
        struct gpio_twl4030_priv *priv = to_gpio_twl4030(chip);
+       int ret = -EINVAL;
 
        mutex_lock(&priv->mutex);
        if (offset < TWL4030_GPIO_MAX)
-               twl4030_set_gpio_dataout(offset, value);
+               ret = twl4030_set_gpio_direction(offset, 0);
 
        priv->direction |= BIT(offset);
        mutex_unlock(&priv->mutex);
 
        twl_set(chip, offset, value);
 
-       return 0;
+       return ret;
 }
 
 static int twl_to_irq(struct gpio_chip *chip, unsigned offset)
@@ -435,7 +436,8 @@ static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
 
 static int gpio_twl4030_remove(struct platform_device *pdev);
 
-static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
+static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev,
+                               struct twl4030_gpio_platform_data *pdata)
 {
        struct twl4030_gpio_platform_data *omap_twl_info;
 
@@ -443,6 +445,9 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
        if (!omap_twl_info)
                return NULL;
 
+       if (pdata)
+               *omap_twl_info = *pdata;
+
        omap_twl_info->use_leds = of_property_read_bool(dev->of_node,
                        "ti,use-leds");
 
@@ -500,7 +505,7 @@ no_irqs:
        mutex_init(&priv->mutex);
 
        if (node)
-               pdata = of_gpio_twl4030(&pdev->dev);
+               pdata = of_gpio_twl4030(&pdev->dev, pdata);
 
        if (pdata == NULL) {
                dev_err(&pdev->dev, "Platform data is missing\n");
index 1a605f2a0f55f8fac1675dd18f37dae366215edc..06fb5cf99dede237bd29f109bbd195bfa2230f5b 100644 (file)
@@ -105,3 +105,4 @@ module_platform_driver(ucb1400_gpio_driver);
 
 MODULE_DESCRIPTION("Philips UCB1400 GPIO driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ucb1400_gpio");
index 4e10b10d3ddde47332f525285e1c549bd9a2c22f..ac53a95936626800143d1ad30320329f0f3ec050 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/idr.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/gpio/driver.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/gpio.h>
@@ -1308,6 +1309,18 @@ struct gpio_chip *gpiochip_find(void *data,
 }
 EXPORT_SYMBOL_GPL(gpiochip_find);
 
+static int gpiochip_match_name(struct gpio_chip *chip, void *data)
+{
+       const char *name = data;
+
+       return !strcmp(chip->label, name);
+}
+
+static struct gpio_chip *find_chip_by_name(const char *name)
+{
+       return gpiochip_find((void *)name, gpiochip_match_name);
+}
+
 #ifdef CONFIG_PINCTRL
 
 /**
@@ -1341,8 +1354,10 @@ int gpiochip_add_pingroup_range(struct gpio_chip *chip,
        ret = pinctrl_get_group_pins(pctldev, pin_group,
                                        &pin_range->range.pins,
                                        &pin_range->range.npins);
-       if (ret < 0)
+       if (ret < 0) {
+               kfree(pin_range);
                return ret;
+       }
 
        pinctrl_add_gpio_range(pctldev, &pin_range->range);
 
@@ -2260,26 +2275,10 @@ void gpiod_add_table(struct gpiod_lookup *table, size_t size)
        mutex_unlock(&gpio_lookup_lock);
 }
 
-/*
- * Caller must have a acquired gpio_lookup_lock
- */
-static struct gpio_chip *find_chip_by_name(const char *name)
-{
-       struct gpio_chip *chip = NULL;
-
-       list_for_each_entry(chip, &gpio_lookup_list, list) {
-               if (chip->label == NULL)
-                       continue;
-               if (!strcmp(chip->label, name))
-                       break;
-       }
-
-       return chip;
-}
-
 #ifdef CONFIG_OF
 static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
-                                     unsigned int idx, unsigned long *flags)
+                                     unsigned int idx,
+                                     enum gpio_lookup_flags *flags)
 {
        char prop_name[32]; /* 32 is max size of property name */
        enum of_gpio_flags of_flags;
@@ -2297,20 +2296,22 @@ static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
                return desc;
 
        if (of_flags & OF_GPIO_ACTIVE_LOW)
-               *flags |= GPIOF_ACTIVE_LOW;
+               *flags |= GPIO_ACTIVE_LOW;
 
        return desc;
 }
 #else
 static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
-                                     unsigned int idx, unsigned long *flags)
+                                     unsigned int idx,
+                                     enum gpio_lookup_flags *flags)
 {
        return ERR_PTR(-ENODEV);
 }
 #endif
 
 static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
-                                       unsigned int idx, unsigned long *flags)
+                                       unsigned int idx,
+                                       enum gpio_lookup_flags *flags)
 {
        struct acpi_gpio_info info;
        struct gpio_desc *desc;
@@ -2320,13 +2321,14 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
                return desc;
 
        if (info.gpioint && info.active_low)
-               *flags |= GPIOF_ACTIVE_LOW;
+               *flags |= GPIO_ACTIVE_LOW;
 
        return desc;
 }
 
 static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
-                                   unsigned int idx, unsigned long *flags)
+                                   unsigned int idx,
+                                   enum gpio_lookup_flags *flags)
 {
        const char *dev_id = dev ? dev_name(dev) : NULL;
        struct gpio_desc *desc = ERR_PTR(-ENODEV);
@@ -2418,7 +2420,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
 {
        struct gpio_desc *desc;
        int status;
-       unsigned long flags = 0;
+       enum gpio_lookup_flags flags = 0;
 
        dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id);
 
@@ -2444,8 +2446,12 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
        if (status < 0)
                return ERR_PTR(status);
 
-       if (flags & GPIOF_ACTIVE_LOW)
+       if (flags & GPIO_ACTIVE_LOW)
                set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+       if (flags & GPIO_OPEN_DRAIN)
+               set_bit(FLAG_OPEN_DRAIN, &desc->flags);
+       if (flags & GPIO_OPEN_SOURCE)
+               set_bit(FLAG_OPEN_SOURCE, &desc->flags);
 
        return desc;
 }
index bd2bca395792a600deda6c6f2a1a28314ea89374..c22c3097c3e857ba823cd9c339333983842c4ecf 100644 (file)
@@ -516,7 +516,7 @@ int drm_sysfs_device_add(struct drm_minor *minor)
                 minor_str = "card%d";
 
        minor->kdev = kzalloc(sizeof(*minor->kdev), GFP_KERNEL);
-       if (!minor->dev) {
+       if (!minor->kdev) {
                r = -ENOMEM;
                goto error;
        }
index 6199d0b5b958fb2610e83810e117ea89c5057e6e..73ed59eff139a88948c7766dcc0c999398f59254 100644 (file)
@@ -1,8 +1,10 @@
 config DRM_I915
        tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics"
        depends on DRM
-       depends on AGP
-       depends on AGP_INTEL
+       depends on X86 && PCI
+       depends on (AGP || AGP=n)
+       select INTEL_GTT
+       select AGP_INTEL if AGP
        # we need shmfs for the swappable backing store, and in particular
        # the shmem_readpage() which depends upon tmpfs
        select SHMEM
@@ -35,15 +37,14 @@ config DRM_I915
 config DRM_I915_KMS
        bool "Enable modesetting on intel by default"
        depends on DRM_I915
+       default y
        help
-         Choose this option if you want kernel modesetting enabled by default,
-         and you have a new enough userspace to support this. Running old
-         userspaces with this enabled will cause pain.  Note that this causes
-         the driver to bind to PCI devices, which precludes loading things
-         like intelfb.
+         Choose this option if you want kernel modesetting enabled by default.
+
+         If in doubt, say "Y".
 
 config DRM_I915_FBDEV
-       bool "Enable legacy fbdev support for the modesettting intel driver"
+       bool "Enable legacy fbdev support for the modesetting intel driver"
        depends on DRM_I915
        select DRM_KMS_FB_HELPER
        select FB_CFB_FILLRECT
@@ -55,9 +56,12 @@ config DRM_I915_FBDEV
          support. Note that this support also provide the linux console
          support on top of the intel modesetting driver.
 
+         If in doubt, say "Y".
+
 config DRM_I915_PRELIMINARY_HW_SUPPORT
        bool "Enable preliminary support for prerelease Intel hardware by default"
        depends on DRM_I915
+       default n
        help
          Choose this option if you have prerelease Intel hardware and want the
          i915 driver to support it by default.  You can enable such support at
@@ -65,3 +69,15 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT
          option changes the default for that module option.
 
          If in doubt, say "N".
+
+config DRM_I915_UMS
+       bool "Enable userspace modesetting on Intel hardware (DEPRECATED)"
+       depends on DRM_I915
+       default n
+       help
+         Choose this option if you still need userspace modesetting.
+
+         Userspace modesetting is deprecated for quite some time now, so
+         enable this only if you have ancient versions of the DDX drivers.
+
+         If in doubt, say "N".
index c4a255be697921caade4bf3dd064217e82230763..954acb2c7021d8eb9a90fe1e49ea5bc806f1f344 100644 (file)
@@ -87,49 +87,6 @@ struct ns2501_priv {
  * when switching the resolution.
  */
 
-static void enable_dvo(struct intel_dvo_device *dvo)
-{
-       struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
-       struct i2c_adapter *adapter = dvo->i2c_bus;
-       struct intel_gmbus *bus = container_of(adapter,
-                                              struct intel_gmbus,
-                                              adapter);
-       struct drm_i915_private *dev_priv = bus->dev_priv;
-
-       DRM_DEBUG_KMS("%s: Trying to re-enable the DVO\n", __FUNCTION__);
-
-       ns->dvoc = I915_READ(DVO_C);
-       ns->pll_a = I915_READ(_DPLL_A);
-       ns->srcdim = I915_READ(DVOC_SRCDIM);
-       ns->fw_blc = I915_READ(FW_BLC);
-
-       I915_WRITE(DVOC, 0x10004084);
-       I915_WRITE(_DPLL_A, 0xd0820000);
-       I915_WRITE(DVOC_SRCDIM, 0x400300);      // 1024x768
-       I915_WRITE(FW_BLC, 0x1080304);
-
-       I915_WRITE(DVOC, 0x90004084);
-}
-
-/*
- * Restore the I915 registers modified by the above
- * trigger function.
- */
-static void restore_dvo(struct intel_dvo_device *dvo)
-{
-       struct i2c_adapter *adapter = dvo->i2c_bus;
-       struct intel_gmbus *bus = container_of(adapter,
-                                              struct intel_gmbus,
-                                              adapter);
-       struct drm_i915_private *dev_priv = bus->dev_priv;
-       struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
-
-       I915_WRITE(DVOC, ns->dvoc);
-       I915_WRITE(_DPLL_A, ns->pll_a);
-       I915_WRITE(DVOC_SRCDIM, ns->srcdim);
-       I915_WRITE(FW_BLC, ns->fw_blc);
-}
-
 /*
 ** Read a register from the ns2501.
 ** Returns true if successful, false otherwise.
@@ -300,7 +257,7 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo,
                            struct drm_display_mode *adjusted_mode)
 {
        bool ok;
-       bool restore = false;
+       int retries = 10;
        struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
 
        DRM_DEBUG_KMS
@@ -476,20 +433,7 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo,
                        ns->reg_8_shadow |= NS2501_8_BPAS;
                }
                ok &= ns2501_writeb(dvo, NS2501_REG8, ns->reg_8_shadow);
-
-               if (!ok) {
-                       if (restore)
-                               restore_dvo(dvo);
-                       enable_dvo(dvo);
-                       restore = true;
-               }
-       } while (!ok);
-       /*
-        * Restore the old i915 registers before
-        * forcing the ns2501 on.
-        */
-       if (restore)
-               restore_dvo(dvo);
+       } while (!ok && retries--);
 }
 
 /* set the NS2501 power state */
@@ -510,7 +454,7 @@ static bool ns2501_get_hw_state(struct intel_dvo_device *dvo)
 static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
 {
        bool ok;
-       bool restore = false;
+       int retries = 10;
        struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
        unsigned char ch;
 
@@ -537,16 +481,7 @@ static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
                        ok &=
                            ns2501_writeb(dvo, 0x35,
                                          enable ? 0xff : 0x00);
-                       if (!ok) {
-                               if (restore)
-                                       restore_dvo(dvo);
-                               enable_dvo(dvo);
-                               restore = true;
-                       }
-               } while (!ok);
-
-               if (restore)
-                       restore_dvo(dvo);
+               } while (!ok && retries--);
        }
 }
 
index 6ed45a984230c6db3bb8cc4b8fbdc2eec9a661d1..13accf795548be717e554963ec3938a5670a7494 100644 (file)
@@ -947,7 +947,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
                if (ret)
                        return ret;
 
-               gen6_gt_force_wake_get(dev_priv);
+               gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
                reqf = I915_READ(GEN6_RPNSWREQ);
                reqf &= ~GEN6_TURBO_DISABLE;
@@ -970,7 +970,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
                        cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
                cagf *= GT_FREQUENCY_MULTIPLIER;
 
-               gen6_gt_force_wake_put(dev_priv);
+               gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
                mutex_unlock(&dev->struct_mutex);
 
                seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
@@ -1018,17 +1018,16 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
                seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts);
                seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq);
 
-               val = vlv_punit_read(dev_priv, PUNIT_FUSE_BUS1);
+               val = valleyview_rps_max_freq(dev_priv);
                seq_printf(m, "max GPU freq: %d MHz\n",
-                          vlv_gpu_freq(dev_priv->mem_freq, val));
+                          vlv_gpu_freq(dev_priv, val));
 
-               val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM);
+               val = valleyview_rps_min_freq(dev_priv);
                seq_printf(m, "min GPU freq: %d MHz\n",
-                          vlv_gpu_freq(dev_priv->mem_freq, val));
+                          vlv_gpu_freq(dev_priv, val));
 
                seq_printf(m, "current GPU freq: %d MHz\n",
-                          vlv_gpu_freq(dev_priv->mem_freq,
-                                       (freq_sts >> 8) & 0xff));
+                          vlv_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff));
                mutex_unlock(&dev_priv->rps.hw_lock);
        } else {
                seq_puts(m, "no P-state info available\n");
@@ -1565,13 +1564,21 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       unsigned forcewake_count;
+       unsigned forcewake_count = 0, fw_rendercount = 0, fw_mediacount = 0;
 
        spin_lock_irq(&dev_priv->uncore.lock);
-       forcewake_count = dev_priv->uncore.forcewake_count;
+       if (IS_VALLEYVIEW(dev)) {
+               fw_rendercount = dev_priv->uncore.fw_rendercount;
+               fw_mediacount = dev_priv->uncore.fw_mediacount;
+       } else
+               forcewake_count = dev_priv->uncore.forcewake_count;
        spin_unlock_irq(&dev_priv->uncore.lock);
 
-       seq_printf(m, "forcewake count = %u\n", forcewake_count);
+       if (IS_VALLEYVIEW(dev)) {
+               seq_printf(m, "fw_rendercount = %u\n", fw_rendercount);
+               seq_printf(m, "fw_mediacount = %u\n", fw_mediacount);
+       } else
+               seq_printf(m, "forcewake count = %u\n", forcewake_count);
 
        return 0;
 }
@@ -1735,28 +1742,28 @@ static int i915_dpio_info(struct seq_file *m, void *data)
 
        seq_printf(m, "DPIO_CTL: 0x%08x\n", I915_READ(DPIO_CTL));
 
-       seq_printf(m, "DPIO_DIV_A: 0x%08x\n",
-                  vlv_dpio_read(dev_priv, PIPE_A, _DPIO_DIV_A));
-       seq_printf(m, "DPIO_DIV_B: 0x%08x\n",
-                  vlv_dpio_read(dev_priv, PIPE_A, _DPIO_DIV_B));
+       seq_printf(m, "DPIO PLL DW3 CH0 : 0x%08x\n",
+                  vlv_dpio_read(dev_priv, PIPE_A, VLV_PLL_DW3(0)));
+       seq_printf(m, "DPIO PLL DW3 CH1: 0x%08x\n",
+                  vlv_dpio_read(dev_priv, PIPE_A, VLV_PLL_DW3(1)));
 
-       seq_printf(m, "DPIO_REFSFR_A: 0x%08x\n",
-                  vlv_dpio_read(dev_priv, PIPE_A, _DPIO_REFSFR_A));
-       seq_printf(m, "DPIO_REFSFR_B: 0x%08x\n",
-                  vlv_dpio_read(dev_priv, PIPE_A, _DPIO_REFSFR_B));
+       seq_printf(m, "DPIO PLL DW5 CH0: 0x%08x\n",
+                  vlv_dpio_read(dev_priv, PIPE_A, VLV_PLL_DW5(0)));
+       seq_printf(m, "DPIO PLL DW5 CH1: 0x%08x\n",
+                  vlv_dpio_read(dev_priv, PIPE_A, VLV_PLL_DW5(1)));
 
-       seq_printf(m, "DPIO_CORE_CLK_A: 0x%08x\n",
-                  vlv_dpio_read(dev_priv, PIPE_A, _DPIO_CORE_CLK_A));
-       seq_printf(m, "DPIO_CORE_CLK_B: 0x%08x\n",
-                  vlv_dpio_read(dev_priv, PIPE_A, _DPIO_CORE_CLK_B));
+       seq_printf(m, "DPIO PLL DW7 CH0: 0x%08x\n",
+                  vlv_dpio_read(dev_priv, PIPE_A, VLV_PLL_DW7(0)));
+       seq_printf(m, "DPIO PLL DW7 CH1: 0x%08x\n",
+                  vlv_dpio_read(dev_priv, PIPE_A, VLV_PLL_DW7(1)));
 
-       seq_printf(m, "DPIO_LPF_COEFF_A: 0x%08x\n",
-                  vlv_dpio_read(dev_priv, PIPE_A, _DPIO_LPF_COEFF_A));
-       seq_printf(m, "DPIO_LPF_COEFF_B: 0x%08x\n",
-                  vlv_dpio_read(dev_priv, PIPE_A, _DPIO_LPF_COEFF_B));
+       seq_printf(m, "DPIO PLL DW10 CH0: 0x%08x\n",
+                  vlv_dpio_read(dev_priv, PIPE_A, VLV_PLL_DW10(0)));
+       seq_printf(m, "DPIO PLL DW10 CH1: 0x%08x\n",
+                  vlv_dpio_read(dev_priv, PIPE_A, VLV_PLL_DW10(1)));
 
        seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n",
-                  vlv_dpio_read(dev_priv, PIPE_A, DPIO_FASTCLK_DISABLE));
+                  vlv_dpio_read(dev_priv, PIPE_A, VLV_CMN_DW0));
 
        mutex_unlock(&dev_priv->dpio_lock);
 
@@ -1845,6 +1852,76 @@ static int i915_pc8_status(struct seq_file *m, void *unused)
        return 0;
 }
 
+static const char *power_domain_str(enum intel_display_power_domain domain)
+{
+       switch (domain) {
+       case POWER_DOMAIN_PIPE_A:
+               return "PIPE_A";
+       case POWER_DOMAIN_PIPE_B:
+               return "PIPE_B";
+       case POWER_DOMAIN_PIPE_C:
+               return "PIPE_C";
+       case POWER_DOMAIN_PIPE_A_PANEL_FITTER:
+               return "PIPE_A_PANEL_FITTER";
+       case POWER_DOMAIN_PIPE_B_PANEL_FITTER:
+               return "PIPE_B_PANEL_FITTER";
+       case POWER_DOMAIN_PIPE_C_PANEL_FITTER:
+               return "PIPE_C_PANEL_FITTER";
+       case POWER_DOMAIN_TRANSCODER_A:
+               return "TRANSCODER_A";
+       case POWER_DOMAIN_TRANSCODER_B:
+               return "TRANSCODER_B";
+       case POWER_DOMAIN_TRANSCODER_C:
+               return "TRANSCODER_C";
+       case POWER_DOMAIN_TRANSCODER_EDP:
+               return "TRANSCODER_EDP";
+       case POWER_DOMAIN_VGA:
+               return "VGA";
+       case POWER_DOMAIN_AUDIO:
+               return "AUDIO";
+       case POWER_DOMAIN_INIT:
+               return "INIT";
+       default:
+               WARN_ON(1);
+               return "?";
+       }
+}
+
+static int i915_power_domain_info(struct seq_file *m, void *unused)
+{
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+       struct drm_device *dev = node->minor->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct i915_power_domains *power_domains = &dev_priv->power_domains;
+       int i;
+
+       mutex_lock(&power_domains->lock);
+
+       seq_printf(m, "%-25s %s\n", "Power well/domain", "Use count");
+       for (i = 0; i < power_domains->power_well_count; i++) {
+               struct i915_power_well *power_well;
+               enum intel_display_power_domain power_domain;
+
+               power_well = &power_domains->power_wells[i];
+               seq_printf(m, "%-25s %d\n", power_well->name,
+                          power_well->count);
+
+               for (power_domain = 0; power_domain < POWER_DOMAIN_NUM;
+                    power_domain++) {
+                       if (!(BIT(power_domain) & power_well->domains))
+                               continue;
+
+                       seq_printf(m, "  %-23s %d\n",
+                                power_domain_str(power_domain),
+                                power_domains->domain_use_count[power_domain]);
+               }
+       }
+
+       mutex_unlock(&power_domains->lock);
+
+       return 0;
+}
+
 struct pipe_crc_info {
        const char *name;
        struct drm_device *dev;
@@ -1857,6 +1934,9 @@ static int i915_pipe_crc_open(struct inode *inode, struct file *filep)
        struct drm_i915_private *dev_priv = info->dev->dev_private;
        struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
 
+       if (info->pipe >= INTEL_INFO(info->dev)->num_pipes)
+               return -ENODEV;
+
        spin_lock_irq(&pipe_crc->lock);
 
        if (pipe_crc->opened) {
@@ -2347,7 +2427,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
-       u32 val;
+       u32 val = 0; /* shut up gcc */
        int ret;
 
        if (pipe_crc->source == source)
@@ -2742,7 +2822,7 @@ i915_drop_caches_set(void *data, u64 val)
        struct i915_vma *vma, *x;
        int ret;
 
-       DRM_DEBUG_DRIVER("Dropping caches: 0x%08llx\n", val);
+       DRM_DEBUG("Dropping caches: 0x%08llx\n", val);
 
        /* No need to check and wait for gpu resets, only libdrm auto-restarts
         * on ioctls on -EAGAIN. */
@@ -2810,8 +2890,7 @@ i915_max_freq_get(void *data, u64 *val)
                return ret;
 
        if (IS_VALLEYVIEW(dev))
-               *val = vlv_gpu_freq(dev_priv->mem_freq,
-                                   dev_priv->rps.max_delay);
+               *val = vlv_gpu_freq(dev_priv, dev_priv->rps.max_delay);
        else
                *val = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
        mutex_unlock(&dev_priv->rps.hw_lock);
@@ -2841,9 +2920,9 @@ i915_max_freq_set(void *data, u64 val)
         * Turbo will still be enabled, but won't go above the set value.
         */
        if (IS_VALLEYVIEW(dev)) {
-               val = vlv_freq_opcode(dev_priv->mem_freq, val);
+               val = vlv_freq_opcode(dev_priv, val);
                dev_priv->rps.max_delay = val;
-               gen6_set_rps(dev, val);
+               valleyview_set_rps(dev, val);
        } else {
                do_div(val, GT_FREQUENCY_MULTIPLIER);
                dev_priv->rps.max_delay = val;
@@ -2876,8 +2955,7 @@ i915_min_freq_get(void *data, u64 *val)
                return ret;
 
        if (IS_VALLEYVIEW(dev))
-               *val = vlv_gpu_freq(dev_priv->mem_freq,
-                                   dev_priv->rps.min_delay);
+               *val = vlv_gpu_freq(dev_priv, dev_priv->rps.min_delay);
        else
                *val = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
        mutex_unlock(&dev_priv->rps.hw_lock);
@@ -2907,7 +2985,7 @@ i915_min_freq_set(void *data, u64 val)
         * Turbo will still be enabled, but won't go below the set value.
         */
        if (IS_VALLEYVIEW(dev)) {
-               val = vlv_freq_opcode(dev_priv->mem_freq, val);
+               val = vlv_freq_opcode(dev_priv, val);
                dev_priv->rps.min_delay = val;
                valleyview_set_rps(dev, val);
        } else {
@@ -2983,7 +3061,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
        if (INTEL_INFO(dev)->gen < 6)
                return 0;
 
-       gen6_gt_force_wake_get(dev_priv);
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
        return 0;
 }
@@ -2996,7 +3074,7 @@ static int i915_forcewake_release(struct inode *inode, struct file *file)
        if (INTEL_INFO(dev)->gen < 6)
                return 0;
 
-       gen6_gt_force_wake_put(dev_priv);
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 
        return 0;
 }
@@ -3079,6 +3157,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
        {"i915_edp_psr_status", i915_edp_psr_status, 0},
        {"i915_energy_uJ", i915_energy_uJ, 0},
        {"i915_pc8_status", i915_pc8_status, 0},
+       {"i915_power_domain_info", i915_power_domain_info, 0},
 };
 #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
 
@@ -3102,10 +3181,10 @@ static const struct i915_debugfs_files {
 void intel_display_crc_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int i;
+       enum pipe pipe;
 
-       for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) {
-               struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[i];
+       for_each_pipe(pipe) {
+               struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
 
                pipe_crc->opened = false;
                spin_lock_init(&pipe_crc->lock);
index 0cab2d045135b66d0462c88d390e43eff3df7b20..89e4cf1bb0739a1713799bad2fc6bcbb5fcdae13 100644 (file)
@@ -1486,7 +1486,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        spin_lock_init(&dev_priv->irq_lock);
        spin_lock_init(&dev_priv->gpu_error.lock);
-       spin_lock_init(&dev_priv->backlight.lock);
+       spin_lock_init(&dev_priv->backlight_lock);
        spin_lock_init(&dev_priv->uncore.lock);
        spin_lock_init(&dev_priv->mm.object_stat_lock);
        mutex_init(&dev_priv->dpio_lock);
@@ -1639,8 +1639,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
                        goto out_gem_unload;
        }
 
-       if (HAS_POWER_WELL(dev))
-               intel_power_domains_init(dev);
+       intel_power_domains_init(dev);
 
        if (drm_core_check_feature(dev, DRIVER_MODESET)) {
                ret = i915_load_modeset_init(dev);
@@ -1667,8 +1666,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        return 0;
 
 out_power_well:
-       if (HAS_POWER_WELL(dev))
-               intel_power_domains_remove(dev);
+       intel_power_domains_remove(dev);
        drm_vblank_cleanup(dev);
 out_gem_unload:
        if (dev_priv->mm.inactive_shrinker.scan_objects)
@@ -1706,13 +1704,11 @@ int i915_driver_unload(struct drm_device *dev)
 
        intel_gpu_ips_teardown();
 
-       if (HAS_POWER_WELL(dev)) {
-               /* The i915.ko module is still not prepared to be loaded when
-                * the power well is not enabled, so just enable it in case
-                * we're going to unload/reload. */
-               intel_display_set_init_power(dev, true);
-               intel_power_domains_remove(dev);
-       }
+       /* The i915.ko module is still not prepared to be loaded when
+        * the power well is not enabled, so just enable it in case
+        * we're going to unload/reload. */
+       intel_display_set_init_power(dev, true);
+       intel_power_domains_remove(dev);
 
        i915_teardown_sysfs(dev);
 
@@ -1777,7 +1773,6 @@ int i915_driver_unload(struct drm_device *dev)
 
        list_del(&dev_priv->gtt.base.global_link);
        WARN_ON(!list_empty(&dev_priv->vm_list));
-       drm_mm_takedown(&dev_priv->gtt.base.mm);
 
        drm_vblank_cleanup(dev);
 
@@ -1908,6 +1903,7 @@ const struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_get_reset_stats_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
index 989be12cdd6e962e625b8376734f101ace947d1c..0ec0fb32a10371a3311e4fc5338150bf4de0bcbf 100644 (file)
@@ -114,7 +114,7 @@ MODULE_PARM_DESC(enable_hangcheck,
                "(default: true)");
 
 int i915_enable_ppgtt __read_mostly = -1;
-module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600);
+module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0400);
 MODULE_PARM_DESC(i915_enable_ppgtt,
                "Enable PPGTT (default: true)");
 
@@ -155,7 +155,6 @@ MODULE_PARM_DESC(prefault_disable,
                "Disable page prefaulting for pread/pwrite/reloc (default:false). For developers only.");
 
 static struct drm_driver driver;
-extern int intel_agp_enabled;
 
 static const struct intel_device_info intel_i830_info = {
        .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2,
@@ -265,6 +264,7 @@ static const struct intel_device_info intel_ironlake_m_info = {
 static const struct intel_device_info intel_sandybridge_d_info = {
        .gen = 6, .num_pipes = 2,
        .need_gfx_hws = 1, .has_hotplug = 1,
+       .has_fbc = 1,
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING,
        .has_llc = 1,
 };
@@ -280,6 +280,7 @@ static const struct intel_device_info intel_sandybridge_m_info = {
 #define GEN7_FEATURES  \
        .gen = 7, .num_pipes = 3, \
        .need_gfx_hws = 1, .has_hotplug = 1, \
+       .has_fbc = 1, \
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \
        .has_llc = 1
 
@@ -292,7 +293,6 @@ static const struct intel_device_info intel_ivybridge_m_info = {
        GEN7_FEATURES,
        .is_ivybridge = 1,
        .is_mobile = 1,
-       .has_fbc = 1,
 };
 
 static const struct intel_device_info intel_ivybridge_q_info = {
@@ -307,6 +307,7 @@ static const struct intel_device_info intel_valleyview_m_info = {
        .num_pipes = 2,
        .is_valleyview = 1,
        .display_mmio_offset = VLV_DISPLAY_BASE,
+       .has_fbc = 0, /* legal, last one wins */
        .has_llc = 0, /* legal, last one wins */
 };
 
@@ -315,6 +316,7 @@ static const struct intel_device_info intel_valleyview_d_info = {
        .num_pipes = 2,
        .is_valleyview = 1,
        .display_mmio_offset = VLV_DISPLAY_BASE,
+       .has_fbc = 0, /* legal, last one wins */
        .has_llc = 0, /* legal, last one wins */
 };
 
@@ -332,7 +334,6 @@ static const struct intel_device_info intel_haswell_m_info = {
        .is_mobile = 1,
        .has_ddi = 1,
        .has_fpga_dbg = 1,
-       .has_fbc = 1,
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
 };
 
@@ -534,8 +535,10 @@ static int i915_drm_freeze(struct drm_device *dev)
                 * Disable CRTCs directly since we want to preserve sw state
                 * for _thaw.
                 */
+               mutex_lock(&dev->mode_config.mutex);
                list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
                        dev_priv->display.crtc_disable(crtc);
+               mutex_unlock(&dev->mode_config.mutex);
 
                intel_modeset_suspend_hw(dev);
        }
@@ -759,14 +762,14 @@ int i915_reset(struct drm_device *dev)
                DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
                dev_priv->gpu_error.stop_rings = 0;
                if (ret == -ENODEV) {
-                       DRM_ERROR("Reset not implemented, but ignoring "
-                                 "error for simulated gpu hangs\n");
+                       DRM_INFO("Reset not implemented, but ignoring "
+                                "error for simulated gpu hangs\n");
                        ret = 0;
                }
        }
 
        if (ret) {
-               DRM_ERROR("Failed to reset chip.\n");
+               DRM_ERROR("Failed to reset chip: %i\n", ret);
                mutex_unlock(&dev->struct_mutex);
                return ret;
        }
@@ -787,12 +790,9 @@ int i915_reset(struct drm_device *dev)
         */
        if (drm_core_check_feature(dev, DRIVER_MODESET) ||
                        !dev_priv->ums.mm_suspended) {
-               bool hw_contexts_disabled = dev_priv->hw_contexts_disabled;
                dev_priv->ums.mm_suspended = 0;
 
                ret = i915_gem_init_hw(dev);
-               if (!hw_contexts_disabled && dev_priv->hw_contexts_disabled)
-                       DRM_ERROR("HW contexts didn't survive reset\n");
                mutex_unlock(&dev->struct_mutex);
                if (ret) {
                        DRM_ERROR("Failed hw init on reset %d\n", ret);
@@ -828,17 +828,7 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (PCI_FUNC(pdev->devfn))
                return -ENODEV;
 
-       /* We've managed to ship a kms-enabled ddx that shipped with an XvMC
-        * implementation for gen3 (and only gen3) that used legacy drm maps
-        * (gasp!) to share buffers between X and the client. Hence we need to
-        * keep around the fake agp stuff for gen3, even when kms is enabled. */
-       if (intel_info->gen != 3) {
-               driver.driver_features &=
-                       ~(DRIVER_USE_AGP | DRIVER_REQUIRE_AGP);
-       } else if (!intel_agp_enabled) {
-               DRM_ERROR("drm/i915 can't work without intel_agp module!\n");
-               return -ENODEV;
-       }
+       driver.driver_features &= ~(DRIVER_USE_AGP | DRIVER_REQUIRE_AGP);
 
        return drm_get_pci_dev(pdev, ent, &driver);
 }
@@ -1021,14 +1011,24 @@ static int __init i915_init(void)
                driver.driver_features &= ~DRIVER_MODESET;
 #endif
 
-       if (!(driver.driver_features & DRIVER_MODESET))
+       if (!(driver.driver_features & DRIVER_MODESET)) {
                driver.get_vblank_timestamp = NULL;
+#ifndef CONFIG_DRM_I915_UMS
+               /* Silently fail loading to not upset userspace. */
+               return 0;
+#endif
+       }
 
        return drm_pci_init(&driver, &i915_pci_driver);
 }
 
 static void __exit i915_exit(void)
 {
+#ifndef CONFIG_DRM_I915_UMS
+       if (!(driver.driver_features & DRIVER_MODESET))
+               return; /* Never loaded a driver. */
+#endif
+
        drm_pci_exit(&driver, &i915_pci_driver);
 }
 
index ccdbecca070d2340919d5499f80824ddb84db4ac..780f815b6c9f228b17d8cbd11bb93f2ac91fefaf 100644 (file)
@@ -89,6 +89,18 @@ enum port {
 };
 #define port_name(p) ((p) + 'A')
 
+#define I915_NUM_PHYS_VLV 1
+
+enum dpio_channel {
+       DPIO_CH0,
+       DPIO_CH1
+};
+
+enum dpio_phy {
+       DPIO_PHY0,
+       DPIO_PHY1
+};
+
 enum intel_display_power_domain {
        POWER_DOMAIN_PIPE_A,
        POWER_DOMAIN_PIPE_B,
@@ -101,6 +113,7 @@ enum intel_display_power_domain {
        POWER_DOMAIN_TRANSCODER_C,
        POWER_DOMAIN_TRANSCODER_EDP,
        POWER_DOMAIN_VGA,
+       POWER_DOMAIN_AUDIO,
        POWER_DOMAIN_INIT,
 
        POWER_DOMAIN_NUM,
@@ -351,6 +364,7 @@ struct drm_i915_error_state {
        enum intel_ring_hangcheck_action hangcheck_action[I915_NUM_RINGS];
 };
 
+struct intel_connector;
 struct intel_crtc_config;
 struct intel_crtc;
 struct intel_limit;
@@ -413,11 +427,20 @@ struct drm_i915_display_funcs {
        /* render clock increase/decrease */
        /* display clock increase/decrease */
        /* pll clock increase/decrease */
+
+       int (*setup_backlight)(struct intel_connector *connector);
+       uint32_t (*get_backlight)(struct intel_connector *connector);
+       void (*set_backlight)(struct intel_connector *connector,
+                             uint32_t level);
+       void (*disable_backlight)(struct intel_connector *connector);
+       void (*enable_backlight)(struct intel_connector *connector);
 };
 
 struct intel_uncore_funcs {
-       void (*force_wake_get)(struct drm_i915_private *dev_priv);
-       void (*force_wake_put)(struct drm_i915_private *dev_priv);
+       void (*force_wake_get)(struct drm_i915_private *dev_priv,
+                                                       int fw_engine);
+       void (*force_wake_put)(struct drm_i915_private *dev_priv,
+                                                       int fw_engine);
 
        uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
        uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
@@ -442,6 +465,9 @@ struct intel_uncore {
        unsigned fifo_count;
        unsigned forcewake_count;
 
+       unsigned fw_rendercount;
+       unsigned fw_mediacount;
+
        struct delayed_work force_wake_work;
 };
 
@@ -708,7 +734,6 @@ enum intel_sbi_destination {
 #define QUIRK_PIPEA_FORCE (1<<0)
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
-#define QUIRK_NO_PCH_PWM_ENABLE (1<<3)
 
 struct intel_fbdev;
 struct intel_fbc_work;
@@ -761,8 +786,6 @@ struct i915_suspend_saved_registers {
        u32 saveBLC_PWM_CTL;
        u32 saveBLC_PWM_CTL2;
        u32 saveBLC_HIST_CTL_B;
-       u32 saveBLC_PWM_CTL_B;
-       u32 saveBLC_PWM_CTL2_B;
        u32 saveBLC_CPU_PWM_CTL;
        u32 saveBLC_CPU_PWM_CTL2;
        u32 saveFPB0;
@@ -932,21 +955,29 @@ struct intel_ilk_power_mgmt {
 
 /* Power well structure for haswell */
 struct i915_power_well {
+       const char *name;
+       bool always_on;
        /* power well enable/disable usage count */
        int count;
+       unsigned long domains;
+       void *data;
+       void (*set)(struct drm_device *dev, struct i915_power_well *power_well,
+                   bool enable);
+       bool (*is_enabled)(struct drm_device *dev,
+                          struct i915_power_well *power_well);
 };
 
-#define I915_MAX_POWER_WELLS 1
-
 struct i915_power_domains {
        /*
         * Power wells needed for initialization at driver init and suspend
         * time are on. They are kept on until after the first modeset.
         */
        bool init_power_on;
+       int power_well_count;
 
        struct mutex lock;
-       struct i915_power_well power_wells[I915_MAX_POWER_WELLS];
+       int domain_use_count[POWER_DOMAIN_NUM];
+       struct i915_power_well *power_wells;
 };
 
 struct i915_dri1_state {
@@ -1077,34 +1108,30 @@ struct i915_gpu_error {
        unsigned long missed_irq_rings;
 
        /**
-        * State variable and reset counter controlling the reset flow
+        * State variable controlling the reset flow and count
         *
-        * Upper bits are for the reset counter.  This counter is used by the
-        * wait_seqno code to race-free noticed that a reset event happened and
-        * that it needs to restart the entire ioctl (since most likely the
-        * seqno it waited for won't ever signal anytime soon).
+        * This is a counter which gets incremented when reset is triggered,
+        * and again when reset has been handled. So odd values (lowest bit set)
+        * means that reset is in progress and even values that
+        * (reset_counter >> 1):th reset was successfully completed.
+        *
+        * If reset is not completed succesfully, the I915_WEDGE bit is
+        * set meaning that hardware is terminally sour and there is no
+        * recovery. All waiters on the reset_queue will be woken when
+        * that happens.
+        *
+        * This counter is used by the wait_seqno code to notice that reset
+        * event happened and it needs to restart the entire ioctl (since most
+        * likely the seqno it waited for won't ever signal anytime soon).
         *
         * This is important for lock-free wait paths, where no contended lock
         * naturally enforces the correct ordering between the bail-out of the
         * waiter and the gpu reset work code.
-        *
-        * Lowest bit controls the reset state machine: Set means a reset is in
-        * progress. This state will (presuming we don't have any bugs) decay
-        * into either unset (successful reset) or the special WEDGED value (hw
-        * terminally sour). All waiters on the reset_queue will be woken when
-        * that happens.
         */
        atomic_t reset_counter;
 
-       /**
-        * Special values/flags for reset_counter
-        *
-        * Note that the code relies on
-        *      I915_WEDGED & I915_RESET_IN_PROGRESS_FLAG
-        * being true.
-        */
 #define I915_RESET_IN_PROGRESS_FLAG    1
-#define I915_WEDGED                    0xffffffff
+#define I915_WEDGED                    (1 << 31)
 
        /**
         * Waitqueue to signal when the reset has completed. Used by clients
@@ -1368,13 +1395,8 @@ typedef struct drm_i915_private {
        struct intel_overlay *overlay;
        unsigned int sprite_scaling_enabled;
 
-       /* backlight */
-       struct {
-               int level;
-               bool enabled;
-               spinlock_t lock; /* bl registers and the above bl fields */
-               struct backlight_device *device;
-       } backlight;
+       /* backlight registers and fields in struct intel_panel */
+       spinlock_t backlight_lock;
 
        /* LVDS info */
        bool no_aux_handshake;
@@ -1426,6 +1448,7 @@ typedef struct drm_i915_private {
        int num_shared_dpll;
        struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
        struct intel_ddi_plls ddi_plls;
+       int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
 
        /* Reclocking support */
        bool render_reclock_avail;
@@ -1470,7 +1493,6 @@ typedef struct drm_i915_private {
        struct drm_property *broadcast_rgb_property;
        struct drm_property *force_audio_property;
 
-       bool hw_contexts_disabled;
        uint32_t hw_context_size;
        struct list_head context_list;
 
@@ -1755,8 +1777,13 @@ struct drm_i915_file_private {
 #define IS_MOBILE(dev)         (INTEL_INFO(dev)->is_mobile)
 #define IS_HSW_EARLY_SDV(dev)  (IS_HASWELL(dev) && \
                                 ((dev)->pdev->device & 0xFF00) == 0x0C00)
-#define IS_ULT(dev)            (IS_HASWELL(dev) && \
+#define IS_BDW_ULT(dev)                (IS_BROADWELL(dev) && \
+                                (((dev)->pdev->device & 0xf) == 0x2  || \
+                                ((dev)->pdev->device & 0xf) == 0x6 || \
+                                ((dev)->pdev->device & 0xf) == 0xe))
+#define IS_HSW_ULT(dev)                (IS_HASWELL(dev) && \
                                 ((dev)->pdev->device & 0xFF00) == 0x0A00)
+#define IS_ULT(dev)            (IS_HSW_ULT(dev) || IS_BDW_ULT(dev))
 #define IS_HSW_GT3(dev)                (IS_HASWELL(dev) && \
                                 ((dev)->pdev->device & 0x00F0) == 0x0020)
 #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
@@ -1813,7 +1840,6 @@ struct drm_i915_file_private {
 #define HAS_IPS(dev)           (IS_ULT(dev) || IS_BROADWELL(dev))
 
 #define HAS_DDI(dev)           (INTEL_INFO(dev)->has_ddi)
-#define HAS_POWER_WELL(dev)    (IS_HASWELL(dev) || IS_BROADWELL(dev))
 #define HAS_FPGA_DBG_UNCLAIMED(dev)    (INTEL_INFO(dev)->has_fpga_dbg)
 #define HAS_PSR(dev)           (IS_HASWELL(dev) || IS_BROADWELL(dev))
 #define HAS_PC8(dev)           (IS_HASWELL(dev)) /* XXX HSW:ULX */
@@ -1908,7 +1934,6 @@ extern void intel_pm_init(struct drm_device *dev);
 extern void intel_uncore_sanitize(struct drm_device *dev);
 extern void intel_uncore_early_sanitize(struct drm_device *dev);
 extern void intel_uncore_init(struct drm_device *dev);
-extern void intel_uncore_clear_errors(struct drm_device *dev);
 extern void intel_uncore_check_errors(struct drm_device *dev);
 extern void intel_uncore_fini(struct drm_device *dev);
 
@@ -2060,12 +2085,17 @@ int __must_check i915_gem_check_wedge(struct i915_gpu_error *error,
 static inline bool i915_reset_in_progress(struct i915_gpu_error *error)
 {
        return unlikely(atomic_read(&error->reset_counter)
-                       & I915_RESET_IN_PROGRESS_FLAG);
+                       & (I915_RESET_IN_PROGRESS_FLAG | I915_WEDGED));
 }
 
 static inline bool i915_terminally_wedged(struct i915_gpu_error *error)
 {
-       return atomic_read(&error->reset_counter) == I915_WEDGED;
+       return atomic_read(&error->reset_counter) & I915_WEDGED;
+}
+
+static inline u32 i915_reset_count(struct i915_gpu_error *error)
+{
+       return ((atomic_read(&error->reset_counter) & ~I915_WEDGED) + 1) / 2;
 }
 
 void i915_gem_reset(struct drm_device *dev);
@@ -2177,7 +2207,7 @@ i915_gem_obj_ggtt_pin(struct drm_i915_gem_object *obj,
 }
 
 /* i915_gem_context.c */
-void i915_gem_context_init(struct drm_device *dev);
+int __must_check i915_gem_context_init(struct drm_device *dev);
 void i915_gem_context_fini(struct drm_device *dev);
 void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
 int i915_switch_context(struct intel_ring_buffer *ring,
@@ -2395,6 +2425,8 @@ extern int intel_enable_rc6(const struct drm_device *dev);
 extern bool i915_semaphore_is_enabled(struct drm_device *dev);
 int i915_reg_read_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file);
+int i915_get_reset_stats_ioctl(struct drm_device *dev, void *data,
+                              struct drm_file *file);
 
 /* overlay */
 extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
@@ -2410,8 +2442,8 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
  * must be set to prevent GT core from power down and stale values being
  * returned.
  */
-void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
-void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
+void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine);
+void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine);
 
 int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val);
 int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val);
@@ -2426,6 +2458,8 @@ u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
 void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
 u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
 void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
 u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg);
 void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
 u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg);
@@ -2435,8 +2469,27 @@ u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
 void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
                     enum intel_sbi_destination destination);
 
-int vlv_gpu_freq(int ddr_freq, int val);
-int vlv_freq_opcode(int ddr_freq, int val);
+int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val);
+int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
+
+void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine);
+void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine);
+
+#define FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg) \
+       (((reg) >= 0x2000 && (reg) < 0x4000) ||\
+       ((reg) >= 0x5000 && (reg) < 0x8000) ||\
+       ((reg) >= 0xB000 && (reg) < 0x12000) ||\
+       ((reg) >= 0x2E000 && (reg) < 0x30000))
+
+#define FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)\
+       (((reg) >= 0x12000 && (reg) < 0x14000) ||\
+       ((reg) >= 0x22000 && (reg) < 0x24000) ||\
+       ((reg) >= 0x30000 && (reg) < 0x40000))
+
+#define FORCEWAKE_RENDER       (1 << 0)
+#define FORCEWAKE_MEDIA                (1 << 1)
+#define FORCEWAKE_ALL          (FORCEWAKE_RENDER | FORCEWAKE_MEDIA)
+
 
 #define I915_READ8(reg)                dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
 #define I915_WRITE8(reg, val)  dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
index 12bbd5eac70db7a22a291dfc5c2e01624803c816..182c521ec392a434f646ce5be022a69f970e4e48 100644 (file)
@@ -4442,10 +4442,9 @@ i915_gem_init_hw(struct drm_device *dev)
        if (dev_priv->ellc_size)
                I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf));
 
-       if (IS_HSW_GT3(dev))
-               I915_WRITE(MI_PREDICATE_RESULT_2, LOWER_SLICE_ENABLED);
-       else
-               I915_WRITE(MI_PREDICATE_RESULT_2, LOWER_SLICE_DISABLED);
+       if (IS_HASWELL(dev))
+               I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev) ?
+                          LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED);
 
        if (HAS_PCH_NOP(dev)) {
                u32 temp = I915_READ(GEN7_MSG_CTL);
@@ -4466,7 +4465,13 @@ i915_gem_init_hw(struct drm_device *dev)
         * XXX: There was some w/a described somewhere suggesting loading
         * contexts before PPGTT.
         */
-       i915_gem_context_init(dev);
+       ret = i915_gem_context_init(dev);
+       if (ret) {
+               i915_gem_cleanup_ringbuffer(dev);
+               DRM_ERROR("Context initialization failed %d\n", ret);
+               return ret;
+       }
+
        if (dev_priv->mm.aliasing_ppgtt) {
                ret = dev_priv->mm.aliasing_ppgtt->enable(dev);
                if (ret) {
index 72a3df32292f79d88d1ba17dc8d620a24ad435ca..41877045a1a0e59fff8b391227842145dcb61789 100644 (file)
@@ -247,36 +247,34 @@ err_destroy:
        return ret;
 }
 
-void i915_gem_context_init(struct drm_device *dev)
+int i915_gem_context_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
+       int ret;
 
-       if (!HAS_HW_CONTEXTS(dev)) {
-               dev_priv->hw_contexts_disabled = true;
-               DRM_DEBUG_DRIVER("Disabling HW Contexts; old hardware\n");
-               return;
-       }
+       if (!HAS_HW_CONTEXTS(dev))
+               return 0;
 
        /* If called from reset, or thaw... we've been here already */
-       if (dev_priv->hw_contexts_disabled ||
-           dev_priv->ring[RCS].default_context)
-               return;
+       if (dev_priv->ring[RCS].default_context)
+               return 0;
 
        dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
 
        if (dev_priv->hw_context_size > (1<<20)) {
-               dev_priv->hw_contexts_disabled = true;
                DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n");
-               return;
+               return -E2BIG;
        }
 
-       if (create_default_context(dev_priv)) {
-               dev_priv->hw_contexts_disabled = true;
-               DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed\n");
-               return;
+       ret = create_default_context(dev_priv);
+       if (ret) {
+               DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed %d\n",
+                                ret);
+               return ret;
        }
 
        DRM_DEBUG_DRIVER("HW context support initialized\n");
+       return 0;
 }
 
 void i915_gem_context_fini(struct drm_device *dev)
@@ -284,7 +282,7 @@ void i915_gem_context_fini(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context;
 
-       if (dev_priv->hw_contexts_disabled)
+       if (!HAS_HW_CONTEXTS(dev))
                return;
 
        /* The only known way to stop the gpu from accessing the hw context is
@@ -327,16 +325,16 @@ i915_gem_context_get_hang_stats(struct drm_device *dev,
                                struct drm_file *file,
                                u32 id)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_file_private *file_priv = file->driver_priv;
        struct i915_hw_context *ctx;
 
        if (id == DEFAULT_CONTEXT_ID)
                return &file_priv->hang_stats;
 
-       ctx = NULL;
-       if (!dev_priv->hw_contexts_disabled)
-               ctx = i915_gem_context_get(file->driver_priv, id);
+       if (!HAS_HW_CONTEXTS(dev))
+               return ERR_PTR(-ENOENT);
+
+       ctx = i915_gem_context_get(file->driver_priv, id);
        if (ctx == NULL)
                return ERR_PTR(-ENOENT);
 
@@ -494,8 +492,6 @@ static int do_switch(struct i915_hw_context *to)
  * @ring: ring for which we'll execute the context switch
  * @file_priv: file_priv associated with the context, may be NULL
  * @id: context id number
- * @seqno: sequence number by which the new context will be switched to
- * @flags:
  *
  * The context life cycle is simple. The context refcount is incremented and
  * decremented by 1 and create and destroy. If the context is in use by the GPU,
@@ -509,7 +505,7 @@ int i915_switch_context(struct intel_ring_buffer *ring,
        struct drm_i915_private *dev_priv = ring->dev->dev_private;
        struct i915_hw_context *to;
 
-       if (dev_priv->hw_contexts_disabled)
+       if (!HAS_HW_CONTEXTS(ring->dev))
                return 0;
 
        WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
@@ -534,7 +530,6 @@ int i915_switch_context(struct intel_ring_buffer *ring,
 int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
                                  struct drm_file *file)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_context_create *args = data;
        struct drm_i915_file_private *file_priv = file->driver_priv;
        struct i915_hw_context *ctx;
@@ -543,7 +538,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
        if (!(dev->driver->driver_features & DRIVER_GEM))
                return -ENODEV;
 
-       if (dev_priv->hw_contexts_disabled)
+       if (!HAS_HW_CONTEXTS(dev))
                return -ENODEV;
 
        ret = i915_mutex_lock_interruptible(dev);
index 7d5752fda5f18b7850beeed588a6f1b3a85cd79a..9bb533e0d76234cdc14ec6d9da31a310114080a5 100644 (file)
@@ -125,13 +125,15 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
 
        ret = i915_gem_object_get_pages(obj);
        if (ret)
-               goto error;
+               goto err;
+
+       i915_gem_object_pin_pages(obj);
 
        ret = -ENOMEM;
 
        pages = drm_malloc_ab(obj->base.size >> PAGE_SHIFT, sizeof(*pages));
        if (pages == NULL)
-               goto error;
+               goto err_unpin;
 
        i = 0;
        for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0)
@@ -141,15 +143,16 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
        drm_free_large(pages);
 
        if (!obj->dma_buf_vmapping)
-               goto error;
+               goto err_unpin;
 
        obj->vmapping_count = 1;
-       i915_gem_object_pin_pages(obj);
 out_unlock:
        mutex_unlock(&dev->struct_mutex);
        return obj->dma_buf_vmapping;
 
-error:
+err_unpin:
+       i915_gem_object_unpin_pages(obj);
+err:
        mutex_unlock(&dev->struct_mutex);
        return ERR_PTR(ret);
 }
index 885d595e0e02255e30fbff181247b70df1af5363..3c90dd1a3bbdb81a0604216924ae86cb578e8ed4 100644 (file)
@@ -33,6 +33,9 @@
 #include "intel_drv.h"
 #include <linux/dma_remapping.h>
 
+#define  __EXEC_OBJECT_HAS_PIN (1<<31)
+#define  __EXEC_OBJECT_HAS_FENCE (1<<30)
+
 struct eb_vmas {
        struct list_head vmas;
        int and;
@@ -43,7 +46,7 @@ struct eb_vmas {
 };
 
 static struct eb_vmas *
-eb_create(struct drm_i915_gem_execbuffer2 *args, struct i915_address_space *vm)
+eb_create(struct drm_i915_gem_execbuffer2 *args)
 {
        struct eb_vmas *eb = NULL;
 
@@ -187,7 +190,28 @@ static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle)
        }
 }
 
-static void eb_destroy(struct eb_vmas *eb) {
+static void
+i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma)
+{
+       struct drm_i915_gem_exec_object2 *entry;
+       struct drm_i915_gem_object *obj = vma->obj;
+
+       if (!drm_mm_node_allocated(&vma->node))
+               return;
+
+       entry = vma->exec_entry;
+
+       if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
+               i915_gem_object_unpin_fence(obj);
+
+       if (entry->flags & __EXEC_OBJECT_HAS_PIN)
+               i915_gem_object_unpin(obj);
+
+       entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
+}
+
+static void eb_destroy(struct eb_vmas *eb)
+{
        while (!list_empty(&eb->vmas)) {
                struct i915_vma *vma;
 
@@ -195,6 +219,7 @@ static void eb_destroy(struct eb_vmas *eb) {
                                       struct i915_vma,
                                       exec_list);
                list_del_init(&vma->exec_list);
+               i915_gem_execbuffer_unreserve_vma(vma);
                drm_gem_object_unreference(&vma->obj->base);
        }
        kfree(eb);
@@ -307,7 +332,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
        target_i915_obj = target_vma->obj;
        target_obj = &target_vma->obj->base;
 
-       target_offset = i915_gem_obj_ggtt_offset(target_i915_obj);
+       target_offset = target_vma->node.start;
 
        /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
         * pipe_control writes because the gpu doesn't properly redirect them
@@ -454,8 +479,7 @@ i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma,
 }
 
 static int
-i915_gem_execbuffer_relocate(struct eb_vmas *eb,
-                            struct i915_address_space *vm)
+i915_gem_execbuffer_relocate(struct eb_vmas *eb)
 {
        struct i915_vma *vma;
        int ret = 0;
@@ -478,9 +502,6 @@ i915_gem_execbuffer_relocate(struct eb_vmas *eb,
        return ret;
 }
 
-#define  __EXEC_OBJECT_HAS_PIN (1<<31)
-#define  __EXEC_OBJECT_HAS_FENCE (1<<30)
-
 static int
 need_reloc_mappable(struct i915_vma *vma)
 {
@@ -552,26 +573,6 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
        return 0;
 }
 
-static void
-i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma)
-{
-       struct drm_i915_gem_exec_object2 *entry;
-       struct drm_i915_gem_object *obj = vma->obj;
-
-       if (!drm_mm_node_allocated(&vma->node))
-               return;
-
-       entry = vma->exec_entry;
-
-       if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
-               i915_gem_object_unpin_fence(obj);
-
-       if (entry->flags & __EXEC_OBJECT_HAS_PIN)
-               i915_gem_object_unpin(obj);
-
-       entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
-}
-
 static int
 i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
                            struct list_head *vmas,
@@ -670,13 +671,14 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
                                goto err;
                }
 
-err:           /* Decrement pin count for bound objects */
-               list_for_each_entry(vma, vmas, exec_list)
-                       i915_gem_execbuffer_unreserve_vma(vma);
-
+err:
                if (ret != -ENOSPC || retry++)
                        return ret;
 
+               /* Decrement pin count for bound objects */
+               list_for_each_entry(vma, vmas, exec_list)
+                       i915_gem_execbuffer_unreserve_vma(vma);
+
                ret = i915_gem_evict_vm(vm, true);
                if (ret)
                        return ret;
@@ -708,6 +710,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
        while (!list_empty(&eb->vmas)) {
                vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list);
                list_del_init(&vma->exec_list);
+               i915_gem_execbuffer_unreserve_vma(vma);
                drm_gem_object_unreference(&vma->obj->base);
        }
 
@@ -1102,7 +1105,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                goto pre_mutex_err;
        }
 
-       eb = eb_create(args, vm);
+       eb = eb_create(args);
        if (eb == NULL) {
                mutex_unlock(&dev->struct_mutex);
                ret = -ENOMEM;
@@ -1125,7 +1128,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 
        /* The objects are in their final locations, apply the relocations. */
        if (need_relocs)
-               ret = i915_gem_execbuffer_relocate(eb, vm);
+               ret = i915_gem_execbuffer_relocate(eb);
        if (ret) {
                if (ret == -EFAULT) {
                        ret = i915_gem_execbuffer_relocate_slow(dev, args, file, ring,
index 3620a1b0a73cbcea019cbd5503250410e51f2807..a54eaabb3a3e9a5e25e6f15437e000768709b38d 100644 (file)
@@ -57,7 +57,9 @@ typedef gen8_gtt_pte_t gen8_ppgtt_pde_t;
 #define HSW_WB_LLC_AGE3                        HSW_CACHEABILITY_CONTROL(0x2)
 #define HSW_WB_LLC_AGE0                        HSW_CACHEABILITY_CONTROL(0x3)
 #define HSW_WB_ELLC_LLC_AGE0           HSW_CACHEABILITY_CONTROL(0xb)
+#define HSW_WB_ELLC_LLC_AGE3           HSW_CACHEABILITY_CONTROL(0x8)
 #define HSW_WT_ELLC_LLC_AGE0           HSW_CACHEABILITY_CONTROL(0x6)
+#define HSW_WT_ELLC_LLC_AGE3           HSW_CACHEABILITY_CONTROL(0x7)
 
 #define GEN8_PTES_PER_PAGE             (PAGE_SIZE / sizeof(gen8_gtt_pte_t))
 #define GEN8_PDES_PER_PAGE             (PAGE_SIZE / sizeof(gen8_ppgtt_pde_t))
@@ -185,10 +187,10 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
        case I915_CACHE_NONE:
                break;
        case I915_CACHE_WT:
-               pte |= HSW_WT_ELLC_LLC_AGE0;
+               pte |= HSW_WT_ELLC_LLC_AGE3;
                break;
        default:
-               pte |= HSW_WB_ELLC_LLC_AGE0;
+               pte |= HSW_WB_ELLC_LLC_AGE3;
                break;
        }
 
@@ -238,10 +240,16 @@ static int gen8_ppgtt_enable(struct drm_device *dev)
                for_each_ring(ring, dev_priv, j) {
                        ret = gen8_write_pdp(ring, i, addr);
                        if (ret)
-                               return ret;
+                               goto err_out;
                }
        }
        return 0;
+
+err_out:
+       for_each_ring(ring, dev_priv, j)
+               I915_WRITE(RING_MODE_GEN7(ring),
+                          _MASKED_BIT_DISABLE(GFX_PPGTT_ENABLE));
+       return ret;
 }
 
 static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
@@ -316,6 +324,8 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
                container_of(vm, struct i915_hw_ppgtt, base);
        int i, j;
 
+       drm_mm_takedown(&vm->mm);
+
        for (i = 0; i < ppgtt->num_pd_pages ; i++) {
                if (ppgtt->pd_dma_addr[i]) {
                        pci_unmap_page(ppgtt->base.dev->pdev,
@@ -335,8 +345,8 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
                kfree(ppgtt->gen8_pt_dma_addr[i]);
        }
 
-       __free_pages(ppgtt->gen8_pt_pages, ppgtt->num_pt_pages << PAGE_SHIFT);
-       __free_pages(ppgtt->pd_pages, ppgtt->num_pd_pages << PAGE_SHIFT);
+       __free_pages(ppgtt->gen8_pt_pages, get_order(ppgtt->num_pt_pages << PAGE_SHIFT));
+       __free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << PAGE_SHIFT));
 }
 
 /**
@@ -379,6 +389,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size)
        ppgtt->base.clear_range = gen8_ppgtt_clear_range;
        ppgtt->base.insert_entries = gen8_ppgtt_insert_entries;
        ppgtt->base.cleanup = gen8_ppgtt_cleanup;
+       ppgtt->base.start = 0;
+       ppgtt->base.total = ppgtt->num_pt_pages * GEN8_PTES_PER_PAGE * PAGE_SIZE;
 
        BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS);
 
@@ -630,6 +642,8 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
        ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
        ppgtt->base.cleanup = gen6_ppgtt_cleanup;
        ppgtt->base.scratch = dev_priv->gtt.base.scratch;
+       ppgtt->base.start = 0;
+       ppgtt->base.total = GEN6_PPGTT_PD_ENTRIES * I915_PPGTT_PT_ENTRIES * PAGE_SIZE;
        ppgtt->pt_pages = kcalloc(ppgtt->num_pd_entries, sizeof(struct page *),
                                  GFP_KERNEL);
        if (!ppgtt->pt_pages)
@@ -1124,7 +1138,6 @@ void i915_gem_setup_global_gtt(struct drm_device *dev,
                if (ret)
                        DRM_DEBUG_KMS("Reservation failed\n");
                obj->has_global_gtt_mapping = 1;
-               list_add(&vma->vma_link, &obj->vma_list);
        }
 
        dev_priv->gtt.base.start = start;
@@ -1239,6 +1252,11 @@ static inline unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl)
        bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK;
        if (bdw_gmch_ctl)
                bdw_gmch_ctl = 1 << bdw_gmch_ctl;
+       if (bdw_gmch_ctl > 4) {
+               WARN_ON(!i915_preliminary_hw_support);
+               return 4<<20;
+       }
+
        return bdw_gmch_ctl << 20;
 }
 
@@ -1395,6 +1413,8 @@ static void gen6_gmch_remove(struct i915_address_space *vm)
 {
 
        struct i915_gtt *gtt = container_of(vm, struct i915_gtt, base);
+
+       drm_mm_takedown(&vm->mm);
        iounmap(gtt->gsm);
        teardown_scratch_page(vm->dev);
 }
index 5d1dedc02f159c8b7a21d23a940df9c5bf0c2bd2..271560080ad59426941c0c5c06cda867a19285dd 100644 (file)
@@ -600,7 +600,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
         * Cook up a vblank counter by also checking the pixel
         * counter against vblank start.
         */
-       return ((high1 << 8) | low) + (pixel >= vbl_start);
+       return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff;
 }
 
 static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
@@ -1015,10 +1015,8 @@ static void gen6_pm_rps_work(struct work_struct *work)
        /* sysfs frequency interfaces may have snuck in while servicing the
         * interrupt
         */
-       if (new_delay < (int)dev_priv->rps.min_delay)
-               new_delay = dev_priv->rps.min_delay;
-       if (new_delay > (int)dev_priv->rps.max_delay)
-               new_delay = dev_priv->rps.max_delay;
+       new_delay = clamp_t(int, new_delay,
+                           dev_priv->rps.min_delay, dev_priv->rps.max_delay);
        dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_delay;
 
        if (IS_VALLEYVIEW(dev_priv->dev))
@@ -1474,6 +1472,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
 
                        intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915);
 
+                       if (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X)
+                               dp_aux_irq_handler(dev);
+
                        I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
                        I915_READ(PORT_HOTPLUG_STAT);
                }
@@ -1993,7 +1994,7 @@ static void i915_error_work_func(struct work_struct *work)
                        kobject_uevent_env(&dev->primary->kdev->kobj,
                                           KOBJ_CHANGE, reset_done_event);
                } else {
-                       atomic_set(&error->reset_counter, I915_WEDGED);
+                       atomic_set_mask(I915_WEDGED, &error->reset_counter);
                }
 
                /*
@@ -3655,6 +3656,10 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
                        intel_hpd_irq_handler(dev, hotplug_trigger,
                                              IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i915);
 
+                       if (IS_G4X(dev) &&
+                           (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X))
+                               dp_aux_irq_handler(dev);
+
                        I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
                        I915_READ(PORT_HOTPLUG_STAT);
                }
index f9eafb6ed523a2d0f8fbd2ff981705c644733790..3be449d884a7eff86316f9849ed0866301a1e441 100644 (file)
  */
 #define MI_LOAD_REGISTER_IMM(x)        MI_INSTR(0x22, 2*x-1)
 #define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*x-1)
+#define  MI_SRM_LRM_GLOBAL_GTT         (1<<22)
 #define MI_FLUSH_DW            MI_INSTR(0x26, 1) /* for GEN6 */
 #define   MI_FLUSH_DW_STORE_INDEX      (1<<21)
 #define   MI_INVALIDATE_TLB            (1<<18)
 #define   IOSF_BYTE_ENABLES_SHIFT              4
 #define   IOSF_BAR_SHIFT                       1
 #define   IOSF_SB_BUSY                         (1<<0)
+#define   IOSF_PORT_BUNIT                      0x3
 #define   IOSF_PORT_PUNIT                      0x4
 #define   IOSF_PORT_NC                         0x11
 #define   IOSF_PORT_DPIO                       0x12
 #define VLV_IOSF_DATA                          (VLV_DISPLAY_BASE + 0x2104)
 #define VLV_IOSF_ADDR                          (VLV_DISPLAY_BASE + 0x2108)
 
+/* See configdb bunit SB addr map */
+#define BUNIT_REG_BISOC                                0x11
+
 #define PUNIT_OPCODE_REG_READ                  6
 #define PUNIT_OPCODE_REG_WRITE                 7
 
+#define PUNIT_REG_DSPFREQ                      0x36
+#define   DSPFREQSTAT_SHIFT                    30
+#define   DSPFREQSTAT_MASK                     (0x3 << DSPFREQSTAT_SHIFT)
+#define   DSPFREQGUAR_SHIFT                    14
+#define   DSPFREQGUAR_MASK                     (0x3 << DSPFREQGUAR_SHIFT)
 #define PUNIT_REG_PWRGT_CTRL                   0x60
 #define PUNIT_REG_PWRGT_STATUS                 0x61
 #define          PUNIT_CLK_GATE                        1
 #define  DSI_PLL_N1_DIV_MASK                   (3 << 16)
 #define  DSI_PLL_M1_DIV_SHIFT                  0
 #define  DSI_PLL_M1_DIV_MASK                   (0x1ff << 0)
+#define CCK_DISPLAY_CLOCK_CONTROL              0x6b
 
 /*
  * DPIO - a special bus for various display related registers to hide behind
 #define  DPIO_SFR_BYPASS               (1<<1)
 #define  DPIO_CMNRST                   (1<<0)
 
-#define _DPIO_TX3_SWING_CTL4_A         0x690
-#define _DPIO_TX3_SWING_CTL4_B         0x2a90
-#define DPIO_TX3_SWING_CTL4(pipe) _PIPE(pipe, _DPIO_TX3_SWING_CTL4_A, \
-                                       _DPIO_TX3_SWING_CTL4_B)
+#define DPIO_PHY(pipe)                 ((pipe) >> 1)
+#define DPIO_PHY_IOSF_PORT(phy)                (dev_priv->dpio_phy_iosf_port[phy])
 
 /*
  * Per pipe/PLL DPIO regs
  */
-#define _DPIO_DIV_A                    0x800c
+#define _VLV_PLL_DW3_CH0               0x800c
 #define   DPIO_POST_DIV_SHIFT          (28) /* 3 bits */
 #define   DPIO_POST_DIV_DAC            0
 #define   DPIO_POST_DIV_HDMIDP         1 /* DAC 225-400M rate */
 #define   DPIO_ENABLE_CALIBRATION      (1<<11)
 #define   DPIO_M1DIV_SHIFT             (8) /* 3 bits */
 #define   DPIO_M2DIV_MASK              0xff
-#define _DPIO_DIV_B                    0x802c
-#define DPIO_DIV(pipe) _PIPE(pipe, _DPIO_DIV_A, _DPIO_DIV_B)
+#define _VLV_PLL_DW3_CH1               0x802c
+#define VLV_PLL_DW3(ch) _PIPE(ch, _VLV_PLL_DW3_CH0, _VLV_PLL_DW3_CH1)
 
-#define _DPIO_REFSFR_A                 0x8014
+#define _VLV_PLL_DW5_CH0               0x8014
 #define   DPIO_REFSEL_OVERRIDE         27
 #define   DPIO_PLL_MODESEL_SHIFT       24 /* 3 bits */
 #define   DPIO_BIAS_CURRENT_CTL_SHIFT  21 /* 3 bits, always 0x7 */
 #define   DPIO_PLL_REFCLK_SEL_MASK     3
 #define   DPIO_DRIVER_CTL_SHIFT                12 /* always set to 0x8 */
 #define   DPIO_CLK_BIAS_CTL_SHIFT      8 /* always set to 0x5 */
-#define _DPIO_REFSFR_B                 0x8034
-#define DPIO_REFSFR(pipe) _PIPE(pipe, _DPIO_REFSFR_A, _DPIO_REFSFR_B)
+#define _VLV_PLL_DW5_CH1               0x8034
+#define VLV_PLL_DW5(ch) _PIPE(ch, _VLV_PLL_DW5_CH0, _VLV_PLL_DW5_CH1)
 
-#define _DPIO_CORE_CLK_A               0x801c
-#define _DPIO_CORE_CLK_B               0x803c
-#define DPIO_CORE_CLK(pipe) _PIPE(pipe, _DPIO_CORE_CLK_A, _DPIO_CORE_CLK_B)
+#define _VLV_PLL_DW7_CH0               0x801c
+#define _VLV_PLL_DW7_CH1               0x803c
+#define VLV_PLL_DW7(ch) _PIPE(ch, _VLV_PLL_DW7_CH0, _VLV_PLL_DW7_CH1)
 
-#define _DPIO_IREF_CTL_A               0x8040
-#define _DPIO_IREF_CTL_B               0x8060
-#define DPIO_IREF_CTL(pipe) _PIPE(pipe, _DPIO_IREF_CTL_A, _DPIO_IREF_CTL_B)
+#define _VLV_PLL_DW8_CH0               0x8040
+#define _VLV_PLL_DW8_CH1               0x8060
+#define VLV_PLL_DW8(ch) _PIPE(ch, _VLV_PLL_DW8_CH0, _VLV_PLL_DW8_CH1)
 
-#define DPIO_IREF_BCAST                        0xc044
-#define _DPIO_IREF_A                   0x8044
-#define _DPIO_IREF_B                   0x8064
-#define DPIO_IREF(pipe) _PIPE(pipe, _DPIO_IREF_A, _DPIO_IREF_B)
+#define VLV_PLL_DW9_BCAST              0xc044
+#define _VLV_PLL_DW9_CH0               0x8044
+#define _VLV_PLL_DW9_CH1               0x8064
+#define VLV_PLL_DW9(ch) _PIPE(ch, _VLV_PLL_DW9_CH0, _VLV_PLL_DW9_CH1)
 
-#define _DPIO_PLL_CML_A                        0x804c
-#define _DPIO_PLL_CML_B                        0x806c
-#define DPIO_PLL_CML(pipe) _PIPE(pipe, _DPIO_PLL_CML_A, _DPIO_PLL_CML_B)
+#define _VLV_PLL_DW10_CH0              0x8048
+#define _VLV_PLL_DW10_CH1              0x8068
+#define VLV_PLL_DW10(ch) _PIPE(ch, _VLV_PLL_DW10_CH0, _VLV_PLL_DW10_CH1)
 
-#define _DPIO_LPF_COEFF_A              0x8048
-#define _DPIO_LPF_COEFF_B              0x8068
-#define DPIO_LPF_COEFF(pipe) _PIPE(pipe, _DPIO_LPF_COEFF_A, _DPIO_LPF_COEFF_B)
+#define _VLV_PLL_DW11_CH0              0x804c
+#define _VLV_PLL_DW11_CH1              0x806c
+#define VLV_PLL_DW11(ch) _PIPE(ch, _VLV_PLL_DW11_CH0, _VLV_PLL_DW11_CH1)
 
-#define DPIO_CALIBRATION               0x80ac
+/* Spec for ref block start counts at DW10 */
+#define VLV_REF_DW13                   0x80ac
 
-#define DPIO_FASTCLK_DISABLE           0x8100
+#define VLV_CMN_DW0                    0x8100
 
 /*
  * Per DDI channel DPIO regs
  */
 
-#define _DPIO_PCS_TX_0                 0x8200
-#define _DPIO_PCS_TX_1                 0x8400
+#define _VLV_PCS_DW0_CH0               0x8200
+#define _VLV_PCS_DW0_CH1               0x8400
 #define   DPIO_PCS_TX_LANE2_RESET      (1<<16)
 #define   DPIO_PCS_TX_LANE1_RESET      (1<<7)
-#define DPIO_PCS_TX(port) _PORT(port, _DPIO_PCS_TX_0, _DPIO_PCS_TX_1)
+#define VLV_PCS_DW0(ch) _PORT(ch, _VLV_PCS_DW0_CH0, _VLV_PCS_DW0_CH1)
 
-#define _DPIO_PCS_CLK_0                        0x8204
-#define _DPIO_PCS_CLK_1                        0x8404
+#define _VLV_PCS_DW1_CH0               0x8204
+#define _VLV_PCS_DW1_CH1               0x8404
 #define   DPIO_PCS_CLK_CRI_RXEB_EIOS_EN        (1<<22)
 #define   DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN (1<<21)
 #define   DPIO_PCS_CLK_DATAWIDTH_SHIFT (6)
 #define   DPIO_PCS_CLK_SOFT_RESET      (1<<5)
-#define DPIO_PCS_CLK(port) _PORT(port, _DPIO_PCS_CLK_0, _DPIO_PCS_CLK_1)
-
-#define _DPIO_PCS_CTL_OVR1_A           0x8224
-#define _DPIO_PCS_CTL_OVR1_B           0x8424
-#define DPIO_PCS_CTL_OVER1(port) _PORT(port, _DPIO_PCS_CTL_OVR1_A, \
-                                      _DPIO_PCS_CTL_OVR1_B)
-
-#define _DPIO_PCS_STAGGER0_A           0x822c
-#define _DPIO_PCS_STAGGER0_B           0x842c
-#define DPIO_PCS_STAGGER0(port) _PORT(port, _DPIO_PCS_STAGGER0_A, \
-                                     _DPIO_PCS_STAGGER0_B)
-
-#define _DPIO_PCS_STAGGER1_A           0x8230
-#define _DPIO_PCS_STAGGER1_B           0x8430
-#define DPIO_PCS_STAGGER1(port) _PORT(port, _DPIO_PCS_STAGGER1_A, \
-                                     _DPIO_PCS_STAGGER1_B)
-
-#define _DPIO_PCS_CLOCKBUF0_A          0x8238
-#define _DPIO_PCS_CLOCKBUF0_B          0x8438
-#define DPIO_PCS_CLOCKBUF0(port) _PORT(port, _DPIO_PCS_CLOCKBUF0_A, \
-                                      _DPIO_PCS_CLOCKBUF0_B)
-
-#define _DPIO_PCS_CLOCKBUF8_A          0x825c
-#define _DPIO_PCS_CLOCKBUF8_B          0x845c
-#define DPIO_PCS_CLOCKBUF8(port) _PORT(port, _DPIO_PCS_CLOCKBUF8_A, \
-                                      _DPIO_PCS_CLOCKBUF8_B)
-
-#define _DPIO_TX_SWING_CTL2_A          0x8288
-#define _DPIO_TX_SWING_CTL2_B          0x8488
-#define DPIO_TX_SWING_CTL2(port) _PORT(port, _DPIO_TX_SWING_CTL2_A, \
-                                      _DPIO_TX_SWING_CTL2_B)
-
-#define _DPIO_TX_SWING_CTL3_A          0x828c
-#define _DPIO_TX_SWING_CTL3_B          0x848c
-#define DPIO_TX_SWING_CTL3(port) _PORT(port, _DPIO_TX_SWING_CTL3_A, \
-                                      _DPIO_TX_SWING_CTL3_B)
-
-#define _DPIO_TX_SWING_CTL4_A          0x8290
-#define _DPIO_TX_SWING_CTL4_B          0x8490
-#define DPIO_TX_SWING_CTL4(port) _PORT(port, _DPIO_TX_SWING_CTL4_A, \
-                                      _DPIO_TX_SWING_CTL4_B)
-
-#define _DPIO_TX_OCALINIT_0            0x8294
-#define _DPIO_TX_OCALINIT_1            0x8494
+#define VLV_PCS_DW1(ch) _PORT(ch, _VLV_PCS_DW1_CH0, _VLV_PCS_DW1_CH1)
+
+#define _VLV_PCS_DW8_CH0               0x8220
+#define _VLV_PCS_DW8_CH1               0x8420
+#define VLV_PCS_DW8(ch) _PORT(ch, _VLV_PCS_DW8_CH0, _VLV_PCS_DW8_CH1)
+
+#define _VLV_PCS01_DW8_CH0             0x0220
+#define _VLV_PCS23_DW8_CH0             0x0420
+#define _VLV_PCS01_DW8_CH1             0x2620
+#define _VLV_PCS23_DW8_CH1             0x2820
+#define VLV_PCS01_DW8(port) _PORT(port, _VLV_PCS01_DW8_CH0, _VLV_PCS01_DW8_CH1)
+#define VLV_PCS23_DW8(port) _PORT(port, _VLV_PCS23_DW8_CH0, _VLV_PCS23_DW8_CH1)
+
+#define _VLV_PCS_DW9_CH0               0x8224
+#define _VLV_PCS_DW9_CH1               0x8424
+#define        VLV_PCS_DW9(ch) _PORT(ch, _VLV_PCS_DW9_CH0, _VLV_PCS_DW9_CH1)
+
+#define _VLV_PCS_DW11_CH0              0x822c
+#define _VLV_PCS_DW11_CH1              0x842c
+#define VLV_PCS_DW11(ch) _PORT(ch, _VLV_PCS_DW11_CH0, _VLV_PCS_DW11_CH1)
+
+#define _VLV_PCS_DW12_CH0              0x8230
+#define _VLV_PCS_DW12_CH1              0x8430
+#define VLV_PCS_DW12(ch) _PORT(ch, _VLV_PCS_DW12_CH0, _VLV_PCS_DW12_CH1)
+
+#define _VLV_PCS_DW14_CH0              0x8238
+#define _VLV_PCS_DW14_CH1              0x8438
+#define        VLV_PCS_DW14(ch) _PORT(ch, _VLV_PCS_DW14_CH0, _VLV_PCS_DW14_CH1)
+
+#define _VLV_PCS_DW23_CH0              0x825c
+#define _VLV_PCS_DW23_CH1              0x845c
+#define VLV_PCS_DW23(ch) _PORT(ch, _VLV_PCS_DW23_CH0, _VLV_PCS_DW23_CH1)
+
+#define _VLV_TX_DW2_CH0                        0x8288
+#define _VLV_TX_DW2_CH1                        0x8488
+#define VLV_TX_DW2(ch) _PORT(ch, _VLV_TX_DW2_CH0, _VLV_TX_DW2_CH1)
+
+#define _VLV_TX_DW3_CH0                        0x828c
+#define _VLV_TX_DW3_CH1                        0x848c
+#define VLV_TX_DW3(ch) _PORT(ch, _VLV_TX_DW3_CH0, _VLV_TX_DW3_CH1)
+
+#define _VLV_TX_DW4_CH0                        0x8290
+#define _VLV_TX_DW4_CH1                        0x8490
+#define VLV_TX_DW4(ch) _PORT(ch, _VLV_TX_DW4_CH0, _VLV_TX_DW4_CH1)
+
+#define _VLV_TX3_DW4_CH0               0x690
+#define _VLV_TX3_DW4_CH1               0x2a90
+#define VLV_TX3_DW4(ch) _PORT(ch, _VLV_TX3_DW4_CH0, _VLV_TX3_DW4_CH1)
+
+#define _VLV_TX_DW5_CH0                        0x8294
+#define _VLV_TX_DW5_CH1                        0x8494
 #define   DPIO_TX_OCALINIT_EN          (1<<31)
-#define DPIO_TX_OCALINIT(port) _PORT(port, _DPIO_TX_OCALINIT_0, \
-                                    _DPIO_TX_OCALINIT_1)
-
-#define _DPIO_TX_CTL_0                 0x82ac
-#define _DPIO_TX_CTL_1                 0x84ac
-#define DPIO_TX_CTL(port) _PORT(port, _DPIO_TX_CTL_0, _DPIO_TX_CTL_1)
-
-#define _DPIO_TX_LANE_0                        0x82b8
-#define _DPIO_TX_LANE_1                        0x84b8
-#define DPIO_TX_LANE(port) _PORT(port, _DPIO_TX_LANE_0, _DPIO_TX_LANE_1)
-
-#define _DPIO_DATA_CHANNEL1            0x8220
-#define _DPIO_DATA_CHANNEL2            0x8420
-#define DPIO_DATA_CHANNEL(port) _PORT(port, _DPIO_DATA_CHANNEL1, _DPIO_DATA_CHANNEL2)
-
-#define _DPIO_PORT0_PCS0               0x0220
-#define _DPIO_PORT0_PCS1               0x0420
-#define _DPIO_PORT1_PCS2               0x2620
-#define _DPIO_PORT1_PCS3               0x2820
-#define DPIO_DATA_LANE_A(port) _PORT(port, _DPIO_PORT0_PCS0, _DPIO_PORT1_PCS2)
-#define DPIO_DATA_LANE_B(port) _PORT(port, _DPIO_PORT0_PCS1, _DPIO_PORT1_PCS3)
-#define DPIO_DATA_CHANNEL1              0x8220
-#define DPIO_DATA_CHANNEL2              0x8420
+#define VLV_TX_DW5(ch) _PORT(ch, _VLV_TX_DW5_CH0, _VLV_TX_DW5_CH1)
+
+#define _VLV_TX_DW11_CH0               0x82ac
+#define _VLV_TX_DW11_CH1               0x84ac
+#define VLV_TX_DW11(ch) _PORT(ch, _VLV_TX_DW11_CH0, _VLV_TX_DW11_CH1)
+
+#define _VLV_TX_DW14_CH0               0x82b8
+#define _VLV_TX_DW14_CH1               0x84b8
+#define VLV_TX_DW14(ch) _PORT(ch, _VLV_TX_DW14_CH0, _VLV_TX_DW14_CH1)
 
 /*
  * Fence registers
 #define   CRT_HOTPLUG_MONITOR_COLOR            (3 << 8)
 #define   CRT_HOTPLUG_MONITOR_MONO             (2 << 8)
 #define   CRT_HOTPLUG_MONITOR_NONE             (0 << 8)
+#define   DP_AUX_CHANNEL_D_INT_STATUS_G4X      (1 << 6)
+#define   DP_AUX_CHANNEL_C_INT_STATUS_G4X      (1 << 5)
+#define   DP_AUX_CHANNEL_B_INT_STATUS_G4X      (1 << 4)
+#define   DP_AUX_CHANNEL_MASK_INT_STATUS_G4X   (1 << 4)
 /* SDVO is different across gen3/4 */
 #define   SDVOC_HOTPLUG_INT_STATUS_G4X         (1 << 3)
 #define   SDVOB_HOTPLUG_INT_STATUS_G4X         (1 << 2)
 
 #define _SPACNTR               (VLV_DISPLAY_BASE + 0x72180)
 #define   SP_ENABLE                    (1<<31)
-#define   SP_GEAMMA_ENABLE             (1<<30)
+#define   SP_GAMMA_ENABLE              (1<<30)
 #define   SP_PIXFORMAT_MASK            (0xf<<26)
 #define   SP_FORMAT_YUV422             (0<<26)
 #define   SP_FORMAT_BGR565             (5<<26)
 #define    FORCEWAKE_MT_ENABLE                 (1<<5)
 
 #define  GTFIFODBG                             0x120000
-#define    GT_FIFO_CPU_ERROR_MASK              7
+#define    GT_FIFO_SBDROPERR                   (1<<6)
+#define    GT_FIFO_BLOBDROPERR                 (1<<5)
+#define    GT_FIFO_SB_READ_ABORTERR            (1<<4)
+#define    GT_FIFO_DROPERR                     (1<<3)
 #define    GT_FIFO_OVFERR                      (1<<2)
 #define    GT_FIFO_IAWRERR                     (1<<1)
 #define    GT_FIFO_IARDERR                     (1<<0)
 
-#define  GT_FIFO_FREE_ENTRIES                  0x120008
+#define  GTFIFOCTL                             0x120008
+#define    GT_FIFO_FREE_ENTRIES_MASK           0x7f
 #define    GT_FIFO_NUM_RESERVED_ENTRIES                20
 
 #define  HSW_IDICR                             0x9008
 #define   GEN6_RC_CTL_RC6_ENABLE               (1<<18)
 #define   GEN6_RC_CTL_RC1e_ENABLE              (1<<20)
 #define   GEN6_RC_CTL_RC7_ENABLE               (1<<22)
+#define   VLV_RC_CTL_CTX_RST_PARALLEL          (1<<24)
 #define   GEN7_RC_CTL_TO_MODE                  (1<<28)
 #define   GEN6_RC_CTL_EI_MODE(x)               ((x)<<27)
 #define   GEN6_RC_CTL_HW_ENABLE                        (1<<31)
index 98790c7cccb1ab0902662e4cc541de9966f2058c..6b8fef7fb3bb94f3aa442c867452637e9dd0919f 100644 (file)
@@ -192,7 +192,6 @@ static void i915_restore_vga(struct drm_device *dev)
 static void i915_save_display(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       unsigned long flags;
 
        /* Display arbitration control */
        if (INTEL_INFO(dev)->gen <= 4)
@@ -203,46 +202,27 @@ static void i915_save_display(struct drm_device *dev)
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                i915_save_display_reg(dev);
 
-       spin_lock_irqsave(&dev_priv->backlight.lock, flags);
-
        /* LVDS state */
        if (HAS_PCH_SPLIT(dev)) {
                dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
-               dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
-               dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
-               dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
-               dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
                if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
                        dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS);
        } else if (IS_VALLEYVIEW(dev)) {
                dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
                dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
 
-               dev_priv->regfile.saveBLC_PWM_CTL =
-                       I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
                dev_priv->regfile.saveBLC_HIST_CTL =
                        I915_READ(VLV_BLC_HIST_CTL(PIPE_A));
-               dev_priv->regfile.saveBLC_PWM_CTL2 =
-                       I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
-               dev_priv->regfile.saveBLC_PWM_CTL_B =
-                       I915_READ(VLV_BLC_PWM_CTL(PIPE_B));
                dev_priv->regfile.saveBLC_HIST_CTL_B =
                        I915_READ(VLV_BLC_HIST_CTL(PIPE_B));
-               dev_priv->regfile.saveBLC_PWM_CTL2_B =
-                       I915_READ(VLV_BLC_PWM_CTL2(PIPE_B));
        } else {
                dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
                dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
-               dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
                dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL);
-               if (INTEL_INFO(dev)->gen >= 4)
-                       dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
                if (IS_MOBILE(dev) && !IS_I830(dev))
                        dev_priv->regfile.saveLVDS = I915_READ(LVDS);
        }
 
-       spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
-
        if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
                dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
 
@@ -278,7 +258,6 @@ static void i915_restore_display(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 mask = 0xffffffff;
-       unsigned long flags;
 
        /* Display arbitration */
        if (INTEL_INFO(dev)->gen <= 4)
@@ -287,12 +266,6 @@ static void i915_restore_display(struct drm_device *dev)
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                i915_restore_display_reg(dev);
 
-       spin_lock_irqsave(&dev_priv->backlight.lock, flags);
-
-       /* LVDS state */
-       if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
-               I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
-
        if (drm_core_check_feature(dev, DRIVER_MODESET))
                mask = ~LVDS_PORT_EN;
 
@@ -305,13 +278,6 @@ static void i915_restore_display(struct drm_device *dev)
                I915_WRITE(PFIT_CONTROL, dev_priv->regfile.savePFIT_CONTROL);
 
        if (HAS_PCH_SPLIT(dev)) {
-               I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
-               I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
-               /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
-                * otherwise we get blank eDP screen after S3 on some machines
-                */
-               I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2);
-               I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL);
                I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
                I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
                I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
@@ -319,21 +285,12 @@ static void i915_restore_display(struct drm_device *dev)
                I915_WRITE(RSTDBYCTL,
                           dev_priv->regfile.saveMCHBAR_RENDER_STANDBY);
        } else if (IS_VALLEYVIEW(dev)) {
-               I915_WRITE(VLV_BLC_PWM_CTL(PIPE_A),
-                          dev_priv->regfile.saveBLC_PWM_CTL);
                I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A),
                           dev_priv->regfile.saveBLC_HIST_CTL);
-               I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_A),
-                          dev_priv->regfile.saveBLC_PWM_CTL2);
-               I915_WRITE(VLV_BLC_PWM_CTL(PIPE_B),
-                          dev_priv->regfile.saveBLC_PWM_CTL);
                I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B),
                           dev_priv->regfile.saveBLC_HIST_CTL);
-               I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_B),
-                          dev_priv->regfile.saveBLC_PWM_CTL2);
        } else {
                I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS);
-               I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
                I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL);
                I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
                I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
@@ -341,8 +298,6 @@ static void i915_restore_display(struct drm_device *dev)
                I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
        }
 
-       spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
-
        /* only restore FBC info on the platform that supports FBC*/
        intel_disable_fbc(dev);
        if (I915_HAS_FBC(dev)) {
index cef38fd320a7c5c53c687ca5b67b0d1d3192d615..05d8b1680c227c79dea56761a72d2c55ba8c372a 100644 (file)
@@ -183,13 +183,13 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
        int slice = (int)(uintptr_t)attr->private;
        int ret;
 
+       if (!HAS_HW_CONTEXTS(drm_dev))
+               return -ENXIO;
+
        ret = l3_access_valid(drm_dev, offset);
        if (ret)
                return ret;
 
-       if (dev_priv->hw_contexts_disabled)
-               return -ENXIO;
-
        ret = i915_mutex_lock_interruptible(drm_dev);
        if (ret)
                return ret;
@@ -259,7 +259,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
        if (IS_VALLEYVIEW(dev_priv->dev)) {
                u32 freq;
                freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
-               ret = vlv_gpu_freq(dev_priv->mem_freq, (freq >> 8) & 0xff);
+               ret = vlv_gpu_freq(dev_priv, (freq >> 8) & 0xff);
        } else {
                ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER;
        }
@@ -276,8 +276,7 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
        struct drm_i915_private *dev_priv = dev->dev_private;
 
        return snprintf(buf, PAGE_SIZE, "%d\n",
-                       vlv_gpu_freq(dev_priv->mem_freq,
-                                    dev_priv->rps.rpe_delay));
+                       vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay));
 }
 
 static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
@@ -291,7 +290,7 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute
 
        mutex_lock(&dev_priv->rps.hw_lock);
        if (IS_VALLEYVIEW(dev_priv->dev))
-               ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.max_delay);
+               ret = vlv_gpu_freq(dev_priv, dev_priv->rps.max_delay);
        else
                ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
        mutex_unlock(&dev_priv->rps.hw_lock);
@@ -318,7 +317,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
        mutex_lock(&dev_priv->rps.hw_lock);
 
        if (IS_VALLEYVIEW(dev_priv->dev)) {
-               val = vlv_freq_opcode(dev_priv->mem_freq, val);
+               val = vlv_freq_opcode(dev_priv, val);
 
                hw_max = valleyview_rps_max_freq(dev_priv);
                hw_min = valleyview_rps_min_freq(dev_priv);
@@ -342,15 +341,15 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
                DRM_DEBUG("User requested overclocking to %d\n",
                          val * GT_FREQUENCY_MULTIPLIER);
 
+       dev_priv->rps.max_delay = val;
+
        if (dev_priv->rps.cur_delay > val) {
-               if (IS_VALLEYVIEW(dev_priv->dev))
-                       valleyview_set_rps(dev_priv->dev, val);
+               if (IS_VALLEYVIEW(dev))
+                       valleyview_set_rps(dev, val);
                else
-                       gen6_set_rps(dev_priv->dev, val);
+                       gen6_set_rps(dev, val);
        }
 
-       dev_priv->rps.max_delay = val;
-
        mutex_unlock(&dev_priv->rps.hw_lock);
 
        return count;
@@ -367,7 +366,7 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute
 
        mutex_lock(&dev_priv->rps.hw_lock);
        if (IS_VALLEYVIEW(dev_priv->dev))
-               ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.min_delay);
+               ret = vlv_gpu_freq(dev_priv, dev_priv->rps.min_delay);
        else
                ret = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
        mutex_unlock(&dev_priv->rps.hw_lock);
@@ -394,7 +393,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
        mutex_lock(&dev_priv->rps.hw_lock);
 
        if (IS_VALLEYVIEW(dev)) {
-               val = vlv_freq_opcode(dev_priv->mem_freq, val);
+               val = vlv_freq_opcode(dev_priv, val);
 
                hw_max = valleyview_rps_max_freq(dev_priv);
                hw_min = valleyview_rps_min_freq(dev_priv);
@@ -411,15 +410,15 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
                return -EINVAL;
        }
 
+       dev_priv->rps.min_delay = val;
+
        if (dev_priv->rps.cur_delay < val) {
                if (IS_VALLEYVIEW(dev))
                        valleyview_set_rps(dev, val);
                else
-                       gen6_set_rps(dev_priv->dev, val);
+                       gen6_set_rps(dev, val);
        }
 
-       dev_priv->rps.min_delay = val;
-
        mutex_unlock(&dev_priv->rps.hw_lock);
 
        return count;
index 967da4772c449a2be05d16bce648fff9bd19a63e..caa18e855815eaf04a39ecb6eedcc572cf4d6290 100644 (file)
@@ -270,6 +270,18 @@ void i915_save_display_reg(struct drm_device *dev)
        }
        /* FIXME: regfile.save TV & SDVO state */
 
+       /* Backlight */
+       if (HAS_PCH_SPLIT(dev)) {
+               dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
+               dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
+               dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
+               dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
+       } else {
+               dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
+               if (INTEL_INFO(dev)->gen >= 4)
+                       dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
+       }
+
        return;
 }
 
@@ -280,6 +292,21 @@ void i915_restore_display_reg(struct drm_device *dev)
        int dpll_b_reg, fpb0_reg, fpb1_reg;
        int i;
 
+       /* Backlight */
+       if (HAS_PCH_SPLIT(dev)) {
+               I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
+               I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
+               /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
+                * otherwise we get blank eDP screen after S3 on some machines
+                */
+               I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2);
+               I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL);
+       } else {
+               if (INTEL_INFO(dev)->gen >= 4)
+                       I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
+               I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
+       }
+
        /* Display port ratios (must be done before clock is set) */
        if (SUPPORTS_INTEGRATED_DP(dev)) {
                I915_WRITE(_PIPEA_DATA_M_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_M);
index dfff0907f70e53643093c3f6aa8d9258ab8dc5d5..5325b25ccbb4b1b72af10f627f5c7fa82e092d89 100644 (file)
@@ -6,8 +6,6 @@
 #include <linux/pci.h>
 #include <linux/acpi.h>
 #include <linux/vga_switcheroo.h>
-#include <acpi/acpi_drivers.h>
-
 #include <drm/drmP.h>
 #include "i915_drv.h"
 
index b5b1b9b23adf1b24559e7ffdce658ba37e6bbbab..e2e39e65f10954b8076b3ed01b565f0cb173bb0d 100644 (file)
@@ -222,8 +222,9 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
        intel_modeset_check_state(connector->dev);
 }
 
-static int intel_crt_mode_valid(struct drm_connector *connector,
-                               struct drm_display_mode *mode)
+static enum drm_mode_status
+intel_crt_mode_valid(struct drm_connector *connector,
+                    struct drm_display_mode *mode)
 {
        struct drm_device *dev = connector->dev;
 
index 330077bcd0bddb22ecf056766dd88cd7ed70bfaf..c8382f55870cc2fbc47bed42886447c052b3630f 100644 (file)
@@ -173,7 +173,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
                ddi_translations = ddi_translations_dp;
                break;
        case PORT_D:
-               if (intel_dpd_is_edp(dev))
+               if (intel_dp_is_edp(dev, PORT_D))
                        ddi_translations = ddi_translations_edp;
                else
                        ddi_translations = ddi_translations_dp;
@@ -713,8 +713,6 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc)
        uint32_t reg, val;
        int clock = intel_crtc->config.port_clock;
 
-       /* TODO: reuse PLLs when possible (compare values) */
-
        intel_ddi_put_crtc_pll(crtc);
 
        if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
@@ -742,31 +740,40 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc)
        } else if (type == INTEL_OUTPUT_HDMI) {
                unsigned p, n2, r2;
 
-               if (plls->wrpll1_refcount == 0) {
+               intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
+
+               val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 |
+                     WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
+                     WRPLL_DIVIDER_POST(p);
+
+               if (val == I915_READ(WRPLL_CTL1)) {
+                       DRM_DEBUG_KMS("Reusing WRPLL 1 on pipe %c\n",
+                                     pipe_name(pipe));
+                       reg = WRPLL_CTL1;
+               } else if (val == I915_READ(WRPLL_CTL2)) {
+                       DRM_DEBUG_KMS("Reusing WRPLL 2 on pipe %c\n",
+                                     pipe_name(pipe));
+                       reg = WRPLL_CTL2;
+               } else if (plls->wrpll1_refcount == 0) {
                        DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n",
                                      pipe_name(pipe));
-                       plls->wrpll1_refcount++;
                        reg = WRPLL_CTL1;
-                       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1;
                } else if (plls->wrpll2_refcount == 0) {
                        DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n",
                                      pipe_name(pipe));
-                       plls->wrpll2_refcount++;
                        reg = WRPLL_CTL2;
-                       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
                } else {
                        DRM_ERROR("No WRPLLs available!\n");
                        return false;
                }
 
-               WARN(I915_READ(reg) & WRPLL_PLL_ENABLE,
-                    "WRPLL already enabled\n");
-
-               intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
-
-               val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 |
-                     WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
-                     WRPLL_DIVIDER_POST(p);
+               if (reg == WRPLL_CTL1) {
+                       plls->wrpll1_refcount++;
+                       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1;
+               } else {
+                       plls->wrpll2_refcount++;
+                       intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
+               }
 
        } else if (type == INTEL_OUTPUT_ANALOG) {
                if (plls->spll_refcount == 0) {
@@ -1158,9 +1165,10 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
        if (wait)
                intel_wait_ddi_buf_idle(dev_priv, port);
 
-       if (type == INTEL_OUTPUT_EDP) {
+       if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
                struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
                ironlake_edp_panel_vdd_on(intel_dp);
+               intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
                ironlake_edp_panel_off(intel_dp);
        }
 
index 7ec8b488bb1d30b6b950a23eecc833b574ab4db0..0bb3d6d596d98495659667c77bdc6f5cd0811615 100644 (file)
@@ -748,10 +748,10 @@ enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
        return intel_crtc->config.cpu_transcoder;
 }
 
-static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe)
+static void g4x_wait_for_vblank(struct drm_device *dev, int pipe)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 frame, frame_reg = PIPEFRAME(pipe);
+       u32 frame, frame_reg = PIPE_FRMCOUNT_GM45(pipe);
 
        frame = I915_READ(frame_reg);
 
@@ -772,8 +772,8 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipestat_reg = PIPESTAT(pipe);
 
-       if (INTEL_INFO(dev)->gen >= 5) {
-               ironlake_wait_for_vblank(dev, pipe);
+       if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
+               g4x_wait_for_vblank(dev, pipe);
                return;
        }
 
@@ -1361,6 +1361,7 @@ static void intel_init_dpio(struct drm_device *dev)
        if (!IS_VALLEYVIEW(dev))
                return;
 
+       DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO;
        /*
         * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx -
         *  6.  De-assert cmn_reset/side_reset. Same as VLV X0.
@@ -1494,18 +1495,25 @@ static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
        POSTING_READ(DPLL(pipe));
 }
 
-void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port)
+void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
+               struct intel_digital_port *dport)
 {
        u32 port_mask;
 
-       if (!port)
+       switch (dport->port) {
+       case PORT_B:
                port_mask = DPLL_PORTB_READY_MASK;
-       else
+               break;
+       case PORT_C:
                port_mask = DPLL_PORTC_READY_MASK;
+               break;
+       default:
+               BUG();
+       }
 
        if (wait_for((I915_READ(DPLL(0)) & port_mask) == 0, 1000))
                WARN(1, "timed out waiting for port %c ready: 0x%08x\n",
-                    'B' + port, I915_READ(DPLL(0)));
+                    port_name(dport->port), I915_READ(DPLL(0)));
 }
 
 /**
@@ -2233,7 +2241,12 @@ void intel_display_handle_reset(struct drm_device *dev)
                struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
                mutex_lock(&crtc->mutex);
-               if (intel_crtc->active)
+               /*
+                * FIXME: Once we have proper support for primary planes (and
+                * disabling them without disabling the entire crtc) allow again
+                * a NULL crtc->fb.
+                */
+               if (intel_crtc->active && crtc->fb)
                        dev_priv->display.update_plane(crtc, crtc->fb,
                                                       crtc->x, crtc->y);
                mutex_unlock(&crtc->mutex);
@@ -3910,6 +3923,174 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
        I915_WRITE(BCLRPAT(crtc->pipe), 0);
 }
 
+int valleyview_get_vco(struct drm_i915_private *dev_priv)
+{
+       int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
+
+       /* Obtain SKU information */
+       mutex_lock(&dev_priv->dpio_lock);
+       hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
+               CCK_FUSE_HPLL_FREQ_MASK;
+       mutex_unlock(&dev_priv->dpio_lock);
+
+       return vco_freq[hpll_freq];
+}
+
+/* Adjust CDclk dividers to allow high res or save power if possible */
+static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 val, cmd;
+
+       if (cdclk >= 320) /* jump to highest voltage for 400MHz too */
+               cmd = 2;
+       else if (cdclk == 266)
+               cmd = 1;
+       else
+               cmd = 0;
+
+       mutex_lock(&dev_priv->rps.hw_lock);
+       val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+       val &= ~DSPFREQGUAR_MASK;
+       val |= (cmd << DSPFREQGUAR_SHIFT);
+       vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
+       if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) &
+                     DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT),
+                    50)) {
+               DRM_ERROR("timed out waiting for CDclk change\n");
+       }
+       mutex_unlock(&dev_priv->rps.hw_lock);
+
+       if (cdclk == 400) {
+               u32 divider, vco;
+
+               vco = valleyview_get_vco(dev_priv);
+               divider = ((vco << 1) / cdclk) - 1;
+
+               mutex_lock(&dev_priv->dpio_lock);
+               /* adjust cdclk divider */
+               val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
+               val &= ~0xf;
+               val |= divider;
+               vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val);
+               mutex_unlock(&dev_priv->dpio_lock);
+       }
+
+       mutex_lock(&dev_priv->dpio_lock);
+       /* adjust self-refresh exit latency value */
+       val = vlv_bunit_read(dev_priv, BUNIT_REG_BISOC);
+       val &= ~0x7f;
+
+       /*
+        * For high bandwidth configs, we set a higher latency in the bunit
+        * so that the core display fetch happens in time to avoid underruns.
+        */
+       if (cdclk == 400)
+               val |= 4500 / 250; /* 4.5 usec */
+       else
+               val |= 3000 / 250; /* 3.0 usec */
+       vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
+       mutex_unlock(&dev_priv->dpio_lock);
+
+       /* Since we changed the CDclk, we need to update the GMBUSFREQ too */
+       intel_i2c_reset(dev);
+}
+
+static int valleyview_cur_cdclk(struct drm_i915_private *dev_priv)
+{
+       int cur_cdclk, vco;
+       int divider;
+
+       vco = valleyview_get_vco(dev_priv);
+
+       mutex_lock(&dev_priv->dpio_lock);
+       divider = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
+       mutex_unlock(&dev_priv->dpio_lock);
+
+       divider &= 0xf;
+
+       cur_cdclk = (vco << 1) / (divider + 1);
+
+       return cur_cdclk;
+}
+
+static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv,
+                                int max_pixclk)
+{
+       int cur_cdclk;
+
+       cur_cdclk = valleyview_cur_cdclk(dev_priv);
+
+       /*
+        * Really only a few cases to deal with, as only 4 CDclks are supported:
+        *   200MHz
+        *   267MHz
+        *   320MHz
+        *   400MHz
+        * So we check to see whether we're above 90% of the lower bin and
+        * adjust if needed.
+        */
+       if (max_pixclk > 288000) {
+               return 400;
+       } else if (max_pixclk > 240000) {
+               return 320;
+       } else
+               return 266;
+       /* Looks like the 200MHz CDclk freq doesn't work on some configs */
+}
+
+static int intel_mode_max_pixclk(struct drm_i915_private *dev_priv,
+                                unsigned modeset_pipes,
+                                struct intel_crtc_config *pipe_config)
+{
+       struct drm_device *dev = dev_priv->dev;
+       struct intel_crtc *intel_crtc;
+       int max_pixclk = 0;
+
+       list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
+                           base.head) {
+               if (modeset_pipes & (1 << intel_crtc->pipe))
+                       max_pixclk = max(max_pixclk,
+                                        pipe_config->adjusted_mode.crtc_clock);
+               else if (intel_crtc->base.enabled)
+                       max_pixclk = max(max_pixclk,
+                                        intel_crtc->config.adjusted_mode.crtc_clock);
+       }
+
+       return max_pixclk;
+}
+
+static void valleyview_modeset_global_pipes(struct drm_device *dev,
+                                           unsigned *prepare_pipes,
+                                           unsigned modeset_pipes,
+                                           struct intel_crtc_config *pipe_config)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc;
+       int max_pixclk = intel_mode_max_pixclk(dev_priv, modeset_pipes,
+                                              pipe_config);
+       int cur_cdclk = valleyview_cur_cdclk(dev_priv);
+
+       if (valleyview_calc_cdclk(dev_priv, max_pixclk) == cur_cdclk)
+               return;
+
+       list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
+                           base.head)
+               if (intel_crtc->base.enabled)
+                       *prepare_pipes |= (1 << intel_crtc->pipe);
+}
+
+static void valleyview_modeset_global_resources(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int max_pixclk = intel_mode_max_pixclk(dev_priv, 0, NULL);
+       int cur_cdclk = valleyview_cur_cdclk(dev_priv);
+       int req_cdclk = valleyview_calc_cdclk(dev_priv, max_pixclk);
+
+       if (req_cdclk != cur_cdclk)
+               valleyview_set_cdclk(dev, req_cdclk);
+}
+
 static void valleyview_crtc_enable(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
@@ -4634,24 +4815,24 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
         * PLLB opamp always calibrates to max value of 0x3f, force enable it
         * and set it to a reasonable value instead.
         */
-       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_IREF(1));
+       reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
        reg_val &= 0xffffff00;
        reg_val |= 0x00000030;
-       vlv_dpio_write(dev_priv, pipe, DPIO_IREF(1), reg_val);
+       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
 
-       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_CALIBRATION);
+       reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
        reg_val &= 0x8cffffff;
        reg_val = 0x8c000000;
-       vlv_dpio_write(dev_priv, pipe, DPIO_CALIBRATION, reg_val);
+       vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
 
-       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_IREF(1));
+       reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
        reg_val &= 0xffffff00;
-       vlv_dpio_write(dev_priv, pipe, DPIO_IREF(1), reg_val);
+       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
 
-       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_CALIBRATION);
+       reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
        reg_val &= 0x00ffffff;
        reg_val |= 0xb0000000;
-       vlv_dpio_write(dev_priv, pipe, DPIO_CALIBRATION, reg_val);
+       vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
 }
 
 static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
@@ -4720,15 +4901,15 @@ static void vlv_update_pll(struct intel_crtc *crtc)
                vlv_pllb_recal_opamp(dev_priv, pipe);
 
        /* Set up Tx target for periodic Rcomp update */
-       vlv_dpio_write(dev_priv, pipe, DPIO_IREF_BCAST, 0x0100000f);
+       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9_BCAST, 0x0100000f);
 
        /* Disable target IRef on PLL */
-       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_IREF_CTL(pipe));
+       reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW8(pipe));
        reg_val &= 0x00ffffff;
-       vlv_dpio_write(dev_priv, pipe, DPIO_IREF_CTL(pipe), reg_val);
+       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW8(pipe), reg_val);
 
        /* Disable fast lock */
-       vlv_dpio_write(dev_priv, pipe, DPIO_FASTCLK_DISABLE, 0x610);
+       vlv_dpio_write(dev_priv, pipe, VLV_CMN_DW0, 0x610);
 
        /* Set idtafcrecal before PLL is enabled */
        mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
@@ -4742,48 +4923,48 @@ static void vlv_update_pll(struct intel_crtc *crtc)
         * Note: don't use the DAC post divider as it seems unstable.
         */
        mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
-       vlv_dpio_write(dev_priv, pipe, DPIO_DIV(pipe), mdiv);
+       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
 
        mdiv |= DPIO_ENABLE_CALIBRATION;
-       vlv_dpio_write(dev_priv, pipe, DPIO_DIV(pipe), mdiv);
+       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
 
        /* Set HBR and RBR LPF coefficients */
        if (crtc->config.port_clock == 162000 ||
            intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) ||
            intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
-               vlv_dpio_write(dev_priv, pipe, DPIO_LPF_COEFF(pipe),
+               vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
                                 0x009f0003);
        else
-               vlv_dpio_write(dev_priv, pipe, DPIO_LPF_COEFF(pipe),
+               vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
                                 0x00d0000f);
 
        if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) ||
            intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) {
                /* Use SSC source */
                if (!pipe)
-                       vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
+                       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
                                         0x0df40000);
                else
-                       vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
+                       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
                                         0x0df70000);
        } else { /* HDMI or VGA */
                /* Use bend source */
                if (!pipe)
-                       vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
+                       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
                                         0x0df70000);
                else
-                       vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
+                       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
                                         0x0df40000);
        }
 
-       coreclk = vlv_dpio_read(dev_priv, pipe, DPIO_CORE_CLK(pipe));
+       coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe));
        coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
        if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT) ||
            intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP))
                coreclk |= 0x01000000;
-       vlv_dpio_write(dev_priv, pipe, DPIO_CORE_CLK(pipe), coreclk);
+       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
 
-       vlv_dpio_write(dev_priv, pipe, DPIO_PLL_CML(pipe), 0x87871000);
+       vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
 
        /* Enable DPIO clock input */
        dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV |
@@ -5261,7 +5442,7 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
        int refclk = 100000;
 
        mutex_lock(&dev_priv->dpio_lock);
-       mdiv = vlv_dpio_read(dev_priv, pipe, DPIO_DIV(pipe));
+       mdiv = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW3(pipe));
        mutex_unlock(&dev_priv->dpio_lock);
 
        clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
@@ -5815,7 +5996,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
                uint16_t postoff = 0;
 
                if (intel_crtc->config.limited_color_range)
-                       postoff = (16 * (1 << 13) / 255) & 0x1fff;
+                       postoff = (16 * (1 << 12) / 255) & 0x1fff;
 
                I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
                I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff);
@@ -6402,7 +6583,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
 
        /* Make sure we're not on PC8 state before disabling PC8, otherwise
         * we'll hang the machine! */
-       dev_priv->uncore.funcs.force_wake_get(dev_priv);
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
        if (val & LCPLL_POWER_DOWN_ALLOW) {
                val &= ~LCPLL_POWER_DOWN_ALLOW;
@@ -6436,7 +6617,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
                        DRM_ERROR("Switching back to LCPLL failed\n");
        }
 
-       dev_priv->uncore.funcs.force_wake_put(dev_priv);
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 void hsw_enable_pc8_work(struct work_struct *__work)
@@ -8354,7 +8535,8 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
                intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
                                        DERRMR_PIPEB_PRI_FLIP_DONE |
                                        DERRMR_PIPEC_PRI_FLIP_DONE));
-               intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1));
+               intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1) |
+                               MI_SRM_LRM_GLOBAL_GTT);
                intel_ring_emit(ring, DERRMR);
                intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
        }
@@ -9401,6 +9583,21 @@ static int __intel_set_mode(struct drm_crtc *crtc,
                                       "[modeset]");
        }
 
+       /*
+        * See if the config requires any additional preparation, e.g.
+        * to adjust global state with pipes off.  We need to do this
+        * here so we can get the modeset_pipe updated config for the new
+        * mode set on this crtc.  For other crtcs we need to use the
+        * adjusted_mode bits in the crtc directly.
+        */
+       if (IS_VALLEYVIEW(dev)) {
+               valleyview_modeset_global_pipes(dev, &prepare_pipes,
+                                               modeset_pipes, pipe_config);
+
+               /* may have added more to prepare_pipes than we should */
+               prepare_pipes &= ~disable_pipes;
+       }
+
        for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
                intel_crtc_disable(&intel_crtc->base);
 
@@ -10049,7 +10246,7 @@ static void intel_setup_outputs(struct drm_device *dev)
                        intel_ddi_init(dev, PORT_D);
        } else if (HAS_PCH_SPLIT(dev)) {
                int found;
-               dpd_is_edp = intel_dpd_is_edp(dev);
+               dpd_is_edp = intel_dp_is_edp(dev, PORT_D);
 
                if (has_edp_a(dev))
                        intel_dp_init(dev, DP_A, PORT_A);
@@ -10086,8 +10283,7 @@ static void intel_setup_outputs(struct drm_device *dev)
                        intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC,
                                        PORT_C);
                        if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED)
-                               intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C,
-                                             PORT_C);
+                               intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C);
                }
 
                intel_dsi_init(dev);
@@ -10412,8 +10608,11 @@ static void intel_init_display(struct drm_device *dev)
                }
        } else if (IS_G4X(dev)) {
                dev_priv->display.write_eld = g4x_write_eld;
-       } else if (IS_VALLEYVIEW(dev))
+       } else if (IS_VALLEYVIEW(dev)) {
+               dev_priv->display.modeset_global_resources =
+                       valleyview_modeset_global_resources;
                dev_priv->display.write_eld = ironlake_write_eld;
+       }
 
        /* Default just returns -ENODEV to indicate unsupported */
        dev_priv->display.queue_flip = intel_default_queue_flip;
@@ -10440,6 +10639,8 @@ static void intel_init_display(struct drm_device *dev)
                dev_priv->display.queue_flip = intel_gen7_queue_flip;
                break;
        }
+
+       intel_panel_init_backlight_funcs(dev);
 }
 
 /*
@@ -10476,17 +10677,6 @@ static void quirk_invert_brightness(struct drm_device *dev)
        DRM_INFO("applying inverted panel brightness quirk\n");
 }
 
-/*
- * Some machines (Dell XPS13) suffer broken backlight controls if
- * BLM_PCH_PWM_ENABLE is set.
- */
-static void quirk_no_pcm_pwm_enable(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       dev_priv->quirks |= QUIRK_NO_PCH_PWM_ENABLE;
-       DRM_INFO("applying no-PCH_PWM_ENABLE quirk\n");
-}
-
 struct intel_quirk {
        int device;
        int subsystem_vendor;
@@ -10546,11 +10736,6 @@ static struct intel_quirk intel_quirks[] = {
         * seem to use inverted backlight PWM.
         */
        { 0x2a42, 0x1025, PCI_ANY_ID, quirk_invert_brightness },
-
-       /* Dell XPS13 HD Sandy Bridge */
-       { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable },
-       /* Dell XPS13 HD and XPS13 FHD Ivy Bridge */
-       { 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable },
 };
 
 static void intel_init_quirks(struct drm_device *dev)
@@ -10870,7 +11055,7 @@ void i915_redisable_vga(struct drm_device *dev)
         * level, just check if the power well is enabled instead of trying to
         * follow the "don't touch the power well if we don't need it" policy
         * the rest of the driver uses. */
-       if (HAS_POWER_WELL(dev) &&
+       if ((IS_HASWELL(dev) || IS_BROADWELL(dev)) &&
            (I915_READ(HSW_PWR_WELL_DRIVER) & HSW_PWR_WELL_STATE_ENABLED) == 0)
                return;
 
@@ -11091,12 +11276,11 @@ void intel_modeset_cleanup(struct drm_device *dev)
        /* flush any delayed tasks or pending work */
        flush_scheduled_work();
 
-       /* destroy backlight, if any, before the connectors */
-       intel_panel_destroy_backlight(dev);
-
-       /* destroy the sysfs files before encoders/connectors */
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+       /* destroy the backlight and sysfs files before encoders/connectors */
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               intel_panel_destroy_backlight(connector);
                drm_sysfs_connector_remove(connector);
+       }
 
        drm_mode_config_cleanup(dev);
 
@@ -11150,6 +11334,7 @@ struct intel_display_error_state {
        } cursor[I915_MAX_PIPES];
 
        struct intel_pipe_error_state {
+               bool power_domain_on;
                u32 source;
        } pipe[I915_MAX_PIPES];
 
@@ -11164,6 +11349,7 @@ struct intel_display_error_state {
        } plane[I915_MAX_PIPES];
 
        struct intel_transcoder_error_state {
+               bool power_domain_on;
                enum transcoder cpu_transcoder;
 
                u32 conf;
@@ -11197,11 +11383,13 @@ intel_display_capture_error_state(struct drm_device *dev)
        if (error == NULL)
                return NULL;
 
-       if (HAS_POWER_WELL(dev))
+       if (IS_HASWELL(dev) || IS_BROADWELL(dev))
                error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER);
 
        for_each_pipe(i) {
-               if (!intel_display_power_enabled(dev, POWER_DOMAIN_PIPE(i)))
+               error->pipe[i].power_domain_on =
+                       intel_display_power_enabled_sw(dev, POWER_DOMAIN_PIPE(i));
+               if (!error->pipe[i].power_domain_on)
                        continue;
 
                if (INTEL_INFO(dev)->gen <= 6 || IS_VALLEYVIEW(dev)) {
@@ -11237,8 +11425,9 @@ intel_display_capture_error_state(struct drm_device *dev)
        for (i = 0; i < error->num_transcoders; i++) {
                enum transcoder cpu_transcoder = transcoders[i];
 
-               if (!intel_display_power_enabled(dev,
-                               POWER_DOMAIN_TRANSCODER(cpu_transcoder)))
+               error->transcoder[i].power_domain_on =
+                       intel_display_power_enabled_sw(dev, POWER_DOMAIN_PIPE(i));
+               if (!error->transcoder[i].power_domain_on)
                        continue;
 
                error->transcoder[i].cpu_transcoder = cpu_transcoder;
@@ -11268,11 +11457,13 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m,
                return;
 
        err_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes);
-       if (HAS_POWER_WELL(dev))
+       if (IS_HASWELL(dev) || IS_BROADWELL(dev))
                err_printf(m, "PWR_WELL_CTL2: %08x\n",
                           error->power_well_driver);
        for_each_pipe(i) {
                err_printf(m, "Pipe [%d]:\n", i);
+               err_printf(m, "  Power: %s\n",
+                          error->pipe[i].power_domain_on ? "on" : "off");
                err_printf(m, "  SRC: %08x\n", error->pipe[i].source);
 
                err_printf(m, "Plane [%d]:\n", i);
@@ -11298,6 +11489,8 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m,
        for (i = 0; i < error->num_transcoders; i++) {
                err_printf(m, "CPU transcoder: %c\n",
                           transcoder_name(error->transcoder[i].cpu_transcoder));
+               err_printf(m, "  Power: %s\n",
+                          error->transcoder[i].power_domain_on ? "on" : "off");
                err_printf(m, "  CONF: %08x\n", error->transcoder[i].conf);
                err_printf(m, "  HTOTAL: %08x\n", error->transcoder[i].htotal);
                err_printf(m, "  HBLANK: %08x\n", error->transcoder[i].hblank);
index 0b2e842fef0151070b09af535d54fdcee2215602..7c54f6267a1fea815f3c63d992d1080c96639850 100644 (file)
@@ -142,7 +142,7 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
        return (max_link_clock * max_lanes * 8) / 10;
 }
 
-static int
+static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
@@ -404,7 +404,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
        int i, ret, recv_bytes;
        uint32_t status;
        int try, precharge, clock = 0;
-       bool has_aux_irq = INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev);
+       bool has_aux_irq = true;
        uint32_t timeout;
 
        /* dp aux is extremely sensitive to irq latency, hence request the
@@ -1845,23 +1845,23 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
        struct drm_device *dev = encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
-       int port = vlv_dport_to_channel(dport);
+       enum dpio_channel port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
        struct edp_power_seq power_seq;
        u32 val;
 
        mutex_lock(&dev_priv->dpio_lock);
 
-       val = vlv_dpio_read(dev_priv, pipe, DPIO_DATA_LANE_A(port));
+       val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port));
        val = 0;
        if (pipe)
                val |= (1<<21);
        else
                val &= ~(1<<21);
        val |= 0x001000c4;
-       vlv_dpio_write(dev_priv, pipe, DPIO_DATA_CHANNEL(port), val);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF0(port), 0x00760018);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF8(port), 0x00400888);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW8(port), val);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
 
        mutex_unlock(&dev_priv->dpio_lock);
 
@@ -1872,7 +1872,7 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
 
        intel_enable_dp(encoder);
 
-       vlv_wait_port_ready(dev_priv, port);
+       vlv_wait_port_ready(dev_priv, dport);
 }
 
 static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder)
@@ -1882,24 +1882,24 @@ static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc =
                to_intel_crtc(encoder->base.crtc);
-       int port = vlv_dport_to_channel(dport);
+       enum dpio_channel port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
 
        /* Program Tx lane resets to default */
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port),
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port),
                         DPIO_PCS_TX_LANE2_RESET |
                         DPIO_PCS_TX_LANE1_RESET);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port),
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port),
                         DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
                         DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
                         (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
                                 DPIO_PCS_CLK_SOFT_RESET);
 
        /* Fix up inter-pair skew failure */
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER1(port), 0x00750f00);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_CTL(port), 0x00001500);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_LANE(port), 0x40400000);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000);
        mutex_unlock(&dev_priv->dpio_lock);
 }
 
@@ -2050,7 +2050,7 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp)
        unsigned long demph_reg_value, preemph_reg_value,
                uniqtranscale_reg_value;
        uint8_t train_set = intel_dp->train_set[0];
-       int port = vlv_dport_to_channel(dport);
+       enum dpio_channel port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
 
        switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
@@ -2127,14 +2127,14 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp)
        }
 
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0x00000000);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL4(port), demph_reg_value);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL2(port),
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
                         uniqtranscale_reg_value);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL3(port), 0x0C782040);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER0(port), 0x00030000);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port), preemph_reg_value);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0x80000000);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0C782040);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
        mutex_unlock(&dev_priv->dpio_lock);
 
        return 0;
@@ -3326,11 +3326,19 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc)
 }
 
 /* check the VBT to see whether the eDP is on DP-D port */
-bool intel_dpd_is_edp(struct drm_device *dev)
+bool intel_dp_is_edp(struct drm_device *dev, enum port port)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        union child_device_config *p_child;
        int i;
+       static const short port_mapping[] = {
+               [PORT_B] = PORT_IDPB,
+               [PORT_C] = PORT_IDPC,
+               [PORT_D] = PORT_IDPD,
+       };
+
+       if (port == PORT_A)
+               return true;
 
        if (!dev_priv->vbt.child_dev_num)
                return false;
@@ -3338,7 +3346,7 @@ bool intel_dpd_is_edp(struct drm_device *dev)
        for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
                p_child = dev_priv->vbt.child_dev + i;
 
-               if (p_child->common.dvo_port == PORT_IDPD &&
+               if (p_child->common.dvo_port == port_mapping[port] &&
                    (p_child->common.device_type & DEVICE_TYPE_eDP_BITS) ==
                    (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS))
                        return true;
@@ -3616,26 +3624,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
        intel_dp->DP = I915_READ(intel_dp->output_reg);
        intel_dp->attached_connector = intel_connector;
 
-       type = DRM_MODE_CONNECTOR_DisplayPort;
-       /*
-        * FIXME : We need to initialize built-in panels before external panels.
-        * For X0, DP_C is fixed as eDP. Revisit this as part of VLV eDP cleanup
-        */
-       switch (port) {
-       case PORT_A:
+       if (intel_dp_is_edp(dev, port))
                type = DRM_MODE_CONNECTOR_eDP;
-               break;
-       case PORT_C:
-               if (IS_VALLEYVIEW(dev))
-                       type = DRM_MODE_CONNECTOR_eDP;
-               break;
-       case PORT_D:
-               if (HAS_PCH_SPLIT(dev) && intel_dpd_is_edp(dev))
-                       type = DRM_MODE_CONNECTOR_eDP;
-               break;
-       default:        /* silence GCC warning */
-               break;
-       }
+       else
+               type = DRM_MODE_CONNECTOR_DisplayPort;
 
        /*
         * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but
index 1e49aa8f5377395c8803d5a55765199bd38af037..2b5bcb617908901cc56a234e67c254709d0e1096 100644 (file)
@@ -156,6 +156,17 @@ struct intel_encoder {
 struct intel_panel {
        struct drm_display_mode *fixed_mode;
        int fitting_mode;
+
+       /* backlight */
+       struct {
+               bool present;
+               u32 level;
+               u32 max;
+               bool enabled;
+               bool combination_mode;  /* gen 2/4 only */
+               bool active_low_pwm;
+               struct backlight_device *device;
+       } backlight;
 };
 
 struct intel_connector {
@@ -490,9 +501,9 @@ vlv_dport_to_channel(struct intel_digital_port *dport)
 {
        switch (dport->port) {
        case PORT_B:
-               return 0;
+               return DPIO_CH0;
        case PORT_C:
-               return 1;
+               return DPIO_CH1;
        default:
                BUG();
        }
@@ -638,7 +649,8 @@ enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
 void intel_wait_for_vblank(struct drm_device *dev, int pipe);
 void intel_wait_for_pipe_off(struct drm_device *dev, int pipe);
 int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp);
-void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port);
+void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
+                        struct intel_digital_port *dport);
 bool intel_get_load_detect_pipe(struct drm_connector *connector,
                                struct drm_display_mode *mode,
                                struct intel_load_detect_pipe *old);
@@ -694,7 +706,7 @@ void i915_disable_vga_mem(struct drm_device *dev);
 void hsw_enable_ips(struct intel_crtc *crtc);
 void hsw_disable_ips(struct intel_crtc *crtc);
 void intel_display_set_init_power(struct drm_device *dev, bool enable);
-
+int valleyview_get_vco(struct drm_i915_private *dev_priv);
 
 /* intel_dp.c */
 void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
@@ -708,7 +720,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder);
 void intel_dp_check_link_status(struct intel_dp *intel_dp);
 bool intel_dp_compute_config(struct intel_encoder *encoder,
                             struct intel_crtc_config *pipe_config);
-bool intel_dpd_is_edp(struct drm_device *dev);
+bool intel_dp_is_edp(struct drm_device *dev, enum port port);
 void ironlake_edp_backlight_on(struct intel_dp *intel_dp);
 void ironlake_edp_backlight_off(struct intel_dp *intel_dp);
 void ironlake_edp_panel_on(struct intel_dp *intel_dp);
@@ -808,7 +820,8 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 int intel_panel_setup_backlight(struct drm_connector *connector);
 void intel_panel_enable_backlight(struct intel_connector *connector);
 void intel_panel_disable_backlight(struct intel_connector *connector);
-void intel_panel_destroy_backlight(struct drm_device *dev);
+void intel_panel_destroy_backlight(struct drm_connector *connector);
+void intel_panel_init_backlight_funcs(struct drm_device *dev);
 enum drm_connector_status intel_panel_detect(struct drm_device *dev);
 
 
@@ -829,6 +842,8 @@ int intel_power_domains_init(struct drm_device *dev);
 void intel_power_domains_remove(struct drm_device *dev);
 bool intel_display_power_enabled(struct drm_device *dev,
                                 enum intel_display_power_domain domain);
+bool intel_display_power_enabled_sw(struct drm_device *dev,
+                                   enum intel_display_power_domain domain);
 void intel_display_power_get(struct drm_device *dev,
                             enum intel_display_power_domain domain);
 void intel_display_power_put(struct drm_device *dev,
index d257b093ca68757874925999fae766a727755212..7b9b350d29aebbe4ef21d2135977c41ed834830d 100644 (file)
@@ -251,8 +251,9 @@ static void intel_dsi_get_config(struct intel_encoder *encoder,
        /* XXX: read flags, set to adjusted_mode */
 }
 
-static int intel_dsi_mode_valid(struct drm_connector *connector,
-                               struct drm_display_mode *mode)
+static enum drm_mode_status
+intel_dsi_mode_valid(struct drm_connector *connector,
+                    struct drm_display_mode *mode)
 {
        struct intel_connector *intel_connector = to_intel_connector(connector);
        struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
index 3c77365468562ab026910a1e111fb932b288f242..eeff998e52efdea93534ffb680582503f9f2a56c 100644 (file)
@@ -234,8 +234,9 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
        intel_modeset_check_state(connector->dev);
 }
 
-static int intel_dvo_mode_valid(struct drm_connector *connector,
-                               struct drm_display_mode *mode)
+static enum drm_mode_status
+intel_dvo_mode_valid(struct drm_connector *connector,
+                    struct drm_display_mode *mode)
 {
        struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
 
index 895fcb4fbd9446bfbfafc90f95948d9a4bea5c55..284c3eb066f6ffff76de5b7cb0108617126679f2 100644 (file)
@@ -57,18 +57,14 @@ static struct fb_ops intelfb_ops = {
        .fb_debug_leave = drm_fb_helper_debug_leave,
 };
 
-static int intelfb_create(struct drm_fb_helper *helper,
-                         struct drm_fb_helper_surface_size *sizes)
+static int intelfb_alloc(struct drm_fb_helper *helper,
+                        struct drm_fb_helper_surface_size *sizes)
 {
        struct intel_fbdev *ifbdev =
                container_of(helper, struct intel_fbdev, helper);
        struct drm_device *dev = helper->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct fb_info *info;
-       struct drm_framebuffer *fb;
        struct drm_mode_fb_cmd2 mode_cmd = {};
        struct drm_i915_gem_object *obj;
-       struct device *device = &dev->pdev->dev;
        int size, ret;
 
        /* we don't do packed 24bpp */
@@ -94,8 +90,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
                goto out;
        }
 
-       mutex_lock(&dev->struct_mutex);
-
        /* Flush everything out, we'll be doing GTT only from now on */
        ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
        if (ret) {
@@ -103,7 +97,50 @@ static int intelfb_create(struct drm_fb_helper *helper,
                goto out_unref;
        }
 
-       info = framebuffer_alloc(0, device);
+       ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
+       if (ret)
+               goto out_unpin;
+
+       return 0;
+
+out_unpin:
+       i915_gem_object_unpin(obj);
+out_unref:
+       drm_gem_object_unreference(&obj->base);
+out:
+       return ret;
+}
+
+static int intelfb_create(struct drm_fb_helper *helper,
+                         struct drm_fb_helper_surface_size *sizes)
+{
+       struct intel_fbdev *ifbdev =
+               container_of(helper, struct intel_fbdev, helper);
+       struct intel_framebuffer *intel_fb = &ifbdev->ifb;
+       struct drm_device *dev = helper->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct fb_info *info;
+       struct drm_framebuffer *fb;
+       struct drm_i915_gem_object *obj;
+       int size, ret;
+
+       mutex_lock(&dev->struct_mutex);
+
+       if (!intel_fb->obj) {
+               DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
+               ret = intelfb_alloc(helper, sizes);
+               if (ret)
+                       goto out_unlock;
+       } else {
+               DRM_DEBUG_KMS("re-using BIOS fb\n");
+               sizes->fb_width = intel_fb->base.width;
+               sizes->fb_height = intel_fb->base.height;
+       }
+
+       obj = intel_fb->obj;
+       size = obj->base.size;
+
+       info = framebuffer_alloc(0, &dev->pdev->dev);
        if (!info) {
                ret = -ENOMEM;
                goto out_unpin;
@@ -111,10 +148,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
 
        info->par = helper;
 
-       ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
-       if (ret)
-               goto out_unpin;
-
        fb = &ifbdev->ifb.base;
 
        ifbdev->helper.fb = fb;
@@ -170,17 +203,15 @@ static int intelfb_create(struct drm_fb_helper *helper,
                      fb->width, fb->height,
                      i915_gem_obj_ggtt_offset(obj), obj);
 
-
        mutex_unlock(&dev->struct_mutex);
        vga_switcheroo_client_fb_set(dev->pdev, info);
        return 0;
 
 out_unpin:
        i915_gem_object_unpin(obj);
-out_unref:
        drm_gem_object_unreference(&obj->base);
+out_unlock:
        mutex_unlock(&dev->struct_mutex);
-out:
        return ret;
 }
 
index 03f9ca70530c03f441ae037b16cf0c5e80b908ab..6a6ad0c78dc70a5e1049ad46c7bb3d7889b4f2be 100644 (file)
@@ -853,8 +853,9 @@ static int hdmi_portclock_limit(struct intel_hdmi *hdmi)
                return 225000;
 }
 
-static int intel_hdmi_mode_valid(struct drm_connector *connector,
-                                struct drm_display_mode *mode)
+static enum drm_mode_status
+intel_hdmi_mode_valid(struct drm_connector *connector,
+                     struct drm_display_mode *mode)
 {
        if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector)))
                return MODE_CLOCK_HIGH;
@@ -1081,7 +1082,7 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc =
                to_intel_crtc(encoder->base.crtc);
-       int port = vlv_dport_to_channel(dport);
+       enum dpio_channel port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
        u32 val;
 
@@ -1090,41 +1091,33 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
 
        /* Enable clock channels for this port */
        mutex_lock(&dev_priv->dpio_lock);
-       val = vlv_dpio_read(dev_priv, pipe, DPIO_DATA_LANE_A(port));
+       val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port));
        val = 0;
        if (pipe)
                val |= (1<<21);
        else
                val &= ~(1<<21);
        val |= 0x001000c4;
-       vlv_dpio_write(dev_priv, pipe, DPIO_DATA_CHANNEL(port), val);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW8(port), val);
 
        /* HDMI 1.0V-2dB */
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL4(port),
-                        0x2b245f5f);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL2(port),
-                        0x5578b83a);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL3(port),
-                        0x0c782040);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX3_SWING_CTL4(port),
-                        0x2b247878);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER0(port), 0x00030000);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port),
-                        0x00002000);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port),
-                        DPIO_TX_OCALINIT_EN);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), 0x2b245f5f);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port), 0x5578b83a);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0c782040);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX3_DW4(port), 0x2b247878);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), 0x00002000);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN);
 
        /* Program lane clock */
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF0(port),
-                        0x00760018);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF8(port),
-                        0x00400888);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
        mutex_unlock(&dev_priv->dpio_lock);
 
        intel_enable_hdmi(encoder);
 
-       vlv_wait_port_ready(dev_priv, port);
+       vlv_wait_port_ready(dev_priv, dport);
 }
 
 static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
@@ -1134,7 +1127,7 @@ static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc =
                to_intel_crtc(encoder->base.crtc);
-       int port = vlv_dport_to_channel(dport);
+       enum dpio_channel port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
 
        if (!IS_VALLEYVIEW(dev))
@@ -1142,24 +1135,22 @@ static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
 
        /* Program Tx lane resets to default */
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port),
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port),
                         DPIO_PCS_TX_LANE2_RESET |
                         DPIO_PCS_TX_LANE1_RESET);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port),
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port),
                         DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
                         DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
                         (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
                         DPIO_PCS_CLK_SOFT_RESET);
 
        /* Fix up inter-pair skew failure */
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER1(port), 0x00750f00);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_CTL(port), 0x00001500);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_LANE(port), 0x40400000);
-
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port),
-                        0x00002000);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port),
-                        DPIO_TX_OCALINIT_EN);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000);
+
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), 0x00002000);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN);
        mutex_unlock(&dev_priv->dpio_lock);
 }
 
@@ -1169,13 +1160,13 @@ static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
        struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
        struct intel_crtc *intel_crtc =
                to_intel_crtc(encoder->base.crtc);
-       int port = vlv_dport_to_channel(dport);
+       enum dpio_channel port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
 
        /* Reset lanes to avoid HDMI flicker (VLV w/a) */
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port), 0x00000000);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port), 0x00e00060);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), 0x00000000);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port), 0x00e00060);
        mutex_unlock(&dev_priv->dpio_lock);
 }
 
index 2ca17b14b6c1c91710601dfcb34c661b45707347..b1dc33f478991755ec114fe66fbad7bc40fec4c0 100644 (file)
@@ -82,20 +82,11 @@ static int get_disp_clk_div(struct drm_i915_private *dev_priv,
 
 static void gmbus_set_freq(struct drm_i915_private *dev_priv)
 {
-       int vco_freq[] = { 800, 1600, 2000, 2400 };
-       int gmbus_freq = 0, cdclk_div, hpll_freq;
+       int vco, gmbus_freq = 0, cdclk_div;
 
        BUG_ON(!IS_VALLEYVIEW(dev_priv->dev));
 
-       /* Skip setting the gmbus freq if BIOS has already programmed it */
-       if (I915_READ(GMBUSFREQ_VLV) != 0xA0)
-               return;
-
-       /* Obtain SKU information */
-       mutex_lock(&dev_priv->dpio_lock);
-       hpll_freq =
-               vlv_cck_read(dev_priv, CCK_FUSE_REG) & CCK_FUSE_HPLL_FREQ_MASK;
-       mutex_unlock(&dev_priv->dpio_lock);
+       vco = valleyview_get_vco(dev_priv);
 
        /* Get the CDCLK divide ratio */
        cdclk_div = get_disp_clk_div(dev_priv, CDCLK);
@@ -106,7 +97,7 @@ static void gmbus_set_freq(struct drm_i915_private *dev_priv)
         * in fact 1MHz is the correct frequency.
         */
        if (cdclk_div)
-               gmbus_freq = (vco_freq[hpll_freq] << 1) / cdclk_div;
+               gmbus_freq = (vco << 1) / cdclk_div;
 
        if (WARN_ON(gmbus_freq == 0))
                return;
index c3b4da7895ed1c82b185b78ca06d00053cff2402..3deb58e2f394c85c9fc441e84d401da35aa80746 100644 (file)
@@ -256,8 +256,9 @@ static void intel_disable_lvds(struct intel_encoder *encoder)
        POSTING_READ(lvds_encoder->reg);
 }
 
-static int intel_lvds_mode_valid(struct drm_connector *connector,
-                                struct drm_display_mode *mode)
+static enum drm_mode_status
+intel_lvds_mode_valid(struct drm_connector *connector,
+                     struct drm_display_mode *mode)
 {
        struct intel_connector *intel_connector = to_intel_connector(connector);
        struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
index 6d69a9bad86545c6a8cfc8e8ff86480d462c2132..a8febbd3017b437fcd6bca2d067a6d849da29a64 100644 (file)
@@ -396,13 +396,10 @@ int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
 static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_encoder *encoder;
        struct drm_connector *connector;
-       struct intel_connector *intel_connector = NULL;
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
+       struct intel_connector *intel_connector;
+       struct intel_panel *panel;
        struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
-       u32 ret = 0;
-       bool found = false;
 
        DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
 
@@ -414,38 +411,24 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
                return ASLC_BACKLIGHT_FAILED;
 
        mutex_lock(&dev->mode_config.mutex);
+
        /*
-        * Could match the OpRegion connector here instead, but we'd also need
-        * to verify the connector could handle a backlight call.
+        * Update backlight on all connectors that support backlight (usually
+        * only one).
         */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-               if (encoder->crtc == crtc) {
-                       found = true;
-                       break;
-               }
-
-       if (!found) {
-               ret = ASLC_BACKLIGHT_FAILED;
-               goto out;
-       }
-
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-               if (connector->encoder == encoder)
-                       intel_connector = to_intel_connector(connector);
-
-       if (!intel_connector) {
-               ret = ASLC_BACKLIGHT_FAILED;
-               goto out;
-       }
-
        DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
-       intel_panel_set_backlight(intel_connector, bclp, 255);
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               intel_connector = to_intel_connector(connector);
+               panel = &intel_connector->panel;
+               if (panel->backlight.present)
+                       intel_panel_set_backlight(intel_connector, bclp, 255);
+       }
        iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv);
 
-out:
        mutex_unlock(&dev->mode_config.mutex);
 
-       return ret;
+
+       return 0;
 }
 
 static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
index f161ac02c4f6e613efbfc7f763cbb3566dc75248..e480cf41c5365f5551eaff1a04efd458b7e37d12 100644 (file)
@@ -325,203 +325,170 @@ out:
        pipe_config->gmch_pfit.lvds_border_bits = border;
 }
 
-static int is_backlight_combination_mode(struct drm_device *dev)
+static int i915_panel_invert_brightness;
+MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
+       "(-1 force normal, 0 machine defaults, 1 force inversion), please "
+       "report PCI device ID, subsystem vendor and subsystem device ID "
+       "to dri-devel@lists.freedesktop.org, if your machine needs it. "
+       "It will then be included in an upcoming module version.");
+module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
+static u32 intel_panel_compute_brightness(struct intel_connector *connector,
+                                         u32 val)
 {
+       struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
 
-       if (IS_GEN4(dev))
-               return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE;
+       WARN_ON(panel->backlight.max == 0);
 
-       if (IS_GEN2(dev))
-               return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE;
+       if (i915_panel_invert_brightness < 0)
+               return val;
 
-       return 0;
+       if (i915_panel_invert_brightness > 0 ||
+           dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
+               return panel->backlight.max - val;
+       }
+
+       return val;
 }
 
-/* XXX: query mode clock or hardware clock and program max PWM appropriately
- * when it's 0.
- */
-static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe)
+static u32 bdw_get_backlight(struct intel_connector *connector)
 {
+       struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 val;
-
-       WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight.lock));
-
-       /* Restore the CTL value if it lost, e.g. GPU reset */
 
-       if (HAS_PCH_SPLIT(dev_priv->dev)) {
-               val = I915_READ(BLC_PWM_PCH_CTL2);
-               if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
-                       dev_priv->regfile.saveBLC_PWM_CTL2 = val;
-               } else if (val == 0) {
-                       val = dev_priv->regfile.saveBLC_PWM_CTL2;
-                       I915_WRITE(BLC_PWM_PCH_CTL2, val);
-               }
-       } else if (IS_VALLEYVIEW(dev)) {
-               val = I915_READ(VLV_BLC_PWM_CTL(pipe));
-               if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
-                       dev_priv->regfile.saveBLC_PWM_CTL = val;
-                       dev_priv->regfile.saveBLC_PWM_CTL2 =
-                               I915_READ(VLV_BLC_PWM_CTL2(pipe));
-               } else if (val == 0) {
-                       val = dev_priv->regfile.saveBLC_PWM_CTL;
-                       I915_WRITE(VLV_BLC_PWM_CTL(pipe), val);
-                       I915_WRITE(VLV_BLC_PWM_CTL2(pipe),
-                                  dev_priv->regfile.saveBLC_PWM_CTL2);
-               }
+       return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
 
-               if (!val)
-                       val = 0x0f42ffff;
-       } else {
-               val = I915_READ(BLC_PWM_CTL);
-               if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
-                       dev_priv->regfile.saveBLC_PWM_CTL = val;
-                       if (INTEL_INFO(dev)->gen >= 4)
-                               dev_priv->regfile.saveBLC_PWM_CTL2 =
-                                       I915_READ(BLC_PWM_CTL2);
-               } else if (val == 0) {
-                       val = dev_priv->regfile.saveBLC_PWM_CTL;
-                       I915_WRITE(BLC_PWM_CTL, val);
-                       if (INTEL_INFO(dev)->gen >= 4)
-                               I915_WRITE(BLC_PWM_CTL2,
-                                          dev_priv->regfile.saveBLC_PWM_CTL2);
-               }
-       }
+static u32 pch_get_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
-       return val;
+       return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
 }
 
-static u32 intel_panel_get_max_backlight(struct drm_device *dev,
-                                        enum pipe pipe)
+static u32 i9xx_get_backlight(struct intel_connector *connector)
 {
-       u32 max;
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       u32 val;
 
-       max = i915_read_blc_pwm_ctl(dev, pipe);
+       val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+       if (INTEL_INFO(dev)->gen < 4)
+               val >>= 1;
 
-       if (HAS_PCH_SPLIT(dev)) {
-               max >>= 16;
-       } else {
-               if (INTEL_INFO(dev)->gen < 4)
-                       max >>= 17;
-               else
-                       max >>= 16;
+       if (panel->backlight.combination_mode) {
+               u8 lbpc;
 
-               if (is_backlight_combination_mode(dev))
-                       max *= 0xff;
+               pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
+               val *= lbpc;
        }
 
-       DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
-
-       return max;
+       return val;
 }
 
-static int i915_panel_invert_brightness;
-MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
-       "(-1 force normal, 0 machine defaults, 1 force inversion), please "
-       "report PCI device ID, subsystem vendor and subsystem device ID "
-       "to dri-devel@lists.freedesktop.org, if your machine needs it. "
-       "It will then be included in an upcoming module version.");
-module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
-static u32 intel_panel_compute_brightness(struct drm_device *dev,
-                                         enum pipe pipe, u32 val)
+static u32 _vlv_get_backlight(struct drm_device *dev, enum pipe pipe)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (i915_panel_invert_brightness < 0)
-               return val;
+       return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
 
-       if (i915_panel_invert_brightness > 0 ||
-           dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
-               u32 max = intel_panel_get_max_backlight(dev, pipe);
-               if (max)
-                       return max - val;
-       }
+static u32 vlv_get_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       enum pipe pipe = intel_get_pipe_from_connector(connector);
 
-       return val;
+       return _vlv_get_backlight(dev, pipe);
 }
 
-static u32 intel_panel_get_backlight(struct drm_device *dev,
-                                    enum pipe pipe)
+static u32 intel_panel_get_backlight(struct intel_connector *connector)
 {
+       struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 val;
        unsigned long flags;
-       int reg;
 
-       spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+       spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
-       if (HAS_PCH_SPLIT(dev)) {
-               val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
-       } else {
-               if (IS_VALLEYVIEW(dev))
-                       reg = VLV_BLC_PWM_CTL(pipe);
-               else
-                       reg = BLC_PWM_CTL;
-
-               val = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK;
-               if (INTEL_INFO(dev)->gen < 4)
-                       val >>= 1;
+       val = dev_priv->display.get_backlight(connector);
+       val = intel_panel_compute_brightness(connector, val);
 
-               if (is_backlight_combination_mode(dev)) {
-                       u8 lbpc;
-
-                       pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
-                       val *= lbpc;
-               }
-       }
-
-       val = intel_panel_compute_brightness(dev, pipe, val);
-
-       spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+       spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 
        DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
        return val;
 }
 
-static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
+static void bdw_set_backlight(struct intel_connector *connector, u32 level)
 {
+       struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 val = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-       I915_WRITE(BLC_PWM_CPU_CTL, val | level);
+       u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+       I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
 }
 
-static void intel_panel_actually_set_backlight(struct drm_device *dev,
-                                              enum pipe pipe, u32 level)
+static void pch_set_backlight(struct intel_connector *connector, u32 level)
 {
+       struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 tmp;
-       int reg;
 
-       DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
-       level = intel_panel_compute_brightness(dev, pipe, level);
+       tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+       I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
+}
+
+static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       u32 tmp, mask;
 
-       if (HAS_PCH_SPLIT(dev))
-               return intel_pch_panel_set_backlight(dev, level);
+       WARN_ON(panel->backlight.max == 0);
 
-       if (is_backlight_combination_mode(dev)) {
-               u32 max = intel_panel_get_max_backlight(dev, pipe);
+       if (panel->backlight.combination_mode) {
                u8 lbpc;
 
-               /* we're screwed, but keep behaviour backwards compatible */
-               if (!max)
-                       max = 1;
-
-               lbpc = level * 0xfe / max + 1;
+               lbpc = level * 0xfe / panel->backlight.max + 1;
                level /= lbpc;
                pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
        }
 
-       if (IS_VALLEYVIEW(dev))
-               reg = VLV_BLC_PWM_CTL(pipe);
-       else
-               reg = BLC_PWM_CTL;
-
-       tmp = I915_READ(reg);
-       if (INTEL_INFO(dev)->gen < 4)
+       if (IS_GEN4(dev)) {
+               mask = BACKLIGHT_DUTY_CYCLE_MASK;
+       } else {
                level <<= 1;
-       tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
-       I915_WRITE(reg, tmp | level);
+               mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
+       }
+
+       tmp = I915_READ(BLC_PWM_CTL) & ~mask;
+       I915_WRITE(BLC_PWM_CTL, tmp | level);
+}
+
+static void vlv_set_backlight(struct intel_connector *connector, u32 level)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       enum pipe pipe = intel_get_pipe_from_connector(connector);
+       u32 tmp;
+
+       tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+       I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
+}
+
+static void
+intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
+
+       level = intel_panel_compute_brightness(connector, level);
+       dev_priv->display.set_backlight(connector, level);
 }
 
 /* set backlight brightness to level in range [0..max] */
@@ -530,6 +497,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 {
        struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
        enum pipe pipe = intel_get_pipe_from_connector(connector);
        u32 freq;
        unsigned long flags;
@@ -537,34 +505,77 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
        if (pipe == INVALID_PIPE)
                return;
 
-       spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+       spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
-       freq = intel_panel_get_max_backlight(dev, pipe);
-       if (!freq) {
-               /* we are screwed, bail out */
-               goto out;
-       }
+       WARN_ON(panel->backlight.max == 0);
 
-       /* scale to hardware, but be careful to not overflow */
+       /* scale to hardware max, but be careful to not overflow */
+       freq = panel->backlight.max;
        if (freq < max)
                level = level * freq / max;
        else
                level = freq / max * level;
 
-       dev_priv->backlight.level = level;
-       if (dev_priv->backlight.device)
-               dev_priv->backlight.device->props.brightness = level;
+       panel->backlight.level = level;
+       if (panel->backlight.device)
+               panel->backlight.device->props.brightness = level;
 
-       if (dev_priv->backlight.enabled)
-               intel_panel_actually_set_backlight(dev, pipe, level);
-out:
-       spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+       if (panel->backlight.enabled)
+               intel_panel_actually_set_backlight(connector, level);
+
+       spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
+}
+
+static void pch_disable_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 tmp;
+
+       intel_panel_actually_set_backlight(connector, 0);
+
+       tmp = I915_READ(BLC_PWM_CPU_CTL2);
+       I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
+
+       tmp = I915_READ(BLC_PWM_PCH_CTL1);
+       I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
+}
+
+static void i9xx_disable_backlight(struct intel_connector *connector)
+{
+       intel_panel_actually_set_backlight(connector, 0);
+}
+
+static void i965_disable_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 tmp;
+
+       intel_panel_actually_set_backlight(connector, 0);
+
+       tmp = I915_READ(BLC_PWM_CTL2);
+       I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
+}
+
+static void vlv_disable_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       enum pipe pipe = intel_get_pipe_from_connector(connector);
+       u32 tmp;
+
+       intel_panel_actually_set_backlight(connector, 0);
+
+       tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+       I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
 }
 
 void intel_panel_disable_backlight(struct intel_connector *connector)
 {
        struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
        enum pipe pipe = intel_get_pipe_from_connector(connector);
        unsigned long flags;
 
@@ -582,141 +593,215 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
                return;
        }
 
-       spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+       spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
-       dev_priv->backlight.enabled = false;
-       intel_panel_actually_set_backlight(dev, pipe, 0);
+       panel->backlight.enabled = false;
+       dev_priv->display.disable_backlight(connector);
 
-       if (INTEL_INFO(dev)->gen >= 4) {
-               uint32_t reg, tmp;
+       spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
+}
 
-               if (HAS_PCH_SPLIT(dev))
-                       reg = BLC_PWM_CPU_CTL2;
-               else if (IS_VALLEYVIEW(dev))
-                       reg = VLV_BLC_PWM_CTL2(pipe);
-               else
-                       reg = BLC_PWM_CTL2;
+static void bdw_enable_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       u32 pch_ctl1, pch_ctl2;
+
+       pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+       if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
+               DRM_DEBUG_KMS("pch backlight already enabled\n");
+               pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
+               I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+       }
 
-               I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
+       pch_ctl2 = panel->backlight.max << 16;
+       I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
 
-               if (HAS_PCH_SPLIT(dev)) {
-                       tmp = I915_READ(BLC_PWM_PCH_CTL1);
-                       tmp &= ~BLM_PCH_PWM_ENABLE;
-                       I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
-               }
-       }
+       pch_ctl1 = 0;
+       if (panel->backlight.active_low_pwm)
+               pch_ctl1 |= BLM_PCH_POLARITY;
 
-       spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+       /* BDW always uses the pch pwm controls. */
+       pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
+
+       I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+       POSTING_READ(BLC_PWM_PCH_CTL1);
+       I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
+
+       /* This won't stick until the above enable. */
+       intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
-void intel_panel_enable_backlight(struct intel_connector *connector)
+static void pch_enable_backlight(struct intel_connector *connector)
 {
        struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
        enum pipe pipe = intel_get_pipe_from_connector(connector);
        enum transcoder cpu_transcoder =
                intel_pipe_to_cpu_transcoder(dev_priv, pipe);
-       unsigned long flags;
+       u32 cpu_ctl2, pch_ctl1, pch_ctl2;
 
-       if (pipe == INVALID_PIPE)
-               return;
+       cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
+       if (cpu_ctl2 & BLM_PWM_ENABLE) {
+               WARN(1, "cpu backlight already enabled\n");
+               cpu_ctl2 &= ~BLM_PWM_ENABLE;
+               I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
+       }
 
-       DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
+       pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+       if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
+               DRM_DEBUG_KMS("pch backlight already enabled\n");
+               pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
+               I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+       }
 
-       spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+       if (cpu_transcoder == TRANSCODER_EDP)
+               cpu_ctl2 = BLM_TRANSCODER_EDP;
+       else
+               cpu_ctl2 = BLM_PIPE(cpu_transcoder);
+       I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
+       POSTING_READ(BLC_PWM_CPU_CTL2);
+       I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
+
+       /* This won't stick until the above enable. */
+       intel_panel_actually_set_backlight(connector, panel->backlight.level);
+
+       pch_ctl2 = panel->backlight.max << 16;
+       I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
+
+       pch_ctl1 = 0;
+       if (panel->backlight.active_low_pwm)
+               pch_ctl1 |= BLM_PCH_POLARITY;
+
+       I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+       POSTING_READ(BLC_PWM_PCH_CTL1);
+       I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
+}
+
+static void i9xx_enable_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       u32 ctl, freq;
 
-       if (dev_priv->backlight.level == 0) {
-               dev_priv->backlight.level = intel_panel_get_max_backlight(dev,
-                                                                         pipe);
-               if (dev_priv->backlight.device)
-                       dev_priv->backlight.device->props.brightness =
-                               dev_priv->backlight.level;
+       ctl = I915_READ(BLC_PWM_CTL);
+       if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
+               WARN(1, "backlight already enabled\n");
+               I915_WRITE(BLC_PWM_CTL, 0);
        }
 
-       if (INTEL_INFO(dev)->gen >= 4) {
-               uint32_t reg, tmp;
+       freq = panel->backlight.max;
+       if (panel->backlight.combination_mode)
+               freq /= 0xff;
 
-               if (HAS_PCH_SPLIT(dev))
-                       reg = BLC_PWM_CPU_CTL2;
-               else if (IS_VALLEYVIEW(dev))
-                       reg = VLV_BLC_PWM_CTL2(pipe);
-               else
-                       reg = BLC_PWM_CTL2;
+       ctl = freq << 17;
+       if (IS_GEN2(dev) && panel->backlight.combination_mode)
+               ctl |= BLM_LEGACY_MODE;
+       if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
+               ctl |= BLM_POLARITY_PNV;
 
-               tmp = I915_READ(reg);
+       I915_WRITE(BLC_PWM_CTL, ctl);
+       POSTING_READ(BLC_PWM_CTL);
 
-               /* Note that this can also get called through dpms changes. And
-                * we don't track the backlight dpms state, hence check whether
-                * we have to do anything first. */
-               if (tmp & BLM_PWM_ENABLE)
-                       goto set_level;
+       /* XXX: combine this into above write? */
+       intel_panel_actually_set_backlight(connector, panel->backlight.level);
+}
 
-               if (INTEL_INFO(dev)->num_pipes == 3)
-                       tmp &= ~BLM_PIPE_SELECT_IVB;
-               else
-                       tmp &= ~BLM_PIPE_SELECT;
+static void i965_enable_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       enum pipe pipe = intel_get_pipe_from_connector(connector);
+       u32 ctl, ctl2, freq;
 
-               if (cpu_transcoder == TRANSCODER_EDP)
-                       tmp |= BLM_TRANSCODER_EDP;
-               else
-                       tmp |= BLM_PIPE(cpu_transcoder);
-               tmp &= ~BLM_PWM_ENABLE;
-
-               I915_WRITE(reg, tmp);
-               POSTING_READ(reg);
-               I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
-
-               if (HAS_PCH_SPLIT(dev) &&
-                   !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
-                       tmp = I915_READ(BLC_PWM_PCH_CTL1);
-                       tmp |= BLM_PCH_PWM_ENABLE;
-                       tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
-                       I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
-               }
+       ctl2 = I915_READ(BLC_PWM_CTL2);
+       if (ctl2 & BLM_PWM_ENABLE) {
+               WARN(1, "backlight already enabled\n");
+               ctl2 &= ~BLM_PWM_ENABLE;
+               I915_WRITE(BLC_PWM_CTL2, ctl2);
        }
 
-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.
-        */
-       dev_priv->backlight.enabled = true;
-       intel_panel_actually_set_backlight(dev, pipe,
-                                          dev_priv->backlight.level);
+       freq = panel->backlight.max;
+       if (panel->backlight.combination_mode)
+               freq /= 0xff;
+
+       ctl = freq << 16;
+       I915_WRITE(BLC_PWM_CTL, ctl);
+
+       /* XXX: combine this into above write? */
+       intel_panel_actually_set_backlight(connector, panel->backlight.level);
 
-       spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+       ctl2 = BLM_PIPE(pipe);
+       if (panel->backlight.combination_mode)
+               ctl2 |= BLM_COMBINATION_MODE;
+       if (panel->backlight.active_low_pwm)
+               ctl2 |= BLM_POLARITY_I965;
+       I915_WRITE(BLC_PWM_CTL2, ctl2);
+       POSTING_READ(BLC_PWM_CTL2);
+       I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
 }
 
-/* FIXME: use VBT vals to init PWM_CTL and PWM_CTL2 correctly */
-static void intel_panel_init_backlight_regs(struct drm_device *dev)
+static void vlv_enable_backlight(struct intel_connector *connector)
 {
+       struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       enum pipe pipe = intel_get_pipe_from_connector(connector);
+       u32 ctl, ctl2;
 
-       if (IS_VALLEYVIEW(dev)) {
-               enum pipe pipe;
+       ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+       if (ctl2 & BLM_PWM_ENABLE) {
+               WARN(1, "backlight already enabled\n");
+               ctl2 &= ~BLM_PWM_ENABLE;
+               I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
+       }
 
-               for_each_pipe(pipe) {
-                       u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
+       ctl = panel->backlight.max << 16;
+       I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
 
-                       /* Skip if the modulation freq is already set */
-                       if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK)
-                               continue;
+       /* XXX: combine this into above write? */
+       intel_panel_actually_set_backlight(connector, panel->backlight.level);
 
-                       cur_val &= BACKLIGHT_DUTY_CYCLE_MASK;
-                       I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) |
-                                  cur_val);
-               }
-       }
+       ctl2 = 0;
+       if (panel->backlight.active_low_pwm)
+               ctl2 |= BLM_POLARITY_I965;
+       I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
+       POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
+       I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
 }
 
-static void intel_panel_init_backlight(struct drm_device *dev)
+void intel_panel_enable_backlight(struct intel_connector *connector)
 {
+       struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       enum pipe pipe = intel_get_pipe_from_connector(connector);
+       unsigned long flags;
+
+       if (pipe == INVALID_PIPE)
+               return;
+
+       DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
+
+       spin_lock_irqsave(&dev_priv->backlight_lock, flags);
+
+       WARN_ON(panel->backlight.max == 0);
 
-       intel_panel_init_backlight_regs(dev);
+       if (panel->backlight.level == 0) {
+               panel->backlight.level = panel->backlight.max;
+               if (panel->backlight.device)
+                       panel->backlight.device->props.brightness =
+                               panel->backlight.level;
+       }
+
+       dev_priv->display.enable_backlight(connector);
+       panel->backlight.enabled = true;
 
-       dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
-       dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
+       spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
 
 enum drm_connector_status
@@ -742,7 +827,7 @@ intel_panel_detect(struct drm_device *dev)
 }
 
 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
-static int intel_panel_update_status(struct backlight_device *bd)
+static int intel_backlight_device_update_status(struct backlight_device *bd)
 {
        struct intel_connector *connector = bl_get_data(bd);
        struct drm_device *dev = connector->base.dev;
@@ -756,85 +841,306 @@ static int intel_panel_update_status(struct backlight_device *bd)
        return 0;
 }
 
-static int intel_panel_get_brightness(struct backlight_device *bd)
+static int intel_backlight_device_get_brightness(struct backlight_device *bd)
 {
        struct intel_connector *connector = bl_get_data(bd);
        struct drm_device *dev = connector->base.dev;
-       enum pipe pipe;
+       int ret;
 
        mutex_lock(&dev->mode_config.mutex);
-       pipe = intel_get_pipe_from_connector(connector);
+       ret = intel_panel_get_backlight(connector);
        mutex_unlock(&dev->mode_config.mutex);
-       if (pipe == INVALID_PIPE)
-               return 0;
 
-       return intel_panel_get_backlight(connector->base.dev, pipe);
+       return ret;
 }
 
-static const struct backlight_ops intel_panel_bl_ops = {
-       .update_status = intel_panel_update_status,
-       .get_brightness = intel_panel_get_brightness,
+static const struct backlight_ops intel_backlight_device_ops = {
+       .update_status = intel_backlight_device_update_status,
+       .get_brightness = intel_backlight_device_get_brightness,
 };
 
-int intel_panel_setup_backlight(struct drm_connector *connector)
+static int intel_backlight_device_register(struct intel_connector *connector)
 {
-       struct drm_device *dev = connector->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
        struct backlight_properties props;
-       unsigned long flags;
 
-       intel_panel_init_backlight(dev);
-
-       if (WARN_ON(dev_priv->backlight.device))
+       if (WARN_ON(panel->backlight.device))
                return -ENODEV;
 
+       BUG_ON(panel->backlight.max == 0);
+
        memset(&props, 0, sizeof(props));
        props.type = BACKLIGHT_RAW;
-       props.brightness = dev_priv->backlight.level;
+       props.brightness = panel->backlight.level;
+       props.max_brightness = panel->backlight.max;
 
-       spin_lock_irqsave(&dev_priv->backlight.lock, flags);
-       props.max_brightness = intel_panel_get_max_backlight(dev, 0);
-       spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
-
-       if (props.max_brightness == 0) {
-               DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
-               return -ENODEV;
-       }
-       dev_priv->backlight.device =
+       /*
+        * Note: using the same name independent of the connector prevents
+        * registration of multiple backlight devices in the driver.
+        */
+       panel->backlight.device =
                backlight_device_register("intel_backlight",
-                                         connector->kdev,
-                                         to_intel_connector(connector),
-                                         &intel_panel_bl_ops, &props);
+                                         connector->base.kdev,
+                                         connector,
+                                         &intel_backlight_device_ops, &props);
 
-       if (IS_ERR(dev_priv->backlight.device)) {
+       if (IS_ERR(panel->backlight.device)) {
                DRM_ERROR("Failed to register backlight: %ld\n",
-                         PTR_ERR(dev_priv->backlight.device));
-               dev_priv->backlight.device = NULL;
+                         PTR_ERR(panel->backlight.device));
+               panel->backlight.device = NULL;
                return -ENODEV;
        }
        return 0;
 }
 
-void intel_panel_destroy_backlight(struct drm_device *dev)
+static void intel_backlight_device_unregister(struct intel_connector *connector)
+{
+       struct intel_panel *panel = &connector->panel;
+
+       if (panel->backlight.device) {
+               backlight_device_unregister(panel->backlight.device);
+               panel->backlight.device = NULL;
+       }
+}
+#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
+static int intel_backlight_device_register(struct intel_connector *connector)
+{
+       return 0;
+}
+static void intel_backlight_device_unregister(struct intel_connector *connector)
+{
+}
+#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
+
+/*
+ * Note: The setup hooks can't assume pipe is set!
+ *
+ * XXX: Query mode clock or hardware clock and program PWM modulation frequency
+ * appropriately when it's 0. Use VBT and/or sane defaults.
+ */
+static int bdw_setup_backlight(struct intel_connector *connector)
 {
+       struct drm_device *dev = connector->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       if (dev_priv->backlight.device) {
-               backlight_device_unregister(dev_priv->backlight.device);
-               dev_priv->backlight.device = NULL;
+       struct intel_panel *panel = &connector->panel;
+       u32 pch_ctl1, pch_ctl2, val;
+
+       pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+       panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
+
+       pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
+       panel->backlight.max = pch_ctl2 >> 16;
+       if (!panel->backlight.max)
+               return -ENODEV;
+
+       val = bdw_get_backlight(connector);
+       panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+       panel->backlight.enabled = (pch_ctl1 & BLM_PCH_PWM_ENABLE) &&
+               panel->backlight.level != 0;
+
+       return 0;
+}
+
+static int pch_setup_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
+
+       pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+       panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
+
+       pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
+       panel->backlight.max = pch_ctl2 >> 16;
+       if (!panel->backlight.max)
+               return -ENODEV;
+
+       val = pch_get_backlight(connector);
+       panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+       cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
+       panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
+               (pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;
+
+       return 0;
+}
+
+static int i9xx_setup_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       u32 ctl, val;
+
+       ctl = I915_READ(BLC_PWM_CTL);
+
+       if (IS_GEN2(dev))
+               panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
+
+       if (IS_PINEVIEW(dev))
+               panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
+
+       panel->backlight.max = ctl >> 17;
+       if (panel->backlight.combination_mode)
+               panel->backlight.max *= 0xff;
+
+       if (!panel->backlight.max)
+               return -ENODEV;
+
+       val = i9xx_get_backlight(connector);
+       panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+       panel->backlight.enabled = panel->backlight.level != 0;
+
+       return 0;
+}
+
+static int i965_setup_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       u32 ctl, ctl2, val;
+
+       ctl2 = I915_READ(BLC_PWM_CTL2);
+       panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
+       panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
+
+       ctl = I915_READ(BLC_PWM_CTL);
+       panel->backlight.max = ctl >> 16;
+       if (panel->backlight.combination_mode)
+               panel->backlight.max *= 0xff;
+
+       if (!panel->backlight.max)
+               return -ENODEV;
+
+       val = i9xx_get_backlight(connector);
+       panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+       panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
+               panel->backlight.level != 0;
+
+       return 0;
+}
+
+static int vlv_setup_backlight(struct intel_connector *connector)
+{
+       struct drm_device *dev = connector->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_panel *panel = &connector->panel;
+       enum pipe pipe;
+       u32 ctl, ctl2, val;
+
+       for_each_pipe(pipe) {
+               u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
+
+               /* Skip if the modulation freq is already set */
+               if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK)
+                       continue;
+
+               cur_val &= BACKLIGHT_DUTY_CYCLE_MASK;
+               I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) |
+                          cur_val);
        }
+
+       ctl2 = I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
+       panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
+
+       ctl = I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
+       panel->backlight.max = ctl >> 16;
+       if (!panel->backlight.max)
+               return -ENODEV;
+
+       val = _vlv_get_backlight(dev, PIPE_A);
+       panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+       panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
+               panel->backlight.level != 0;
+
+       return 0;
 }
-#else
+
 int intel_panel_setup_backlight(struct drm_connector *connector)
 {
-       intel_panel_init_backlight(connector->dev);
+       struct drm_device *dev = connector->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_connector *intel_connector = to_intel_connector(connector);
+       struct intel_panel *panel = &intel_connector->panel;
+       unsigned long flags;
+       int ret;
+
+       /* set level and max in panel struct */
+       spin_lock_irqsave(&dev_priv->backlight_lock, flags);
+       ret = dev_priv->display.setup_backlight(intel_connector);
+       spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
+
+       if (ret) {
+               DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
+                             drm_get_connector_name(connector));
+               return ret;
+       }
+
+       intel_backlight_device_register(intel_connector);
+
+       panel->backlight.present = true;
+
+       DRM_DEBUG_KMS("backlight initialized, %s, brightness %u/%u, "
+                     "sysfs interface %sregistered\n",
+                     panel->backlight.enabled ? "enabled" : "disabled",
+                     panel->backlight.level, panel->backlight.max,
+                     panel->backlight.device ? "" : "not ");
+
        return 0;
 }
 
-void intel_panel_destroy_backlight(struct drm_device *dev)
+void intel_panel_destroy_backlight(struct drm_connector *connector)
 {
-       return;
+       struct intel_connector *intel_connector = to_intel_connector(connector);
+       struct intel_panel *panel = &intel_connector->panel;
+
+       panel->backlight.present = false;
+       intel_backlight_device_unregister(intel_connector);
+}
+
+/* Set up chip specific backlight functions */
+void intel_panel_init_backlight_funcs(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       if (IS_BROADWELL(dev)) {
+               dev_priv->display.setup_backlight = bdw_setup_backlight;
+               dev_priv->display.enable_backlight = bdw_enable_backlight;
+               dev_priv->display.disable_backlight = pch_disable_backlight;
+               dev_priv->display.set_backlight = bdw_set_backlight;
+               dev_priv->display.get_backlight = bdw_get_backlight;
+       } else if (HAS_PCH_SPLIT(dev)) {
+               dev_priv->display.setup_backlight = pch_setup_backlight;
+               dev_priv->display.enable_backlight = pch_enable_backlight;
+               dev_priv->display.disable_backlight = pch_disable_backlight;
+               dev_priv->display.set_backlight = pch_set_backlight;
+               dev_priv->display.get_backlight = pch_get_backlight;
+       } else if (IS_VALLEYVIEW(dev)) {
+               dev_priv->display.setup_backlight = vlv_setup_backlight;
+               dev_priv->display.enable_backlight = vlv_enable_backlight;
+               dev_priv->display.disable_backlight = vlv_disable_backlight;
+               dev_priv->display.set_backlight = vlv_set_backlight;
+               dev_priv->display.get_backlight = vlv_get_backlight;
+       } else if (IS_GEN4(dev)) {
+               dev_priv->display.setup_backlight = i965_setup_backlight;
+               dev_priv->display.enable_backlight = i965_enable_backlight;
+               dev_priv->display.disable_backlight = i965_disable_backlight;
+               dev_priv->display.set_backlight = i9xx_set_backlight;
+               dev_priv->display.get_backlight = i9xx_get_backlight;
+       } else {
+               dev_priv->display.setup_backlight = i9xx_setup_backlight;
+               dev_priv->display.enable_backlight = i9xx_enable_backlight;
+               dev_priv->display.disable_backlight = i9xx_disable_backlight;
+               dev_priv->display.set_backlight = i9xx_set_backlight;
+               dev_priv->display.get_backlight = i9xx_get_backlight;
+       }
 }
-#endif
 
 int intel_panel_init(struct intel_panel *panel,
                     struct drm_display_mode *fixed_mode)
index caf2ee4e5441426527234453dbb43ed4c4c7273f..e6d98fe86b17174fd79bb86dbd242e14992534a0 100644 (file)
@@ -191,7 +191,11 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)
        u32 blt_ecoskpd;
 
        /* Make sure blitter notifies FBC of writes */
-       gen6_gt_force_wake_get(dev_priv);
+
+       /* Blitter is part of Media powerwell on VLV. No impact of
+        * his param in other platforms for now */
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_MEDIA);
+
        blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
        blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
                GEN6_BLITTER_LOCK_SHIFT;
@@ -202,7 +206,8 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)
                         GEN6_BLITTER_LOCK_SHIFT);
        I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
        POSTING_READ(GEN6_BLITTER_ECOSKPD);
-       gen6_gt_force_wake_put(dev_priv);
+
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_MEDIA);
 }
 
 static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
@@ -222,7 +227,9 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
        dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X);
        /* Set persistent mode for front-buffer rendering, ala X. */
        dpfc_ctl |= DPFC_CTL_PERSISTENT_MODE;
-       dpfc_ctl |= (DPFC_CTL_FENCE_EN | obj->fence_reg);
+       dpfc_ctl |= DPFC_CTL_FENCE_EN;
+       if (IS_GEN5(dev))
+               dpfc_ctl |= obj->fence_reg;
        I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY);
 
        I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN |
@@ -295,7 +302,7 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
 
        sandybridge_blit_fbc_update(dev);
 
-       DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
+       DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane));
 }
 
 bool intel_fbc_enabled(struct drm_device *dev)
@@ -1180,7 +1187,7 @@ static bool g4x_compute_wm0(struct drm_device *dev,
 
        adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
        clock = adjusted_mode->crtc_clock;
-       htotal = adjusted_mode->htotal;
+       htotal = adjusted_mode->crtc_htotal;
        hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
        pixel_size = crtc->fb->bits_per_pixel / 8;
 
@@ -1267,7 +1274,7 @@ static bool g4x_compute_srwm(struct drm_device *dev,
        crtc = intel_get_crtc_for_plane(dev, plane);
        adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
        clock = adjusted_mode->crtc_clock;
-       htotal = adjusted_mode->htotal;
+       htotal = adjusted_mode->crtc_htotal;
        hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
        pixel_size = crtc->fb->bits_per_pixel / 8;
 
@@ -1498,7 +1505,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
                const struct drm_display_mode *adjusted_mode =
                        &to_intel_crtc(crtc)->config.adjusted_mode;
                int clock = adjusted_mode->crtc_clock;
-               int htotal = adjusted_mode->htotal;
+               int htotal = adjusted_mode->crtc_htotal;
                int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
                int pixel_size = crtc->fb->bits_per_pixel / 8;
                unsigned long line_time_us;
@@ -1624,7 +1631,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
                const struct drm_display_mode *adjusted_mode =
                        &to_intel_crtc(enabled)->config.adjusted_mode;
                int clock = adjusted_mode->crtc_clock;
-               int htotal = adjusted_mode->htotal;
+               int htotal = adjusted_mode->crtc_htotal;
                int hdisplay = to_intel_crtc(enabled)->config.pipe_src_w;
                int pixel_size = enabled->fb->bits_per_pixel / 8;
                unsigned long line_time_us;
@@ -1776,7 +1783,7 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane,
        crtc = intel_get_crtc_for_plane(dev, plane);
        adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
        clock = adjusted_mode->crtc_clock;
-       htotal = adjusted_mode->htotal;
+       htotal = adjusted_mode->crtc_htotal;
        hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
        pixel_size = crtc->fb->bits_per_pixel / 8;
 
@@ -2469,8 +2476,9 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
        /* The WM are computed with base on how long it takes to fill a single
         * row at the given clock rate, multiplied by 8.
         * */
-       linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8, mode->clock);
-       ips_linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8,
+       linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8,
+                                    mode->crtc_clock);
+       ips_linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8,
                                         intel_ddi_get_cdclk_freq(dev_priv));
 
        return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) |
@@ -3429,26 +3437,19 @@ static void ironlake_disable_drps(struct drm_device *dev)
  * ourselves, instead of doing a rmw cycle (which might result in us clearing
  * all limits and the gpu stuck at whatever frequency it is at atm).
  */
-static u32 gen6_rps_limits(struct drm_i915_private *dev_priv, u8 *val)
+static u32 gen6_rps_limits(struct drm_i915_private *dev_priv, u8 val)
 {
        u32 limits;
 
-       limits = 0;
-
-       if (*val >= dev_priv->rps.max_delay)
-               *val = dev_priv->rps.max_delay;
-       limits |= dev_priv->rps.max_delay << 24;
-
        /* Only set the down limit when we've reached the lowest level to avoid
         * getting more interrupts, otherwise leave this clear. This prevents a
         * race in the hw when coming out of rc6: There's a tiny window where
         * the hw runs at the minimal clock before selecting the desired
         * frequency, if the down threshold expires in that window we will not
         * receive a down interrupt. */
-       if (*val <= dev_priv->rps.min_delay) {
-               *val = dev_priv->rps.min_delay;
+       limits = dev_priv->rps.max_delay << 24;
+       if (val <= dev_priv->rps.min_delay)
                limits |= dev_priv->rps.min_delay << 16;
-       }
 
        return limits;
 }
@@ -3548,7 +3549,6 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 void gen6_set_rps(struct drm_device *dev, u8 val)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 limits = gen6_rps_limits(dev_priv, &val);
 
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
        WARN_ON(val > dev_priv->rps.max_delay);
@@ -3571,7 +3571,8 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
        /* Make sure we continue to get interrupts
         * until we hit the minimum or maximum frequencies.
         */
-       I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
+       I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
+                  gen6_rps_limits(dev_priv, val));
 
        POSTING_READ(GEN6_RPNSWREQ);
 
@@ -3606,48 +3607,18 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv)
        mutex_unlock(&dev_priv->rps.hw_lock);
 }
 
-/*
- * Wait until the previous freq change has completed,
- * or the timeout elapsed, and then update our notion
- * of the current GPU frequency.
- */
-static void vlv_update_rps_cur_delay(struct drm_i915_private *dev_priv)
-{
-       u32 pval;
-
-       WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
-
-       if (wait_for(((pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS)) & GENFREQSTATUS) == 0, 10))
-               DRM_DEBUG_DRIVER("timed out waiting for Punit\n");
-
-       pval >>= 8;
-
-       if (pval != dev_priv->rps.cur_delay)
-               DRM_DEBUG_DRIVER("Punit overrode GPU freq: %d MHz (%u) requested, but got %d Mhz (%u)\n",
-                                vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.cur_delay),
-                                dev_priv->rps.cur_delay,
-                                vlv_gpu_freq(dev_priv->mem_freq, pval), pval);
-
-       dev_priv->rps.cur_delay = pval;
-}
-
 void valleyview_set_rps(struct drm_device *dev, u8 val)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       gen6_rps_limits(dev_priv, &val);
-
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
        WARN_ON(val > dev_priv->rps.max_delay);
        WARN_ON(val < dev_priv->rps.min_delay);
 
-       vlv_update_rps_cur_delay(dev_priv);
-
        DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n",
-                        vlv_gpu_freq(dev_priv->mem_freq,
-                                     dev_priv->rps.cur_delay),
+                        vlv_gpu_freq(dev_priv, dev_priv->rps.cur_delay),
                         dev_priv->rps.cur_delay,
-                        vlv_gpu_freq(dev_priv->mem_freq, val), val);
+                        vlv_gpu_freq(dev_priv, val), val);
 
        if (val == dev_priv->rps.cur_delay)
                return;
@@ -3656,7 +3627,7 @@ void valleyview_set_rps(struct drm_device *dev, u8 val)
 
        dev_priv->rps.cur_delay = val;
 
-       trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv->mem_freq, val));
+       trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv, val));
 }
 
 static void gen6_disable_rps_interrupts(struct drm_device *dev)
@@ -3774,7 +3745,7 @@ static void gen8_enable_rps(struct drm_device *dev)
 
        /* 1c & 1d: Get forcewake during program sequence. Although the driver
         * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
-       gen6_gt_force_wake_get(dev_priv);
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
        /* 2a: Disable RC states. */
        I915_WRITE(GEN6_RC_CONTROL, 0);
@@ -3831,7 +3802,7 @@ static void gen8_enable_rps(struct drm_device *dev)
 
        gen6_enable_rps_interrupts(dev);
 
-       gen6_gt_force_wake_put(dev_priv);
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 static void gen6_enable_rps(struct drm_device *dev)
@@ -3861,7 +3832,7 @@ static void gen6_enable_rps(struct drm_device *dev)
                I915_WRITE(GTFIFODBG, gtfifodbg);
        }
 
-       gen6_gt_force_wake_get(dev_priv);
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
        rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
        gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
@@ -3953,7 +3924,7 @@ static void gen6_enable_rps(struct drm_device *dev)
                        DRM_ERROR("Couldn't fix incorrect rc6 voltage\n");
        }
 
-       gen6_gt_force_wake_put(dev_priv);
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 void gen6_update_ring_freq(struct drm_device *dev)
@@ -4115,7 +4086,8 @@ static void valleyview_enable_rps(struct drm_device *dev)
 
        valleyview_setup_pctx(dev);
 
-       gen6_gt_force_wake_get(dev_priv);
+       /* If VLV, Forcewake all wells, else re-direct to regular path */
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
        I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
        I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
@@ -4139,7 +4111,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
        for_each_ring(ring, dev_priv, i)
                I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
 
-       I915_WRITE(GEN6_RC6_THRESHOLD, 0xc350);
+       I915_WRITE(GEN6_RC6_THRESHOLD, 0x557);
 
        /* allows RC6 residency counter to work */
        I915_WRITE(VLV_COUNTER_CONTROL,
@@ -4147,65 +4119,47 @@ static void valleyview_enable_rps(struct drm_device *dev)
                                      VLV_MEDIA_RC6_COUNT_EN |
                                      VLV_RENDER_RC6_COUNT_EN));
        if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
-               rc6_mode = GEN7_RC_CTL_TO_MODE;
+               rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
 
        intel_print_rc6_info(dev, rc6_mode);
 
        I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
 
        val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
-       switch ((val >> 6) & 3) {
-       case 0:
-       case 1:
-               dev_priv->mem_freq = 800;
-               break;
-       case 2:
-               dev_priv->mem_freq = 1066;
-               break;
-       case 3:
-               dev_priv->mem_freq = 1333;
-               break;
-       }
-       DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq);
 
        DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & 0x10 ? "yes" : "no");
        DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
 
        dev_priv->rps.cur_delay = (val >> 8) & 0xff;
        DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n",
-                        vlv_gpu_freq(dev_priv->mem_freq,
-                                     dev_priv->rps.cur_delay),
+                        vlv_gpu_freq(dev_priv, dev_priv->rps.cur_delay),
                         dev_priv->rps.cur_delay);
 
        dev_priv->rps.max_delay = valleyview_rps_max_freq(dev_priv);
        dev_priv->rps.hw_max = dev_priv->rps.max_delay;
        DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
-                        vlv_gpu_freq(dev_priv->mem_freq,
-                                     dev_priv->rps.max_delay),
+                        vlv_gpu_freq(dev_priv, dev_priv->rps.max_delay),
                         dev_priv->rps.max_delay);
 
        dev_priv->rps.rpe_delay = valleyview_rps_rpe_freq(dev_priv);
        DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
-                        vlv_gpu_freq(dev_priv->mem_freq,
-                                     dev_priv->rps.rpe_delay),
+                        vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
                         dev_priv->rps.rpe_delay);
 
        dev_priv->rps.min_delay = valleyview_rps_min_freq(dev_priv);
        DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
-                        vlv_gpu_freq(dev_priv->mem_freq,
-                                     dev_priv->rps.min_delay),
+                        vlv_gpu_freq(dev_priv, dev_priv->rps.min_delay),
                         dev_priv->rps.min_delay);
 
        DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
-                        vlv_gpu_freq(dev_priv->mem_freq,
-                                     dev_priv->rps.rpe_delay),
+                        vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
                         dev_priv->rps.rpe_delay);
 
        valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
 
        gen6_enable_rps_interrupts(dev);
 
-       gen6_gt_force_wake_put(dev_priv);
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 void ironlake_teardown_rc6(struct drm_device *dev)
@@ -5462,6 +5416,26 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
 static void valleyview_init_clock_gating(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 val;
+
+       mutex_lock(&dev_priv->rps.hw_lock);
+       val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+       mutex_unlock(&dev_priv->rps.hw_lock);
+       switch ((val >> 6) & 3) {
+       case 0:
+               dev_priv->mem_freq = 800;
+               break;
+       case 1:
+               dev_priv->mem_freq = 1066;
+               break;
+       case 2:
+               dev_priv->mem_freq = 1333;
+               break;
+       case 3:
+               dev_priv->mem_freq = 1333;
+               break;
+       }
+       DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq);
 
        I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
 
@@ -5641,49 +5615,78 @@ void intel_suspend_hw(struct drm_device *dev)
                lpt_suspend_hw(dev);
 }
 
-static bool is_always_on_power_domain(struct drm_device *dev,
-                                     enum intel_display_power_domain domain)
-{
-       unsigned long always_on_domains;
-
-       BUG_ON(BIT(domain) & ~POWER_DOMAIN_MASK);
+#define for_each_power_well(i, power_well, domain_mask, power_domains) \
+       for (i = 0;                                                     \
+            i < (power_domains)->power_well_count &&                   \
+                ((power_well) = &(power_domains)->power_wells[i]);     \
+            i++)                                                       \
+               if ((power_well)->domains & (domain_mask))
 
-       if (IS_BROADWELL(dev)) {
-               always_on_domains = BDW_ALWAYS_ON_POWER_DOMAINS;
-       } else if (IS_HASWELL(dev)) {
-               always_on_domains = HSW_ALWAYS_ON_POWER_DOMAINS;
-       } else {
-               WARN_ON(1);
-               return true;
-       }
-
-       return BIT(domain) & always_on_domains;
-}
+#define for_each_power_well_rev(i, power_well, domain_mask, power_domains) \
+       for (i = (power_domains)->power_well_count - 1;                  \
+            i >= 0 && ((power_well) = &(power_domains)->power_wells[i]);\
+            i--)                                                        \
+               if ((power_well)->domains & (domain_mask))
 
 /**
  * We should only use the power well if we explicitly asked the hardware to
  * enable it, so check if it's enabled and also check if we've requested it to
  * be enabled.
  */
+static bool hsw_power_well_enabled(struct drm_device *dev,
+                                  struct i915_power_well *power_well)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       return I915_READ(HSW_PWR_WELL_DRIVER) ==
+                    (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
+}
+
+bool intel_display_power_enabled_sw(struct drm_device *dev,
+                                   enum intel_display_power_domain domain)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct i915_power_domains *power_domains;
+
+       power_domains = &dev_priv->power_domains;
+
+       return power_domains->domain_use_count[domain];
+}
+
 bool intel_display_power_enabled(struct drm_device *dev,
                                 enum intel_display_power_domain domain)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct i915_power_domains *power_domains;
+       struct i915_power_well *power_well;
+       bool is_enabled;
+       int i;
 
-       if (!HAS_POWER_WELL(dev))
-               return true;
+       power_domains = &dev_priv->power_domains;
 
-       if (is_always_on_power_domain(dev, domain))
-               return true;
+       is_enabled = true;
 
-       return I915_READ(HSW_PWR_WELL_DRIVER) ==
-                    (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
+       mutex_lock(&power_domains->lock);
+       for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
+               if (power_well->always_on)
+                       continue;
+
+               if (!power_well->is_enabled(dev, power_well)) {
+                       is_enabled = false;
+                       break;
+               }
+       }
+       mutex_unlock(&power_domains->lock);
+
+       return is_enabled;
 }
 
-static void __intel_set_power_well(struct drm_device *dev, bool enable)
+static void hsw_set_power_well(struct drm_device *dev,
+                              struct i915_power_well *power_well, bool enable)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        bool is_enabled, enable_requested;
+       unsigned long irqflags;
        uint32_t tmp;
 
        tmp = I915_READ(HSW_PWR_WELL_DRIVER);
@@ -5701,9 +5704,24 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
                                      HSW_PWR_WELL_STATE_ENABLED), 20))
                                DRM_ERROR("Timeout enabling power well\n");
                }
+
+               if (IS_BROADWELL(dev)) {
+                       spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+                       I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_B),
+                                  dev_priv->de_irq_mask[PIPE_B]);
+                       I915_WRITE(GEN8_DE_PIPE_IER(PIPE_B),
+                                  ~dev_priv->de_irq_mask[PIPE_B] |
+                                  GEN8_PIPE_VBLANK);
+                       I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_C),
+                                  dev_priv->de_irq_mask[PIPE_C]);
+                       I915_WRITE(GEN8_DE_PIPE_IER(PIPE_C),
+                                  ~dev_priv->de_irq_mask[PIPE_C] |
+                                  GEN8_PIPE_VBLANK);
+                       POSTING_READ(GEN8_DE_PIPE_IER(PIPE_C));
+                       spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+               }
        } else {
                if (enable_requested) {
-                       unsigned long irqflags;
                        enum pipe p;
 
                        I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
@@ -5730,16 +5748,17 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
 static void __intel_power_well_get(struct drm_device *dev,
                                   struct i915_power_well *power_well)
 {
-       if (!power_well->count++)
-               __intel_set_power_well(dev, true);
+       if (!power_well->count++ && power_well->set)
+               power_well->set(dev, power_well, true);
 }
 
 static void __intel_power_well_put(struct drm_device *dev,
                                   struct i915_power_well *power_well)
 {
        WARN_ON(!power_well->count);
-       if (!--power_well->count && i915_disable_power_well)
-               __intel_set_power_well(dev, false);
+
+       if (!--power_well->count && power_well->set && i915_disable_power_well)
+               power_well->set(dev, power_well, false);
 }
 
 void intel_display_power_get(struct drm_device *dev,
@@ -5747,17 +5766,18 @@ void intel_display_power_get(struct drm_device *dev,
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains;
-
-       if (!HAS_POWER_WELL(dev))
-               return;
-
-       if (is_always_on_power_domain(dev, domain))
-               return;
+       struct i915_power_well *power_well;
+       int i;
 
        power_domains = &dev_priv->power_domains;
 
        mutex_lock(&power_domains->lock);
-       __intel_power_well_get(dev, &power_domains->power_wells[0]);
+
+       for_each_power_well(i, power_well, BIT(domain), power_domains)
+               __intel_power_well_get(dev, power_well);
+
+       power_domains->domain_use_count[domain]++;
+
        mutex_unlock(&power_domains->lock);
 }
 
@@ -5766,17 +5786,19 @@ void intel_display_power_put(struct drm_device *dev,
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains;
-
-       if (!HAS_POWER_WELL(dev))
-               return;
-
-       if (is_always_on_power_domain(dev, domain))
-               return;
+       struct i915_power_well *power_well;
+       int i;
 
        power_domains = &dev_priv->power_domains;
 
        mutex_lock(&power_domains->lock);
-       __intel_power_well_put(dev, &power_domains->power_wells[0]);
+
+       WARN_ON(!power_domains->domain_use_count[domain]);
+       power_domains->domain_use_count[domain]--;
+
+       for_each_power_well_rev(i, power_well, BIT(domain), power_domains)
+               __intel_power_well_put(dev, power_well);
+
        mutex_unlock(&power_domains->lock);
 }
 
@@ -5792,10 +5814,7 @@ void i915_request_power_well(void)
 
        dev_priv = container_of(hsw_pwr, struct drm_i915_private,
                                power_domains);
-
-       mutex_lock(&hsw_pwr->lock);
-       __intel_power_well_get(dev_priv->dev, &hsw_pwr->power_wells[0]);
-       mutex_unlock(&hsw_pwr->lock);
+       intel_display_power_get(dev_priv->dev, POWER_DOMAIN_AUDIO);
 }
 EXPORT_SYMBOL_GPL(i915_request_power_well);
 
@@ -5809,24 +5828,71 @@ void i915_release_power_well(void)
 
        dev_priv = container_of(hsw_pwr, struct drm_i915_private,
                                power_domains);
-
-       mutex_lock(&hsw_pwr->lock);
-       __intel_power_well_put(dev_priv->dev, &hsw_pwr->power_wells[0]);
-       mutex_unlock(&hsw_pwr->lock);
+       intel_display_power_put(dev_priv->dev, POWER_DOMAIN_AUDIO);
 }
 EXPORT_SYMBOL_GPL(i915_release_power_well);
 
+static struct i915_power_well i9xx_always_on_power_well[] = {
+       {
+               .name = "always-on",
+               .always_on = 1,
+               .domains = POWER_DOMAIN_MASK,
+       },
+};
+
+static struct i915_power_well hsw_power_wells[] = {
+       {
+               .name = "always-on",
+               .always_on = 1,
+               .domains = HSW_ALWAYS_ON_POWER_DOMAINS,
+       },
+       {
+               .name = "display",
+               .domains = POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS,
+               .is_enabled = hsw_power_well_enabled,
+               .set = hsw_set_power_well,
+       },
+};
+
+static struct i915_power_well bdw_power_wells[] = {
+       {
+               .name = "always-on",
+               .always_on = 1,
+               .domains = BDW_ALWAYS_ON_POWER_DOMAINS,
+       },
+       {
+               .name = "display",
+               .domains = POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS,
+               .is_enabled = hsw_power_well_enabled,
+               .set = hsw_set_power_well,
+       },
+};
+
+#define set_power_wells(power_domains, __power_wells) ({               \
+       (power_domains)->power_wells = (__power_wells);                 \
+       (power_domains)->power_well_count = ARRAY_SIZE(__power_wells);  \
+})
+
 int intel_power_domains_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains = &dev_priv->power_domains;
-       struct i915_power_well *power_well;
 
        mutex_init(&power_domains->lock);
-       hsw_pwr = power_domains;
 
-       power_well = &power_domains->power_wells[0];
-       power_well->count = 0;
+       /*
+        * The enabling order will be from lower to higher indexed wells,
+        * the disabling order is reversed.
+        */
+       if (IS_HASWELL(dev)) {
+               set_power_wells(power_domains, hsw_power_wells);
+               hsw_pwr = power_domains;
+       } else if (IS_BROADWELL(dev)) {
+               set_power_wells(power_domains, bdw_power_wells);
+               hsw_pwr = power_domains;
+       } else {
+               set_power_wells(power_domains, i9xx_always_on_power_well);
+       }
 
        return 0;
 }
@@ -5841,15 +5907,13 @@ static void intel_power_domains_resume(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains = &dev_priv->power_domains;
        struct i915_power_well *power_well;
-
-       if (!HAS_POWER_WELL(dev))
-               return;
+       int i;
 
        mutex_lock(&power_domains->lock);
-
-       power_well = &power_domains->power_wells[0];
-       __intel_set_power_well(dev, power_well->count > 0);
-
+       for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
+               if (power_well->set)
+                       power_well->set(dev, power_well, power_well->count > 0);
+       }
        mutex_unlock(&power_domains->lock);
 }
 
@@ -5863,13 +5927,13 @@ void intel_power_domains_init_hw(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (!HAS_POWER_WELL(dev))
-               return;
-
        /* For now, we need the power well to be always enabled. */
        intel_display_set_init_power(dev, true);
        intel_power_domains_resume(dev);
 
+       if (!(IS_HASWELL(dev) || IS_BROADWELL(dev)))
+               return;
+
        /* We're taking over the BIOS, so clear any requests made by it since
         * the driver is in charge now. */
        if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST)
@@ -6074,59 +6138,48 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val)
        return 0;
 }
 
-int vlv_gpu_freq(int ddr_freq, int val)
+int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)
 {
-       int mult, base;
+       int div;
 
-       switch (ddr_freq) {
+       /* 4 x czclk */
+       switch (dev_priv->mem_freq) {
        case 800:
-               mult = 20;
-               base = 120;
+               div = 10;
                break;
        case 1066:
-               mult = 22;
-               base = 133;
+               div = 12;
                break;
        case 1333:
-               mult = 21;
-               base = 125;
+               div = 16;
                break;
        default:
                return -1;
        }
 
-       return ((val - 0xbd) * mult) + base;
+       return DIV_ROUND_CLOSEST(dev_priv->mem_freq * (val + 6 - 0xbd), 4 * div);
 }
 
-int vlv_freq_opcode(int ddr_freq, int val)
+int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val)
 {
-       int mult, base;
+       int mul;
 
-       switch (ddr_freq) {
+       /* 4 x czclk */
+       switch (dev_priv->mem_freq) {
        case 800:
-               mult = 20;
-               base = 120;
+               mul = 10;
                break;
        case 1066:
-               mult = 22;
-               base = 133;
+               mul = 12;
                break;
        case 1333:
-               mult = 21;
-               base = 125;
+               mul = 16;
                break;
        default:
                return -1;
        }
 
-       val /= mult;
-       val -= base / mult;
-       val += 0xbd;
-
-       if (val > 0xea)
-               val = 0xea;
-
-       return val;
+       return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv->mem_freq) + 0xbd - 6;
 }
 
 void intel_pm_init(struct drm_device *dev)
index b620337e6d672c164448090016a27d1b713a2a24..e05a0216cd9b19755a34f711051b8b9c35459b8a 100644 (file)
@@ -285,14 +285,16 @@ static int gen7_ring_fbc_flush(struct intel_ring_buffer *ring, u32 value)
        if (!ring->fbc_dirty)
                return 0;
 
-       ret = intel_ring_begin(ring, 4);
+       ret = intel_ring_begin(ring, 6);
        if (ret)
                return ret;
-       intel_ring_emit(ring, MI_NOOP);
        /* WaFbcNukeOn3DBlt:ivb/hsw */
        intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
        intel_ring_emit(ring, MSG_FBC_REND_STATE);
        intel_ring_emit(ring, value);
+       intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1) | MI_SRM_LRM_GLOBAL_GTT);
+       intel_ring_emit(ring, MSG_FBC_REND_STATE);
+       intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
        intel_ring_advance(ring);
 
        ring->fbc_dirty = false;
@@ -354,7 +356,7 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring,
        intel_ring_emit(ring, 0);
        intel_ring_advance(ring);
 
-       if (flush_domains)
+       if (!invalidate_domains && flush_domains)
                return gen7_ring_fbc_flush(ring, FBC_REND_NUKE);
 
        return 0;
@@ -436,7 +438,7 @@ static int init_ring_common(struct intel_ring_buffer *ring)
        int ret = 0;
        u32 head;
 
-       gen6_gt_force_wake_get(dev_priv);
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
        if (I915_NEED_GFX_HWS(dev))
                intel_ring_setup_status_page(ring);
@@ -509,7 +511,7 @@ static int init_ring_common(struct intel_ring_buffer *ring)
        memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
 
 out:
-       gen6_gt_force_wake_put(dev_priv);
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 
        return ret;
 }
@@ -965,6 +967,7 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
        } else if (IS_GEN6(ring->dev)) {
                mmio = RING_HWS_PGA_GEN6(ring->mmio_base);
        } else {
+               /* XXX: gen8 returns to sanity */
                mmio = RING_HWS_PGA(ring->mmio_base);
        }
 
@@ -1029,11 +1032,6 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring)
        if (!dev->irq_enabled)
               return false;
 
-       /* It looks like we need to prevent the gt from suspending while waiting
-        * for an notifiy irq, otherwise irqs seem to get lost on at least the
-        * blt/bsd rings on ivb. */
-       gen6_gt_force_wake_get(dev_priv);
-
        spin_lock_irqsave(&dev_priv->irq_lock, flags);
        if (ring->irq_refcount++ == 0) {
                if (HAS_L3_DPF(dev) && ring->id == RCS)
@@ -1065,8 +1063,6 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring)
                ilk_disable_gt_irq(dev_priv, ring->irq_enable_mask);
        }
        spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
-
-       gen6_gt_force_wake_put(dev_priv);
 }
 
 static bool
@@ -1837,7 +1833,7 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring,
        }
        intel_ring_advance(ring);
 
-       if (IS_GEN7(dev) && flush)
+       if (IS_GEN7(dev) && !invalidate && flush)
                return gen7_ring_fbc_flush(ring, FBC_REND_CACHE_CLEAN);
 
        return 0;
index a583e8f718a7f0f4b87b4fe724336c73ad1a8198..2abeab09e8837aa4c5a695670e15f1b5b7499251 100644 (file)
@@ -413,23 +413,34 @@ static const struct _sdvo_cmd_name {
 static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd,
                                   const void *args, int args_len)
 {
-       int i;
+       int i, pos = 0;
+#define BUF_LEN 256
+       char buffer[BUF_LEN];
+
+#define BUF_PRINT(args...) \
+       pos += snprintf(buffer + pos, max_t(int, BUF_LEN - pos, 0), args)
+
 
-       DRM_DEBUG_KMS("%s: W: %02X ",
-                               SDVO_NAME(intel_sdvo), cmd);
-       for (i = 0; i < args_len; i++)
-               DRM_LOG_KMS("%02X ", ((u8 *)args)[i]);
-       for (; i < 8; i++)
-               DRM_LOG_KMS("   ");
+       for (i = 0; i < args_len; i++) {
+               BUF_PRINT("%02X ", ((u8 *)args)[i]);
+       }
+       for (; i < 8; i++) {
+               BUF_PRINT("   ");
+       }
        for (i = 0; i < ARRAY_SIZE(sdvo_cmd_names); i++) {
                if (cmd == sdvo_cmd_names[i].cmd) {
-                       DRM_LOG_KMS("(%s)", sdvo_cmd_names[i].name);
+                       BUF_PRINT("(%s)", sdvo_cmd_names[i].name);
                        break;
                }
        }
-       if (i == ARRAY_SIZE(sdvo_cmd_names))
-               DRM_LOG_KMS("(%02X)", cmd);
-       DRM_LOG_KMS("\n");
+       if (i == ARRAY_SIZE(sdvo_cmd_names)) {
+               BUF_PRINT("(%02X)", cmd);
+       }
+       BUG_ON(pos >= BUF_LEN - 1);
+#undef BUF_PRINT
+#undef BUF_LEN
+
+       DRM_DEBUG_KMS("%s: W: %02X %s\n", SDVO_NAME(intel_sdvo), cmd, buffer);
 }
 
 static const char *cmd_status_names[] = {
@@ -512,9 +523,10 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
 {
        u8 retry = 15; /* 5 quick checks, followed by 10 long checks */
        u8 status;
-       int i;
+       int i, pos = 0;
+#define BUF_LEN 256
+       char buffer[BUF_LEN];
 
-       DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo));
 
        /*
         * The documentation states that all commands will be
@@ -551,10 +563,13 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
                        goto log_fail;
        }
 
+#define BUF_PRINT(args...) \
+       pos += snprintf(buffer + pos, max_t(int, BUF_LEN - pos, 0), args)
+
        if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
-               DRM_LOG_KMS("(%s)", cmd_status_names[status]);
+               BUF_PRINT("(%s)", cmd_status_names[status]);
        else
-               DRM_LOG_KMS("(??? %d)", status);
+               BUF_PRINT("(??? %d)", status);
 
        if (status != SDVO_CMD_STATUS_SUCCESS)
                goto log_fail;
@@ -565,13 +580,17 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
                                          SDVO_I2C_RETURN_0 + i,
                                          &((u8 *)response)[i]))
                        goto log_fail;
-               DRM_LOG_KMS(" %02X", ((u8 *)response)[i]);
+               BUF_PRINT(" %02X", ((u8 *)response)[i]);
        }
-       DRM_LOG_KMS("\n");
+       BUG_ON(pos >= BUF_LEN - 1);
+#undef BUF_PRINT
+#undef BUF_LEN
+
+       DRM_DEBUG_KMS("%s: R: %s\n", SDVO_NAME(intel_sdvo), buffer);
        return true;
 
 log_fail:
-       DRM_LOG_KMS("... failed\n");
+       DRM_DEBUG_KMS("%s: R: ... failed\n", SDVO_NAME(intel_sdvo));
        return false;
 }
 
@@ -1517,8 +1536,9 @@ static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
        intel_modeset_check_state(connector->dev);
 }
 
-static int intel_sdvo_mode_valid(struct drm_connector *connector,
-                                struct drm_display_mode *mode)
+static enum drm_mode_status
+intel_sdvo_mode_valid(struct drm_connector *connector,
+                     struct drm_display_mode *mode)
 {
        struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
 
index 9944d8135e87f88215d5d07d54a5fd87fcf4dc60..cc6fbcde7d3d607f5b4adcb9f77e3cce29eee5ba 100644 (file)
@@ -90,6 +90,22 @@ void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
        mutex_unlock(&dev_priv->dpio_lock);
 }
 
+u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
+{
+       u32 val = 0;
+
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
+                       PUNIT_OPCODE_REG_READ, reg, &val);
+
+       return val;
+}
+
+void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
+{
+       vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
+                       PUNIT_OPCODE_REG_WRITE, reg, &val);
+}
+
 u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
 {
        u32 val = 0;
@@ -160,27 +176,18 @@ void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
                        PUNIT_OPCODE_REG_WRITE, reg, &val);
 }
 
-static u32 vlv_get_phy_port(enum pipe pipe)
-{
-       u32 port = IOSF_PORT_DPIO;
-
-       WARN_ON ((pipe != PIPE_A) && (pipe != PIPE_B));
-
-       return port;
-}
-
 u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg)
 {
        u32 val = 0;
 
-       vlv_sideband_rw(dev_priv, DPIO_DEVFN, vlv_get_phy_port(pipe),
+       vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)),
                        DPIO_OPCODE_REG_READ, reg, &val);
        return val;
 }
 
 void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val)
 {
-       vlv_sideband_rw(dev_priv, DPIO_DEVFN, vlv_get_phy_port(pipe),
+       vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)),
                        DPIO_OPCODE_REG_WRITE, reg, &val);
 }
 
index b9fabf826f7de71f224bd9b808780f81ba1c9027..90a3f6db8288752343d1215fca58c0d831a35e28 100644 (file)
@@ -104,6 +104,12 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
                break;
        }
 
+       /*
+        * Enable gamma to match primary/cursor plane behaviour.
+        * FIXME should be user controllable via propertiesa.
+        */
+       sprctl |= SP_GAMMA_ENABLE;
+
        if (obj->tiling_mode != I915_TILING_NONE)
                sprctl |= SP_TILED;
 
@@ -257,6 +263,12 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
                BUG();
        }
 
+       /*
+        * Enable gamma to match primary/cursor plane behaviour.
+        * FIXME should be user controllable via propertiesa.
+        */
+       sprctl |= SPRITE_GAMMA_ENABLE;
+
        if (obj->tiling_mode != I915_TILING_NONE)
                sprctl |= SPRITE_TILED;
 
@@ -453,6 +465,12 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
                BUG();
        }
 
+       /*
+        * Enable gamma to match primary/cursor plane behaviour.
+        * FIXME should be user controllable via propertiesa.
+        */
+       dvscntr |= DVS_GAMMA_ENABLE;
+
        if (obj->tiling_mode != I915_TILING_NONE)
                dvscntr |= DVS_TILED;
 
index 0b02078a0b848c4127385b1d3b5d3ab6be755c80..0db5472b4dcd24ed4097e04d2d03149881e0af48 100644 (file)
@@ -64,7 +64,8 @@ static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv)
        __raw_posting_read(dev_priv, ECOBUS);
 }
 
-static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
+static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
+                                                       int fw_engine)
 {
        if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0,
                            FORCEWAKE_ACK_TIMEOUT_MS))
@@ -89,7 +90,8 @@ static void __gen6_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
        __raw_posting_read(dev_priv, ECOBUS);
 }
 
-static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
+static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv,
+                                                       int fw_engine)
 {
        u32 forcewake_ack;
 
@@ -121,12 +123,12 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
        u32 gtfifodbg;
 
        gtfifodbg = __raw_i915_read32(dev_priv, GTFIFODBG);
-       if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK,
-            "MMIO read or write has been dropped %x\n", gtfifodbg))
-               __raw_i915_write32(dev_priv, GTFIFODBG, GT_FIFO_CPU_ERROR_MASK);
+       if (WARN(gtfifodbg, "GT wake FIFO error 0x%x\n", gtfifodbg))
+               __raw_i915_write32(dev_priv, GTFIFODBG, gtfifodbg);
 }
 
-static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
+static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
+                                                       int fw_engine)
 {
        __raw_i915_write32(dev_priv, FORCEWAKE, 0);
        /* something from same cacheline, but !FORCEWAKE */
@@ -134,7 +136,8 @@ static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
        gen6_gt_check_fifodbg(dev_priv);
 }
 
-static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
+static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv,
+                                                       int fw_engine)
 {
        __raw_i915_write32(dev_priv, FORCEWAKE_MT,
                           _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
@@ -149,10 +152,10 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 
        if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
                int loop = 500;
-               u32 fifo = __raw_i915_read32(dev_priv, GT_FIFO_FREE_ENTRIES);
+               u32 fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
                while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
                        udelay(10);
-                       fifo = __raw_i915_read32(dev_priv, GT_FIFO_FREE_ENTRIES);
+                       fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
                }
                if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
                        ++ret;
@@ -171,38 +174,112 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
        __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
 }
 
-static void vlv_force_wake_get(struct drm_i915_private *dev_priv)
+static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
+                                               int fw_engine)
 {
-       if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL) == 0,
-                           FORCEWAKE_ACK_TIMEOUT_MS))
-               DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
+       /* Check for Render Engine */
+       if (FORCEWAKE_RENDER & fw_engine) {
+               if (wait_for_atomic((__raw_i915_read32(dev_priv,
+                                               FORCEWAKE_ACK_VLV) &
+                                               FORCEWAKE_KERNEL) == 0,
+                                       FORCEWAKE_ACK_TIMEOUT_MS))
+                       DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
 
-       __raw_i915_write32(dev_priv, FORCEWAKE_VLV,
-                          _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-       __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
-                          _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+               __raw_i915_write32(dev_priv, FORCEWAKE_VLV,
+                                  _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
 
-       if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL),
-                           FORCEWAKE_ACK_TIMEOUT_MS))
-               DRM_ERROR("Timed out waiting for GT to ack forcewake request.\n");
+               if (wait_for_atomic((__raw_i915_read32(dev_priv,
+                                               FORCEWAKE_ACK_VLV) &
+                                               FORCEWAKE_KERNEL),
+                                       FORCEWAKE_ACK_TIMEOUT_MS))
+                       DRM_ERROR("Timed out: waiting for Render to ack.\n");
+       }
 
-       if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK_MEDIA_VLV) &
-                            FORCEWAKE_KERNEL),
-                           FORCEWAKE_ACK_TIMEOUT_MS))
-               DRM_ERROR("Timed out waiting for media to ack forcewake request.\n");
+       /* Check for Media Engine */
+       if (FORCEWAKE_MEDIA & fw_engine) {
+               if (wait_for_atomic((__raw_i915_read32(dev_priv,
+                                               FORCEWAKE_ACK_MEDIA_VLV) &
+                                               FORCEWAKE_KERNEL) == 0,
+                                       FORCEWAKE_ACK_TIMEOUT_MS))
+                       DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
+
+               __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
+                                  _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+               if (wait_for_atomic((__raw_i915_read32(dev_priv,
+                                               FORCEWAKE_ACK_MEDIA_VLV) &
+                                               FORCEWAKE_KERNEL),
+                                       FORCEWAKE_ACK_TIMEOUT_MS))
+                       DRM_ERROR("Timed out: waiting for media to ack.\n");
+       }
 
        /* WaRsForcewakeWaitTC0:vlv */
        __gen6_gt_wait_for_thread_c0(dev_priv);
+
 }
 
-static void vlv_force_wake_put(struct drm_i915_private *dev_priv)
+static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
+                                       int fw_engine)
 {
-       __raw_i915_write32(dev_priv, FORCEWAKE_VLV,
-                          _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-       __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
-                          _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+
+       /* Check for Render Engine */
+       if (FORCEWAKE_RENDER & fw_engine)
+               __raw_i915_write32(dev_priv, FORCEWAKE_VLV,
+                                       _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+
+
+       /* Check for Media Engine */
+       if (FORCEWAKE_MEDIA & fw_engine)
+               __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
+                               _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+
        /* The below doubles as a POSTING_READ */
        gen6_gt_check_fifodbg(dev_priv);
+
+}
+
+void vlv_force_wake_get(struct drm_i915_private *dev_priv,
+                                               int fw_engine)
+{
+       unsigned long irqflags;
+
+       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+       if (FORCEWAKE_RENDER & fw_engine) {
+               if (dev_priv->uncore.fw_rendercount++ == 0)
+                       dev_priv->uncore.funcs.force_wake_get(dev_priv,
+                                                       FORCEWAKE_RENDER);
+       }
+       if (FORCEWAKE_MEDIA & fw_engine) {
+               if (dev_priv->uncore.fw_mediacount++ == 0)
+                       dev_priv->uncore.funcs.force_wake_get(dev_priv,
+                                                       FORCEWAKE_MEDIA);
+       }
+
+       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
+void vlv_force_wake_put(struct drm_i915_private *dev_priv,
+                                               int fw_engine)
+{
+       unsigned long irqflags;
+
+       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+       if (FORCEWAKE_RENDER & fw_engine) {
+               WARN_ON(dev_priv->uncore.fw_rendercount == 0);
+               if (--dev_priv->uncore.fw_rendercount == 0)
+                       dev_priv->uncore.funcs.force_wake_put(dev_priv,
+                                                       FORCEWAKE_RENDER);
+       }
+
+       if (FORCEWAKE_MEDIA & fw_engine) {
+               WARN_ON(dev_priv->uncore.fw_mediacount == 0);
+               if (--dev_priv->uncore.fw_mediacount == 0)
+                       dev_priv->uncore.funcs.force_wake_put(dev_priv,
+                                                       FORCEWAKE_MEDIA);
+       }
+
+       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void gen6_force_wake_work(struct work_struct *work)
@@ -213,7 +290,7 @@ static void gen6_force_wake_work(struct work_struct *work)
 
        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
        if (--dev_priv->uncore.forcewake_count == 0)
-               dev_priv->uncore.funcs.force_wake_put(dev_priv);
+               dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
@@ -281,29 +358,38 @@ void intel_uncore_sanitize(struct drm_device *dev)
  * be called at the beginning of the sequence followed by a call to
  * gen6_gt_force_wake_put() at the end of the sequence.
  */
-void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
+void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 {
        unsigned long irqflags;
 
        if (!dev_priv->uncore.funcs.force_wake_get)
                return;
 
+       /* Redirect to VLV specific routine */
+       if (IS_VALLEYVIEW(dev_priv->dev))
+               return vlv_force_wake_get(dev_priv, fw_engine);
+
        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
        if (dev_priv->uncore.forcewake_count++ == 0)
-               dev_priv->uncore.funcs.force_wake_get(dev_priv);
+               dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL);
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 /*
  * see gen6_gt_force_wake_get()
  */
-void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
+void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 {
        unsigned long irqflags;
 
        if (!dev_priv->uncore.funcs.force_wake_put)
                return;
 
+       /* Redirect to VLV specific routine */
+       if (IS_VALLEYVIEW(dev_priv->dev))
+               return vlv_force_wake_put(dev_priv, fw_engine);
+
+
        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
        if (--dev_priv->uncore.forcewake_count == 0) {
                dev_priv->uncore.forcewake_count++;
@@ -379,16 +465,51 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
        REG_READ_HEADER(x); \
        if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
                if (dev_priv->uncore.forcewake_count == 0) \
-                       dev_priv->uncore.funcs.force_wake_get(dev_priv); \
+                       dev_priv->uncore.funcs.force_wake_get(dev_priv, \
+                                                       FORCEWAKE_ALL); \
                val = __raw_i915_read##x(dev_priv, reg); \
                if (dev_priv->uncore.forcewake_count == 0) \
-                       dev_priv->uncore.funcs.force_wake_put(dev_priv); \
+                       dev_priv->uncore.funcs.force_wake_put(dev_priv, \
+                                                       FORCEWAKE_ALL); \
+       } else { \
+               val = __raw_i915_read##x(dev_priv, reg); \
+       } \
+       REG_READ_FOOTER; \
+}
+
+#define __vlv_read(x) \
+static u##x \
+vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
+       unsigned fwengine = 0; \
+       unsigned *fwcount; \
+       REG_READ_HEADER(x); \
+       if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) {   \
+               fwengine = FORCEWAKE_RENDER;            \
+               fwcount = &dev_priv->uncore.fw_rendercount;    \
+       }                                               \
+       else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) {       \
+               fwengine = FORCEWAKE_MEDIA;             \
+               fwcount = &dev_priv->uncore.fw_mediacount;     \
+       }  \
+       if (fwengine != 0) {            \
+               if ((*fwcount)++ == 0) \
+                       (dev_priv)->uncore.funcs.force_wake_get(dev_priv, \
+                                                               fwengine); \
+               val = __raw_i915_read##x(dev_priv, reg); \
+               if (--(*fwcount) == 0) \
+                       (dev_priv)->uncore.funcs.force_wake_put(dev_priv, \
+                                                       fwengine); \
        } else { \
                val = __raw_i915_read##x(dev_priv, reg); \
        } \
        REG_READ_FOOTER; \
 }
 
+
+__vlv_read(8)
+__vlv_read(16)
+__vlv_read(32)
+__vlv_read(64)
 __gen6_read(8)
 __gen6_read(16)
 __gen6_read(32)
@@ -402,6 +523,7 @@ __gen4_read(16)
 __gen4_read(32)
 __gen4_read(64)
 
+#undef __vlv_read
 #undef __gen6_read
 #undef __gen5_read
 #undef __gen4_read
@@ -489,11 +611,13 @@ gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
        bool __needs_put = !is_gen8_shadowed(dev_priv, reg); \
        REG_WRITE_HEADER; \
        if (__needs_put) { \
-               dev_priv->uncore.funcs.force_wake_get(dev_priv); \
+               dev_priv->uncore.funcs.force_wake_get(dev_priv, \
+                                                       FORCEWAKE_ALL); \
        } \
        __raw_i915_write##x(dev_priv, reg, val); \
        if (__needs_put) { \
-               dev_priv->uncore.funcs.force_wake_put(dev_priv); \
+               dev_priv->uncore.funcs.force_wake_put(dev_priv, \
+                                                       FORCEWAKE_ALL); \
        } \
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
 }
@@ -534,8 +658,8 @@ void intel_uncore_init(struct drm_device *dev)
                          gen6_force_wake_work);
 
        if (IS_VALLEYVIEW(dev)) {
-               dev_priv->uncore.funcs.force_wake_get = vlv_force_wake_get;
-               dev_priv->uncore.funcs.force_wake_put = vlv_force_wake_put;
+               dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
+               dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
        } else if (IS_HASWELL(dev) || IS_GEN8(dev)) {
                dev_priv->uncore.funcs.force_wake_get = __gen6_gt_force_wake_mt_get;
                dev_priv->uncore.funcs.force_wake_put = __gen6_gt_force_wake_mt_put;
@@ -552,9 +676,9 @@ void intel_uncore_init(struct drm_device *dev)
                 * forcewake being disabled.
                 */
                mutex_lock(&dev->struct_mutex);
-               __gen6_gt_force_wake_mt_get(dev_priv);
+               __gen6_gt_force_wake_mt_get(dev_priv, FORCEWAKE_ALL);
                ecobus = __raw_i915_read32(dev_priv, ECOBUS);
-               __gen6_gt_force_wake_mt_put(dev_priv);
+               __gen6_gt_force_wake_mt_put(dev_priv, FORCEWAKE_ALL);
                mutex_unlock(&dev->struct_mutex);
 
                if (ecobus & FORCEWAKE_MT_ENABLE) {
@@ -601,10 +725,18 @@ void intel_uncore_init(struct drm_device *dev)
                        dev_priv->uncore.funcs.mmio_writel  = gen6_write32;
                        dev_priv->uncore.funcs.mmio_writeq  = gen6_write64;
                }
-               dev_priv->uncore.funcs.mmio_readb  = gen6_read8;
-               dev_priv->uncore.funcs.mmio_readw  = gen6_read16;
-               dev_priv->uncore.funcs.mmio_readl  = gen6_read32;
-               dev_priv->uncore.funcs.mmio_readq  = gen6_read64;
+
+               if (IS_VALLEYVIEW(dev)) {
+                       dev_priv->uncore.funcs.mmio_readb  = vlv_read8;
+                       dev_priv->uncore.funcs.mmio_readw  = vlv_read16;
+                       dev_priv->uncore.funcs.mmio_readl  = vlv_read32;
+                       dev_priv->uncore.funcs.mmio_readq  = vlv_read64;
+               } else {
+                       dev_priv->uncore.funcs.mmio_readb  = gen6_read8;
+                       dev_priv->uncore.funcs.mmio_readw  = gen6_read16;
+                       dev_priv->uncore.funcs.mmio_readl  = gen6_read32;
+                       dev_priv->uncore.funcs.mmio_readq  = gen6_read64;
+               }
                break;
        case 5:
                dev_priv->uncore.funcs.mmio_writeb  = gen5_write8;
@@ -687,6 +819,43 @@ int i915_reg_read_ioctl(struct drm_device *dev,
        return 0;
 }
 
+int i915_get_reset_stats_ioctl(struct drm_device *dev,
+                              void *data, struct drm_file *file)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_reset_stats *args = data;
+       struct i915_ctx_hang_stats *hs;
+       int ret;
+
+       if (args->flags || args->pad)
+               return -EINVAL;
+
+       if (args->ctx_id == DEFAULT_CONTEXT_ID && !capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
+       hs = i915_gem_context_get_hang_stats(dev, file, args->ctx_id);
+       if (IS_ERR(hs)) {
+               mutex_unlock(&dev->struct_mutex);
+               return PTR_ERR(hs);
+       }
+
+       if (capable(CAP_SYS_ADMIN))
+               args->reset_count = i915_reset_count(&dev_priv->gpu_error);
+       else
+               args->reset_count = 0;
+
+       args->batch_active = hs->batch_active;
+       args->batch_pending = hs->batch_pending;
+
+       mutex_unlock(&dev->struct_mutex);
+
+       return 0;
+}
+
 static int i965_reset_complete(struct drm_device *dev)
 {
        u8 gdrst;
@@ -770,12 +939,12 @@ static int gen6_do_reset(struct drm_device *dev)
 
        /* If reset with a user forcewake, try to restore, otherwise turn it off */
        if (dev_priv->uncore.forcewake_count)
-               dev_priv->uncore.funcs.force_wake_get(dev_priv);
+               dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL);
        else
-               dev_priv->uncore.funcs.force_wake_put(dev_priv);
+               dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
 
        /* Restore fifo count */
-       dev_priv->uncore.fifo_count = __raw_i915_read32(dev_priv, GT_FIFO_FREE_ENTRIES);
+       dev_priv->uncore.fifo_count = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
 
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
        return ret;
@@ -784,6 +953,7 @@ static int gen6_do_reset(struct drm_device *dev)
 int intel_gpu_reset(struct drm_device *dev)
 {
        switch (INTEL_INFO(dev)->gen) {
+       case 8:
        case 7:
        case 6: return gen6_do_reset(dev);
        case 5: return ironlake_do_reset(dev);
@@ -792,15 +962,6 @@ int intel_gpu_reset(struct drm_device *dev)
        }
 }
 
-void intel_uncore_clear_errors(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-
-       /* XXX needs spinlock around caller's grouping */
-       if (HAS_FPGA_DBG_UNCLAIMED(dev))
-               __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
-}
-
 void intel_uncore_check_errors(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
index 95c740454049ad1b4a4cf23c2bc63d7038c7a362..1f0b6d238cfaa01a4527e4b02ee0caf8229aa269 100644 (file)
@@ -1,15 +1,10 @@
 #include <linux/pci.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/video.h>
-#include <acpi/acpi.h>
 #include <linux/mxm-wmi.h>
-
 #include <linux/vga_switcheroo.h>
-
 #include <drm/drm_edid.h>
+#include <acpi/video.h>
 
 #include "nouveau_drm.h"
 #include "nouveau_acpi.h"
index 38a4db5bfe21f22b8713bff3ad20466c5f631411..4aff04fa483c5e82acf1c66b1e63833bc23391cf 100644 (file)
@@ -630,7 +630,6 @@ error:
        hwmon->hwmon = NULL;
        return ret;
 #else
-       hwmon->hwmon = NULL;
        return 0;
 #endif
 }
index 0109a9644cb29ef7a6e13ac76a90544effcefd20..821ab7b9409bb866c61d793c4e0ab9d63d73ec98 100644 (file)
@@ -92,6 +92,7 @@ qxl_release_free(struct qxl_device *qdev,
                                                - DRM_FILE_OFFSET);
                qxl_fence_remove_release(&bo->fence, release->id);
                qxl_bo_unref(&bo);
+               kfree(entry);
        }
        spin_lock(&qdev->release_idr_lock);
        idr_remove(&qdev->release_idr, release->id);
index 98a9074b306b640644f576e928d4e28701495bb4..77e9d07c55b6701cbdb0a55bcbc9b68954e5c0d7 100644 (file)
 #include <linux/acpi.h>
 #include <linux/slab.h>
 #include <linux/power_supply.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
+#include <linux/vga_switcheroo.h>
 #include <acpi/video.h>
-
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include "radeon.h"
 #include "radeon_acpi.h"
 #include "atom.h"
 
-#include <linux/vga_switcheroo.h>
-
 #define ACPI_AC_CLASS           "ac_adapter"
 
 extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev);
index 329fbb9b59766f82af6c744e4e85a6ee1dc88208..34e2d39d4ce814cb312de6eee14dae43179cb5c3 100644 (file)
@@ -460,6 +460,7 @@ config HID_MULTITOUCH
          - Stantum multitouch panels
          - Touch International Panels
          - Unitec Panels
+         - Wistron optical touch panels
          - XAT optical touch panels
          - Xiroku optical touch panels
          - Zytronic touch panels
index a42e6a394c5ec33d663f7a00eadd2b362c24763d..0e6a42d37eb6f374ef864f383fc23d15bf844736 100644 (file)
@@ -297,6 +297,9 @@ static int appleir_probe(struct hid_device *hid, const struct hid_device_id *id)
 
        appleir->hid = hid;
 
+       /* force input as some remotes bypass the input registration */
+       hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
+
        spin_lock_init(&appleir->lock);
        setup_timer(&appleir->key_up_timer,
                    key_up_tick, (unsigned long) appleir);
index 8c10f2742233e2f731aa7b798f49b178cee93279..253fe23ef7fe5332ea03f96449f312a69a6b80c0 100644 (file)
@@ -1723,6 +1723,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_MANTICORE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
@@ -1879,7 +1880,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
 
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO2, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
        { }
 };
index 76559629568c44dc2fd5b38c072faf446c063b17..f9304cb37154982da4de6774894c213bf412163f 100644 (file)
 #define USB_VENDOR_ID_KYE              0x0458
 #define USB_DEVICE_ID_KYE_ERGO_525V    0x0087
 #define USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE 0x0138
+#define USB_DEVICE_ID_GENIUS_MANTICORE 0x0153
 #define USB_DEVICE_ID_GENIUS_GX_IMPERATOR      0x4018
 #define USB_DEVICE_ID_KYE_GPEN_560     0x5003
 #define USB_DEVICE_ID_KYE_EASYPEN_I405X        0x5010
 #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN   0x0003
 
 #define USB_VENDOR_ID_NINTENDO         0x057e
-#define USB_VENDOR_ID_NINTENDO2                0x054c
 #define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306
 #define USB_DEVICE_ID_NINTENDO_WIIMOTE2        0x0330
 
 #define USB_DEVICE_ID_SUPER_DUAL_BOX_PRO 0x8802
 #define USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO 0x8804
 
+#define USB_VENDOR_ID_WISTRON          0x0fb8
+#define USB_DEVICE_ID_WISTRON_OPTICAL_TOUCH            0x1109
+
 #define USB_VENDOR_ID_X_TENSIONS               0x1ae7
 #define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE    0x9001
 
index 73845120295eba6f678679715c9ca3f97917a643..ecb5ca669e97615cb47cbb9d31381bf76e33f367 100644 (file)
@@ -341,6 +341,9 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
        case USB_DEVICE_ID_GENIUS_GX_IMPERATOR:
                rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 83,
                                        "Genius Gx Imperator Keyboard");
+       case USB_DEVICE_ID_GENIUS_MANTICORE:
+               rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 104,
+                                       "Genius Manticore Keyboard");
                break;
        }
        return rdesc;
@@ -418,6 +421,14 @@ static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id)
                        goto enabling_err;
                }
                break;
+       case USB_DEVICE_ID_GENIUS_MANTICORE:
+               /*
+                * The manticore keyboard needs to have all the interfaces
+                * opened at least once to be fully functional.
+                */
+               if (hid_hw_open(hdev))
+                       hid_hw_close(hdev);
+               break;
        }
 
        return 0;
@@ -439,6 +450,8 @@ static const struct hid_device_id kye_devices[] = {
                                USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
                                USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
+                               USB_DEVICE_ID_GENIUS_MANTICORE) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, kye_devices);
index a2cedb8ae1c0cf57c98e185e7b285d7555834b1a..d83b1e8b505b512769d8c5955eb8a0b8ca4e5b23 100644 (file)
@@ -1335,6 +1335,12 @@ static const struct hid_device_id mt_devices[] = {
        { .driver_data = MT_CLS_NSMU,
                MT_USB_DEVICE(USB_VENDOR_ID_UNITEC,
                        USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
+
+       /* Wistron panels */
+       { .driver_data = MT_CLS_NSMU,
+               MT_USB_DEVICE(USB_VENDOR_ID_WISTRON,
+                       USB_DEVICE_ID_WISTRON_OPTICAL_TOUCH) },
+
        /* XAT */
        { .driver_data = MT_CLS_NSMU,
                MT_USB_DEVICE(USB_VENDOR_ID_XAT,
index da551d11376257a328419e22ad7cd487784bea51..b60bc38903db39f885c4a1d7a680790540edef47 100644 (file)
 
 #include "hid-ids.h"
 
-#define VAIO_RDESC_CONSTANT     (1 << 0)
-#define SIXAXIS_CONTROLLER_USB  (1 << 1)
-#define SIXAXIS_CONTROLLER_BT   (1 << 2)
-#define BUZZ_CONTROLLER         (1 << 3)
-#define PS3REMOTE              (1 << 4)
+#define VAIO_RDESC_CONSTANT     BIT(0)
+#define SIXAXIS_CONTROLLER_USB  BIT(1)
+#define SIXAXIS_CONTROLLER_BT   BIT(2)
+#define BUZZ_CONTROLLER         BIT(3)
+#define PS3REMOTE              BIT(4)
+
+#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER)
 
 static const u8 sixaxis_rdesc_fixup[] = {
        0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
@@ -223,14 +225,17 @@ static const unsigned int buzz_keymap[] = {
 };
 
 struct sony_sc {
+       struct hid_device *hdev;
+       struct led_classdev *leds[4];
        unsigned long quirks;
+       struct work_struct state_worker;
 
-       void *extra;
-};
+#ifdef CONFIG_SONY_FF
+       __u8 left;
+       __u8 right;
+#endif
 
-struct buzz_extra {
-       int led_state;
-       struct led_classdev *leds[4];
+       __u8 led_state;
 };
 
 static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -459,58 +464,66 @@ static void buzz_set_leds(struct hid_device *hdev, int leds)
        hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
 }
 
-static void buzz_led_set_brightness(struct led_classdev *led,
+static void sony_set_leds(struct hid_device *hdev, __u8 leds)
+{
+       struct sony_sc *drv_data = hid_get_drvdata(hdev);
+
+       if (drv_data->quirks & BUZZ_CONTROLLER) {
+               buzz_set_leds(hdev, leds);
+       } else if (drv_data->quirks & SIXAXIS_CONTROLLER_USB) {
+               drv_data->led_state = leds;
+               schedule_work(&drv_data->state_worker);
+       }
+}
+
+static void sony_led_set_brightness(struct led_classdev *led,
                                    enum led_brightness value)
 {
        struct device *dev = led->dev->parent;
        struct hid_device *hdev = container_of(dev, struct hid_device, dev);
        struct sony_sc *drv_data;
-       struct buzz_extra *buzz;
 
        int n;
 
        drv_data = hid_get_drvdata(hdev);
-       if (!drv_data || !drv_data->extra) {
+       if (!drv_data) {
                hid_err(hdev, "No device data\n");
                return;
        }
-       buzz = drv_data->extra;
 
        for (n = 0; n < 4; n++) {
-               if (led == buzz->leds[n]) {
-                       int on = !! (buzz->led_state & (1 << n));
+               if (led == drv_data->leds[n]) {
+                       int on = !!(drv_data->led_state & (1 << n));
                        if (value == LED_OFF && on) {
-                               buzz->led_state &= ~(1 << n);
-                               buzz_set_leds(hdev, buzz->led_state);
+                               drv_data->led_state &= ~(1 << n);
+                               sony_set_leds(hdev, drv_data->led_state);
                        } else if (value != LED_OFF && !on) {
-                               buzz->led_state |= (1 << n);
-                               buzz_set_leds(hdev, buzz->led_state);
+                               drv_data->led_state |= (1 << n);
+                               sony_set_leds(hdev, drv_data->led_state);
                        }
                        break;
                }
        }
 }
 
-static enum led_brightness buzz_led_get_brightness(struct led_classdev *led)
+static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
 {
        struct device *dev = led->dev->parent;
        struct hid_device *hdev = container_of(dev, struct hid_device, dev);
        struct sony_sc *drv_data;
-       struct buzz_extra *buzz;
 
        int n;
        int on = 0;
 
        drv_data = hid_get_drvdata(hdev);
-       if (!drv_data || !drv_data->extra) {
+       if (!drv_data) {
                hid_err(hdev, "No device data\n");
                return LED_OFF;
        }
-       buzz = drv_data->extra;
 
        for (n = 0; n < 4; n++) {
-               if (led == buzz->leds[n]) {
-                       on = !! (buzz->led_state & (1 << n));
+               if (led == drv_data->leds[n]) {
+                       on = !!(drv_data->led_state & (1 << n));
                        break;
                }
        }
@@ -518,35 +531,55 @@ static enum led_brightness buzz_led_get_brightness(struct led_classdev *led)
        return on ? LED_FULL : LED_OFF;
 }
 
-static int buzz_init(struct hid_device *hdev)
+static void sony_leds_remove(struct hid_device *hdev)
+{
+       struct sony_sc *drv_data;
+       struct led_classdev *led;
+       int n;
+
+       drv_data = hid_get_drvdata(hdev);
+       BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
+
+       for (n = 0; n < 4; n++) {
+               led = drv_data->leds[n];
+               drv_data->leds[n] = NULL;
+               if (!led)
+                       continue;
+               led_classdev_unregister(led);
+               kfree(led);
+       }
+}
+
+static int sony_leds_init(struct hid_device *hdev)
 {
        struct sony_sc *drv_data;
-       struct buzz_extra *buzz;
        int n, ret = 0;
        struct led_classdev *led;
        size_t name_sz;
        char *name;
+       size_t name_len;
+       const char *name_fmt;
 
        drv_data = hid_get_drvdata(hdev);
-       BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
-
-       /* Validate expected report characteristics. */
-       if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
-               return -ENODEV;
-
-       buzz = kzalloc(sizeof(*buzz), GFP_KERNEL);
-       if (!buzz) {
-               hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
-               return -ENOMEM;
+       BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
+
+       if (drv_data->quirks & BUZZ_CONTROLLER) {
+               name_len = strlen("::buzz#");
+               name_fmt = "%s::buzz%d";
+               /* Validate expected report characteristics. */
+               if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
+                       return -ENODEV;
+       } else {
+               name_len = strlen("::sony#");
+               name_fmt = "%s::sony%d";
        }
-       drv_data->extra = buzz;
 
        /* Clear LEDs as we have no way of reading their initial state. This is
         * only relevant if the driver is loaded after somebody actively set the
         * LEDs to on */
-       buzz_set_leds(hdev, 0x00);
+       sony_set_leds(hdev, 0x00);
 
-       name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1;
+       name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
 
        for (n = 0; n < 4; n++) {
                led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
@@ -556,12 +589,12 @@ static int buzz_init(struct hid_device *hdev)
                }
 
                name = (void *)(&led[1]);
-               snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1);
+               snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
                led->name = name;
                led->brightness = 0;
                led->max_brightness = 1;
-               led->brightness_get = buzz_led_get_brightness;
-               led->brightness_set = buzz_led_set_brightness;
+               led->brightness_get = sony_led_get_brightness;
+               led->brightness_set = sony_led_set_brightness;
 
                if (led_classdev_register(&hdev->dev, led)) {
                        hid_err(hdev, "Failed to register LED %d\n", n);
@@ -569,80 +602,57 @@ static int buzz_init(struct hid_device *hdev)
                        goto error_leds;
                }
 
-               buzz->leds[n] = led;
+               drv_data->leds[n] = led;
        }
 
        return ret;
 
 error_leds:
-       for (n = 0; n < 4; n++) {
-               led = buzz->leds[n];
-               buzz->leds[n] = NULL;
-               if (!led)
-                       continue;
-               led_classdev_unregister(led);
-               kfree(led);
-       }
+       sony_leds_remove(hdev);
 
-       kfree(drv_data->extra);
-       drv_data->extra = NULL;
        return ret;
 }
 
-static void buzz_remove(struct hid_device *hdev)
-{
-       struct sony_sc *drv_data;
-       struct buzz_extra *buzz;
-       struct led_classdev *led;
-       int n;
-
-       drv_data = hid_get_drvdata(hdev);
-       BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
-
-       buzz = drv_data->extra;
-
-       for (n = 0; n < 4; n++) {
-               led = buzz->leds[n];
-               buzz->leds[n] = NULL;
-               if (!led)
-                       continue;
-               led_classdev_unregister(led);
-               kfree(led);
-       }
-
-       kfree(drv_data->extra);
-       drv_data->extra = NULL;
-}
-
-#ifdef CONFIG_SONY_FF
-static int sony_play_effect(struct input_dev *dev, void *data,
-                           struct ff_effect *effect)
+static void sony_state_worker(struct work_struct *work)
 {
+       struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
        unsigned char buf[] = {
                0x01,
                0x00, 0xff, 0x00, 0xff, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x03,
+               0x00, 0x00, 0x00, 0x00, 0x00,
                0xff, 0x27, 0x10, 0x00, 0x32,
                0xff, 0x27, 0x10, 0x00, 0x32,
                0xff, 0x27, 0x10, 0x00, 0x32,
                0xff, 0x27, 0x10, 0x00, 0x32,
                0x00, 0x00, 0x00, 0x00, 0x00
        };
-       __u8 left;
-       __u8 right;
+
+#ifdef CONFIG_SONY_FF
+       buf[3] = sc->right;
+       buf[5] = sc->left;
+#endif
+
+       buf[10] |= (sc->led_state & 0xf) << 1;
+
+       sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf),
+                                       HID_OUTPUT_REPORT);
+}
+
+#ifdef CONFIG_SONY_FF
+static int sony_play_effect(struct input_dev *dev, void *data,
+                           struct ff_effect *effect)
+{
        struct hid_device *hid = input_get_drvdata(dev);
+       struct sony_sc *sc = hid_get_drvdata(hid);
 
        if (effect->type != FF_RUMBLE)
                return 0;
 
-       left = effect->u.rumble.strong_magnitude / 256;
-       right = effect->u.rumble.weak_magnitude ? 1 : 0;
-
-       buf[3] = right;
-       buf[5] = left;
+       sc->left = effect->u.rumble.strong_magnitude / 256;
+       sc->right = effect->u.rumble.weak_magnitude ? 1 : 0;
 
-       return hid->hid_output_raw_report(hid, buf, sizeof(buf),
-                                         HID_OUTPUT_REPORT);
+       schedule_work(&sc->state_worker);
+       return 0;
 }
 
 static int sony_init_ff(struct hid_device *hdev)
@@ -655,11 +665,22 @@ static int sony_init_ff(struct hid_device *hdev)
        return input_ff_create_memless(input_dev, NULL, sony_play_effect);
 }
 
+static void sony_destroy_ff(struct hid_device *hdev)
+{
+       struct sony_sc *sc = hid_get_drvdata(hdev);
+
+       cancel_work_sync(&sc->state_worker);
+}
+
 #else
 static int sony_init_ff(struct hid_device *hdev)
 {
        return 0;
 }
+
+static void sony_destroy_ff(struct hid_device *hdev)
+{
+}
 #endif
 
 static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
@@ -677,6 +698,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
        sc->quirks = quirks;
        hid_set_drvdata(hdev, sc);
+       sc->hdev = hdev;
 
        ret = hid_parse(hdev);
        if (ret) {
@@ -700,23 +722,30 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
        if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
                hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;
                ret = sixaxis_set_operational_usb(hdev);
+               INIT_WORK(&sc->state_worker, sony_state_worker);
        }
        else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
                ret = sixaxis_set_operational_bt(hdev);
-       else if (sc->quirks & BUZZ_CONTROLLER)
-               ret = buzz_init(hdev);
        else
                ret = 0;
 
        if (ret < 0)
                goto err_stop;
 
+       if (sc->quirks & SONY_LED_SUPPORT) {
+               ret = sony_leds_init(hdev);
+               if (ret < 0)
+                       goto err_stop;
+       }
+
        ret = sony_init_ff(hdev);
        if (ret < 0)
                goto err_stop;
 
        return 0;
 err_stop:
+       if (sc->quirks & SONY_LED_SUPPORT)
+               sony_leds_remove(hdev);
        hid_hw_stop(hdev);
        return ret;
 }
@@ -725,8 +754,10 @@ static void sony_remove(struct hid_device *hdev)
 {
        struct sony_sc *sc = hid_get_drvdata(hdev);
 
-       if (sc->quirks & BUZZ_CONTROLLER)
-               buzz_remove(hdev);
+       if (sc->quirks & SONY_LED_SUPPORT)
+               sony_leds_remove(hdev);
+
+       sony_destroy_ff(hdev);
 
        hid_hw_stop(hdev);
 }
index 1446f526ee8bbade2290b615fc14b6aae35dc09f..abb20db2b443ccdcc34159a97fcc83307db65c40 100644 (file)
@@ -834,8 +834,7 @@ static void wiimote_init_set_type(struct wiimote_data *wdata,
                goto done;
        }
 
-       if (vendor == USB_VENDOR_ID_NINTENDO ||
-           vendor == USB_VENDOR_ID_NINTENDO2) {
+       if (vendor == USB_VENDOR_ID_NINTENDO) {
                if (product == USB_DEVICE_ID_NINTENDO_WIIMOTE) {
                        devtype = WIIMOTE_DEV_GEN10;
                        goto done;
@@ -1856,8 +1855,6 @@ static void wiimote_hid_remove(struct hid_device *hdev)
 static const struct hid_device_id wiimote_hid_devices[] = {
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
                                USB_DEVICE_ID_NINTENDO_WIIMOTE) },
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO2,
-                               USB_DEVICE_ID_NINTENDO_WIIMOTE) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
                                USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
        { }
index 5f7e55f4b7f052e29f754f78cabe8dd6a4593fb4..e914f27554913ab08c903be673a5c641731058b6 100644 (file)
@@ -1061,6 +1061,7 @@ static int i2c_hid_suspend(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
 
+       disable_irq(client->irq);
        if (device_may_wakeup(&client->dev))
                enable_irq_wake(client->irq);
 
@@ -1075,6 +1076,7 @@ static int i2c_hid_resume(struct device *dev)
        int ret;
        struct i2c_client *client = to_i2c_client(dev);
 
+       enable_irq(client->irq);
        ret = i2c_hid_hwreset(client);
        if (ret)
                return ret;
index 93b00d76374cee2b82be0a9deab2a0f8d7c6755b..cedc6da93c19c5c77136127feb207a424899a321 100644 (file)
@@ -287,7 +287,7 @@ static int uhid_event_from_user(const char __user *buffer, size_t len,
                         */
                        struct uhid_create_req_compat *compat;
 
-                       compat = kmalloc(sizeof(*compat), GFP_KERNEL);
+                       compat = kzalloc(sizeof(*compat), GFP_KERNEL);
                        if (!compat)
                                return -ENOMEM;
 
index 796086980f4a622dfe2857eec1d00ff33cdff787..9a332e683db77d170f2f1b281e813db02896df4a 100644 (file)
@@ -146,7 +146,7 @@ static void usb_kbd_irq(struct urb *urb)
                                input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
                        else
                                hid_info(urb->dev,
-                                        "Unknown key (scancode %#x) released.\n",
+                                        "Unknown key (scancode %#x) pressed.\n",
                                         kbd->new[i]);
                }
        }
index 48aad4faea068e88cbe61976aa3444d9c8a80a58..077bb1bdac34ef4ed87c65c7bf0d204fd42001b4 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/sysctl.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_bus.h>
 #include <linux/completion.h>
 #include <linux/hyperv.h>
 #include <linux/kernel_stat.h>
@@ -39,7 +38,6 @@
 #include <asm/mshyperv.h>
 #include "hyperv_vmbus.h"
 
-
 static struct acpi_device  *hv_acpi_dev;
 
 static struct tasklet_struct msg_dpc;
index 52d548f1dc1ddbccceedab0c7f2bf9e1d53766f2..f6ca3b21aebd989bcdadeb749e4250134dfbe16e 100644 (file)
@@ -573,8 +573,8 @@ config SENSORS_IT87
        help
          If you say yes here you get support for ITE IT8705F, IT8712F,
          IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E,
-         IT8771E, IT8772E, IT8782F, and IT8783E/F sensor chips, and the
-         SiS950 clone.
+         IT8771E, IT8772E, IT8782F, IT8783E/F and IT8603E sensor chips,
+         and the SiS950 clone.
 
          This driver can also be built as a module.  If so, the module
          will be called it87.
index 6a34f7f48eb9172272a25d4467bf1a190f7dc1e3..579bdf93be433b54a23fa8827badd7ace8dbb762 100644 (file)
@@ -30,8 +30,7 @@
 #include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/err.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
+#include <linux/acpi.h>
 
 #define ACPI_POWER_METER_NAME          "power_meter"
 ACPI_MODULE_NAME(ACPI_POWER_METER_NAME);
index 1d7ff46812c3dc9d72abb977b02cbf4db04fbd2c..ae208f61219804cbac02bc850582c1ad7cfc5f84 100644 (file)
 #include <linux/dmi.h>
 #include <linux/jiffies.h>
 #include <linux/err.h>
-
-#include <acpi/acpi.h>
-#include <acpi/acpixf.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
-
+#include <linux/acpi.h>
 
 #define ATK_HID "ATK0110"
 
index 29ffa27c60b89b60bf84db948cf56a890772599e..e4ea690f1302d51c53b038d014ad691e9d608c59 100644 (file)
@@ -10,7 +10,8 @@
  *  This driver supports only the Environment Controller in the IT8705F and
  *  similar parts.  The other devices are supported by different drivers.
  *
- *  Supports: IT8705F  Super I/O chip w/LPC interface
+ *  Supports: IT8603E  Super I/O chip w/LPC interface
+ *            IT8705F  Super I/O chip w/LPC interface
  *            IT8712F  Super I/O chip w/LPC interface
  *            IT8716F  Super I/O chip w/LPC interface
  *            IT8718F  Super I/O chip w/LPC interface
@@ -64,7 +65,7 @@
 #define DRVNAME "it87"
 
 enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8771,
-            it8772, it8782, it8783 };
+            it8772, it8782, it8783, it8603 };
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
@@ -146,6 +147,7 @@ static inline void superio_exit(void)
 #define IT8772E_DEVID 0x8772
 #define IT8782F_DEVID 0x8782
 #define IT8783E_DEVID 0x8783
+#define IT8306E_DEVID 0x8603
 #define IT87_ACT_REG  0x30
 #define IT87_BASE_REG 0x60
 
@@ -315,6 +317,12 @@ static const struct it87_devices it87_devices[] = {
                  | FEAT_TEMP_OLD_PECI,
                .old_peci_mask = 0x4,
        },
+       [it8603] = {
+               .name = "it8603",
+               .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
+                 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
+               .peci_mask = 0x07,
+       },
 };
 
 #define has_16bit_fans(data)   ((data)->features & FEAT_16BIT_FANS)
@@ -361,7 +369,7 @@ struct it87_data {
        unsigned long last_updated;     /* In jiffies */
 
        u16 in_scaled;          /* Internal voltage sensors are scaled */
-       u8 in[9][3];            /* [nr][0]=in, [1]=min, [2]=max */
+       u8 in[10][3];           /* [nr][0]=in, [1]=min, [2]=max */
        u8 has_fan;             /* Bitfield, fans enabled */
        u16 fan[5][2];          /* Register values, [nr][0]=fan, [1]=min */
        u8 has_temp;            /* Bitfield, temp sensors enabled */
@@ -578,6 +586,7 @@ static SENSOR_DEVICE_ATTR_2(in7_max, S_IRUGO | S_IWUSR, show_in, set_in,
                            7, 2);
 
 static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0);
+static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 9, 0);
 
 /* 3 temperatures */
 static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
@@ -734,7 +743,7 @@ static int pwm_mode(const struct it87_data *data, int nr)
 {
        int ctrl = data->fan_main_ctrl & (1 << nr);
 
-       if (ctrl == 0)                                  /* Full speed */
+       if (ctrl == 0 && data->type != it8603)          /* Full speed */
                return 0;
        if (data->pwm_ctrl[nr] & 0x80)                  /* Automatic mode */
                return 2;
@@ -929,6 +938,10 @@ static ssize_t set_pwm_enable(struct device *dev,
                        return -EINVAL;
        }
 
+       /* IT8603E does not have on/off mode */
+       if (val == 0 && data->type == it8603)
+               return -EINVAL;
+
        mutex_lock(&data->update_lock);
 
        if (val == 0) {
@@ -948,10 +961,13 @@ static ssize_t set_pwm_enable(struct device *dev,
                else                                    /* Automatic mode */
                        data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
                it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
-               /* set SmartGuardian mode */
-               data->fan_main_ctrl |= (1 << nr);
-               it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
-                                data->fan_main_ctrl);
+
+               if (data->type != it8603) {
+                       /* set SmartGuardian mode */
+                       data->fan_main_ctrl |= (1 << nr);
+                       it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+                                        data->fan_main_ctrl);
+               }
        }
 
        mutex_unlock(&data->update_lock);
@@ -1415,6 +1431,8 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
 static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
 static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
 static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2);
+/* special AVCC3 IT8306E in9 */
+static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 0);
 
 static ssize_t show_name(struct device *dev, struct device_attribute
                         *devattr, char *buf)
@@ -1424,7 +1442,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute
 }
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
-static struct attribute *it87_attributes_in[9][5] = {
+static struct attribute *it87_attributes_in[10][5] = {
 {
        &sensor_dev_attr_in0_input.dev_attr.attr,
        &sensor_dev_attr_in0_min.dev_attr.attr,
@@ -1476,9 +1494,12 @@ static struct attribute *it87_attributes_in[9][5] = {
 }, {
        &sensor_dev_attr_in8_input.dev_attr.attr,
        NULL
+}, {
+       &sensor_dev_attr_in9_input.dev_attr.attr,
+       NULL
 } };
 
-static const struct attribute_group it87_group_in[9] = {
+static const struct attribute_group it87_group_in[10] = {
        { .attrs = it87_attributes_in[0] },
        { .attrs = it87_attributes_in[1] },
        { .attrs = it87_attributes_in[2] },
@@ -1488,6 +1509,7 @@ static const struct attribute_group it87_group_in[9] = {
        { .attrs = it87_attributes_in[6] },
        { .attrs = it87_attributes_in[7] },
        { .attrs = it87_attributes_in[8] },
+       { .attrs = it87_attributes_in[9] },
 };
 
 static struct attribute *it87_attributes_temp[3][6] = {
@@ -1685,6 +1707,7 @@ static struct attribute *it87_attributes_label[] = {
        &sensor_dev_attr_in3_label.dev_attr.attr,
        &sensor_dev_attr_in7_label.dev_attr.attr,
        &sensor_dev_attr_in8_label.dev_attr.attr,
+       &sensor_dev_attr_in9_label.dev_attr.attr,
        NULL
 };
 
@@ -1742,6 +1765,9 @@ static int __init it87_find(unsigned short *address,
        case IT8783E_DEVID:
                sio_data->type = it8783;
                break;
+       case IT8306E_DEVID:
+               sio_data->type = it8603;
+               break;
        case 0xffff:    /* No device at all */
                goto exit;
        default:
@@ -1763,11 +1789,16 @@ static int __init it87_find(unsigned short *address,
 
        err = 0;
        sio_data->revision = superio_inb(DEVREV) & 0x0f;
-       pr_info("Found IT%04xF chip at 0x%x, revision %d\n",
-               chip_type, *address, sio_data->revision);
+       pr_info("Found IT%04x%c chip at 0x%x, revision %d\n", chip_type,
+               chip_type == 0x8771 || chip_type == 0x8772 ||
+               chip_type == 0x8603 ? 'E' : 'F', *address,
+               sio_data->revision);
 
        /* in8 (Vbat) is always internal */
        sio_data->internal = (1 << 2);
+       /* Only the IT8603E has in9 */
+       if (sio_data->type != it8603)
+               sio_data->skip_in |= (1 << 9);
 
        /* Read GPIO config and VID value from LDN 7 (GPIO) */
        if (sio_data->type == it87) {
@@ -1844,7 +1875,38 @@ static int __init it87_find(unsigned short *address,
                        sio_data->internal |= (1 << 1);
 
                sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
+       } else if (sio_data->type == it8603) {
+               int reg27, reg29;
 
+               sio_data->skip_vid = 1; /* No VID */
+               superio_select(GPIO);
+
+               reg27 = superio_inb(IT87_SIO_GPIO3_REG);
+
+               /* Check if fan3 is there or not */
+               if (reg27 & (1 << 6))
+                       sio_data->skip_pwm |= (1 << 2);
+               if (reg27 & (1 << 7))
+                       sio_data->skip_fan |= (1 << 2);
+
+               /* Check if fan2 is there or not */
+               reg29 = superio_inb(IT87_SIO_GPIO5_REG);
+               if (reg29 & (1 << 1))
+                       sio_data->skip_pwm |= (1 << 1);
+               if (reg29 & (1 << 2))
+                       sio_data->skip_fan |= (1 << 1);
+
+               sio_data->skip_in |= (1 << 5); /* No VIN5 */
+               sio_data->skip_in |= (1 << 6); /* No VIN6 */
+
+               /* no fan4 */
+               sio_data->skip_pwm |= (1 << 3);
+               sio_data->skip_fan |= (1 << 3);
+
+               sio_data->internal |= (1 << 1); /* in7 is VSB */
+               sio_data->internal |= (1 << 3); /* in9 is AVCC */
+
+               sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
        } else {
                int reg;
                bool uart6;
@@ -1966,7 +2028,7 @@ static void it87_remove_files(struct device *dev)
        int i;
 
        sysfs_remove_group(&dev->kobj, &it87_group);
-       for (i = 0; i < 9; i++) {
+       for (i = 0; i < 10; i++) {
                if (sio_data->skip_in & (1 << i))
                        continue;
                sysfs_remove_group(&dev->kobj, &it87_group_in[i]);
@@ -2080,6 +2142,8 @@ static int it87_probe(struct platform_device *pdev)
                        data->in_scaled |= (1 << 7);    /* in7 is VSB */
                if (sio_data->internal & (1 << 2))
                        data->in_scaled |= (1 << 8);    /* in8 is Vbat */
+               if (sio_data->internal & (1 << 3))
+                       data->in_scaled |= (1 << 9);    /* in9 is AVCC */
        } else if (sio_data->type == it8782 || sio_data->type == it8783) {
                if (sio_data->internal & (1 << 0))
                        data->in_scaled |= (1 << 3);    /* in3 is VCC5V */
@@ -2102,7 +2166,7 @@ static int it87_probe(struct platform_device *pdev)
        if (err)
                return err;
 
-       for (i = 0; i < 9; i++) {
+       for (i = 0; i < 10; i++) {
                if (sio_data->skip_in & (1 << i))
                        continue;
                err = sysfs_create_group(&dev->kobj, &it87_group_in[i]);
@@ -2202,7 +2266,7 @@ static int it87_probe(struct platform_device *pdev)
        }
 
        /* Export labels for internal sensors */
-       for (i = 0; i < 3; i++) {
+       for (i = 0; i < 4; i++) {
                if (!(sio_data->internal & (1 << i)))
                        continue;
                err = sysfs_create_file(&dev->kobj,
@@ -2383,8 +2447,9 @@ static void it87_init_device(struct platform_device *pdev)
        }
        data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
 
-       /* Set tachometers to 16-bit mode if needed */
-       if (has_16bit_fans(data)) {
+       /* Set tachometers to 16-bit mode if needed, IT8603E (and IT8728F?)
+        * has it by default */
+       if (has_16bit_fans(data) && data->type != it8603) {
                tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
                if (~tmp & 0x07 & data->has_fan) {
                        dev_dbg(&pdev->dev,
@@ -2464,6 +2529,8 @@ static struct it87_data *it87_update_device(struct device *dev)
                }
                /* in8 (battery) has no limit registers */
                data->in[8][0] = it87_read_value(data, IT87_REG_VIN(8));
+               if (data->type == it8603)
+                       data->in[9][0] = it87_read_value(data, 0x2f);
 
                for (i = 0; i < 5; i++) {
                        /* Skip disabled fans */
index 4c4c1421bf28f66462d8d0bf5f2ee70947005ac0..8b8f3aa49726873b89267ebe45f4e145eab2c7bb 100644 (file)
@@ -1610,12 +1610,14 @@ static int lm90_probe(struct i2c_client *client,
                                                "lm90", client);
                if (err < 0) {
                        dev_err(dev, "cannot request IRQ %d\n", client->irq);
-                       goto exit_remove_files;
+                       goto exit_unregister;
                }
        }
 
        return 0;
 
+exit_unregister:
+       hwmon_device_unregister(data->hwmon_dev);
 exit_remove_files:
        lm90_remove_files(client, data);
 exit_restore:
index 036cf03aeb612a7c62641c65e94552eb6c09af04..18a74a6751a97101568cb5d084b0f840e19322f7 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/clk.h>
 #include <linux/slab.h>
 
 /* Hardware register offsets and field defintions */
@@ -891,7 +890,7 @@ static const struct of_device_id bcm_kona_i2c_of_match[] = {
        {.compatible = "brcm,kona-i2c",},
        {},
 };
-MODULE_DEVICE_TABLE(of, kona_i2c_of_match);
+MODULE_DEVICE_TABLE(of, bcm_kona_i2c_of_match);
 
 static struct platform_driver bcm_kona_i2c_driver = {
        .driver = {
index d7e8600f31fbba8c4eaec181e9c1b277b7c7740d..77df97b932af5399a39b0c52ec7e256aff4c8325 100644 (file)
@@ -299,6 +299,7 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
        strlcpy(adap->name, "bcm2835 I2C adapter", sizeof(adap->name));
        adap->algo = &bcm2835_i2c_algo;
        adap->dev.parent = &pdev->dev;
+       adap->dev.of_node = pdev->dev.of_node;
 
        bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0);
 
index ff05d9fef4a8ee22f40c981bd11e90e9ad24e51e..af0b5830303d761378d9111ac141bda6502dd665 100644 (file)
@@ -125,12 +125,12 @@ static struct davinci_i2c_platform_data davinci_i2c_platform_data_default = {
 static inline void davinci_i2c_write_reg(struct davinci_i2c_dev *i2c_dev,
                                         int reg, u16 val)
 {
-       __raw_writew(val, i2c_dev->base + reg);
+       writew_relaxed(val, i2c_dev->base + reg);
 }
 
 static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
 {
-       return __raw_readw(i2c_dev->base + reg);
+       return readw_relaxed(i2c_dev->base + reg);
 }
 
 /* Generate a pulse on the i2c clock pin. */
index dae3ddfe7619cf69899d974992ea0e7b43264b59..721f7ebf9a3bcb034867dd8acfbb33236bf21e46 100644 (file)
@@ -25,8 +25,6 @@
 #define USB_VENDOR_ID_DIOLAN           0x0abf
 #define USB_DEVICE_ID_DIOLAN_U2C       0x3370
 
-#define DIOLAN_OUT_EP          0x02
-#define DIOLAN_IN_EP           0x84
 
 /* commands via USB, must match command ids in the firmware */
 #define CMD_I2C_READ           0x01
@@ -84,6 +82,7 @@
 struct i2c_diolan_u2c {
        u8 obuffer[DIOLAN_OUTBUF_LEN];  /* output buffer */
        u8 ibuffer[DIOLAN_INBUF_LEN];   /* input buffer */
+       int ep_in, ep_out;              /* Endpoints    */
        struct usb_device *usb_dev;     /* the usb device for this device */
        struct usb_interface *interface;/* the interface for this device */
        struct i2c_adapter adapter;     /* i2c related things */
@@ -109,7 +108,7 @@ static int diolan_usb_transfer(struct i2c_diolan_u2c *dev)
                return -EINVAL;
 
        ret = usb_bulk_msg(dev->usb_dev,
-                          usb_sndbulkpipe(dev->usb_dev, DIOLAN_OUT_EP),
+                          usb_sndbulkpipe(dev->usb_dev, dev->ep_out),
                           dev->obuffer, dev->olen, &actual,
                           DIOLAN_USB_TIMEOUT);
        if (!ret) {
@@ -118,7 +117,7 @@ static int diolan_usb_transfer(struct i2c_diolan_u2c *dev)
 
                        tmpret = usb_bulk_msg(dev->usb_dev,
                                              usb_rcvbulkpipe(dev->usb_dev,
-                                                             DIOLAN_IN_EP),
+                                                             dev->ep_in),
                                              dev->ibuffer,
                                              sizeof(dev->ibuffer), &actual,
                                              DIOLAN_USB_TIMEOUT);
@@ -210,7 +209,7 @@ static void diolan_flush_input(struct i2c_diolan_u2c *dev)
                int ret;
 
                ret = usb_bulk_msg(dev->usb_dev,
-                                  usb_rcvbulkpipe(dev->usb_dev, DIOLAN_IN_EP),
+                                  usb_rcvbulkpipe(dev->usb_dev, dev->ep_in),
                                   dev->ibuffer, sizeof(dev->ibuffer), &actual,
                                   DIOLAN_USB_TIMEOUT);
                if (ret < 0 || actual == 0)
@@ -445,9 +444,14 @@ static void diolan_u2c_free(struct i2c_diolan_u2c *dev)
 static int diolan_u2c_probe(struct usb_interface *interface,
                            const struct usb_device_id *id)
 {
+       struct usb_host_interface *hostif = interface->cur_altsetting;
        struct i2c_diolan_u2c *dev;
        int ret;
 
+       if (hostif->desc.bInterfaceNumber != 0
+           || hostif->desc.bNumEndpoints < 2)
+               return -ENODEV;
+
        /* allocate memory for our device state and initialize it */
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (dev == NULL) {
@@ -455,6 +459,8 @@ static int diolan_u2c_probe(struct usb_interface *interface,
                ret = -ENOMEM;
                goto error;
        }
+       dev->ep_out = hostif->endpoint[0].desc.bEndpointAddress;
+       dev->ep_in = hostif->endpoint[1].desc.bEndpointAddress;
 
        dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
        dev->interface = interface;
index a6a891d7970dd373414ca23ea7dd6924535dee38..90dcc2eaac5fb688fedba904b181be2312e40b3d 100644 (file)
@@ -266,13 +266,13 @@ static const u8 reg_map_ip_v2[] = {
 static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
                                      int reg, u16 val)
 {
-       __raw_writew(val, i2c_dev->base +
+       writew_relaxed(val, i2c_dev->base +
                        (i2c_dev->regs[reg] << i2c_dev->reg_shift));
 }
 
 static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
 {
-       return __raw_readw(i2c_dev->base +
+       return readw_relaxed(i2c_dev->base +
                                (i2c_dev->regs[reg] << i2c_dev->reg_shift));
 }
 
@@ -1037,6 +1037,20 @@ static const struct i2c_algorithm omap_i2c_algo = {
 };
 
 #ifdef CONFIG_OF
+static struct omap_i2c_bus_platform_data omap2420_pdata = {
+       .rev = OMAP_I2C_IP_VERSION_1,
+       .flags = OMAP_I2C_FLAG_NO_FIFO |
+                       OMAP_I2C_FLAG_SIMPLE_CLOCK |
+                       OMAP_I2C_FLAG_16BIT_DATA_REG |
+                       OMAP_I2C_FLAG_BUS_SHIFT_2,
+};
+
+static struct omap_i2c_bus_platform_data omap2430_pdata = {
+       .rev = OMAP_I2C_IP_VERSION_1,
+       .flags = OMAP_I2C_FLAG_BUS_SHIFT_2 |
+                       OMAP_I2C_FLAG_FORCE_19200_INT_CLK,
+};
+
 static struct omap_i2c_bus_platform_data omap3_pdata = {
        .rev = OMAP_I2C_IP_VERSION_1,
        .flags = OMAP_I2C_FLAG_BUS_SHIFT_2,
@@ -1055,6 +1069,14 @@ static const struct of_device_id omap_i2c_of_match[] = {
                .compatible = "ti,omap3-i2c",
                .data = &omap3_pdata,
        },
+       {
+               .compatible = "ti,omap2430-i2c",
+               .data = &omap2430_pdata,
+       },
+       {
+               .compatible = "ti,omap2420-i2c",
+               .data = &omap2420_pdata,
+       },
        { },
 };
 MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
@@ -1140,9 +1162,9 @@ omap_i2c_probe(struct platform_device *pdev)
         * Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2.
         * On omap1/3/2 Offset 4 is IE Reg the bit [15:14] is 0 at reset.
         * Also since the omap_i2c_read_reg uses reg_map_ip_* a
-        * raw_readw is done.
+        * readw_relaxed is done.
         */
-       rev = __raw_readw(dev->base + 0x04);
+       rev = readw_relaxed(dev->base + 0x04);
 
        dev->scheme = OMAP_I2C_SCHEME(rev);
        switch (dev->scheme) {
index b1d38590ac0196f1da49d4d67e411b3741175b9f..46eaf58d881b4e31032327e7c248979d693d9c11 100644 (file)
@@ -198,7 +198,7 @@ fail_base2:
                                continue;
                        }
                }         
-               buddha_board = ZTWO_VADDR(board);
+               buddha_board = (unsigned long)ZTWO_VADDR(board);
                
                /* write to BUDDHA_IRQ_MR to enable the board IRQ */
                /* X-Surf doesn't have this.  IRQs are always on */
index d9e1f7ccfe6f086df549160a88ca191e52fca32f..b6940992a6ff95c699eddb8c7e2fb484a2f16ed3 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <acpi/acpi.h>
 #include <linux/ide.h>
 #include <linux/pci.h>
 #include <linux/dmi.h>
@@ -98,6 +97,17 @@ bool ide_port_acpi(ide_hwif_t *hwif)
        return ide_noacpi == 0 && hwif->acpidata;
 }
 
+static acpi_handle acpi_get_child(acpi_handle handle, u64 addr)
+{
+       struct acpi_device *adev;
+
+       if (!handle || acpi_bus_get_device(handle, &adev))
+               return NULL;
+
+       adev = acpi_find_child_device(adev, addr, false);
+       return adev ? adev->handle : NULL;
+}
+
 /**
  * ide_get_dev_handle - finds acpi_handle and PCI device.function
  * @dev: device to locate
index cbd4e9abc47e8f47f512915d224f916166921110..92d1206482a62ca57128690e49735dea2f00aaa3 100644 (file)
@@ -329,7 +329,7 @@ static struct cpuidle_state atom_cstates[] __initdata = {
        {
                .enter = NULL }
 };
-static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX] = {
+static struct cpuidle_state avn_cstates[] __initdata = {
        {
                .name = "C1-AVN",
                .desc = "MWAIT 0x00",
@@ -340,7 +340,7 @@ static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX] = {
        {
                .name = "C6-AVN",
                .desc = "MWAIT 0x51",
-               .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
+               .flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 15,
                .target_residency = 45,
                .enter = &intel_idle },
index dcda17395c4e68f31f3382cd0c393a5845b025c5..3dcdbad654565f2c5d590c99b0c81800afd9702f 100644 (file)
@@ -262,6 +262,18 @@ static int accel_3d_parse_report(struct platform_device *pdev,
                        st->accel[1].index, st->accel[1].report_id,
                        st->accel[2].index, st->accel[2].report_id);
 
+       /* Set Sensitivity field ids, when there is no individual modifier */
+       if (st->common_attributes.sensitivity.index < 0) {
+               sensor_hub_input_get_attribute_info(hsdev,
+                       HID_FEATURE_REPORT, usage_id,
+                       HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+                       HID_USAGE_SENSOR_DATA_ACCELERATION,
+                       &st->common_attributes.sensitivity);
+               dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n",
+                       st->common_attributes.sensitivity.index,
+                       st->common_attributes.sensitivity.report_id);
+       }
+
        return ret;
 }
 
@@ -350,7 +362,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
 error_iio_unreg:
        iio_device_unregister(indio_dev);
 error_remove_trigger:
-       hid_sensor_remove_trigger(indio_dev);
+       hid_sensor_remove_trigger(&accel_state->common_attributes);
 error_unreg_buffer_funcs:
        iio_triggered_buffer_cleanup(indio_dev);
 error_free_dev_mem:
@@ -363,10 +375,11 @@ static int hid_accel_3d_remove(struct platform_device *pdev)
 {
        struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+       struct accel_3d_state *accel_state = iio_priv(indio_dev);
 
        sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D);
        iio_device_unregister(indio_dev);
-       hid_sensor_remove_trigger(indio_dev);
+       hid_sensor_remove_trigger(&accel_state->common_attributes);
        iio_triggered_buffer_cleanup(indio_dev);
        kfree(indio_dev->channels);
 
index d72118d1189c8648161496919ab17f7ad514df95..98ba761cbb9ce6943913c03b0a65d861e6956661 100644 (file)
@@ -112,9 +112,10 @@ static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
        mutex_lock(&st->buf_lock);
        st->tx[0] = KXSD9_READ(address);
        ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
-       if (ret)
-               return ret;
-       return (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
+       if (!ret)
+               ret = (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
+       mutex_unlock(&st->buf_lock);
+       return ret;
 }
 
 static IIO_CONST_ATTR(accel_scale_available,
index 17df74908db120a6e33e3f43a51fc4e67784da59..5b1aa027c034b09c1569047231716ea66f75f919 100644 (file)
@@ -1047,6 +1047,7 @@ static int at91_adc_probe(struct platform_device *pdev)
        } else {
                if (!st->caps->has_tsmr) {
                        dev_err(&pdev->dev, "We don't support non-TSMR adc\n");
+                       ret = -ENODEV;
                        goto error_disable_adc_clk;
                }
 
index 12948325431c98a1a01effc90d1bec0f6a564b50..47dcb34ff44c47f6317a62c99e025df6eb6b27f6 100644 (file)
@@ -88,10 +88,10 @@ static const int mcp3422_sample_rates[4] = {
 
 /* sample rates to sign extension table */
 static const int mcp3422_sign_extend[4] = {
-       [MCP3422_SRATE_240] = 12,
-       [MCP3422_SRATE_60] = 14,
-       [MCP3422_SRATE_15] = 16,
-       [MCP3422_SRATE_3] = 18 };
+       [MCP3422_SRATE_240] = 11,
+       [MCP3422_SRATE_60] = 13,
+       [MCP3422_SRATE_15] = 15,
+       [MCP3422_SRATE_3] = 17 };
 
 /* Client data (each client gets its own) */
 struct mcp3422 {
@@ -362,7 +362,7 @@ static int mcp3422_probe(struct i2c_client *client,
                | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240));
        mcp3422_update_config(adc, config);
 
-       err = iio_device_register(indio_dev);
+       err = devm_iio_device_register(&client->dev, indio_dev);
        if (err < 0)
                return err;
 
@@ -371,12 +371,6 @@ static int mcp3422_probe(struct i2c_client *client,
        return 0;
 }
 
-static int mcp3422_remove(struct i2c_client *client)
-{
-       iio_device_unregister(i2c_get_clientdata(client));
-       return 0;
-}
-
 static const struct i2c_device_id mcp3422_id[] = {
        { "mcp3422", 2 },
        { "mcp3423", 3 },
@@ -400,7 +394,6 @@ static struct i2c_driver mcp3422_driver = {
                .of_match_table = of_match_ptr(mcp3422_of_match),
        },
        .probe = mcp3422_probe,
-       .remove = mcp3422_remove,
        .id_table = mcp3422_id,
 };
 module_i2c_driver(mcp3422_driver);
index 728411ec764203c371270c390ac77176d788ffd9..d4d748214e4b364dc716889d2b66363353c2ee56 100644 (file)
@@ -229,12 +229,15 @@ static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
        unsigned long flags,
        const struct iio_buffer_setup_ops *setup_ops)
 {
+       struct iio_buffer *buffer;
        int ret;
 
-       indio_dev->buffer = iio_kfifo_allocate(indio_dev);
-       if (!indio_dev->buffer)
+       buffer = iio_kfifo_allocate(indio_dev);
+       if (!buffer)
                return -ENOMEM;
 
+       iio_device_attach_buffer(indio_dev, buffer);
+
        ret = request_threaded_irq(irq, pollfunc_th, pollfunc_bh,
                                flags, indio_dev->name, indio_dev);
        if (ret)
index 09727a71e9fa1578744c4334ad83679274ff24d2..d0add8f9416ba8edf9b0263c8ba0b50831eef58a 100644 (file)
@@ -42,12 +42,6 @@ struct vprbrd_adc {
        .indexed = 1,                                   \
        .channel = _index,                              \
        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
-       .scan_index = _index,                           \
-       .scan_type = {                                  \
-               .sign = 'u',                            \
-               .realbits = 8,                          \
-               .storagebits = 8,                       \
-       },                                              \
 }
 
 static struct iio_chan_spec const vprbrd_adc_iio_channels[] = {
@@ -73,7 +67,7 @@ static int vprbrd_iio_read_raw(struct iio_dev *iio_dev,
                mutex_lock(&vb->lock);
 
                admsg->cmd = VPRBRD_ADC_CMD_GET;
-               admsg->chan = chan->scan_index;
+               admsg->chan = chan->channel;
                admsg->val = 0x00;
 
                ret = usb_control_msg(vb->usb_dev,
@@ -139,7 +133,7 @@ static int vprbrd_adc_probe(struct platform_device *pdev)
        indio_dev->channels = vprbrd_adc_iio_channels;
        indio_dev->num_channels = ARRAY_SIZE(vprbrd_adc_iio_channels);
 
-       ret = iio_device_register(indio_dev);
+       ret = devm_iio_device_register(&pdev->dev, indio_dev);
        if (ret) {
                dev_err(&pdev->dev, "could not register iio (adc)");
                return ret;
@@ -150,22 +144,12 @@ static int vprbrd_adc_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int vprbrd_adc_remove(struct platform_device *pdev)
-{
-       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
-
-       iio_device_unregister(indio_dev);
-
-       return 0;
-}
-
 static struct platform_driver vprbrd_adc_driver = {
        .driver = {
                .name   = "viperboard-adc",
                .owner  = THIS_MODULE,
        },
        .probe          = vprbrd_adc_probe,
-       .remove         = vprbrd_adc_remove,
 };
 
 module_platform_driver(vprbrd_adc_driver);
index b6e77e0fc420133af7a324de6a0531bfb045f33d..bbd6426c9726d8f4e0bf36f1e138901c19ff99e8 100644 (file)
@@ -55,11 +55,10 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
        return 0;
 }
 
-void hid_sensor_remove_trigger(struct iio_dev *indio_dev)
+void hid_sensor_remove_trigger(struct hid_sensor_common *attrb)
 {
-       iio_trigger_unregister(indio_dev->trig);
-       iio_trigger_free(indio_dev->trig);
-       indio_dev->trig = NULL;
+       iio_trigger_unregister(attrb->trigger);
+       iio_trigger_free(attrb->trigger);
 }
 EXPORT_SYMBOL(hid_sensor_remove_trigger);
 
@@ -90,7 +89,7 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
                dev_err(&indio_dev->dev, "Trigger Register Failed\n");
                goto error_free_trig;
        }
-       indio_dev->trig = trig;
+       indio_dev->trig = attrb->trigger = trig;
 
        return ret;
 
index 9a8731478eda4cdb95867e5dffdd10d1ec9bcbae..ca02f7811aa8c6f6a44dc8a955a064dfa1e07219 100644 (file)
@@ -21,6 +21,6 @@
 
 int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
                                struct hid_sensor_common *attrb);
-void hid_sensor_remove_trigger(struct iio_dev *indio_dev);
+void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
 
 #endif
index 3eeaa82075f7bca0649b5e15afb0c02f21a32458..7d1e90811c718e2b494df7fbc00910cdea8eaf08 100644 (file)
@@ -514,16 +514,7 @@ static int ad5421_probe(struct spi_device *spi)
                        return ret;
        }
 
-       return iio_device_register(indio_dev);
-}
-
-static int ad5421_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-
-       iio_device_unregister(indio_dev);
-
-       return 0;
+       return devm_iio_device_register(&spi->dev, indio_dev);
 }
 
 static struct spi_driver ad5421_driver = {
@@ -532,7 +523,6 @@ static struct spi_driver ad5421_driver = {
                   .owner = THIS_MODULE,
        },
        .probe = ad5421_probe,
-       .remove = ad5421_remove,
 };
 module_spi_driver(ad5421_driver);
 
index 9a78d5abb2f6646579fe6ffea21acd51dce91ca7..ee1e95a3a0c31b65c91104340fed80ca97bb5b55 100644 (file)
@@ -589,16 +589,7 @@ static int ad5755_probe(struct spi_device *spi)
        if (ret)
                return ret;
 
-       return iio_device_register(indio_dev);
-}
-
-static int ad5755_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-
-       iio_device_unregister(indio_dev);
-
-       return 0;
+       return devm_iio_device_register(&spi->dev, indio_dev);
 }
 
 static const struct spi_device_id ad5755_id[] = {
@@ -617,7 +608,6 @@ static struct spi_driver ad5755_driver = {
                .owner = THIS_MODULE,
        },
        .probe = ad5755_probe,
-       .remove = ad5755_remove,
        .id_table = ad5755_id,
 };
 module_spi_driver(ad5755_driver);
index 445c2aecfadde205921049a1e0b42d64342318d5..8d08c7ed1ea64d554f9414eb15c8ad41303c3381 100644 (file)
@@ -161,13 +161,7 @@ static int adis16130_probe(struct spi_device *spi)
        indio_dev->info = &adis16130_info;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
-       return iio_device_register(indio_dev);
-}
-
-static int adis16130_remove(struct spi_device *spi)
-{
-       iio_device_unregister(spi_get_drvdata(spi));
-       return 0;
+       return devm_iio_device_register(&spi->dev, indio_dev);
 }
 
 static struct spi_driver adis16130_driver = {
@@ -176,7 +170,6 @@ static struct spi_driver adis16130_driver = {
                .owner = THIS_MODULE,
        },
        .probe = adis16130_probe,
-       .remove = adis16130_remove,
 };
 module_spi_driver(adis16130_driver);
 
index 1e546ba7ba45e1c92acf9ae926b9c29c386785ef..eb0e08ec9e20d43fce5233e44d8144006fd433a3 100644 (file)
@@ -434,23 +434,14 @@ static int adxrs450_probe(struct spi_device *spi)
        indio_dev->num_channels = ARRAY_SIZE(adxrs450_channels);
        indio_dev->name = spi->dev.driver->name;
 
-       ret = iio_device_register(indio_dev);
+       ret = devm_iio_device_register(&spi->dev, indio_dev);
        if (ret)
                return ret;
 
        /* Get the device into a sane initial state */
        ret = adxrs450_initial_setup(indio_dev);
        if (ret)
-               goto error_initial;
-       return 0;
-error_initial:
-       iio_device_unregister(indio_dev);
-       return ret;
-}
-
-static int adxrs450_remove(struct spi_device *spi)
-{
-       iio_device_unregister(spi_get_drvdata(spi));
+               return ret;
 
        return 0;
 }
@@ -468,7 +459,6 @@ static struct spi_driver adxrs450_driver = {
                .owner = THIS_MODULE,
        },
        .probe = adxrs450_probe,
-       .remove = adxrs450_remove,
        .id_table       = adxrs450_id,
 };
 module_spi_driver(adxrs450_driver);
index ea01c6bcfb56825979efc7bfc588eeb9e429e059..59d6bc3e04df870b9c894f2063a2eb9205cb1c42 100644 (file)
@@ -262,6 +262,17 @@ static int gyro_3d_parse_report(struct platform_device *pdev,
                        st->gyro[1].index, st->gyro[1].report_id,
                        st->gyro[2].index, st->gyro[2].report_id);
 
+       /* Set Sensitivity field ids, when there is no individual modifier */
+       if (st->common_attributes.sensitivity.index < 0) {
+               sensor_hub_input_get_attribute_info(hsdev,
+                       HID_FEATURE_REPORT, usage_id,
+                       HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+                       HID_USAGE_SENSOR_DATA_ANGL_VELOCITY,
+                       &st->common_attributes.sensitivity);
+               dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n",
+                       st->common_attributes.sensitivity.index,
+                       st->common_attributes.sensitivity.report_id);
+       }
        return ret;
 }
 
@@ -348,7 +359,7 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
 error_iio_unreg:
        iio_device_unregister(indio_dev);
 error_remove_trigger:
-       hid_sensor_remove_trigger(indio_dev);
+       hid_sensor_remove_trigger(&gyro_state->common_attributes);
 error_unreg_buffer_funcs:
        iio_triggered_buffer_cleanup(indio_dev);
 error_free_dev_mem:
@@ -361,10 +372,11 @@ static int hid_gyro_3d_remove(struct platform_device *pdev)
 {
        struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+       struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
 
        sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
        iio_device_unregister(indio_dev);
-       hid_sensor_remove_trigger(indio_dev);
+       hid_sensor_remove_trigger(&gyro_state->common_attributes);
        iio_triggered_buffer_cleanup(indio_dev);
        kfree(indio_dev->channels);
 
index 18f72e3d0ed6e6c8e9bb73ec8616124a2422aed4..2fe88c189f74cd346c01dd45f81060f92a077c59 100644 (file)
@@ -107,6 +107,11 @@ static const char * const iio_chan_info_postfix[] = {
        [IIO_CHAN_INFO_INT_TIME] = "integration_time",
 };
 
+/**
+ * iio_find_channel_from_si() - get channel from its scan index
+ * @indio_dev:         device
+ * @si:                        scan index to match
+ */
 const struct iio_chan_spec
 *iio_find_channel_from_si(struct iio_dev *indio_dev, int si)
 {
@@ -922,6 +927,10 @@ struct device_type iio_device_type = {
        .release = iio_dev_release,
 };
 
+/**
+ * iio_device_alloc() - allocate an iio_dev from a driver
+ * @sizeof_priv:       Space to allocate for private structure.
+ **/
 struct iio_dev *iio_device_alloc(int sizeof_priv)
 {
        struct iio_dev *dev;
@@ -962,6 +971,10 @@ struct iio_dev *iio_device_alloc(int sizeof_priv)
 }
 EXPORT_SYMBOL(iio_device_alloc);
 
+/**
+ * iio_device_free() - free an iio_dev from a driver
+ * @dev:               the iio_dev associated with the device
+ **/
 void iio_device_free(struct iio_dev *dev)
 {
        if (dev)
@@ -984,6 +997,20 @@ static int devm_iio_device_match(struct device *dev, void *res, void *data)
        return *r == data;
 }
 
+/**
+ * devm_iio_device_alloc - Resource-managed iio_device_alloc()
+ * @dev:               Device to allocate iio_dev for
+ * @sizeof_priv:       Space to allocate for private structure.
+ *
+ * Managed iio_device_alloc. iio_dev allocated with this function is
+ * automatically freed on driver detach.
+ *
+ * If an iio_dev allocated with this function needs to be freed separately,
+ * devm_iio_device_free() must be used.
+ *
+ * RETURNS:
+ * Pointer to allocated iio_dev on success, NULL on failure.
+ */
 struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
 {
        struct iio_dev **ptr, *iio_dev;
@@ -1006,6 +1033,13 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
 }
 EXPORT_SYMBOL_GPL(devm_iio_device_alloc);
 
+/**
+ * devm_iio_device_free - Resource-managed iio_device_free()
+ * @dev:               Device this iio_dev belongs to
+ * @iio_dev:           the iio_dev associated with the device
+ *
+ * Free iio_dev allocated with devm_iio_device_alloc().
+ */
 void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev)
 {
        int rc;
@@ -1080,6 +1114,10 @@ static const struct file_operations iio_buffer_fileops = {
 
 static const struct iio_buffer_setup_ops noop_ring_setup_ops;
 
+/**
+ * iio_device_register() - register a device with the IIO subsystem
+ * @indio_dev:         Device structure filled by the device driver
+ **/
 int iio_device_register(struct iio_dev *indio_dev)
 {
        int ret;
@@ -1141,6 +1179,10 @@ error_ret:
 }
 EXPORT_SYMBOL(iio_device_register);
 
+/**
+ * iio_device_unregister() - unregister a device from the IIO subsystem
+ * @indio_dev:         Device structure representing the device.
+ **/
 void iio_device_unregister(struct iio_dev *indio_dev)
 {
        mutex_lock(&indio_dev->info_exist_lock);
@@ -1161,6 +1203,65 @@ void iio_device_unregister(struct iio_dev *indio_dev)
        mutex_unlock(&indio_dev->info_exist_lock);
 }
 EXPORT_SYMBOL(iio_device_unregister);
+
+static void devm_iio_device_unreg(struct device *dev, void *res)
+{
+       iio_device_unregister(*(struct iio_dev **)res);
+}
+
+/**
+ * devm_iio_device_register - Resource-managed iio_device_register()
+ * @dev:       Device to allocate iio_dev for
+ * @indio_dev: Device structure filled by the device driver
+ *
+ * Managed iio_device_register.  The IIO device registered with this
+ * function is automatically unregistered on driver detach. This function
+ * calls iio_device_register() internally. Refer to that function for more
+ * information.
+ *
+ * If an iio_dev registered with this function needs to be unregistered
+ * separately, devm_iio_device_unregister() must be used.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev)
+{
+       struct iio_dev **ptr;
+       int ret;
+
+       ptr = devres_alloc(devm_iio_device_unreg, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return -ENOMEM;
+
+       *ptr = indio_dev;
+       ret = iio_device_register(indio_dev);
+       if (!ret)
+               devres_add(dev, ptr);
+       else
+               devres_free(ptr);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_register);
+
+/**
+ * devm_iio_device_unregister - Resource-managed iio_device_unregister()
+ * @dev:       Device this iio_dev belongs to
+ * @indio_dev: the iio_dev associated with the device
+ *
+ * Unregister iio_dev registered with devm_iio_device_register().
+ */
+void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev)
+{
+       int rc;
+
+       rc = devres_release(dev, devm_iio_device_unreg,
+                           devm_iio_device_match, indio_dev);
+       WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_unregister);
+
 subsys_initcall(iio_init);
 module_exit(iio_exit);
 
index c10eab64bc0524eca6caa476d224c370fcd49262..bc043fab4cd12cbcd86f182e67d69b4da78f8a07 100644 (file)
@@ -42,6 +42,12 @@ struct iio_event_interface {
        struct attribute_group  group;
 };
 
+/**
+ * iio_push_event() - try to add event to the list for userspace reading
+ * @indio_dev:         IIO device structure
+ * @ev_code:           What event
+ * @timestamp:         When the event occurred
+ **/
 int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
 {
        struct iio_event_interface *ev_int = indio_dev->event_interface;
index bf5e70a32d3fb6011be6324c20ad45d4ba704064..7ba2f002ffcad423527d096703c099b5007d116c 100644 (file)
@@ -318,7 +318,7 @@ static ssize_t iio_trigger_read_current(struct device *dev,
  * iio_trigger_write_current() - trigger consumer sysfs set current trigger
  *
  * For trigger consumers the current_trigger interface allows the trigger
- * used for this device to be specified at run time based on the triggers
+ * used for this device to be specified at run time based on the trigger's
  * name.
  **/
 static ssize_t iio_trigger_write_current(struct device *dev,
@@ -356,7 +356,7 @@ static ssize_t iio_trigger_write_current(struct device *dev,
 
        indio_dev->trig = trig;
 
-       if (oldtrig && indio_dev->trig != oldtrig)
+       if (oldtrig)
                iio_trigger_put(oldtrig);
        if (indio_dev->trig)
                iio_trigger_get(indio_dev->trig);
@@ -506,6 +506,23 @@ static int devm_iio_trigger_match(struct device *dev, void *res, void *data)
        return *r == data;
 }
 
+/**
+ * devm_iio_trigger_alloc - Resource-managed iio_trigger_alloc()
+ * @dev:               Device to allocate iio_trigger for
+ * @fmt:               trigger name format. If it includes format
+ *                     specifiers, the additional arguments following
+ *                     format are formatted and inserted in the resulting
+ *                     string replacing their respective specifiers.
+ *
+ * Managed iio_trigger_alloc.  iio_trigger allocated with this function is
+ * automatically freed on driver detach.
+ *
+ * If an iio_trigger allocated with this function needs to be freed separately,
+ * devm_iio_trigger_free() must be used.
+ *
+ * RETURNS:
+ * Pointer to allocated iio_trigger on success, NULL on failure.
+ */
 struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
                                                const char *fmt, ...)
 {
@@ -532,6 +549,13 @@ struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc);
 
+/**
+ * devm_iio_trigger_free - Resource-managed iio_trigger_free()
+ * @dev:               Device this iio_dev belongs to
+ * @iio_trig:          the iio_trigger associated with the device
+ *
+ * Free iio_trigger allocated with devm_iio_trigger_alloc().
+ */
 void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig)
 {
        int rc;
index f98c2b509254e2b8fdce8cd77db408f11b244495..b0d65df3ede2050d4c9944e819b45917ef945c87 100644 (file)
@@ -81,6 +81,8 @@ config SENSORS_LM3533
 config TCS3472
        tristate "TAOS TCS3472 color light-to-digital converter"
        depends on I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
         If you say yes here you get support for the TAOS TCS3472
         family of color light-to-digital converters with IR filter.
index fa6ae8cf89eaa9edfdfffe379939bc7cc8a491f0..621541fb10a9867ea8cecbbecd532b3be65fd3e3 100644 (file)
@@ -229,6 +229,17 @@ static int als_parse_report(struct platform_device *pdev,
        dev_dbg(&pdev->dev, "als %x:%x\n", st->als_illum.index,
                        st->als_illum.report_id);
 
+       /* Set Sensitivity field ids, when there is no individual modifier */
+       if (st->common_attributes.sensitivity.index < 0) {
+               sensor_hub_input_get_attribute_info(hsdev,
+                       HID_FEATURE_REPORT, usage_id,
+                       HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+                       HID_USAGE_SENSOR_DATA_LIGHT,
+                       &st->common_attributes.sensitivity);
+               dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n",
+                       st->common_attributes.sensitivity.index,
+                       st->common_attributes.sensitivity.report_id);
+       }
        return ret;
 }
 
@@ -314,7 +325,7 @@ static int hid_als_probe(struct platform_device *pdev)
 error_iio_unreg:
        iio_device_unregister(indio_dev);
 error_remove_trigger:
-       hid_sensor_remove_trigger(indio_dev);
+       hid_sensor_remove_trigger(&als_state->common_attributes);
 error_unreg_buffer_funcs:
        iio_triggered_buffer_cleanup(indio_dev);
 error_free_dev_mem:
@@ -327,10 +338,11 @@ static int hid_als_remove(struct platform_device *pdev)
 {
        struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+       struct als_state *als_state = iio_priv(indio_dev);
 
        sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ALS);
        iio_device_unregister(indio_dev);
-       hid_sensor_remove_trigger(indio_dev);
+       hid_sensor_remove_trigger(&als_state->common_attributes);
        iio_triggered_buffer_cleanup(indio_dev);
        kfree(indio_dev->channels);
 
index 5e5d9dea22c598016c225848333c1e31595c811f..0c6e459c86b1de6450e8de0fa05b3a3f8df57a3b 100644 (file)
@@ -714,6 +714,7 @@ static int tsl2563_probe(struct i2c_client *client,
        struct iio_dev *indio_dev;
        struct tsl2563_chip *chip;
        struct tsl2563_platform_data *pdata = client->dev.platform_data;
+       struct device_node *np = client->dev.of_node;
        int err = 0;
        u8 id = 0;
 
@@ -750,6 +751,9 @@ static int tsl2563_probe(struct i2c_client *client,
 
        if (pdata)
                chip->cover_comp_gain = pdata->cover_comp_gain;
+       else if (np)
+               of_property_read_u32(np, "amstaos,cover-comp-gain",
+                                    &chip->cover_comp_gain);
        else
                chip->cover_comp_gain = 1;
 
index ecb3341ef9c07a8e56ddaf1de8d76d31456e6d2a..384ac23f576f3dddcfa276f8070b8b8009b099c6 100644 (file)
@@ -179,13 +179,7 @@ static int vcnl4000_probe(struct i2c_client *client,
        indio_dev->name = VCNL4000_DRV_NAME;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
-       return iio_device_register(indio_dev);
-}
-
-static int vcnl4000_remove(struct i2c_client *client)
-{
-       iio_device_unregister(i2c_get_clientdata(client));
-       return 0;
+       return devm_iio_device_register(&client->dev, indio_dev);
 }
 
 static struct i2c_driver vcnl4000_driver = {
@@ -194,7 +188,6 @@ static struct i2c_driver vcnl4000_driver = {
                .owner  = THIS_MODULE,
        },
        .probe  = vcnl4000_probe,
-       .remove = vcnl4000_remove,
        .id_table = vcnl4000_id,
 };
 
index 0cf09637b35b64f16a37c3adece1416cc453fee1..d86d226dcd67e09b585652ef983c9ccb038cdb99 100644 (file)
@@ -19,6 +19,8 @@ config AK8975
 config MAG3110
        tristate "Freescale MAG3110 3-Axis Magnetometer"
        depends on I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for the Freescale MAG3110 3-Axis
          magnetometer.
index 2634920562fb7263bad4ac9d8c6c75fe7a434b49..6d162b7e7af5835a16b2c8e276374ea084874204 100644 (file)
@@ -263,6 +263,18 @@ static int magn_3d_parse_report(struct platform_device *pdev,
                        st->magn[1].index, st->magn[1].report_id,
                        st->magn[2].index, st->magn[2].report_id);
 
+       /* Set Sensitivity field ids, when there is no individual modifier */
+       if (st->common_attributes.sensitivity.index < 0) {
+               sensor_hub_input_get_attribute_info(hsdev,
+                       HID_FEATURE_REPORT, usage_id,
+                       HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+                       HID_USAGE_SENSOR_DATA_ORIENTATION,
+                       &st->common_attributes.sensitivity);
+               dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n",
+                       st->common_attributes.sensitivity.index,
+                       st->common_attributes.sensitivity.report_id);
+       }
+
        return ret;
 }
 
@@ -351,7 +363,7 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
 error_iio_unreg:
        iio_device_unregister(indio_dev);
 error_remove_trigger:
-       hid_sensor_remove_trigger(indio_dev);
+       hid_sensor_remove_trigger(&magn_state->common_attributes);
 error_unreg_buffer_funcs:
        iio_triggered_buffer_cleanup(indio_dev);
 error_free_dev_mem:
@@ -364,10 +376,11 @@ static int hid_magn_3d_remove(struct platform_device *pdev)
 {
        struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+       struct magn_3d_state *magn_state = iio_priv(indio_dev);
 
        sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
        iio_device_unregister(indio_dev);
-       hid_sensor_remove_trigger(indio_dev);
+       hid_sensor_remove_trigger(&magn_state->common_attributes);
        iio_triggered_buffer_cleanup(indio_dev);
        kfree(indio_dev->channels);
 
index 783c5b417356e0ecaf0d3c095f33c2b4a24fa496..becf54496967aee126fb6449b54341394645d9bd 100644 (file)
@@ -250,7 +250,12 @@ done:
        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
                BIT(IIO_CHAN_INFO_SCALE), \
        .scan_index = idx, \
-       .scan_type = IIO_ST('s', 16, 16, IIO_BE), \
+       .scan_type = { \
+               .sign = 's', \
+               .realbits = 16, \
+               .storagebits = 16, \
+               .endianness = IIO_BE, \
+       }, \
 }
 
 static const struct iio_chan_spec mag3110_channels[] = {
index 4f2e0f9bad8c100d89a43265daa0af8bb3b7450b..a8b9cae5c17355ba8268308d5428fd38c6cc6b55 100644 (file)
@@ -5,6 +5,18 @@
 
 menu "Pressure sensors"
 
+config MPL3115
+       tristate "Freescale MPL3115A2 pressure sensor driver"
+       depends on I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       help
+         Say yes here to build support for the Freescale MPL3115A2
+         pressure sensor / altimeter.
+
+          To compile this driver as a module, choose M here: the module
+          will be called mpl3115.
+
 config IIO_ST_PRESS
        tristate "STMicroelectronics pressure sensor Driver"
        depends on (I2C || SPI_MASTER) && SYSFS
index be71464c27525be86adcf577be3d04dea0978f6e..42bb9fcf54362d7abbbc4e21cd757443608c38fa 100644 (file)
@@ -3,6 +3,7 @@
 #
 
 # When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_MPL3115) += mpl3115.o
 obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o
 st_pressure-y := st_pressure_core.o
 st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o
diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c
new file mode 100644 (file)
index 0000000..ac8c8ab
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * mpl3115.c - Support for Freescale MPL3115A2 pressure/temperature sensor
+ *
+ * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * (7-bit I2C slave address 0x60)
+ *
+ * TODO: FIFO buffer, altimeter mode, oversampling, continuous mode,
+ * interrupts, user offset correction, raw mode
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/delay.h>
+
+#define MPL3115_STATUS 0x00
+#define MPL3115_OUT_PRESS 0x01 /* MSB first, 20 bit */
+#define MPL3115_OUT_TEMP 0x04 /* MSB first, 12 bit */
+#define MPL3115_WHO_AM_I 0x0c
+#define MPL3115_CTRL_REG1 0x26
+
+#define MPL3115_DEVICE_ID 0xc4
+
+#define MPL3115_STATUS_PRESS_RDY BIT(2)
+#define MPL3115_STATUS_TEMP_RDY BIT(1)
+
+#define MPL3115_CTRL_RESET BIT(2) /* software reset */
+#define MPL3115_CTRL_OST BIT(1) /* initiate measurement */
+#define MPL3115_CTRL_ACTIVE BIT(0) /* continuous measurement */
+#define MPL3115_CTRL_OS_258MS (BIT(5) | BIT(4)) /* 64x oversampling */
+
+struct mpl3115_data {
+       struct i2c_client *client;
+       struct mutex lock;
+       u8 ctrl_reg1;
+};
+
+static int mpl3115_request(struct mpl3115_data *data)
+{
+       int ret, tries = 15;
+
+       /* trigger measurement */
+       ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
+               data->ctrl_reg1 | MPL3115_CTRL_OST);
+       if (ret < 0)
+               return ret;
+
+       while (tries-- > 0) {
+               ret = i2c_smbus_read_byte_data(data->client, MPL3115_CTRL_REG1);
+               if (ret < 0)
+                       return ret;
+               /* wait for data ready, i.e. OST cleared */
+               if (!(ret & MPL3115_CTRL_OST))
+                       break;
+               msleep(20);
+       }
+
+       if (tries < 0) {
+               dev_err(&data->client->dev, "data not ready\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int mpl3115_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int *val, int *val2, long mask)
+{
+       struct mpl3115_data *data = iio_priv(indio_dev);
+       s32 tmp = 0;
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (iio_buffer_enabled(indio_dev))
+                       return -EBUSY;
+
+               switch (chan->type) {
+               case IIO_PRESSURE: /* in 0.25 pascal / LSB */
+                       mutex_lock(&data->lock);
+                       ret = mpl3115_request(data);
+                       if (ret < 0) {
+                               mutex_unlock(&data->lock);
+                               return ret;
+                       }
+                       ret = i2c_smbus_read_i2c_block_data(data->client,
+                               MPL3115_OUT_PRESS, 3, (u8 *) &tmp);
+                       mutex_unlock(&data->lock);
+                       if (ret < 0)
+                               return ret;
+                       *val = sign_extend32(be32_to_cpu(tmp) >> 12, 23);
+                       return IIO_VAL_INT;
+               case IIO_TEMP: /* in 0.0625 celsius / LSB */
+                       mutex_lock(&data->lock);
+                       ret = mpl3115_request(data);
+                       if (ret < 0) {
+                               mutex_unlock(&data->lock);
+                               return ret;
+                       }
+                       ret = i2c_smbus_read_i2c_block_data(data->client,
+                               MPL3115_OUT_TEMP, 2, (u8 *) &tmp);
+                       mutex_unlock(&data->lock);
+                       if (ret < 0)
+                               return ret;
+                       *val = sign_extend32(be32_to_cpu(tmp) >> 20, 15);
+                       return IIO_VAL_INT;
+               default:
+                       return -EINVAL;
+               }
+       case IIO_CHAN_INFO_SCALE:
+               switch (chan->type) {
+               case IIO_PRESSURE:
+                       *val = 0;
+                       *val2 = 250; /* want kilopascal */
+                       return IIO_VAL_INT_PLUS_MICRO;
+               case IIO_TEMP:
+                       *val = 0;
+                       *val2 = 62500;
+                       return IIO_VAL_INT_PLUS_MICRO;
+               default:
+                       return -EINVAL;
+               }
+       }
+       return -EINVAL;
+}
+
+static irqreturn_t mpl3115_trigger_handler(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct mpl3115_data *data = iio_priv(indio_dev);
+       u8 buffer[16]; /* 32-bit channel + 16-bit channel + padding + ts */
+       int ret, pos = 0;
+
+       mutex_lock(&data->lock);
+       ret = mpl3115_request(data);
+       if (ret < 0) {
+               mutex_unlock(&data->lock);
+               goto done;
+       }
+
+       memset(buffer, 0, sizeof(buffer));
+       if (test_bit(0, indio_dev->active_scan_mask)) {
+               ret = i2c_smbus_read_i2c_block_data(data->client,
+                       MPL3115_OUT_PRESS, 3, &buffer[pos]);
+               if (ret < 0) {
+                       mutex_unlock(&data->lock);
+                       goto done;
+               }
+               pos += 4;
+       }
+
+       if (test_bit(1, indio_dev->active_scan_mask)) {
+               ret = i2c_smbus_read_i2c_block_data(data->client,
+                       MPL3115_OUT_TEMP, 2, &buffer[pos]);
+               if (ret < 0) {
+                       mutex_unlock(&data->lock);
+                       goto done;
+               }
+       }
+       mutex_unlock(&data->lock);
+
+       iio_push_to_buffers_with_timestamp(indio_dev, buffer,
+               iio_get_time_ns());
+
+done:
+       iio_trigger_notify_done(indio_dev->trig);
+       return IRQ_HANDLED;
+}
+
+static const struct iio_chan_spec mpl3115_channels[] = {
+       {
+               .type = IIO_PRESSURE,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+                       BIT(IIO_CHAN_INFO_SCALE),
+               .scan_index = 0,
+               .scan_type = {
+                       .sign = 's',
+                       .realbits = 20,
+                       .storagebits = 32,
+                       .shift = 12,
+                       .endianness = IIO_BE,
+               }
+       },
+       {
+               .type = IIO_TEMP,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+                       BIT(IIO_CHAN_INFO_SCALE),
+               .scan_index = 1,
+               .scan_type = {
+                       .sign = 's',
+                       .realbits = 12,
+                       .storagebits = 16,
+                       .shift = 4,
+                       .endianness = IIO_BE,
+               }
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(2),
+};
+
+static const struct iio_info mpl3115_info = {
+       .read_raw = &mpl3115_read_raw,
+       .driver_module = THIS_MODULE,
+};
+
+static int mpl3115_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct mpl3115_data *data;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       ret = i2c_smbus_read_byte_data(client, MPL3115_WHO_AM_I);
+       if (ret < 0)
+               return ret;
+       if (ret != MPL3115_DEVICE_ID)
+               return -ENODEV;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       data->client = client;
+       mutex_init(&data->lock);
+
+       i2c_set_clientdata(client, indio_dev);
+       indio_dev->info = &mpl3115_info;
+       indio_dev->name = id->name;
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = mpl3115_channels;
+       indio_dev->num_channels = ARRAY_SIZE(mpl3115_channels);
+
+       /* software reset, I2C transfer is aborted (fails) */
+       i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
+               MPL3115_CTRL_RESET);
+       msleep(50);
+
+       data->ctrl_reg1 = MPL3115_CTRL_OS_258MS;
+       ret = i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
+               data->ctrl_reg1);
+       if (ret < 0)
+               return ret;
+
+       ret = iio_triggered_buffer_setup(indio_dev, NULL,
+               mpl3115_trigger_handler, NULL);
+       if (ret < 0)
+               return ret;
+
+       ret = iio_device_register(indio_dev);
+       if (ret < 0)
+               goto buffer_cleanup;
+       return 0;
+
+buffer_cleanup:
+       iio_triggered_buffer_cleanup(indio_dev);
+       return ret;
+}
+
+static int mpl3115_standby(struct mpl3115_data *data)
+{
+       return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
+               data->ctrl_reg1 & ~MPL3115_CTRL_ACTIVE);
+}
+
+static int mpl3115_remove(struct i2c_client *client)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+       iio_device_unregister(indio_dev);
+       iio_triggered_buffer_cleanup(indio_dev);
+       mpl3115_standby(iio_priv(indio_dev));
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mpl3115_suspend(struct device *dev)
+{
+       return mpl3115_standby(iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev))));
+}
+
+static int mpl3115_resume(struct device *dev)
+{
+       struct mpl3115_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
+
+       return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
+               data->ctrl_reg1);
+}
+
+static SIMPLE_DEV_PM_OPS(mpl3115_pm_ops, mpl3115_suspend, mpl3115_resume);
+#define MPL3115_PM_OPS (&mpl3115_pm_ops)
+#else
+#define MPL3115_PM_OPS NULL
+#endif
+
+static const struct i2c_device_id mpl3115_id[] = {
+       { "mpl3115", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, mpl3115_id);
+
+static struct i2c_driver mpl3115_driver = {
+       .driver = {
+               .name   = "mpl3115",
+               .pm     = MPL3115_PM_OPS,
+       },
+       .probe = mpl3115_probe,
+       .remove = mpl3115_remove,
+       .id_table = mpl3115_id,
+};
+module_i2c_driver(mpl3115_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Freescale MPL3115 pressure/temperature driver");
+MODULE_LICENSE("GPL");
index dbd2047f1641f0751340eade88c408f31201f318..3ed23513d881301fa06c1bde1ed14f56546d0147 100644 (file)
@@ -536,7 +536,8 @@ static int adp5588_probe(struct i2c_client *client,
                __set_bit(EV_REP, input->evbit);
 
        for (i = 0; i < input->keycodemax; i++)
-               __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit);
+               if (kpad->keycode[i] <= KEY_MAX)
+                       __set_bit(kpad->keycode[i], input->keybit);
        __clear_bit(KEY_RESERVED, input->keybit);
 
        if (kpad->gpimapsize)
index 67d12b3427c9ee9bcb5da69d276a6bc814467586..60dafd4fa692e1d41457c471d5a79ef0bcdf21f0 100644 (file)
@@ -992,7 +992,8 @@ static int adp5589_probe(struct i2c_client *client,
                __set_bit(EV_REP, input->evbit);
 
        for (i = 0; i < input->keycodemax; i++)
-               __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit);
+               if (kpad->keycode[i] <= KEY_MAX)
+                       __set_bit(kpad->keycode[i], input->keybit);
        __clear_bit(KEY_RESERVED, input->keybit);
 
        if (kpad->gpimapsize)
index fc88fb48d70d6740ef96f8fdbe9afc32760218c5..09b91d09308780ceebc25d9f860f88eb56b68183 100644 (file)
@@ -289,7 +289,8 @@ static int bfin_kpad_probe(struct platform_device *pdev)
                __set_bit(EV_REP, input->evbit);
 
        for (i = 0; i < input->keycodemax; i++)
-               __set_bit(bf54x_kpad->keycode[i] & KEY_MAX, input->keybit);
+               if (bf54x_kpad->keycode[i] <= KEY_MAX)
+                       __set_bit(bf54x_kpad->keycode[i], input->keybit);
        __clear_bit(KEY_RESERVED, input->keybit);
 
        error = input_register_device(input);
index 5f4967d01bc36a621655f64eea7e2c1408ef43b7..4ffc39732513fcd0a20a28d611c2b077ccd0e6bb 100644 (file)
@@ -222,6 +222,15 @@ config INPUT_GP2A
          To compile this driver as a module, choose M here: the
          module will be called gp2ap002a00f.
 
+config INPUT_GPIO_BEEPER
+       tristate "Generic GPIO Beeper support"
+       depends on OF_GPIO
+       help
+         Say Y here if you have a beeper connected to a GPIO pin.
+
+         To compile this driver as a module, choose M here: the
+         module will be called gpio-beeper.
+
 config INPUT_GPIO_TILT_POLLED
        tristate "Polled GPIO tilt switch"
        depends on GPIOLIB
index 0ebfb6dbf0f7788afd75b7a88bd171ff90b567b6..cda71fc52fb3a6bd026bd5edf878f03834996b88 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_INPUT_DA9052_ONKEY)      += da9052_onkey.o
 obj-$(CONFIG_INPUT_DA9055_ONKEY)       += da9055_onkey.o
 obj-$(CONFIG_INPUT_DM355EVM)           += dm355evm_keys.o
 obj-$(CONFIG_INPUT_GP2A)               += gp2ap002a00f.o
+obj-$(CONFIG_INPUT_GPIO_BEEPER)                += gpio-beeper.o
 obj-$(CONFIG_INPUT_GPIO_TILT_POLLED)   += gpio_tilt_polled.o
 obj-$(CONFIG_HP_SDC_RTC)               += hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IMS_PCU)            += ims-pcu.o
index 5d4402365a5207258dbd9b4b7d68f18489fa1598..d781b5e520655f074071fb6fc6f9a6e9390086bd 100644 (file)
@@ -28,8 +28,8 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/types.h>
+#include <linux/acpi.h>
 #include <asm/uaccess.h>
-#include <acpi/acpi_drivers.h>
 
 #define ACPI_ATLAS_NAME                "Atlas ACPI"
 #define ACPI_ATLAS_CLASS       "Atlas"
diff --git a/drivers/input/misc/gpio-beeper.c b/drivers/input/misc/gpio-beeper.c
new file mode 100644 (file)
index 0000000..b757435
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Generic GPIO beeper driver
+ *
+ * Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+
+#define BEEPER_MODNAME         "gpio-beeper"
+
+struct gpio_beeper {
+       struct work_struct      work;
+       int                     gpio;
+       bool                    active_low;
+       bool                    beeping;
+};
+
+static void gpio_beeper_toggle(struct gpio_beeper *beep, bool on)
+{
+       gpio_set_value_cansleep(beep->gpio, on ^ beep->active_low);
+}
+
+static void gpio_beeper_work(struct work_struct *work)
+{
+       struct gpio_beeper *beep = container_of(work, struct gpio_beeper, work);
+
+       gpio_beeper_toggle(beep, beep->beeping);
+}
+
+static int gpio_beeper_event(struct input_dev *dev, unsigned int type,
+                            unsigned int code, int value)
+{
+       struct gpio_beeper *beep = input_get_drvdata(dev);
+
+       if (type != EV_SND || code != SND_BELL)
+               return -ENOTSUPP;
+
+       if (value < 0)
+               return -EINVAL;
+
+       beep->beeping = value;
+       /* Schedule work to actually turn the beeper on or off */
+       schedule_work(&beep->work);
+
+       return 0;
+}
+
+static void gpio_beeper_close(struct input_dev *input)
+{
+       struct gpio_beeper *beep = input_get_drvdata(input);
+
+       cancel_work_sync(&beep->work);
+       gpio_beeper_toggle(beep, false);
+}
+
+static int gpio_beeper_probe(struct platform_device *pdev)
+{
+       struct gpio_beeper *beep;
+       enum of_gpio_flags flags;
+       struct input_dev *input;
+       unsigned long gflags;
+       int err;
+
+       beep = devm_kzalloc(&pdev->dev, sizeof(*beep), GFP_KERNEL);
+       if (!beep)
+               return -ENOMEM;
+
+       beep->gpio = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
+       if (!gpio_is_valid(beep->gpio))
+               return beep->gpio;
+
+       input = devm_input_allocate_device(&pdev->dev);
+       if (!input)
+               return -ENOMEM;
+
+       INIT_WORK(&beep->work, gpio_beeper_work);
+
+       input->name             = pdev->name;
+       input->id.bustype       = BUS_HOST;
+       input->id.vendor        = 0x0001;
+       input->id.product       = 0x0001;
+       input->id.version       = 0x0100;
+       input->close            = gpio_beeper_close;
+       input->event            = gpio_beeper_event;
+
+       input_set_capability(input, EV_SND, SND_BELL);
+
+       beep->active_low = flags & OF_GPIO_ACTIVE_LOW;
+       gflags = beep->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+
+       err = devm_gpio_request_one(&pdev->dev, beep->gpio, gflags, pdev->name);
+       if (err)
+               return err;
+
+       input_set_drvdata(input, beep);
+
+       return input_register_device(input);
+}
+
+static struct of_device_id gpio_beeper_of_match[] = {
+       { .compatible = BEEPER_MODNAME, },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gpio_beeper_of_match);
+
+static struct platform_driver gpio_beeper_platform_driver = {
+       .driver = {
+               .name           = BEEPER_MODNAME,
+               .owner          = THIS_MODULE,
+               .of_match_table = gpio_beeper_of_match,
+       },
+       .probe  = gpio_beeper_probe,
+};
+module_platform_driver(gpio_beeper_platform_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("Generic GPIO beeper driver");
index 86b822806e95b504f9f4b23303365cff0d6b6a1d..45e0e3e55de28dfdbdfb347ebdba74ca2e698544 100644 (file)
@@ -180,7 +180,10 @@ static int64_t hp_sdc_rtc_read_i8042timer (uint8_t loadcmd, int numreg)
        if (WARN_ON(down_interruptible(&i8042tregs)))
                return -1;
 
-       if (hp_sdc_enqueue_transaction(&t)) return -1;
+       if (hp_sdc_enqueue_transaction(&t)) {
+               up(&i8042tregs);
+               return -1;
+       }
        
        /* Sleep until results come back. */
        if (WARN_ON(down_interruptible(&i8042tregs)))
index e37392976fdd5f3f252ca5f2af2a2477fc8265b7..0deca5a3c87fe1adacdce8259a052738486749cb 100644 (file)
@@ -113,9 +113,12 @@ static int pcf8574_kp_probe(struct i2c_client *client, const struct i2c_device_i
        idev->keycodemax = ARRAY_SIZE(lp->btncode);
 
        for (i = 0; i < ARRAY_SIZE(pcf8574_kp_btncode); i++) {
-               lp->btncode[i] = pcf8574_kp_btncode[i];
-               __set_bit(lp->btncode[i] & KEY_MAX, idev->keybit);
+               if (lp->btncode[i] <= KEY_MAX) {
+                       lp->btncode[i] = pcf8574_kp_btncode[i];
+                       __set_bit(lp->btncode[i], idev->keybit);
+               }
        }
+       __clear_bit(KEY_RESERVED, idev->keybit);
 
        sprintf(lp->name, DRV_NAME);
        sprintf(lp->phys, "kp_data/input0");
index b9a05fda03e402c2d8e382626a890d6099604231..fb3b63b2f85c3615619452ef9ee2e6f0528d8245 100644 (file)
@@ -52,15 +52,15 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr)
        return IRQ_HANDLED;
 }
 
-static int __init twl4030_pwrbutton_probe(struct platform_device *pdev)
+static int twl4030_pwrbutton_probe(struct platform_device *pdev)
 {
        struct input_dev *pwr;
        int irq = platform_get_irq(pdev, 0);
        int err;
 
-       pwr = input_allocate_device();
+       pwr = devm_input_allocate_device(&pdev->dev);
        if (!pwr) {
-               dev_dbg(&pdev->dev, "Can't allocate power button\n");
+               dev_err(&pdev->dev, "Can't allocate power button\n");
                return -ENOMEM;
        }
 
@@ -70,52 +70,42 @@ static int __init twl4030_pwrbutton_probe(struct platform_device *pdev)
        pwr->phys = "twl4030_pwrbutton/input0";
        pwr->dev.parent = &pdev->dev;
 
-       err = request_threaded_irq(irq, NULL, powerbutton_irq,
+       err = devm_request_threaded_irq(&pwr->dev, irq, NULL, powerbutton_irq,
                        IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
                        "twl4030_pwrbutton", pwr);
        if (err < 0) {
-               dev_dbg(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err);
-               goto free_input_dev;
+               dev_err(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err);
+               return err;
        }
 
        err = input_register_device(pwr);
        if (err) {
-               dev_dbg(&pdev->dev, "Can't register power button: %d\n", err);
-               goto free_irq;
+               dev_err(&pdev->dev, "Can't register power button: %d\n", err);
+               return err;
        }
 
        platform_set_drvdata(pdev, pwr);
 
        return 0;
-
-free_irq:
-       free_irq(irq, pwr);
-free_input_dev:
-       input_free_device(pwr);
-       return err;
 }
 
-static int __exit twl4030_pwrbutton_remove(struct platform_device *pdev)
-{
-       struct input_dev *pwr = platform_get_drvdata(pdev);
-       int irq = platform_get_irq(pdev, 0);
-
-       free_irq(irq, pwr);
-       input_unregister_device(pwr);
-
-       return 0;
-}
+#ifdef CONFIG_OF
+static const struct of_device_id twl4030_pwrbutton_dt_match_table[] = {
+       { .compatible = "ti,twl4030-pwrbutton" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, twl4030_pwrbutton_dt_match_table);
+#endif
 
 static struct platform_driver twl4030_pwrbutton_driver = {
-       .remove         = __exit_p(twl4030_pwrbutton_remove),
+       .probe          = twl4030_pwrbutton_probe,
        .driver         = {
                .name   = "twl4030_pwrbutton",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(twl4030_pwrbutton_dt_match_table),
        },
 };
-
-module_platform_driver_probe(twl4030_pwrbutton_driver,
-                       twl4030_pwrbutton_probe);
+module_platform_driver(twl4030_pwrbutton_driver);
 
 MODULE_ALIAS("platform:twl4030_pwrbutton");
 MODULE_DESCRIPTION("Triton2 Power Button");
index 4e2fd44865e1cad4819db1a7f959912a76adaabf..b7c206db0df86fd34053f644b07e8b92abf2c4c0 100644 (file)
@@ -167,8 +167,6 @@ static int amba_kmi_remove(struct amba_device *dev)
 {
        struct amba_kmi_port *kmi = amba_get_drvdata(dev);
 
-       amba_set_drvdata(dev, NULL);
-
        serio_unregister_port(kmi->io);
        clk_put(kmi->clk);
        iounmap(kmi->base);
index 76f83836fd5a557b513eb8d3e91b2e964bfa5507..13062f667e82650467495702b35b038cff616130 100644 (file)
@@ -181,7 +181,6 @@ static void pcips2_remove(struct pci_dev *dev)
        struct pcips2_data *ps2if = pci_get_drvdata(dev);
 
        serio_unregister_port(ps2if->io);
-       pci_set_drvdata(dev, NULL);
        kfree(ps2if);
        pci_release_regions(dev);
        pci_disable_device(dev);
index 867e7c33ac55072b19f2ff339705c4e90f6b428d..8318826d976eabdc55a5cd1c13269d720901edcf 100644 (file)
@@ -304,7 +304,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
        struct usb_device *dev = interface_to_usbdev(intf);
        char limit = 0;
        /* result has to be defined as int for some devices */
-       int result = 0;
+       int result = 0, touch_max = 0;
        int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
        unsigned char *report;
 
@@ -351,7 +351,8 @@ static int wacom_parse_hid(struct usb_interface *intf,
                                if (usage == WCM_DESKTOP) {
                                        if (finger) {
                                                features->device_type = BTN_TOOL_FINGER;
-
+                                               /* touch device at least supports one touch point */
+                                               touch_max = 1;
                                                switch (features->type) {
                                                case TABLETPC2FG:
                                                        features->pktlen = WACOM_PKGLEN_TPC2FG;
@@ -504,6 +505,8 @@ static int wacom_parse_hid(struct usb_interface *intf,
        }
 
  out:
+       if (!features->touch_max && touch_max)
+               features->touch_max = touch_max;
        result = 0;
        kfree(report);
        return result;
@@ -1199,7 +1202,8 @@ static void wacom_wireless_work(struct work_struct *work)
                        goto fail;
 
                /* Touch interface */
-               if (wacom_wac1->features.touch_max) {
+               if (wacom_wac1->features.touch_max ||
+                   wacom_wac1->features.type == INTUOSHT) {
                        wacom_wac2->features =
                                *((struct wacom_features *)id->driver_info);
                        wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
@@ -1322,7 +1326,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
         * HID descriptor. If this is the touch interface (wMaxPacketSize
         * of WACOM_PKGLEN_BBTOUCH3), override the table values.
         */
-       if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
+       if (features->type >= INTUOS5S && features->type <= INTUOSHT) {
                if (endpoint->wMaxPacketSize == WACOM_PKGLEN_BBTOUCH3) {
                        features->device_type = BTN_TOOL_FINGER;
                        features->pktlen = WACOM_PKGLEN_BBTOUCH3;
@@ -1392,7 +1396,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
                        goto fail5;
                }
        }
-
        return 0;
 
  fail5: wacom_destroy_leds(wacom);
index 782c2535f1d81a26db96716ac406405b2b03a78b..7655088f78e0efc4bab45fa62cfc442230b460c1 100644 (file)
@@ -1151,8 +1151,8 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
                int width, height;
 
                if (features->type >= INTUOSPS && features->type <= INTUOSPL) {
-                       width  = data[5];
-                       height = data[6];
+                       width  = data[5] * 100;
+                       height = data[6] * 100;
                } else {
                        /*
                         * "a" is a scaled-down area which we assume is
@@ -1176,10 +1176,16 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
 static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
 {
        struct input_dev *input = wacom->input;
+       struct wacom_features *features = &wacom->features;
 
-       input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
+       if (features->type == INTUOSHT) {
+               input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0);
+               input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0);
+       } else {
+               input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
+               input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
+       }
        input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
-       input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
        input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
 }
 
@@ -1217,7 +1223,7 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
        unsigned char *data = wacom->data;
        int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
 
-       if (data[0] != 0x02)
+       if (data[0] != WACOM_REPORT_PENABLED)
            return 0;
 
        prox = (data[1] & 0x20) == 0x20;
@@ -1297,7 +1303,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
        unsigned char *data = wacom->data;
        int connected;
 
-       if (len != WACOM_PKGLEN_WIRELESS || data[0] != 0x80)
+       if (len != WACOM_PKGLEN_WIRELESS || data[0] != WACOM_REPORT_WL)
                return 0;
 
        connected = data[1] & 0x01;
@@ -1391,6 +1397,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
                break;
 
        case BAMBOO_PT:
+       case INTUOSHT:
                sync = wacom_bpt_irq(wacom_wac, len);
                break;
 
@@ -1459,7 +1466,7 @@ void wacom_setup_device_quirks(struct wacom_features *features)
 
        /* these device have multiple inputs */
        if (features->type >= WIRELESS ||
-           (features->type >= INTUOS5S && features->type <= INTUOSPL) ||
+           (features->type >= INTUOS5S && features->type <= INTUOSHT) ||
            (features->oVid && features->oPid))
                features->quirks |= WACOM_QUIRK_MULTI_INPUT;
 
@@ -1771,33 +1778,43 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
                break;
 
+       case INTUOSHT:
        case BAMBOO_PT:
                __clear_bit(ABS_MISC, input_dev->absbit);
 
-               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
-
                if (features->device_type == BTN_TOOL_FINGER) {
-                       unsigned int flags = INPUT_MT_POINTER;
 
                        __set_bit(BTN_LEFT, input_dev->keybit);
                        __set_bit(BTN_FORWARD, input_dev->keybit);
                        __set_bit(BTN_BACK, input_dev->keybit);
                        __set_bit(BTN_RIGHT, input_dev->keybit);
 
-                       if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
-                               input_set_abs_params(input_dev,
+                       if (features->touch_max) {
+                               /* touch interface */
+                               unsigned int flags = INPUT_MT_POINTER;
+
+                               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+                               if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
+                                       input_set_abs_params(input_dev,
                                                     ABS_MT_TOUCH_MAJOR,
                                                     0, features->x_max, 0, 0);
-                               input_set_abs_params(input_dev,
+                                       input_set_abs_params(input_dev,
                                                     ABS_MT_TOUCH_MINOR,
                                                     0, features->y_max, 0, 0);
+                               } else {
+                                       __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+                                       __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+                                       flags = 0;
+                               }
+                               input_mt_init_slots(input_dev, features->touch_max, flags);
                        } else {
-                               __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
-                               __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
-                               flags = 0;
+                               /* buttons/keys only interface */
+                               __clear_bit(ABS_X, input_dev->absbit);
+                               __clear_bit(ABS_Y, input_dev->absbit);
+                               __clear_bit(BTN_TOUCH, input_dev->keybit);
                        }
-                       input_mt_init_slots(input_dev, features->touch_max, flags);
                } else if (features->device_type == BTN_TOOL_PEN) {
+                       __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
                        __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
                        __set_bit(BTN_TOOL_PEN, input_dev->keybit);
                        __set_bit(BTN_STYLUS, input_dev->keybit);
@@ -2200,6 +2217,17 @@ static const struct wacom_features wacom_features_0x300 =
 static const struct wacom_features wacom_features_0x301 =
        { "Wacom Bamboo One M",    WACOM_PKGLEN_BBPEN,    21648, 13530, 1023,
          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x302 =
+       { "Wacom Intuos PT S",     WACOM_PKGLEN_BBPEN,    15200,  9500, 1023,
+         31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+         .touch_max = 16 };
+static const struct wacom_features wacom_features_0x303 =
+       { "Wacom Intuos PT M",     WACOM_PKGLEN_BBPEN,    21600, 13500, 1023,
+         31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+         .touch_max = 16 };
+static const struct wacom_features wacom_features_0x30E =
+       { "Wacom Intuos S",        WACOM_PKGLEN_BBPEN,    15200,  9500, 1023,
+         31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
 static const struct wacom_features wacom_features_0x6004 =
        { "ISD-V4",               WACOM_PKGLEN_GRAPHIRE,  12800,  8000,  255,
          0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -2337,6 +2365,9 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0x10F) },
        { USB_DEVICE_WACOM(0x300) },
        { USB_DEVICE_WACOM(0x301) },
+       { USB_DEVICE_DETAILED(0x302, USB_CLASS_HID, 0, 0) },
+       { USB_DEVICE_DETAILED(0x303, USB_CLASS_HID, 0, 0) },
+       { USB_DEVICE_DETAILED(0x30E, USB_CLASS_HID, 0, 0) },
        { USB_DEVICE_WACOM(0x304) },
        { USB_DEVICE_DETAILED(0x314, USB_CLASS_HID, 0, 0) },
        { USB_DEVICE_DETAILED(0x315, USB_CLASS_HID, 0, 0) },
index fd23a3790605070a41ec37f19eff051b0e89be5a..854cceb6d6deec48ba8da9432e57c6a83bd69043 100644 (file)
@@ -54,6 +54,7 @@
 #define WACOM_REPORT_TPCST             16
 #define WACOM_REPORT_TPC1FGE           18
 #define WACOM_REPORT_24HDT             1
+#define WACOM_REPORT_WL                        128
 
 /* device quirks */
 #define WACOM_QUIRK_MULTI_INPUT                0x0001
@@ -81,6 +82,7 @@ enum {
        INTUOSPS,
        INTUOSPM,
        INTUOSPL,
+       INTUOSHT,
        WACOM_21UX2,
        WACOM_22HD,
        DTK,
index 00d1e547b21119bb72e723633a08023f3eb2052f..961d58d3264769fb3daec51182effd8742bd1b5e 100644 (file)
@@ -906,6 +906,17 @@ config TOUCHSCREEN_STMPE
          To compile this driver as a module, choose M here: the
          module will be called stmpe-ts.
 
+config TOUCHSCREEN_SUR40
+       tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen"
+       depends on USB
+       select INPUT_POLLDEV
+       help
+         Say Y here if you want support for the Samsung SUR40 touchscreen
+         (also known as Microsoft Surface 2.0 or Microsoft PixelSense).
+
+         To compile this driver as a module, choose M here: the
+         module will be called sur40.
+
 config TOUCHSCREEN_TPS6507X
        tristate "TPS6507x based touchscreens"
        depends on I2C
index 7587883b8d387b30cbcf63be49f2c8cc55e58974..62801f213346a8e358af358e409e0768130744bc 100644 (file)
@@ -54,6 +54,7 @@ obj-$(CONFIG_TOUCHSCREEN_PIXCIR)      += pixcir_i2c_ts.o
 obj-$(CONFIG_TOUCHSCREEN_S3C2410)      += s3c2410_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ST1232)       += st1232.o
 obj-$(CONFIG_TOUCHSCREEN_STMPE)                += stmpe-ts.o
+obj-$(CONFIG_TOUCHSCREEN_SUR40)                += sur40.o
 obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC)        += ti_am335x_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_TNETV107X)    += tnetv107x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)   += touchit213.o
index 268a35e55d7f160fd632a673276f67ee6672665f..279c0e42b8a7515a161550621ac82dd2ccd7d0f0 100644 (file)
@@ -391,7 +391,7 @@ static int __exit atmel_wm97xx_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int atmel_wm97xx_suspend(struct *dev)
+static int atmel_wm97xx_suspend(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev);
index 42d830efa316ec9c44f53306123e0ffb2a2d04b5..a035a390f8e29f4caa36e4949fd54d469e9cdc24 100644 (file)
@@ -1246,8 +1246,7 @@ static void cyttsp4_watchdog_timer(unsigned long handle)
 
        dev_vdbg(cd->dev, "%s: Watchdog timer triggered\n", __func__);
 
-       if (!work_pending(&cd->watchdog_work))
-               schedule_work(&cd->watchdog_work);
+       schedule_work(&cd->watchdog_work);
 
        return;
 }
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
new file mode 100644 (file)
index 0000000..cfd1b7e
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+ * Surface2.0/SUR40/PixelSense input driver
+ *
+ * Copyright (c) 2013 by Florian 'floe' Echtler <floe@butterbrot.org>
+ *
+ * Derived from the USB Skeleton driver 1.1,
+ * Copyright (c) 2003 Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * and from the Apple USB BCM5974 multitouch driver,
+ * Copyright (c) 2008 Henrik Rydberg (rydberg@euromail.se)
+ *
+ * and from the generic hid-multitouch driver,
+ * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/completion.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/printk.h>
+#include <linux/input-polldev.h>
+#include <linux/input/mt.h>
+#include <linux/usb/input.h>
+
+/* read 512 bytes from endpoint 0x86 -> get header + blobs */
+struct sur40_header {
+
+       __le16 type;       /* always 0x0001 */
+       __le16 count;      /* count of blobs (if 0: continue prev. packet) */
+
+       __le32 packet_id;  /* unique ID for all packets in one frame */
+
+       __le32 timestamp;  /* milliseconds (inc. by 16 or 17 each frame) */
+       __le32 unknown;    /* "epoch?" always 02/03 00 00 00 */
+
+} __packed;
+
+struct sur40_blob {
+
+       __le16 blob_id;
+
+       u8 action;         /* 0x02 = enter/exit, 0x03 = update (?) */
+       u8 unknown;        /* always 0x01 or 0x02 (no idea what this is?) */
+
+       __le16 bb_pos_x;   /* upper left corner of bounding box */
+       __le16 bb_pos_y;
+
+       __le16 bb_size_x;  /* size of bounding box */
+       __le16 bb_size_y;
+
+       __le16 pos_x;      /* finger tip position */
+       __le16 pos_y;
+
+       __le16 ctr_x;      /* centroid position */
+       __le16 ctr_y;
+
+       __le16 axis_x;     /* somehow related to major/minor axis, mostly: */
+       __le16 axis_y;     /* axis_x == bb_size_y && axis_y == bb_size_x */
+
+       __le32 angle;      /* orientation in radians relative to x axis -
+                             actually an IEEE754 float, don't use in kernel */
+
+       __le32 area;       /* size in pixels/pressure (?) */
+
+       u8 padding[32];
+
+} __packed;
+
+/* combined header/blob data */
+struct sur40_data {
+       struct sur40_header header;
+       struct sur40_blob   blobs[];
+} __packed;
+
+
+/* version information */
+#define DRIVER_SHORT   "sur40"
+#define DRIVER_AUTHOR  "Florian 'floe' Echtler <floe@butterbrot.org>"
+#define DRIVER_DESC    "Surface2.0/SUR40/PixelSense input driver"
+
+/* vendor and device IDs */
+#define ID_MICROSOFT 0x045e
+#define ID_SUR40     0x0775
+
+/* sensor resolution */
+#define SENSOR_RES_X 1920
+#define SENSOR_RES_Y 1080
+
+/* touch data endpoint */
+#define TOUCH_ENDPOINT 0x86
+
+/* polling interval (ms) */
+#define POLL_INTERVAL 10
+
+/* maximum number of contacts FIXME: this is a guess? */
+#define MAX_CONTACTS 64
+
+/* control commands */
+#define SUR40_GET_VERSION 0xb0 /* 12 bytes string    */
+#define SUR40_UNKNOWN1    0xb3 /*  5 bytes           */
+#define SUR40_UNKNOWN2    0xc1 /* 24 bytes           */
+
+#define SUR40_GET_STATE   0xc5 /*  4 bytes state (?) */
+#define SUR40_GET_SENSORS 0xb1 /*  8 bytes sensors   */
+
+/*
+ * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
+ * here by mistake which is very likely to have corrupted the firmware EEPROM
+ * on two separate SUR40 devices. Thanks to Alan Stern who spotted this bug.
+ * Should you ever run into a similar problem, the background story to this
+ * incident and instructions on how to fix the corrupted EEPROM are available
+ * at https://floe.butterbrot.org/matrix/hacking/surface/brick.html
+*/
+
+struct sur40_state {
+
+       struct usb_device *usbdev;
+       struct device *dev;
+       struct input_polled_dev *input;
+
+       struct sur40_data *bulk_in_buffer;
+       size_t bulk_in_size;
+       u8 bulk_in_epaddr;
+
+       char phys[64];
+};
+
+static int sur40_command(struct sur40_state *dev,
+                        u8 command, u16 index, void *buffer, u16 size)
+{
+       return usb_control_msg(dev->usbdev, usb_rcvctrlpipe(dev->usbdev, 0),
+                              command,
+                              USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+                              0x00, index, buffer, size, 1000);
+}
+
+/* Initialization routine, called from sur40_open */
+static int sur40_init(struct sur40_state *dev)
+{
+       int result;
+       u8 buffer[24];
+
+       /* stupidly replay the original MS driver init sequence */
+       result = sur40_command(dev, SUR40_GET_VERSION, 0x00, buffer, 12);
+       if (result < 0)
+               return result;
+
+       result = sur40_command(dev, SUR40_GET_VERSION, 0x01, buffer, 12);
+       if (result < 0)
+               return result;
+
+       result = sur40_command(dev, SUR40_GET_VERSION, 0x02, buffer, 12);
+       if (result < 0)
+               return result;
+
+       result = sur40_command(dev, SUR40_UNKNOWN2,    0x00, buffer, 24);
+       if (result < 0)
+               return result;
+
+       result = sur40_command(dev, SUR40_UNKNOWN1,    0x00, buffer,  5);
+       if (result < 0)
+               return result;
+
+       result = sur40_command(dev, SUR40_GET_VERSION, 0x03, buffer, 12);
+
+       /*
+        * Discard the result buffer - no known data inside except
+        * some version strings, maybe extract these sometime...
+        */
+
+       return result;
+}
+
+/*
+ * Callback routines from input_polled_dev
+ */
+
+/* Enable the device, polling will now start. */
+static void sur40_open(struct input_polled_dev *polldev)
+{
+       struct sur40_state *sur40 = polldev->private;
+
+       dev_dbg(sur40->dev, "open\n");
+       sur40_init(sur40);
+}
+
+/* Disable device, polling has stopped. */
+static void sur40_close(struct input_polled_dev *polldev)
+{
+       struct sur40_state *sur40 = polldev->private;
+
+       dev_dbg(sur40->dev, "close\n");
+       /*
+        * There is no known way to stop the device, so we simply
+        * stop polling.
+        */
+}
+
+/*
+ * This function is called when a whole contact has been processed,
+ * so that it can assign it to a slot and store the data there.
+ */
+static void sur40_report_blob(struct sur40_blob *blob, struct input_dev *input)
+{
+       int wide, major, minor;
+
+       int bb_size_x = le16_to_cpu(blob->bb_size_x);
+       int bb_size_y = le16_to_cpu(blob->bb_size_y);
+
+       int pos_x = le16_to_cpu(blob->pos_x);
+       int pos_y = le16_to_cpu(blob->pos_y);
+
+       int ctr_x = le16_to_cpu(blob->ctr_x);
+       int ctr_y = le16_to_cpu(blob->ctr_y);
+
+       int slotnum = input_mt_get_slot_by_key(input, blob->blob_id);
+       if (slotnum < 0 || slotnum >= MAX_CONTACTS)
+               return;
+
+       input_mt_slot(input, slotnum);
+       input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
+       wide = (bb_size_x > bb_size_y);
+       major = max(bb_size_x, bb_size_y);
+       minor = min(bb_size_x, bb_size_y);
+
+       input_report_abs(input, ABS_MT_POSITION_X, pos_x);
+       input_report_abs(input, ABS_MT_POSITION_Y, pos_y);
+       input_report_abs(input, ABS_MT_TOOL_X, ctr_x);
+       input_report_abs(input, ABS_MT_TOOL_Y, ctr_y);
+
+       /* TODO: use a better orientation measure */
+       input_report_abs(input, ABS_MT_ORIENTATION, wide);
+       input_report_abs(input, ABS_MT_TOUCH_MAJOR, major);
+       input_report_abs(input, ABS_MT_TOUCH_MINOR, minor);
+}
+
+/* core function: poll for new input data */
+static void sur40_poll(struct input_polled_dev *polldev)
+{
+
+       struct sur40_state *sur40 = polldev->private;
+       struct input_dev *input = polldev->input;
+       int result, bulk_read, need_blobs, packet_blobs, i;
+       u32 packet_id;
+
+       struct sur40_header *header = &sur40->bulk_in_buffer->header;
+       struct sur40_blob *inblob = &sur40->bulk_in_buffer->blobs[0];
+
+       dev_dbg(sur40->dev, "poll\n");
+
+       need_blobs = -1;
+
+       do {
+
+               /* perform a blocking bulk read to get data from the device */
+               result = usb_bulk_msg(sur40->usbdev,
+                       usb_rcvbulkpipe(sur40->usbdev, sur40->bulk_in_epaddr),
+                       sur40->bulk_in_buffer, sur40->bulk_in_size,
+                       &bulk_read, 1000);
+
+               dev_dbg(sur40->dev, "received %d bytes\n", bulk_read);
+
+               if (result < 0) {
+                       dev_err(sur40->dev, "error in usb_bulk_read\n");
+                       return;
+               }
+
+               result = bulk_read - sizeof(struct sur40_header);
+
+               if (result % sizeof(struct sur40_blob) != 0) {
+                       dev_err(sur40->dev, "transfer size mismatch\n");
+                       return;
+               }
+
+               /* first packet? */
+               if (need_blobs == -1) {
+                       need_blobs = le16_to_cpu(header->count);
+                       dev_dbg(sur40->dev, "need %d blobs\n", need_blobs);
+                       packet_id = header->packet_id;
+               }
+
+               /*
+                * Sanity check. when video data is also being retrieved, the
+                * packet ID will usually increase in the middle of a series
+                * instead of at the end.
+                */
+               if (packet_id != header->packet_id)
+                       dev_warn(sur40->dev, "packet ID mismatch\n");
+
+               packet_blobs = result / sizeof(struct sur40_blob);
+               dev_dbg(sur40->dev, "received %d blobs\n", packet_blobs);
+
+               /* packets always contain at least 4 blobs, even if empty */
+               if (packet_blobs > need_blobs)
+                       packet_blobs = need_blobs;
+
+               for (i = 0; i < packet_blobs; i++) {
+                       need_blobs--;
+                       dev_dbg(sur40->dev, "processing blob\n");
+                       sur40_report_blob(&(inblob[i]), input);
+               }
+
+       } while (need_blobs > 0);
+
+       input_mt_sync_frame(input);
+       input_sync(input);
+}
+
+/* Initialize input device parameters. */
+static void sur40_input_setup(struct input_dev *input_dev)
+{
+       __set_bit(EV_KEY, input_dev->evbit);
+       __set_bit(EV_ABS, input_dev->evbit);
+
+       input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+                            0, SENSOR_RES_X, 0, 0);
+       input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+                            0, SENSOR_RES_Y, 0, 0);
+
+       input_set_abs_params(input_dev, ABS_MT_TOOL_X,
+                            0, SENSOR_RES_X, 0, 0);
+       input_set_abs_params(input_dev, ABS_MT_TOOL_Y,
+                            0, SENSOR_RES_Y, 0, 0);
+
+       /* max value unknown, but major/minor axis
+        * can never be larger than screen */
+       input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+                            0, SENSOR_RES_X, 0, 0);
+       input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
+                            0, SENSOR_RES_Y, 0, 0);
+
+       input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
+
+       input_mt_init_slots(input_dev, MAX_CONTACTS,
+                           INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+}
+
+/* Check candidate USB interface. */
+static int sur40_probe(struct usb_interface *interface,
+                      const struct usb_device_id *id)
+{
+       struct usb_device *usbdev = interface_to_usbdev(interface);
+       struct sur40_state *sur40;
+       struct usb_host_interface *iface_desc;
+       struct usb_endpoint_descriptor *endpoint;
+       struct input_polled_dev *poll_dev;
+       int error;
+
+       /* Check if we really have the right interface. */
+       iface_desc = &interface->altsetting[0];
+       if (iface_desc->desc.bInterfaceClass != 0xFF)
+               return -ENODEV;
+
+       /* Use endpoint #4 (0x86). */
+       endpoint = &iface_desc->endpoint[4].desc;
+       if (endpoint->bEndpointAddress != TOUCH_ENDPOINT)
+               return -ENODEV;
+
+       /* Allocate memory for our device state and initialize it. */
+       sur40 = kzalloc(sizeof(struct sur40_state), GFP_KERNEL);
+       if (!sur40)
+               return -ENOMEM;
+
+       poll_dev = input_allocate_polled_device();
+       if (!poll_dev) {
+               error = -ENOMEM;
+               goto err_free_dev;
+       }
+
+       /* Set up polled input device control structure */
+       poll_dev->private = sur40;
+       poll_dev->poll_interval = POLL_INTERVAL;
+       poll_dev->open = sur40_open;
+       poll_dev->poll = sur40_poll;
+       poll_dev->close = sur40_close;
+
+       /* Set up regular input device structure */
+       sur40_input_setup(poll_dev->input);
+
+       poll_dev->input->name = "Samsung SUR40";
+       usb_to_input_id(usbdev, &poll_dev->input->id);
+       usb_make_path(usbdev, sur40->phys, sizeof(sur40->phys));
+       strlcat(sur40->phys, "/input0", sizeof(sur40->phys));
+       poll_dev->input->phys = sur40->phys;
+       poll_dev->input->dev.parent = &interface->dev;
+
+       sur40->usbdev = usbdev;
+       sur40->dev = &interface->dev;
+       sur40->input = poll_dev;
+
+       /* use the bulk-in endpoint tested above */
+       sur40->bulk_in_size = usb_endpoint_maxp(endpoint);
+       sur40->bulk_in_epaddr = endpoint->bEndpointAddress;
+       sur40->bulk_in_buffer = kmalloc(sur40->bulk_in_size, GFP_KERNEL);
+       if (!sur40->bulk_in_buffer) {
+               dev_err(&interface->dev, "Unable to allocate input buffer.");
+               error = -ENOMEM;
+               goto err_free_polldev;
+       }
+
+       error = input_register_polled_device(poll_dev);
+       if (error) {
+               dev_err(&interface->dev,
+                       "Unable to register polled input device.");
+               goto err_free_buffer;
+       }
+
+       /* we can register the device now, as it is ready */
+       usb_set_intfdata(interface, sur40);
+       dev_dbg(&interface->dev, "%s is now attached\n", DRIVER_DESC);
+
+       return 0;
+
+err_free_buffer:
+       kfree(sur40->bulk_in_buffer);
+err_free_polldev:
+       input_free_polled_device(sur40->input);
+err_free_dev:
+       kfree(sur40);
+
+       return error;
+}
+
+/* Unregister device & clean up. */
+static void sur40_disconnect(struct usb_interface *interface)
+{
+       struct sur40_state *sur40 = usb_get_intfdata(interface);
+
+       input_unregister_polled_device(sur40->input);
+       input_free_polled_device(sur40->input);
+       kfree(sur40->bulk_in_buffer);
+       kfree(sur40);
+
+       usb_set_intfdata(interface, NULL);
+       dev_dbg(&interface->dev, "%s is now disconnected\n", DRIVER_DESC);
+}
+
+static const struct usb_device_id sur40_table[] = {
+       { USB_DEVICE(ID_MICROSOFT, ID_SUR40) },  /* Samsung SUR40 */
+       { }                                      /* terminating null entry */
+};
+MODULE_DEVICE_TABLE(usb, sur40_table);
+
+/* USB-specific object needed to register this driver with the USB subsystem. */
+static struct usb_driver sur40_driver = {
+       .name = DRIVER_SHORT,
+       .probe = sur40_probe,
+       .disconnect = sur40_disconnect,
+       .id_table = sur40_table,
+};
+
+module_usb_driver(sur40_driver);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
index 0b67ba476b4cdc204e6dc98aec29d006b217a4bc..1bf9906b5a3fc189276c39d065a2cc58b36ddbd3 100644 (file)
@@ -26,6 +26,9 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c/tsc2007.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #define TSC2007_MEASURE_TEMP0          (0x0 << 4)
 #define TSC2007_MEASURE_AUX            (0x2 << 4)
@@ -72,15 +75,18 @@ struct tsc2007 {
        u16                     model;
        u16                     x_plate_ohms;
        u16                     max_rt;
-       unsigned long           poll_delay;
        unsigned long           poll_period;
+       int                     fuzzx;
+       int                     fuzzy;
+       int                     fuzzz;
 
+       unsigned                gpio;
        int                     irq;
 
        wait_queue_head_t       wait;
        bool                    stopped;
 
-       int                     (*get_pendown_state)(void);
+       int                     (*get_pendown_state)(struct device *);
        void                    (*clear_penirq)(void);
 };
 
@@ -161,7 +167,7 @@ static bool tsc2007_is_pen_down(struct tsc2007 *ts)
        if (!ts->get_pendown_state)
                return true;
 
-       return ts->get_pendown_state();
+       return ts->get_pendown_state(&ts->client->dev);
 }
 
 static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
@@ -178,7 +184,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
 
                rt = tsc2007_calculate_pressure(ts, &tc);
 
-               if (rt == 0 && !ts->get_pendown_state) {
+               if (!rt && !ts->get_pendown_state) {
                        /*
                         * If pressure reported is 0 and we don't have
                         * callback to check pendown state, we have to
@@ -228,7 +234,7 @@ static irqreturn_t tsc2007_hard_irq(int irq, void *handle)
 {
        struct tsc2007 *ts = handle;
 
-       if (!ts->get_pendown_state || likely(ts->get_pendown_state()))
+       if (tsc2007_is_pen_down(ts))
                return IRQ_WAKE_THREAD;
 
        if (ts->clear_penirq)
@@ -273,49 +279,134 @@ static void tsc2007_close(struct input_dev *input_dev)
        tsc2007_stop(ts);
 }
 
-static int tsc2007_probe(struct i2c_client *client,
-                                  const struct i2c_device_id *id)
+#ifdef CONFIG_OF
+static int tsc2007_get_pendown_state_gpio(struct device *dev)
 {
-       struct tsc2007 *ts;
-       struct tsc2007_platform_data *pdata = client->dev.platform_data;
-       struct input_dev *input_dev;
-       int err;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct tsc2007 *ts = i2c_get_clientdata(client);
+
+       return !gpio_get_value(ts->gpio);
+}
+
+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
+{
+       struct device_node *np = client->dev.of_node;
+       u32 val32;
+       u64 val64;
 
-       if (!pdata) {
-               dev_err(&client->dev, "platform data is required!\n");
+       if (!np) {
+               dev_err(&client->dev, "missing device tree data\n");
                return -EINVAL;
        }
 
-       if (!i2c_check_functionality(client->adapter,
-                                    I2C_FUNC_SMBUS_READ_WORD_DATA))
-               return -EIO;
+       if (!of_property_read_u32(np, "ti,max-rt", &val32))
+               ts->max_rt = val32;
+       else
+               ts->max_rt = MAX_12BIT;
+
+       if (!of_property_read_u32(np, "ti,fuzzx", &val32))
+               ts->fuzzx = val32;
+
+       if (!of_property_read_u32(np, "ti,fuzzy", &val32))
+               ts->fuzzy = val32;
+
+       if (!of_property_read_u32(np, "ti,fuzzz", &val32))
+               ts->fuzzz = val32;
+
+       if (!of_property_read_u64(np, "ti,poll-period", &val64))
+               ts->poll_period = val64;
+       else
+               ts->poll_period = 1;
 
-       ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL);
-       input_dev = input_allocate_device();
-       if (!ts || !input_dev) {
-               err = -ENOMEM;
-               goto err_free_mem;
+       if (!of_property_read_u32(np, "ti,x-plate-ohms", &val32)) {
+               ts->x_plate_ohms = val32;
+       } else {
+               dev_err(&client->dev, "missing ti,x-plate-ohms devicetree property.");
+               return -EINVAL;
        }
 
-       ts->client = client;
-       ts->irq = client->irq;
-       ts->input = input_dev;
-       init_waitqueue_head(&ts->wait);
+       ts->gpio = of_get_gpio(np, 0);
+       if (gpio_is_valid(ts->gpio))
+               ts->get_pendown_state = tsc2007_get_pendown_state_gpio;
+       else
+               dev_warn(&client->dev,
+                        "GPIO not specified in DT (of_get_gpio returned %d)\n",
+                        ts->gpio);
+
+       return 0;
+}
+#else
+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
+{
+       dev_err(&client->dev, "platform data is required!\n");
+       return -EINVAL;
+}
+#endif
 
+static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
+                             const struct tsc2007_platform_data *pdata,
+                             const struct i2c_device_id *id)
+{
        ts->model             = pdata->model;
        ts->x_plate_ohms      = pdata->x_plate_ohms;
        ts->max_rt            = pdata->max_rt ? : MAX_12BIT;
-       ts->poll_delay        = pdata->poll_delay ? : 1;
        ts->poll_period       = pdata->poll_period ? : 1;
        ts->get_pendown_state = pdata->get_pendown_state;
        ts->clear_penirq      = pdata->clear_penirq;
+       ts->fuzzx             = pdata->fuzzx;
+       ts->fuzzy             = pdata->fuzzy;
+       ts->fuzzz             = pdata->fuzzz;
 
        if (pdata->x_plate_ohms == 0) {
                dev_err(&client->dev, "x_plate_ohms is not set up in platform data");
-               err = -EINVAL;
-               goto err_free_mem;
+               return -EINVAL;
        }
 
+       return 0;
+}
+
+static void tsc2007_call_exit_platform_hw(void *data)
+{
+       struct device *dev = data;
+       const struct tsc2007_platform_data *pdata = dev_get_platdata(dev);
+
+       pdata->exit_platform_hw();
+}
+
+static int tsc2007_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
+       struct tsc2007 *ts;
+       struct input_dev *input_dev;
+       int err;
+
+       if (!i2c_check_functionality(client->adapter,
+                                    I2C_FUNC_SMBUS_READ_WORD_DATA))
+               return -EIO;
+
+       ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL);
+       if (!ts)
+               return -ENOMEM;
+
+       if (pdata)
+               err = tsc2007_probe_pdev(client, ts, pdata, id);
+       else
+               err = tsc2007_probe_dt(client, ts);
+       if (err)
+               return err;
+
+       input_dev = devm_input_allocate_device(&client->dev);
+       if (!input_dev)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, ts);
+
+       ts->client = client;
+       ts->irq = client->irq;
+       ts->input = input_dev;
+       init_waitqueue_head(&ts->wait);
+
        snprintf(ts->phys, sizeof(ts->phys),
                 "%s/input0", dev_name(&client->dev));
 
@@ -331,53 +422,46 @@ static int tsc2007_probe(struct i2c_client *client,
        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
        input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
-       input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0);
-       input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0);
+       input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0);
+       input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);
        input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
-                       pdata->fuzzz, 0);
+                            ts->fuzzz, 0);
+
+       if (pdata) {
+               if (pdata->exit_platform_hw) {
+                       err = devm_add_action(&client->dev,
+                                             tsc2007_call_exit_platform_hw,
+                                             &client->dev);
+                       if (err) {
+                               dev_err(&client->dev,
+                                       "Failed to register exit_platform_hw action, %d\n",
+                                       err);
+                               return err;
+                       }
+               }
 
-       if (pdata->init_platform_hw)
-               pdata->init_platform_hw();
+               if (pdata->init_platform_hw)
+                       pdata->init_platform_hw();
+       }
 
-       err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq,
-                                  IRQF_ONESHOT, client->dev.driver->name, ts);
-       if (err < 0) {
-               dev_err(&client->dev, "irq %d busy?\n", ts->irq);
-               goto err_free_mem;
+       err = devm_request_threaded_irq(&client->dev, ts->irq,
+                                       tsc2007_hard_irq, tsc2007_soft_irq,
+                                       IRQF_ONESHOT,
+                                       client->dev.driver->name, ts);
+       if (err) {
+               dev_err(&client->dev, "Failed to request irq %d: %d\n",
+                       ts->irq, err);
+               return err;
        }
 
        tsc2007_stop(ts);
 
        err = input_register_device(input_dev);
-       if (err)
-               goto err_free_irq;
-
-       i2c_set_clientdata(client, ts);
-
-       return 0;
-
- err_free_irq:
-       free_irq(ts->irq, ts);
-       if (pdata->exit_platform_hw)
-               pdata->exit_platform_hw();
- err_free_mem:
-       input_free_device(input_dev);
-       kfree(ts);
-       return err;
-}
-
-static int tsc2007_remove(struct i2c_client *client)
-{
-       struct tsc2007  *ts = i2c_get_clientdata(client);
-       struct tsc2007_platform_data *pdata = client->dev.platform_data;
-
-       free_irq(ts->irq, ts);
-
-       if (pdata->exit_platform_hw)
-               pdata->exit_platform_hw();
-
-       input_unregister_device(ts->input);
-       kfree(ts);
+       if (err) {
+               dev_err(&client->dev,
+                       "Failed to register input device: %d\n", err);
+               return err;
+       }
 
        return 0;
 }
@@ -389,14 +473,22 @@ static const struct i2c_device_id tsc2007_idtable[] = {
 
 MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);
 
+#ifdef CONFIG_OF
+static const struct of_device_id tsc2007_of_match[] = {
+       { .compatible = "ti,tsc2007" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tsc2007_of_match);
+#endif
+
 static struct i2c_driver tsc2007_driver = {
        .driver = {
                .owner  = THIS_MODULE,
-               .name   = "tsc2007"
+               .name   = "tsc2007",
+               .of_match_table = of_match_ptr(tsc2007_of_match),
        },
        .id_table       = tsc2007_idtable,
        .probe          = tsc2007_probe,
-       .remove         = tsc2007_remove,
 };
 
 module_i2c_driver(tsc2007_driver);
index 8f798be6e398d98ccacc5ba85f3f5b76c4096683..28b4bea7c1094d79a483ee5256c21a91d3829396 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/msi.h>
 #include <linux/amd-iommu.h>
 #include <linux/export.h>
-#include <acpi/acpi.h>
 #include <asm/pci-direct.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
index bab10b1002fbf04bae1fe8e2b36cbb6f280dea51..0cb7528b30a134416b4343b08a458f80dcb6aecf 100644 (file)
@@ -6,11 +6,11 @@
 #include <linux/hpet.h>
 #include <linux/pci.h>
 #include <linux/irq.h>
+#include <linux/intel-iommu.h>
+#include <linux/acpi.h>
 #include <asm/io_apic.h>
 #include <asm/smp.h>
 #include <asm/cpu.h>
-#include <linux/intel-iommu.h>
-#include <acpi/acpi.h>
 #include <asm/irq_remapping.h>
 #include <asm/pci-direct.h>
 #include <asm/msidef.h>
index 3792a1aa52b88d3439cdc66195230cc1b20f0f2a..07bc79c340125be220f7b667b9cb8e16db36d4ab 100644 (file)
@@ -61,3 +61,7 @@ config VERSATILE_FPGA_IRQ_NR
        int
        default 4
        depends on VERSATILE_FPGA_IRQ
+
+config XTENSA_MX
+       bool
+       select IRQ_DOMAIN
index c60b9010b152cf4980336eac485daa8bceec9412..679e2d102a296e84a60acdc9d24a3cbcffe7d5d5 100644 (file)
@@ -1,6 +1,7 @@
 obj-$(CONFIG_IRQCHIP)                  += irqchip.o
 
 obj-$(CONFIG_ARCH_BCM2835)             += irq-bcm2835.o
+obj-$(CONFIG_ARCH_DOVE)                        += irq-dove.o
 obj-$(CONFIG_ARCH_EXYNOS)              += exynos-combiner.o
 obj-$(CONFIG_ARCH_MMP)                 += irq-mmp.o
 obj-$(CONFIG_ARCH_MVEBU)               += irq-armada-370-xp.o
@@ -22,3 +23,5 @@ obj-$(CONFIG_RENESAS_IRQC)            += irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)       += irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)              += irq-vt8500.o
 obj-$(CONFIG_TB10X_IRQC)               += irq-tb10x.o
+obj-$(CONFIG_XTENSA)                   += irq-xtensa-pic.o
+obj-$(CONFIG_XTENSA_MX)                        += irq-xtensa-mx.o
index 868ed40cb6bf070ba5b6b5a4156cda73f54fa9fa..40e6440348ff5d9ace76ff17510bbf40ae648415 100644 (file)
@@ -171,8 +171,7 @@ static struct irq_domain_ops combiner_irq_domain_ops = {
 
 static void __init combiner_init(void __iomem *combiner_base,
                                 struct device_node *np,
-                                unsigned int max_nr,
-                                int irq_base)
+                                unsigned int max_nr)
 {
        int i, irq;
        unsigned int nr_irq;
@@ -186,7 +185,7 @@ static void __init combiner_init(void __iomem *combiner_base,
                return;
        }
 
-       combiner_irq_domain = irq_domain_add_simple(np, nr_irq, irq_base,
+       combiner_irq_domain = irq_domain_add_linear(np, nr_irq,
                                &combiner_irq_domain_ops, combiner_data);
        if (WARN_ON(!combiner_irq_domain)) {
                pr_warning("%s: irq domain init failed\n", __func__);
@@ -207,7 +206,6 @@ static int __init combiner_of_init(struct device_node *np,
 {
        void __iomem *combiner_base;
        unsigned int max_nr = 20;
-       int irq_base = -1;
 
        combiner_base = of_iomap(np, 0);
        if (!combiner_base) {
@@ -221,14 +219,7 @@ static int __init combiner_of_init(struct device_node *np,
                        __func__, max_nr);
        }
 
-       /* 
-        * FIXME: This is a hardwired COMBINER_IRQ(0,0). Once all devices
-        * get their IRQ from DT, remove this in order to get dynamic
-        * allocation.
-        */
-       irq_base = 160;
-
-       combiner_init(combiner_base, np, max_nr, irq_base);
+       combiner_init(combiner_base, np, max_nr);
 
        return 0;
 }
diff --git a/drivers/irqchip/irq-dove.c b/drivers/irqchip/irq-dove.c
new file mode 100644 (file)
index 0000000..788acd8
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Marvell Dove SoCs PMU IRQ chip driver.
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+
+#include "irqchip.h"
+
+#define DOVE_PMU_IRQ_CAUSE     0x00
+#define DOVE_PMU_IRQ_MASK      0x04
+
+static void dove_pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       struct irq_domain *d = irq_get_handler_data(irq);
+       struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0);
+       u32 stat = readl_relaxed(gc->reg_base + DOVE_PMU_IRQ_CAUSE) &
+                  gc->mask_cache;
+
+       while (stat) {
+               u32 hwirq = ffs(stat) - 1;
+
+               generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq));
+               stat &= ~(1 << hwirq);
+       }
+}
+
+static void pmu_irq_ack(struct irq_data *d)
+{
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
+       u32 mask = ~d->mask;
+
+       /*
+        * The PMU mask register is not RW0C: it is RW.  This means that
+        * the bits take whatever value is written to them; if you write
+        * a '1', you will set the interrupt.
+        *
+        * Unfortunately this means there is NO race free way to clear
+        * these interrupts.
+        *
+        * So, let's structure the code so that the window is as small as
+        * possible.
+        */
+       irq_gc_lock(gc);
+       mask &= irq_reg_readl(gc->reg_base +  ct->regs.ack);
+       irq_reg_writel(mask, gc->reg_base +  ct->regs.ack);
+       irq_gc_unlock(gc);
+}
+
+static int __init dove_pmu_irq_init(struct device_node *np,
+                                   struct device_node *parent)
+{
+       unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+       struct resource r;
+       struct irq_domain *domain;
+       struct irq_chip_generic *gc;
+       int ret, irq, nrirqs = 7;
+
+       domain = irq_domain_add_linear(np, nrirqs,
+                                      &irq_generic_chip_ops, NULL);
+       if (!domain) {
+               pr_err("%s: unable to add irq domain\n", np->name);
+               return -ENOMEM;
+       }
+
+       ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name,
+                            handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE);
+       if (ret) {
+               pr_err("%s: unable to alloc irq domain gc\n", np->name);
+               return ret;
+       }
+
+       ret = of_address_to_resource(np, 0, &r);
+       if (ret) {
+               pr_err("%s: unable to get resource\n", np->name);
+               return ret;
+       }
+
+       if (!request_mem_region(r.start, resource_size(&r), np->name)) {
+               pr_err("%s: unable to request mem region\n", np->name);
+               return -ENOMEM;
+       }
+
+       /* Map the parent interrupt for the chained handler */
+       irq = irq_of_parse_and_map(np, 0);
+       if (irq <= 0) {
+               pr_err("%s: unable to parse irq\n", np->name);
+               return -EINVAL;
+       }
+
+       gc = irq_get_domain_generic_chip(domain, 0);
+       gc->reg_base = ioremap(r.start, resource_size(&r));
+       if (!gc->reg_base) {
+               pr_err("%s: unable to map resource\n", np->name);
+               return -ENOMEM;
+       }
+
+       gc->chip_types[0].regs.ack = DOVE_PMU_IRQ_CAUSE;
+       gc->chip_types[0].regs.mask = DOVE_PMU_IRQ_MASK;
+       gc->chip_types[0].chip.irq_ack = pmu_irq_ack;
+       gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+       gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+       /* mask and clear all interrupts */
+       writel(0, gc->reg_base + DOVE_PMU_IRQ_MASK);
+       writel(0, gc->reg_base + DOVE_PMU_IRQ_CAUSE);
+
+       irq_set_handler_data(irq, domain);
+       irq_set_chained_handler(irq, dove_pmu_irq_handler);
+
+       return 0;
+}
+IRQCHIP_DECLARE(dove_pmu_intc,
+               "marvell,dove-pmu-intc", dove_pmu_irq_init);
index 9031171c141b52c5e9175fdbf6eec9bd0c4224b3..341c6016812de0e17fbd4c1601708723409351c5 100644 (file)
@@ -957,12 +957,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
        if (WARN_ON(!gic->domain))
                return;
 
+       if (gic_nr == 0) {
 #ifdef CONFIG_SMP
-       set_smp_cross_call(gic_raise_softirq);
-       register_cpu_notifier(&gic_cpu_notifier);
+               set_smp_cross_call(gic_raise_softirq);
+               register_cpu_notifier(&gic_cpu_notifier);
 #endif
-
-       set_handle_irq(gic_handle_irq);
+               set_handle_irq(gic_handle_irq);
+       }
 
        gic_chip.flags |= gic_arch_extn.flags;
        gic_dist_init(gic);
index 82cec63a90112e184c96a2e21e612df977adf7b7..3ee78f02e5d7d940d531aa6ab03c8dc681c9cb3c 100644 (file)
@@ -149,8 +149,9 @@ static void intc_irqpin_read_modify_write(struct intc_irqpin_priv *p,
 static void intc_irqpin_mask_unmask_prio(struct intc_irqpin_priv *p,
                                         int irq, int do_mask)
 {
-       int bitfield_width = 4; /* PRIO assumed to have fixed bitfield width */
-       int shift = (7 - irq) * bitfield_width; /* PRIO assumed to be 32-bit */
+       /* The PRIO register is assumed to be 32-bit with fixed 4-bit fields. */
+       int bitfield_width = 4;
+       int shift = 32 - (irq + 1) * bitfield_width;
 
        intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_PRIO,
                                      shift, bitfield_width,
@@ -159,8 +160,9 @@ static void intc_irqpin_mask_unmask_prio(struct intc_irqpin_priv *p,
 
 static int intc_irqpin_set_sense(struct intc_irqpin_priv *p, int irq, int value)
 {
+       /* The SENSE register is assumed to be 32-bit. */
        int bitfield_width = p->config.sense_bitfield_width;
-       int shift = (7 - irq) * bitfield_width; /* SENSE assumed to be 32-bit */
+       int shift = 32 - (irq + 1) * bitfield_width;
 
        dev_dbg(&p->pdev->dev, "sense irq = %d, mode = %d\n", irq, value);
 
diff --git a/drivers/irqchip/irq-xtensa-mx.c b/drivers/irqchip/irq-xtensa-mx.c
new file mode 100644 (file)
index 0000000..86f91f0
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Xtensa MX interrupt distributor
+ *
+ * Copyright (C) 2002 - 2013 Tensilica, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+
+#include <asm/mxregs.h>
+
+#include "irqchip.h"
+
+#define HW_IRQ_IPI_COUNT 2
+#define HW_IRQ_MX_BASE 2
+#define HW_IRQ_EXTERN_BASE 3
+
+static DEFINE_PER_CPU(unsigned int, cached_irq_mask);
+
+static int xtensa_mx_irq_map(struct irq_domain *d, unsigned int irq,
+               irq_hw_number_t hw)
+{
+       if (hw < HW_IRQ_IPI_COUNT) {
+               struct irq_chip *irq_chip = d->host_data;
+               irq_set_chip_and_handler_name(irq, irq_chip,
+                               handle_percpu_irq, "ipi");
+               irq_set_status_flags(irq, IRQ_LEVEL);
+               return 0;
+       }
+       return xtensa_irq_map(d, irq, hw);
+}
+
+/*
+ * Device Tree IRQ specifier translation function which works with one or
+ * two cell bindings. First cell value maps directly to the hwirq number.
+ * Second cell if present specifies whether hwirq number is external (1) or
+ * internal (0).
+ */
+static int xtensa_mx_irq_domain_xlate(struct irq_domain *d,
+               struct device_node *ctrlr,
+               const u32 *intspec, unsigned int intsize,
+               unsigned long *out_hwirq, unsigned int *out_type)
+{
+       return xtensa_irq_domain_xlate(intspec, intsize,
+                       intspec[0], intspec[0] + HW_IRQ_EXTERN_BASE,
+                       out_hwirq, out_type);
+}
+
+static const struct irq_domain_ops xtensa_mx_irq_domain_ops = {
+       .xlate = xtensa_mx_irq_domain_xlate,
+       .map = xtensa_mx_irq_map,
+};
+
+void secondary_init_irq(void)
+{
+       this_cpu_write(cached_irq_mask,
+                       XCHAL_INTTYPE_MASK_EXTERN_EDGE |
+                       XCHAL_INTTYPE_MASK_EXTERN_LEVEL);
+       set_sr(XCHAL_INTTYPE_MASK_EXTERN_EDGE |
+                       XCHAL_INTTYPE_MASK_EXTERN_LEVEL, intenable);
+}
+
+static void xtensa_mx_irq_mask(struct irq_data *d)
+{
+       unsigned long mask = 1u << d->hwirq;
+
+       if (mask & (XCHAL_INTTYPE_MASK_EXTERN_EDGE |
+                               XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) {
+               set_er(1u << (xtensa_get_ext_irq_no(d->hwirq) -
+                                       HW_IRQ_MX_BASE), MIENG);
+       } else {
+               int cpu = get_cpu();
+               per_cpu(cached_irq_mask, cpu) &= ~mask;
+               set_sr(per_cpu(cached_irq_mask, cpu), intenable);
+               put_cpu();
+       }
+}
+
+static void xtensa_mx_irq_unmask(struct irq_data *d)
+{
+       unsigned long mask = 1u << d->hwirq;
+
+       if (mask & (XCHAL_INTTYPE_MASK_EXTERN_EDGE |
+                               XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) {
+               set_er(1u << (xtensa_get_ext_irq_no(d->hwirq) -
+                                       HW_IRQ_MX_BASE), MIENGSET);
+       } else {
+               int cpu = get_cpu();
+               per_cpu(cached_irq_mask, cpu) |= mask;
+               set_sr(per_cpu(cached_irq_mask, cpu), intenable);
+               put_cpu();
+       }
+}
+
+static void xtensa_mx_irq_enable(struct irq_data *d)
+{
+       variant_irq_enable(d->hwirq);
+       xtensa_mx_irq_unmask(d);
+}
+
+static void xtensa_mx_irq_disable(struct irq_data *d)
+{
+       xtensa_mx_irq_mask(d);
+       variant_irq_disable(d->hwirq);
+}
+
+static void xtensa_mx_irq_ack(struct irq_data *d)
+{
+       set_sr(1 << d->hwirq, intclear);
+}
+
+static int xtensa_mx_irq_retrigger(struct irq_data *d)
+{
+       set_sr(1 << d->hwirq, intset);
+       return 1;
+}
+
+static int xtensa_mx_irq_set_affinity(struct irq_data *d,
+               const struct cpumask *dest, bool force)
+{
+       unsigned mask = 1u << cpumask_any(dest);
+
+       set_er(mask, MIROUT(d->hwirq - HW_IRQ_MX_BASE));
+       return 0;
+
+}
+
+static struct irq_chip xtensa_mx_irq_chip = {
+       .name           = "xtensa-mx",
+       .irq_enable     = xtensa_mx_irq_enable,
+       .irq_disable    = xtensa_mx_irq_disable,
+       .irq_mask       = xtensa_mx_irq_mask,
+       .irq_unmask     = xtensa_mx_irq_unmask,
+       .irq_ack        = xtensa_mx_irq_ack,
+       .irq_retrigger  = xtensa_mx_irq_retrigger,
+       .irq_set_affinity = xtensa_mx_irq_set_affinity,
+};
+
+int __init xtensa_mx_init_legacy(struct device_node *interrupt_parent)
+{
+       struct irq_domain *root_domain =
+               irq_domain_add_legacy(NULL, NR_IRQS, 0, 0,
+                               &xtensa_mx_irq_domain_ops,
+                               &xtensa_mx_irq_chip);
+       irq_set_default_host(root_domain);
+       secondary_init_irq();
+       return 0;
+}
+
+static int __init xtensa_mx_init(struct device_node *np,
+               struct device_node *interrupt_parent)
+{
+       struct irq_domain *root_domain =
+               irq_domain_add_linear(np, NR_IRQS, &xtensa_mx_irq_domain_ops,
+                               &xtensa_mx_irq_chip);
+       irq_set_default_host(root_domain);
+       secondary_init_irq();
+       return 0;
+}
+IRQCHIP_DECLARE(xtensa_mx_irq_chip, "xtensa,mx", xtensa_mx_init);
diff --git a/drivers/irqchip/irq-xtensa-pic.c b/drivers/irqchip/irq-xtensa-pic.c
new file mode 100644 (file)
index 0000000..846d181
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Xtensa built-in interrupt controller
+ *
+ * Copyright (C) 2002 - 2013 Tensilica, Inc.
+ * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Chris Zankel <chris@zankel.net>
+ * Kevin Chea
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+
+#include "irqchip.h"
+
+unsigned int cached_irq_mask;
+
+/*
+ * Device Tree IRQ specifier translation function which works with one or
+ * two cell bindings. First cell value maps directly to the hwirq number.
+ * Second cell if present specifies whether hwirq number is external (1) or
+ * internal (0).
+ */
+static int xtensa_pic_irq_domain_xlate(struct irq_domain *d,
+               struct device_node *ctrlr,
+               const u32 *intspec, unsigned int intsize,
+               unsigned long *out_hwirq, unsigned int *out_type)
+{
+       return xtensa_irq_domain_xlate(intspec, intsize,
+                       intspec[0], intspec[0],
+                       out_hwirq, out_type);
+}
+
+static const struct irq_domain_ops xtensa_irq_domain_ops = {
+       .xlate = xtensa_pic_irq_domain_xlate,
+       .map = xtensa_irq_map,
+};
+
+static void xtensa_irq_mask(struct irq_data *d)
+{
+       cached_irq_mask &= ~(1 << d->hwirq);
+       set_sr(cached_irq_mask, intenable);
+}
+
+static void xtensa_irq_unmask(struct irq_data *d)
+{
+       cached_irq_mask |= 1 << d->hwirq;
+       set_sr(cached_irq_mask, intenable);
+}
+
+static void xtensa_irq_enable(struct irq_data *d)
+{
+       variant_irq_enable(d->hwirq);
+       xtensa_irq_unmask(d);
+}
+
+static void xtensa_irq_disable(struct irq_data *d)
+{
+       xtensa_irq_mask(d);
+       variant_irq_disable(d->hwirq);
+}
+
+static void xtensa_irq_ack(struct irq_data *d)
+{
+       set_sr(1 << d->hwirq, intclear);
+}
+
+static int xtensa_irq_retrigger(struct irq_data *d)
+{
+       set_sr(1 << d->hwirq, intset);
+       return 1;
+}
+
+static struct irq_chip xtensa_irq_chip = {
+       .name           = "xtensa",
+       .irq_enable     = xtensa_irq_enable,
+       .irq_disable    = xtensa_irq_disable,
+       .irq_mask       = xtensa_irq_mask,
+       .irq_unmask     = xtensa_irq_unmask,
+       .irq_ack        = xtensa_irq_ack,
+       .irq_retrigger  = xtensa_irq_retrigger,
+};
+
+int __init xtensa_pic_init_legacy(struct device_node *interrupt_parent)
+{
+       struct irq_domain *root_domain =
+               irq_domain_add_legacy(NULL, NR_IRQS, 0, 0,
+                               &xtensa_irq_domain_ops, &xtensa_irq_chip);
+       irq_set_default_host(root_domain);
+       return 0;
+}
+
+static int __init xtensa_pic_init(struct device_node *np,
+               struct device_node *interrupt_parent)
+{
+       struct irq_domain *root_domain =
+               irq_domain_add_linear(np, NR_IRQS, &xtensa_irq_domain_ops,
+                               &xtensa_irq_chip);
+       irq_set_default_host(root_domain);
+       return 0;
+}
+IRQCHIP_DECLARE(xtensa_irq_chip, "xtensa,pic", xtensa_pic_init);
index 8cc304f36728a4e217cbf6716f893a3e6f5aed0c..503df834c690e2d9adc351a7981926d6b0279436 100644 (file)
@@ -4,77 +4,87 @@
  * The TCA6507 is a programmable LED controller that can drive 7
  * separate lines either by holding them low, or by pulsing them
  * with modulated width.
- * The modulation can be varied in a simple pattern to produce a blink or
- * double-blink.
+ * The modulation can be varied in a simple pattern to produce a
+ * blink or double-blink.
  *
- * This driver can configure each line either as a 'GPIO' which is out-only
- * (no pull-up) or as an LED with variable brightness and hardware-assisted
- * blinking.
+ * This driver can configure each line either as a 'GPIO' which is
+ * out-only (pull-up resistor required) or as an LED with variable
+ * brightness and hardware-assisted blinking.
  *
- * Apart from OFF and ON there are three programmable brightness levels which
- * can be programmed from 0 to 15 and indicate how many 500usec intervals in
- * each 8msec that the led is 'on'.  The levels are named MASTER, BANK0 and
- * BANK1.
+ * Apart from OFF and ON there are three programmable brightness
+ * levels which can be programmed from 0 to 15 and indicate how many
+ * 500usec intervals in each 8msec that the led is 'on'.  The levels
+ * are named MASTER, BANK0 and BANK1.
  *
- * There are two different blink rates that can be programmed, each with
- * separate time for rise, on, fall, off and second-off.  Thus if 3 or more
- * different non-trivial rates are required, software must be used for the extra
- * rates. The two different blink rates must align with the two levels BANK0 and
- * BANK1.
- * This driver does not support double-blink so 'second-off' always matches
- * 'off'.
+ * There are two different blink rates that can be programmed, each
+ * with separate time for rise, on, fall, off and second-off.  Thus if
+ * 3 or more different non-trivial rates are required, software must
+ * be used for the extra rates. The two different blink rates must
+ * align with the two levels BANK0 and BANK1.  This driver does not
+ * support double-blink so 'second-off' always matches 'off'.
  *
- * Only 16 different times can be programmed in a roughly logarithmic scale from
- * 64ms to 16320ms.  To be precise the possible times are:
+ * Only 16 different times can be programmed in a roughly logarithmic
+ * scale from 64ms to 16320ms.  To be precise the possible times are:
  *    0, 64, 128, 192, 256, 384, 512, 768,
  *    1024, 1536, 2048, 3072, 4096, 5760, 8128, 16320
  *
- * Times that cannot be closely matched with these must be
- * handled in software.  This driver allows 12.5% error in matching.
+ * Times that cannot be closely matched with these must be handled in
+ * software.  This driver allows 12.5% error in matching.
  *
- * This driver does not allow rise/fall rates to be set explicitly.  When trying
- * to match a given 'on' or 'off' period, an appropriate pair of 'change' and
- * 'hold' times are chosen to get a close match.  If the target delay is even,
- * the 'change' number will be the smaller; if odd, the 'hold' number will be
- * the smaller.
-
- * Choosing pairs of delays with 12.5% errors allows us to match delays in the
- * ranges: 56-72, 112-144, 168-216, 224-27504, 28560-36720.
- * 26% of the achievable sums can be matched by multiple pairings. For example
- * 1536 == 1536+0, 1024+512, or 768+768.  This driver will always choose the
- * pairing with the least maximum - 768+768 in this case.  Other pairings are
- * not available.
+ * This driver does not allow rise/fall rates to be set explicitly.
+ * When trying to match a given 'on' or 'off' period, an appropriate
+ * pair of 'change' and 'hold' times are chosen to get a close match.
+ * If the target delay is even, the 'change' number will be the
+ * smaller; if odd, the 'hold' number will be the smaller.
+
+ * Choosing pairs of delays with 12.5% errors allows us to match
+ * delays in the ranges: 56-72, 112-144, 168-216, 224-27504,
+ * 28560-36720.
+ * 26% of the achievable sums can be matched by multiple pairings.
+ * For example 1536 == 1536+0, 1024+512, or 768+768.
+ * This driver will always choose the pairing with the least
+ * maximum - 768+768 in this case.  Other pairings are not available.
  *
- * Access to the 3 levels and 2 blinks are on a first-come, first-served basis.
- * Access can be shared by multiple leds if they have the same level and
- * either same blink rates, or some don't blink.
- * When a led changes, it relinquishes access and tries again, so it might
- * lose access to hardware blink.
- * If a blink engine cannot be allocated, software blink is used.
- * If the desired brightness cannot be allocated, the closest available non-zero
- * brightness is used.  As 'full' is always available, the worst case would be
- * to have two different blink rates at '1', with Max at '2', then other leds
- * will have to choose between '2' and '16'.  Hopefully this is not likely.
+ * Access to the 3 levels and 2 blinks are on a first-come,
+ * first-served basis.  Access can be shared by multiple leds if they
+ * have the same level and either same blink rates, or some don't
+ * blink.  When a led changes, it relinquishes access and tries again,
+ * so it might lose access to hardware blink.
  *
- * Each bank (BANK0 and BANK1) has two usage counts - LEDs using the brightness
- * and LEDs using the blink.  It can only be reprogrammed when the appropriate
- * counter is zero.  The MASTER level has a single usage count.
+ * If a blink engine cannot be allocated, software blink is used.  If
+ * the desired brightness cannot be allocated, the closest available
+ * non-zero brightness is used.  As 'full' is always available, the
+ * worst case would be to have two different blink rates at '1', with
+ * Max at '2', then other leds will have to choose between '2' and
+ * '16'.  Hopefully this is not likely.
  *
- * Each Led has programmable 'on' and 'off' time as milliseconds.  With each
- * there is a flag saying if it was explicitly requested or defaulted.
- * Similarly the banks know if each time was explicit or a default.  Defaults
- * are permitted to be changed freely - they are not recognised when matching.
+ * Each bank (BANK0 and BANK1) has two usage counts - LEDs using the
+ * brightness and LEDs using the blink.  It can only be reprogrammed
+ * when the appropriate counter is zero.  The MASTER level has a
+ * single usage count.
  *
+ * Each LED has programmable 'on' and 'off' time as milliseconds.
+ * With each there is a flag saying if it was explicitly requested or
+ * defaulted.  Similarly the banks know if each time was explicit or a
+ * default.  Defaults are permitted to be changed freely - they are
+ * not recognised when matching.
  *
- * An led-tca6507 device must be provided with platform data.  This data
- * lists for each output: the name, default trigger, and whether the signal
- * is being used as a GPiO rather than an led.  'struct led_plaform_data'
- * is used for this.  If 'name' is NULL, the output isn't used.  If 'flags'
- * is TCA6507_MAKE_CPIO, the output is a GPO.
- * The "struct led_platform_data" can be embedded in a
- * "struct tca6507_platform_data" which adds a 'gpio_base' for the GPiOs,
- * and a 'setup' callback which is called once the GPiOs are available.
  *
+ * An led-tca6507 device must be provided with platform data or
+ * configured via devicetree.
+ *
+ * The platform-data lists for each output: the name, default trigger,
+ * and whether the signal is being used as a GPIO rather than an LED.
+ * 'struct led_plaform_data' is used for this.  If 'name' is NULL, the
+ * output isn't used.  If 'flags' is TCA6507_MAKE_GPIO, the output is
+ * a GPO.  The "struct led_platform_data" can be embedded in a "struct
+ * tca6507_platform_data" which adds a 'gpio_base' for the GPIOs, and
+ * a 'setup' callback which is called once the GPIOs are available.
+ *
+ * When configured via devicetree there is one child for each output.
+ * The "reg" determines the output number and "compatible" determines
+ * whether it is an LED or a GPIO.  "linux,default-trigger" can set a
+ * default trigger.
  */
 
 #include <linux/module.h>
@@ -192,17 +202,18 @@ MODULE_DEVICE_TABLE(i2c, tca6507_id);
 static int choose_times(int msec, int *c1p, int *c2p)
 {
        /*
-        * Choose two timecodes which add to 'msec' as near as possible.
-        * The first returned is the 'on' or 'off' time.  The second is to be
-        * used as a 'fade-on' or 'fade-off' time.  If 'msec' is even,
-        * the first will not be smaller than the second.  If 'msec' is odd,
-        * the first will not be larger than the second.
-        * If we cannot get a sum within 1/8 of 'msec' fail with -EINVAL,
-        * otherwise return the sum that was achieved, plus 1 if the first is
-        * smaller.
-        * If two possibilities are equally good (e.g. 512+0, 256+256), choose
-        * the first pair so there is more change-time visible (i.e. it is
-        * softer).
+        * Choose two timecodes which add to 'msec' as near as
+        * possible.  The first returned is the 'on' or 'off' time.
+        * The second is to be used as a 'fade-on' or 'fade-off' time.
+        * If 'msec' is even, the first will not be smaller than the
+        * second.  If 'msec' is odd, the first will not be larger
+        * than the second.
+        * If we cannot get a sum within 1/8 of 'msec' fail with
+        * -EINVAL, otherwise return the sum that was achieved, plus 1
+        * if the first is smaller.
+        * If two possibilities are equally good (e.g. 512+0,
+        * 256+256), choose the first pair so there is more
+        * change-time visible (i.e. it is softer).
         */
        int c1, c2;
        int tmax = msec * 9 / 8;
@@ -255,8 +266,8 @@ static int choose_times(int msec, int *c1p, int *c2p)
 }
 
 /*
- * Update the register file with the appropriate 3-bit state for
- * the given led.
+ * Update the register file with the appropriate 3-bit state for the
+ * given led.
  */
 static void set_select(struct tca6507_chip *tca, int led, int val)
 {
@@ -274,9 +285,9 @@ static void set_select(struct tca6507_chip *tca, int led, int val)
        }
 }
 
-/* Update the register file with the appropriate 4-bit code for
- * one bank or other.  This can be used for timers, for levels, or
- * for initialisation.
+/* Update the register file with the appropriate 4-bit code for one
+ * bank or other.  This can be used for timers, for levels, or for
+ * initialization.
  */
 static void set_code(struct tca6507_chip *tca, int reg, int bank, int new)
 {
@@ -309,7 +320,7 @@ static void set_level(struct tca6507_chip *tca, int bank, int level)
        tca->bank[bank].level = level;
 }
 
-/* Record all relevant time code for a given bank */
+/* Record all relevant time codes for a given bank */
 static void set_times(struct tca6507_chip *tca, int bank)
 {
        int c1, c2;
@@ -317,7 +328,8 @@ static void set_times(struct tca6507_chip *tca, int bank)
 
        result = choose_times(tca->bank[bank].ontime, &c1, &c2);
        dev_dbg(&tca->client->dev,
-               "Chose on  times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1],
+               "Chose on  times %d(%d) %d(%d) for %dms\n",
+               c1, time_codes[c1],
                c2, time_codes[c2], tca->bank[bank].ontime);
        set_code(tca, TCA6507_FADE_ON, bank, c2);
        set_code(tca, TCA6507_FULL_ON, bank, c1);
@@ -325,7 +337,8 @@ static void set_times(struct tca6507_chip *tca, int bank)
 
        result = choose_times(tca->bank[bank].offtime, &c1, &c2);
        dev_dbg(&tca->client->dev,
-               "Chose off times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1],
+               "Chose off times %d(%d) %d(%d) for %dms\n",
+               c1, time_codes[c1],
                c2, time_codes[c2], tca->bank[bank].offtime);
        set_code(tca, TCA6507_FADE_OFF, bank, c2);
        set_code(tca, TCA6507_FIRST_OFF, bank, c1);
@@ -373,7 +386,8 @@ static void led_release(struct tca6507_led *led)
 
 static int led_prepare(struct tca6507_led *led)
 {
-       /* Assign this led to a bank, configuring that bank if necessary. */
+       /* Assign this led to a bank, configuring that bank if
+        * necessary. */
        int level = TO_LEVEL(led->led_cdev.brightness);
        struct tca6507_chip *tca = led->chip;
        int c1, c2;
@@ -389,10 +403,10 @@ static int led_prepare(struct tca6507_led *led)
 
        if (led->ontime == 0 || led->offtime == 0) {
                /*
-                * Just set the brightness, choosing first usable bank.
-                * If none perfect, choose best.
-                * Count backwards so we check MASTER bank first
-                * to avoid wasting a timer.
+                * Just set the brightness, choosing first usable
+                * bank.  If none perfect, choose best.  Count
+                * backwards so we check MASTER bank first to avoid
+                * wasting a timer.
                 */
                int best = -1;/* full-on */
                int diff = 15-level;
@@ -433,9 +447,9 @@ static int led_prepare(struct tca6507_led *led)
        }
 
        /*
-        * We have on/off time so we need to try to allocate a timing bank.
-        * First check if times are compatible with hardware and give up if
-        * not.
+        * We have on/off time so we need to try to allocate a timing
+        * bank.  First check if times are compatible with hardware
+        * and give up if not.
         */
        if (choose_times(led->ontime, &c1, &c2) < 0)
                return -EINVAL;
@@ -523,8 +537,8 @@ static int led_assign(struct tca6507_led *led)
        err = led_prepare(led);
        if (err) {
                /*
-                * Can only fail on timer setup.  In that case we need to
-                * re-establish as steady level.
+                * Can only fail on timer setup.  In that case we need
+                * to re-establish as steady level.
                 */
                led->ontime = 0;
                led->offtime = 0;
@@ -594,8 +608,8 @@ static void tca6507_gpio_set_value(struct gpio_chip *gc,
 
        spin_lock_irqsave(&tca->lock, flags);
        /*
-        * 'OFF' is floating high, and 'ON' is pulled down, so it has the
-        * inverse sense of 'val'.
+        * 'OFF' is floating high, and 'ON' is pulled down, so it has
+        * the inverse sense of 'val'.
         */
        set_select(tca, tca->gpio_map[offset],
                   val ? TCA6507_LS_LED_OFF : TCA6507_LS_LED_ON);
@@ -638,6 +652,9 @@ static int tca6507_probe_gpios(struct i2c_client *client,
        tca->gpio.direction_output = tca6507_gpio_direction_output;
        tca->gpio.set = tca6507_gpio_set_value;
        tca->gpio.dev = &client->dev;
+#ifdef CONFIG_OF_GPIO
+       tca->gpio.of_node = of_node_get(client->dev.of_node);
+#endif
        err = gpiochip_add(&tca->gpio);
        if (err) {
                tca->gpio.ngpio = 0;
@@ -682,7 +699,7 @@ tca6507_led_dt_init(struct i2c_client *client)
                return ERR_PTR(-ENODEV);
 
        tca_leds = devm_kzalloc(&client->dev,
-                       sizeof(struct led_info) * count, GFP_KERNEL);
+                       sizeof(struct led_info) * NUM_LEDS, GFP_KERNEL);
        if (!tca_leds)
                return ERR_PTR(-ENOMEM);
 
@@ -695,9 +712,11 @@ tca6507_led_dt_init(struct i2c_client *client)
                        of_get_property(child, "label", NULL) ? : child->name;
                led.default_trigger =
                        of_get_property(child, "linux,default-trigger", NULL);
-
+               led.flags = 0;
+               if (of_property_match_string(child, "compatible", "gpio") >= 0)
+                       led.flags |= TCA6507_MAKE_GPIO;
                ret = of_property_read_u32(child, "reg", &reg);
-               if (ret != 0)
+               if (ret != 0 || reg < 0 || reg >= NUM_LEDS)
                        continue;
 
                tca_leds[reg] = led;
@@ -708,7 +727,8 @@ tca6507_led_dt_init(struct i2c_client *client)
                return ERR_PTR(-ENOMEM);
 
        pdata->leds.leds = tca_leds;
-       pdata->leds.num_leds = count;
+       pdata->leds.num_leds = NUM_LEDS;
+       pdata->gpio_base = -1;
 
        return pdata;
 }
index 6753b65f8edeb2db67625a6fdf468b7c8b634928..d2f0120bc878379f460fc9a9d0416d2ae2e89bdd 100644 (file)
@@ -40,6 +40,7 @@ obj-$(CONFIG_WINDFARM_RM31)     += windfarm_fcu_controls.o \
                                   windfarm_ad7417_sensor.o \
                                   windfarm_lm75_sensor.o \
                                   windfarm_lm87_sensor.o \
+                                  windfarm_max6690_sensor.o \
                                   windfarm_pid.o \
                                   windfarm_cpufreq_clamp.o \
                                   windfarm_rm31.o
index 4beb55a0ff30dc9da10c340270e9cbd1c0e1c0b0..964353c5329d4d997ca16aae8c4bfdf72b7b816e 100644 (file)
@@ -279,7 +279,6 @@ struct bcache_device {
        unsigned long           sectors_dirty_last;
        long                    sectors_dirty_derivative;
 
-       mempool_t               *unaligned_bvec;
        struct bio_set          *bio_split;
 
        unsigned                data_csum:1;
@@ -902,7 +901,6 @@ void bch_bbio_endio(struct cache_set *, struct bio *, int, const char *);
 void bch_bbio_free(struct bio *, struct cache_set *);
 struct bio *bch_bbio_alloc(struct cache_set *);
 
-struct bio *bch_bio_split(struct bio *, int, gfp_t, struct bio_set *);
 void bch_generic_make_request(struct bio *, struct bio_split_pool *);
 void __bch_submit_bbio(struct bio *, struct cache_set *);
 void bch_submit_bbio(struct bio *, struct cache_set *, struct bkey *, unsigned);
index 5e2765aadce174e9b7cffd479667a2c48bcf500f..b62f3792537454c13cd7ba7c881428a54e8cbfa4 100644 (file)
@@ -299,7 +299,7 @@ void bch_btree_node_read(struct btree *b)
 
        bio = bch_bbio_alloc(b->c);
        bio->bi_rw      = REQ_META|READ_SYNC;
-       bio->bi_size    = KEY_SIZE(&b->key) << 9;
+       bio->bi_iter.bi_size = KEY_SIZE(&b->key) << 9;
        bio->bi_end_io  = btree_node_read_endio;
        bio->bi_private = &cl;
 
@@ -362,7 +362,7 @@ static void btree_node_write_done(struct closure *cl)
        struct bio_vec *bv;
        int n;
 
-       __bio_for_each_segment(bv, b->bio, n, 0)
+       bio_for_each_segment_all(bv, b->bio, n)
                __free_page(bv->bv_page);
 
        __btree_node_write_done(cl);
@@ -395,7 +395,7 @@ static void do_btree_node_write(struct btree *b)
        b->bio->bi_end_io       = btree_node_write_endio;
        b->bio->bi_private      = cl;
        b->bio->bi_rw           = REQ_META|WRITE_SYNC|REQ_FUA;
-       b->bio->bi_size         = set_blocks(i, b->c) * block_bytes(b->c);
+       b->bio->bi_iter.bi_size = set_blocks(i, b->c) * block_bytes(b->c);
        bch_bio_map(b->bio, i);
 
        /*
@@ -421,7 +421,7 @@ static void do_btree_node_write(struct btree *b)
                struct bio_vec *bv;
                void *base = (void *) ((unsigned long) i & ~(PAGE_SIZE - 1));
 
-               bio_for_each_segment(bv, b->bio, j)
+               bio_for_each_segment_all(bv, b->bio, j)
                        memcpy(page_address(bv->bv_page),
                               base + j * PAGE_SIZE, PAGE_SIZE);
 
index 264fcfbd629016aa1ab890cce56de2699c49be70..03cb4d114e1624997d114a3ac4a131d80d3d90fb 100644 (file)
@@ -173,7 +173,8 @@ void bch_data_verify(struct cached_dev *dc, struct bio *bio)
 {
        char name[BDEVNAME_SIZE];
        struct bio *check;
-       struct bio_vec *bv;
+       struct bio_vec bv, *bv2;
+       struct bvec_iter iter;
        int i;
 
        check = bio_clone(bio, GFP_NOIO);
@@ -185,23 +186,23 @@ void bch_data_verify(struct cached_dev *dc, struct bio *bio)
 
        submit_bio_wait(READ_SYNC, check);
 
-       bio_for_each_segment(bv, bio, i) {
-               void *p1 = kmap_atomic(bv->bv_page);
-               void *p2 = page_address(check->bi_io_vec[i].bv_page);
+       bio_for_each_segment(bv, bio, iter) {
+               void *p1 = kmap_atomic(bv.bv_page);
+               void *p2 = page_address(check->bi_io_vec[iter.bi_idx].bv_page);
 
-               cache_set_err_on(memcmp(p1 + bv->bv_offset,
-                                       p2 + bv->bv_offset,
-                                       bv->bv_len),
+               cache_set_err_on(memcmp(p1 + bv.bv_offset,
+                                       p2 + bv.bv_offset,
+                                       bv.bv_len),
                                 dc->disk.c,
                                 "verify failed at dev %s sector %llu",
                                 bdevname(dc->bdev, name),
-                                (uint64_t) bio->bi_sector);
+                                (uint64_t) bio->bi_iter.bi_sector);
 
                kunmap_atomic(p1);
        }
 
-       bio_for_each_segment_all(bv, check, i)
-               __free_page(bv->bv_page);
+       bio_for_each_segment_all(bv2, check, i)
+               __free_page(bv2->bv_page);
 out_put:
        bio_put(check);
 }
index 9056632995b1b8a2de9de607c60cd693704c9c65..fa028fa82df41bf509e15d140f9b3b943c5a8c2d 100644 (file)
 
 #include <linux/blkdev.h>
 
-static void bch_bi_idx_hack_endio(struct bio *bio, int error)
-{
-       struct bio *p = bio->bi_private;
-
-       bio_endio(p, error);
-       bio_put(bio);
-}
-
-static void bch_generic_make_request_hack(struct bio *bio)
-{
-       if (bio->bi_idx) {
-               struct bio *clone = bio_alloc(GFP_NOIO, bio_segments(bio));
-
-               memcpy(clone->bi_io_vec,
-                      bio_iovec(bio),
-                      bio_segments(bio) * sizeof(struct bio_vec));
-
-               clone->bi_sector        = bio->bi_sector;
-               clone->bi_bdev          = bio->bi_bdev;
-               clone->bi_rw            = bio->bi_rw;
-               clone->bi_vcnt          = bio_segments(bio);
-               clone->bi_size          = bio->bi_size;
-
-               clone->bi_private       = bio;
-               clone->bi_end_io        = bch_bi_idx_hack_endio;
-
-               bio = clone;
-       }
-
-       /*
-        * Hack, since drivers that clone bios clone up to bi_max_vecs, but our
-        * bios might have had more than that (before we split them per device
-        * limitations).
-        *
-        * To be taken out once immutable bvec stuff is in.
-        */
-       bio->bi_max_vecs = bio->bi_vcnt;
-
-       generic_make_request(bio);
-}
-
-/**
- * bch_bio_split - split a bio
- * @bio:       bio to split
- * @sectors:   number of sectors to split from the front of @bio
- * @gfp:       gfp mask
- * @bs:                bio set to allocate from
- *
- * Allocates and returns a new bio which represents @sectors from the start of
- * @bio, and updates @bio to represent the remaining sectors.
- *
- * If bio_sectors(@bio) was less than or equal to @sectors, returns @bio
- * unchanged.
- *
- * The newly allocated bio will point to @bio's bi_io_vec, if the split was on a
- * bvec boundry; it is the caller's responsibility to ensure that @bio is not
- * freed before the split.
- */
-struct bio *bch_bio_split(struct bio *bio, int sectors,
-                         gfp_t gfp, struct bio_set *bs)
-{
-       unsigned idx = bio->bi_idx, vcnt = 0, nbytes = sectors << 9;
-       struct bio_vec *bv;
-       struct bio *ret = NULL;
-
-       BUG_ON(sectors <= 0);
-
-       if (sectors >= bio_sectors(bio))
-               return bio;
-
-       if (bio->bi_rw & REQ_DISCARD) {
-               ret = bio_alloc_bioset(gfp, 1, bs);
-               if (!ret)
-                       return NULL;
-               idx = 0;
-               goto out;
-       }
-
-       bio_for_each_segment(bv, bio, idx) {
-               vcnt = idx - bio->bi_idx;
-
-               if (!nbytes) {
-                       ret = bio_alloc_bioset(gfp, vcnt, bs);
-                       if (!ret)
-                               return NULL;
-
-                       memcpy(ret->bi_io_vec, bio_iovec(bio),
-                              sizeof(struct bio_vec) * vcnt);
-
-                       break;
-               } else if (nbytes < bv->bv_len) {
-                       ret = bio_alloc_bioset(gfp, ++vcnt, bs);
-                       if (!ret)
-                               return NULL;
-
-                       memcpy(ret->bi_io_vec, bio_iovec(bio),
-                              sizeof(struct bio_vec) * vcnt);
-
-                       ret->bi_io_vec[vcnt - 1].bv_len = nbytes;
-                       bv->bv_offset   += nbytes;
-                       bv->bv_len      -= nbytes;
-                       break;
-               }
-
-               nbytes -= bv->bv_len;
-       }
-out:
-       ret->bi_bdev    = bio->bi_bdev;
-       ret->bi_sector  = bio->bi_sector;
-       ret->bi_size    = sectors << 9;
-       ret->bi_rw      = bio->bi_rw;
-       ret->bi_vcnt    = vcnt;
-       ret->bi_max_vecs = vcnt;
-
-       bio->bi_sector  += sectors;
-       bio->bi_size    -= sectors << 9;
-       bio->bi_idx      = idx;
-
-       if (bio_integrity(bio)) {
-               if (bio_integrity_clone(ret, bio, gfp)) {
-                       bio_put(ret);
-                       return NULL;
-               }
-
-               bio_integrity_trim(ret, 0, bio_sectors(ret));
-               bio_integrity_trim(bio, bio_sectors(ret), bio_sectors(bio));
-       }
-
-       return ret;
-}
-
 static unsigned bch_bio_max_sectors(struct bio *bio)
 {
-       unsigned ret = bio_sectors(bio);
        struct request_queue *q = bdev_get_queue(bio->bi_bdev);
-       unsigned max_segments = min_t(unsigned, BIO_MAX_PAGES,
-                                     queue_max_segments(q));
+       struct bio_vec bv;
+       struct bvec_iter iter;
+       unsigned ret = 0, seg = 0;
 
        if (bio->bi_rw & REQ_DISCARD)
-               return min(ret, q->limits.max_discard_sectors);
-
-       if (bio_segments(bio) > max_segments ||
-           q->merge_bvec_fn) {
-               struct bio_vec *bv;
-               int i, seg = 0;
-
-               ret = 0;
-
-               bio_for_each_segment(bv, bio, i) {
-                       struct bvec_merge_data bvm = {
-                               .bi_bdev        = bio->bi_bdev,
-                               .bi_sector      = bio->bi_sector,
-                               .bi_size        = ret << 9,
-                               .bi_rw          = bio->bi_rw,
-                       };
-
-                       if (seg == max_segments)
-                               break;
+               return min(bio_sectors(bio), q->limits.max_discard_sectors);
+
+       bio_for_each_segment(bv, bio, iter) {
+               struct bvec_merge_data bvm = {
+                       .bi_bdev        = bio->bi_bdev,
+                       .bi_sector      = bio->bi_iter.bi_sector,
+                       .bi_size        = ret << 9,
+                       .bi_rw          = bio->bi_rw,
+               };
+
+               if (seg == min_t(unsigned, BIO_MAX_PAGES,
+                                queue_max_segments(q)))
+                       break;
 
-                       if (q->merge_bvec_fn &&
-                           q->merge_bvec_fn(q, &bvm, bv) < (int) bv->bv_len)
-                               break;
+               if (q->merge_bvec_fn &&
+                   q->merge_bvec_fn(q, &bvm, &bv) < (int) bv.bv_len)
+                       break;
 
-                       seg++;
-                       ret += bv->bv_len >> 9;
-               }
+               seg++;
+               ret += bv.bv_len >> 9;
        }
 
        ret = min(ret, queue_max_sectors(q));
 
        WARN_ON(!ret);
-       ret = max_t(int, ret, bio_iovec(bio)->bv_len >> 9);
+       ret = max_t(int, ret, bio_iovec(bio).bv_len >> 9);
 
        return ret;
 }
@@ -193,7 +55,7 @@ static void bch_bio_submit_split_done(struct closure *cl)
 
        s->bio->bi_end_io = s->bi_end_io;
        s->bio->bi_private = s->bi_private;
-       bio_endio(s->bio, 0);
+       bio_endio_nodec(s->bio, 0);
 
        closure_debug_destroy(&s->cl);
        mempool_free(s, s->p->bio_split_hook);
@@ -232,19 +94,19 @@ void bch_generic_make_request(struct bio *bio, struct bio_split_pool *p)
        bio_get(bio);
 
        do {
-               n = bch_bio_split(bio, bch_bio_max_sectors(bio),
-                                 GFP_NOIO, s->p->bio_split);
+               n = bio_next_split(bio, bch_bio_max_sectors(bio),
+                                  GFP_NOIO, s->p->bio_split);
 
                n->bi_end_io    = bch_bio_submit_split_endio;
                n->bi_private   = &s->cl;
 
                closure_get(&s->cl);
-               bch_generic_make_request_hack(n);
+               generic_make_request(n);
        } while (n != bio);
 
        continue_at(&s->cl, bch_bio_submit_split_done, NULL);
 submit:
-       bch_generic_make_request_hack(bio);
+       generic_make_request(bio);
 }
 
 /* Bios with headers */
@@ -272,8 +134,8 @@ void __bch_submit_bbio(struct bio *bio, struct cache_set *c)
 {
        struct bbio *b = container_of(bio, struct bbio, bio);
 
-       bio->bi_sector  = PTR_OFFSET(&b->key, 0);
-       bio->bi_bdev    = PTR_CACHE(c, &b->key, 0)->bdev;
+       bio->bi_iter.bi_sector  = PTR_OFFSET(&b->key, 0);
+       bio->bi_bdev            = PTR_CACHE(c, &b->key, 0)->bdev;
 
        b->submit_time_us = local_clock_us();
        closure_bio_submit(bio, bio->bi_private, PTR_CACHE(c, &b->key, 0));
index ecdaa671bd50457bf38d1cf9f896ffd1c8352546..7eafdf09a0ae11cb1c4108926e4d1c51ac90c9f4 100644 (file)
@@ -51,10 +51,10 @@ reread:             left = ca->sb.bucket_size - offset;
                len = min_t(unsigned, left, PAGE_SECTORS * 8);
 
                bio_reset(bio);
-               bio->bi_sector  = bucket + offset;
+               bio->bi_iter.bi_sector  = bucket + offset;
                bio->bi_bdev    = ca->bdev;
                bio->bi_rw      = READ;
-               bio->bi_size    = len << 9;
+               bio->bi_iter.bi_size    = len << 9;
 
                bio->bi_end_io  = journal_read_endio;
                bio->bi_private = &cl;
@@ -437,13 +437,13 @@ static void do_journal_discard(struct cache *ca)
                atomic_set(&ja->discard_in_flight, DISCARD_IN_FLIGHT);
 
                bio_init(bio);
-               bio->bi_sector          = bucket_to_sector(ca->set,
+               bio->bi_iter.bi_sector  = bucket_to_sector(ca->set,
                                                ca->sb.d[ja->discard_idx]);
                bio->bi_bdev            = ca->bdev;
                bio->bi_rw              = REQ_WRITE|REQ_DISCARD;
                bio->bi_max_vecs        = 1;
                bio->bi_io_vec          = bio->bi_inline_vecs;
-               bio->bi_size            = bucket_bytes(ca);
+               bio->bi_iter.bi_size    = bucket_bytes(ca);
                bio->bi_end_io          = journal_discard_endio;
 
                closure_get(&ca->set->cl);
@@ -608,10 +608,10 @@ static void journal_write_unlocked(struct closure *cl)
                atomic_long_add(sectors, &ca->meta_sectors_written);
 
                bio_reset(bio);
-               bio->bi_sector  = PTR_OFFSET(k, i);
+               bio->bi_iter.bi_sector  = PTR_OFFSET(k, i);
                bio->bi_bdev    = ca->bdev;
                bio->bi_rw      = REQ_WRITE|REQ_SYNC|REQ_META|REQ_FLUSH|REQ_FUA;
-               bio->bi_size    = sectors << 9;
+               bio->bi_iter.bi_size = sectors << 9;
 
                bio->bi_end_io  = journal_write_endio;
                bio->bi_private = w;
index 7c1275e66025b691ec8ee4896448d46e28a2c5d9..581f95df8265579e94a9546d84644be8deb335c2 100644 (file)
@@ -82,7 +82,7 @@ static void moving_init(struct moving_io *io)
        bio_get(bio);
        bio_set_prio(bio, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0));
 
-       bio->bi_size            = KEY_SIZE(&io->w->key) << 9;
+       bio->bi_iter.bi_size    = KEY_SIZE(&io->w->key) << 9;
        bio->bi_max_vecs        = DIV_ROUND_UP(KEY_SIZE(&io->w->key),
                                               PAGE_SECTORS);
        bio->bi_private         = &io->cl;
@@ -98,7 +98,7 @@ static void write_moving(struct closure *cl)
        if (!op->error) {
                moving_init(io);
 
-               io->bio.bio.bi_sector = KEY_START(&io->w->key);
+               io->bio.bio.bi_iter.bi_sector = KEY_START(&io->w->key);
                op->write_prio          = 1;
                op->bio                 = &io->bio.bio;
 
index fbcc851ed5a5a74b09d763c455d132dee68e7eb3..5878cdb3952948d78e029f4ed0a343d7a7807cab 100644 (file)
@@ -198,14 +198,14 @@ static bool verify(struct cached_dev *dc, struct bio *bio)
 
 static void bio_csum(struct bio *bio, struct bkey *k)
 {
-       struct bio_vec *bv;
+       struct bio_vec bv;
+       struct bvec_iter iter;
        uint64_t csum = 0;
-       int i;
 
-       bio_for_each_segment(bv, bio, i) {
-               void *d = kmap(bv->bv_page) + bv->bv_offset;
-               csum = bch_crc64_update(csum, d, bv->bv_len);
-               kunmap(bv->bv_page);
+       bio_for_each_segment(bv, bio, iter) {
+               void *d = kmap(bv.bv_page) + bv.bv_offset;
+               csum = bch_crc64_update(csum, d, bv.bv_len);
+               kunmap(bv.bv_page);
        }
 
        k->ptr[KEY_PTRS(k)] = csum & (~0ULL >> 1);
@@ -261,7 +261,7 @@ static void bch_data_invalidate(struct closure *cl)
        struct bio *bio = op->bio;
 
        pr_debug("invalidating %i sectors from %llu",
-                bio_sectors(bio), (uint64_t) bio->bi_sector);
+                bio_sectors(bio), (uint64_t) bio->bi_iter.bi_sector);
 
        while (bio_sectors(bio)) {
                unsigned sectors = min(bio_sectors(bio),
@@ -270,11 +270,11 @@ static void bch_data_invalidate(struct closure *cl)
                if (bch_keylist_realloc(&op->insert_keys, 0, op->c))
                        goto out;
 
-               bio->bi_sector  += sectors;
-               bio->bi_size    -= sectors << 9;
+               bio->bi_iter.bi_sector  += sectors;
+               bio->bi_iter.bi_size    -= sectors << 9;
 
                bch_keylist_add(&op->insert_keys,
-                               &KEY(op->inode, bio->bi_sector, sectors));
+                               &KEY(op->inode, bio->bi_iter.bi_sector, sectors));
        }
 
        op->insert_data_done = true;
@@ -364,14 +364,14 @@ static void bch_data_insert_start(struct closure *cl)
                k = op->insert_keys.top;
                bkey_init(k);
                SET_KEY_INODE(k, op->inode);
-               SET_KEY_OFFSET(k, bio->bi_sector);
+               SET_KEY_OFFSET(k, bio->bi_iter.bi_sector);
 
                if (!bch_alloc_sectors(op->c, k, bio_sectors(bio),
                                       op->write_point, op->write_prio,
                                       op->writeback))
                        goto err;
 
-               n = bch_bio_split(bio, KEY_SIZE(k), GFP_NOIO, split);
+               n = bio_next_split(bio, KEY_SIZE(k), GFP_NOIO, split);
 
                n->bi_end_io    = bch_data_insert_endio;
                n->bi_private   = cl;
@@ -522,7 +522,7 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
             (bio->bi_rw & REQ_WRITE)))
                goto skip;
 
-       if (bio->bi_sector & (c->sb.block_size - 1) ||
+       if (bio->bi_iter.bi_sector & (c->sb.block_size - 1) ||
            bio_sectors(bio) & (c->sb.block_size - 1)) {
                pr_debug("skipping unaligned io");
                goto skip;
@@ -546,8 +546,8 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
 
        spin_lock(&dc->io_lock);
 
-       hlist_for_each_entry(i, iohash(dc, bio->bi_sector), hash)
-               if (i->last == bio->bi_sector &&
+       hlist_for_each_entry(i, iohash(dc, bio->bi_iter.bi_sector), hash)
+               if (i->last == bio->bi_iter.bi_sector &&
                    time_before(jiffies, i->jiffies))
                        goto found;
 
@@ -556,8 +556,8 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
        add_sequential(task);
        i->sequential = 0;
 found:
-       if (i->sequential + bio->bi_size > i->sequential)
-               i->sequential   += bio->bi_size;
+       if (i->sequential + bio->bi_iter.bi_size > i->sequential)
+               i->sequential   += bio->bi_iter.bi_size;
 
        i->last                  = bio_end_sector(bio);
        i->jiffies               = jiffies + msecs_to_jiffies(5000);
@@ -606,7 +606,6 @@ struct search {
        unsigned                insert_bio_sectors;
 
        unsigned                recoverable:1;
-       unsigned                unaligned_bvec:1;
        unsigned                write:1;
        unsigned                read_dirty_data:1;
 
@@ -650,15 +649,15 @@ static int cache_lookup_fn(struct btree_op *op, struct btree *b, struct bkey *k)
        struct bkey *bio_key;
        unsigned ptr;
 
-       if (bkey_cmp(k, &KEY(s->iop.inode, bio->bi_sector, 0)) <= 0)
+       if (bkey_cmp(k, &KEY(s->iop.inode, bio->bi_iter.bi_sector, 0)) <= 0)
                return MAP_CONTINUE;
 
        if (KEY_INODE(k) != s->iop.inode ||
-           KEY_START(k) > bio->bi_sector) {
+           KEY_START(k) > bio->bi_iter.bi_sector) {
                unsigned bio_sectors = bio_sectors(bio);
                unsigned sectors = KEY_INODE(k) == s->iop.inode
                        ? min_t(uint64_t, INT_MAX,
-                               KEY_START(k) - bio->bi_sector)
+                               KEY_START(k) - bio->bi_iter.bi_sector)
                        : INT_MAX;
 
                int ret = s->d->cache_miss(b, s, bio, sectors);
@@ -680,14 +679,14 @@ static int cache_lookup_fn(struct btree_op *op, struct btree *b, struct bkey *k)
        if (KEY_DIRTY(k))
                s->read_dirty_data = true;
 
-       n = bch_bio_split(bio, min_t(uint64_t, INT_MAX,
-                                    KEY_OFFSET(k) - bio->bi_sector),
-                         GFP_NOIO, s->d->bio_split);
+       n = bio_next_split(bio, min_t(uint64_t, INT_MAX,
+                                     KEY_OFFSET(k) - bio->bi_iter.bi_sector),
+                          GFP_NOIO, s->d->bio_split);
 
        bio_key = &container_of(n, struct bbio, bio)->key;
        bch_bkey_copy_single_ptr(bio_key, k, ptr);
 
-       bch_cut_front(&KEY(s->iop.inode, n->bi_sector, 0), bio_key);
+       bch_cut_front(&KEY(s->iop.inode, n->bi_iter.bi_sector, 0), bio_key);
        bch_cut_back(&KEY(s->iop.inode, bio_end_sector(n), 0), bio_key);
 
        n->bi_end_io    = bch_cache_read_endio;
@@ -714,7 +713,7 @@ static void cache_lookup(struct closure *cl)
        struct bio *bio = &s->bio.bio;
 
        int ret = bch_btree_map_keys(&s->op, s->iop.c,
-                                    &KEY(s->iop.inode, bio->bi_sector, 0),
+                                    &KEY(s->iop.inode, bio->bi_iter.bi_sector, 0),
                                     cache_lookup_fn, MAP_END_KEY);
        if (ret == -EAGAIN)
                continue_at(cl, cache_lookup, bcache_wq);
@@ -759,10 +758,12 @@ static void bio_complete(struct search *s)
 static void do_bio_hook(struct search *s)
 {
        struct bio *bio = &s->bio.bio;
-       memcpy(bio, s->orig_bio, sizeof(struct bio));
 
+       bio_init(bio);
+       __bio_clone_fast(bio, s->orig_bio);
        bio->bi_end_io          = request_endio;
        bio->bi_private         = &s->cl;
+
        atomic_set(&bio->bi_cnt, 3);
 }
 
@@ -774,9 +775,6 @@ static void search_free(struct closure *cl)
        if (s->iop.bio)
                bio_put(s->iop.bio);
 
-       if (s->unaligned_bvec)
-               mempool_free(s->bio.bio.bi_io_vec, s->d->unaligned_bvec);
-
        closure_debug_destroy(cl);
        mempool_free(s, s->d->c->search);
 }
@@ -784,7 +782,6 @@ static void search_free(struct closure *cl)
 static struct search *search_alloc(struct bio *bio, struct bcache_device *d)
 {
        struct search *s;
-       struct bio_vec *bv;
 
        s = mempool_alloc(d->c->search, GFP_NOIO);
        memset(s, 0, offsetof(struct search, iop.insert_keys));
@@ -803,15 +800,6 @@ static struct search *search_alloc(struct bio *bio, struct bcache_device *d)
        s->start_time           = jiffies;
        do_bio_hook(s);
 
-       if (bio->bi_size != bio_segments(bio) * PAGE_SIZE) {
-               bv = mempool_alloc(d->unaligned_bvec, GFP_NOIO);
-               memcpy(bv, bio_iovec(bio),
-                      sizeof(struct bio_vec) * bio_segments(bio));
-
-               s->bio.bio.bi_io_vec    = bv;
-               s->unaligned_bvec       = 1;
-       }
-
        return s;
 }
 
@@ -850,26 +838,13 @@ static void cached_dev_read_error(struct closure *cl)
 {
        struct search *s = container_of(cl, struct search, cl);
        struct bio *bio = &s->bio.bio;
-       struct bio_vec *bv;
-       int i;
 
        if (s->recoverable) {
                /* Retry from the backing device: */
                trace_bcache_read_retry(s->orig_bio);
 
                s->iop.error = 0;
-               bv = s->bio.bio.bi_io_vec;
                do_bio_hook(s);
-               s->bio.bio.bi_io_vec = bv;
-
-               if (!s->unaligned_bvec)
-                       bio_for_each_segment(bv, s->orig_bio, i)
-                               bv->bv_offset = 0, bv->bv_len = PAGE_SIZE;
-               else
-                       memcpy(s->bio.bio.bi_io_vec,
-                              bio_iovec(s->orig_bio),
-                              sizeof(struct bio_vec) *
-                              bio_segments(s->orig_bio));
 
                /* XXX: invalidate cache */
 
@@ -894,9 +869,9 @@ static void cached_dev_read_done(struct closure *cl)
 
        if (s->iop.bio) {
                bio_reset(s->iop.bio);
-               s->iop.bio->bi_sector = s->cache_miss->bi_sector;
+               s->iop.bio->bi_iter.bi_sector = s->cache_miss->bi_iter.bi_sector;
                s->iop.bio->bi_bdev = s->cache_miss->bi_bdev;
-               s->iop.bio->bi_size = s->insert_bio_sectors << 9;
+               s->iop.bio->bi_iter.bi_size = s->insert_bio_sectors << 9;
                bch_bio_map(s->iop.bio, NULL);
 
                bio_copy_data(s->cache_miss, s->iop.bio);
@@ -905,8 +880,7 @@ static void cached_dev_read_done(struct closure *cl)
                s->cache_miss = NULL;
        }
 
-       if (verify(dc, &s->bio.bio) && s->recoverable &&
-           !s->unaligned_bvec && !s->read_dirty_data)
+       if (verify(dc, &s->bio.bio) && s->recoverable && !s->read_dirty_data)
                bch_data_verify(dc, s->orig_bio);
 
        bio_complete(s);
@@ -946,7 +920,7 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
        struct bio *miss, *cache_bio;
 
        if (s->cache_miss || s->iop.bypass) {
-               miss = bch_bio_split(bio, sectors, GFP_NOIO, s->d->bio_split);
+               miss = bio_next_split(bio, sectors, GFP_NOIO, s->d->bio_split);
                ret = miss == bio ? MAP_DONE : MAP_CONTINUE;
                goto out_submit;
        }
@@ -960,7 +934,7 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
        s->insert_bio_sectors = min(sectors, bio_sectors(bio) + reada);
 
        s->iop.replace_key = KEY(s->iop.inode,
-                                bio->bi_sector + s->insert_bio_sectors,
+                                bio->bi_iter.bi_sector + s->insert_bio_sectors,
                                 s->insert_bio_sectors);
 
        ret = bch_btree_insert_check_key(b, &s->op, &s->iop.replace_key);
@@ -969,7 +943,7 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
 
        s->iop.replace = true;
 
-       miss = bch_bio_split(bio, sectors, GFP_NOIO, s->d->bio_split);
+       miss = bio_next_split(bio, sectors, GFP_NOIO, s->d->bio_split);
 
        /* btree_search_recurse()'s btree iterator is no good anymore */
        ret = miss == bio ? MAP_DONE : -EINTR;
@@ -980,9 +954,9 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
        if (!cache_bio)
                goto out_submit;
 
-       cache_bio->bi_sector    = miss->bi_sector;
-       cache_bio->bi_bdev      = miss->bi_bdev;
-       cache_bio->bi_size      = s->insert_bio_sectors << 9;
+       cache_bio->bi_iter.bi_sector    = miss->bi_iter.bi_sector;
+       cache_bio->bi_bdev              = miss->bi_bdev;
+       cache_bio->bi_iter.bi_size      = s->insert_bio_sectors << 9;
 
        cache_bio->bi_end_io    = request_endio;
        cache_bio->bi_private   = &s->cl;
@@ -1032,7 +1006,7 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s)
 {
        struct closure *cl = &s->cl;
        struct bio *bio = &s->bio.bio;
-       struct bkey start = KEY(dc->disk.id, bio->bi_sector, 0);
+       struct bkey start = KEY(dc->disk.id, bio->bi_iter.bi_sector, 0);
        struct bkey end = KEY(dc->disk.id, bio_end_sector(bio), 0);
 
        bch_keybuf_check_overlapping(&s->iop.c->moving_gc_keys, &start, &end);
@@ -1088,8 +1062,7 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s)
                        closure_bio_submit(flush, cl, s->d);
                }
        } else {
-               s->iop.bio = bio_clone_bioset(bio, GFP_NOIO,
-                                             dc->disk.bio_split);
+               s->iop.bio = bio_clone_fast(bio, GFP_NOIO, dc->disk.bio_split);
 
                closure_bio_submit(bio, cl, s->d);
        }
@@ -1127,13 +1100,13 @@ static void cached_dev_make_request(struct request_queue *q, struct bio *bio)
        part_stat_unlock();
 
        bio->bi_bdev = dc->bdev;
-       bio->bi_sector += dc->sb.data_offset;
+       bio->bi_iter.bi_sector += dc->sb.data_offset;
 
        if (cached_dev_get(dc)) {
                s = search_alloc(bio, d);
                trace_bcache_request_start(s->d, bio);
 
-               if (!bio->bi_size) {
+               if (!bio->bi_iter.bi_size) {
                        /*
                         * can't call bch_journal_meta from under
                         * generic_make_request
@@ -1205,24 +1178,24 @@ void bch_cached_dev_request_init(struct cached_dev *dc)
 static int flash_dev_cache_miss(struct btree *b, struct search *s,
                                struct bio *bio, unsigned sectors)
 {
-       struct bio_vec *bv;
-       int i;
+       struct bio_vec bv;
+       struct bvec_iter iter;
 
        /* Zero fill bio */
 
-       bio_for_each_segment(bv, bio, i) {
-               unsigned j = min(bv->bv_len >> 9, sectors);
+       bio_for_each_segment(bv, bio, iter) {
+               unsigned j = min(bv.bv_len >> 9, sectors);
 
-               void *p = kmap(bv->bv_page);
-               memset(p + bv->bv_offset, 0, j << 9);
-               kunmap(bv->bv_page);
+               void *p = kmap(bv.bv_page);
+               memset(p + bv.bv_offset, 0, j << 9);
+               kunmap(bv.bv_page);
 
                sectors -= j;
        }
 
-       bio_advance(bio, min(sectors << 9, bio->bi_size));
+       bio_advance(bio, min(sectors << 9, bio->bi_iter.bi_size));
 
-       if (!bio->bi_size)
+       if (!bio->bi_iter.bi_size)
                return MAP_DONE;
 
        return MAP_CONTINUE;
@@ -1256,7 +1229,7 @@ static void flash_dev_make_request(struct request_queue *q, struct bio *bio)
 
        trace_bcache_request_start(s->d, bio);
 
-       if (!bio->bi_size) {
+       if (!bio->bi_iter.bi_size) {
                /*
                 * can't call bch_journal_meta from under
                 * generic_make_request
@@ -1266,7 +1239,7 @@ static void flash_dev_make_request(struct request_queue *q, struct bio *bio)
                                      bcache_wq);
        } else if (rw) {
                bch_keybuf_check_overlapping(&s->iop.c->moving_gc_keys,
-                                       &KEY(d->id, bio->bi_sector, 0),
+                                       &KEY(d->id, bio->bi_iter.bi_sector, 0),
                                        &KEY(d->id, bio_end_sector(bio), 0));
 
                s->iop.bypass           = (bio->bi_rw & REQ_DISCARD) != 0;
index dec15cd2d797eaaa7fa0585abf8867c9f70a4cef..60fb6044b9535fcb1864b12af36b479014ad641b 100644 (file)
@@ -233,9 +233,9 @@ static void __write_super(struct cache_sb *sb, struct bio *bio)
        struct cache_sb *out = page_address(bio->bi_io_vec[0].bv_page);
        unsigned i;
 
-       bio->bi_sector  = SB_SECTOR;
-       bio->bi_rw      = REQ_SYNC|REQ_META;
-       bio->bi_size    = SB_SIZE;
+       bio->bi_iter.bi_sector  = SB_SECTOR;
+       bio->bi_rw              = REQ_SYNC|REQ_META;
+       bio->bi_iter.bi_size    = SB_SIZE;
        bch_bio_map(bio, NULL);
 
        out->offset             = cpu_to_le64(sb->offset);
@@ -347,7 +347,7 @@ static void uuid_io(struct cache_set *c, unsigned long rw,
                struct bio *bio = bch_bbio_alloc(c);
 
                bio->bi_rw      = REQ_SYNC|REQ_META|rw;
-               bio->bi_size    = KEY_SIZE(k) << 9;
+               bio->bi_iter.bi_size = KEY_SIZE(k) << 9;
 
                bio->bi_end_io  = uuid_endio;
                bio->bi_private = cl;
@@ -503,10 +503,10 @@ static void prio_io(struct cache *ca, uint64_t bucket, unsigned long rw)
 
        closure_init_stack(cl);
 
-       bio->bi_sector  = bucket * ca->sb.bucket_size;
-       bio->bi_bdev    = ca->bdev;
-       bio->bi_rw      = REQ_SYNC|REQ_META|rw;
-       bio->bi_size    = bucket_bytes(ca);
+       bio->bi_iter.bi_sector  = bucket * ca->sb.bucket_size;
+       bio->bi_bdev            = ca->bdev;
+       bio->bi_rw              = REQ_SYNC|REQ_META|rw;
+       bio->bi_iter.bi_size    = bucket_bytes(ca);
 
        bio->bi_end_io  = prio_endio;
        bio->bi_private = ca;
@@ -739,8 +739,6 @@ static void bcache_device_free(struct bcache_device *d)
        }
 
        bio_split_pool_free(&d->bio_split_hook);
-       if (d->unaligned_bvec)
-               mempool_destroy(d->unaligned_bvec);
        if (d->bio_split)
                bioset_free(d->bio_split);
        if (is_vmalloc_addr(d->full_dirty_stripes))
@@ -793,8 +791,6 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,
                return minor;
 
        if (!(d->bio_split = bioset_create(4, offsetof(struct bbio, bio))) ||
-           !(d->unaligned_bvec = mempool_create_kmalloc_pool(1,
-                               sizeof(struct bio_vec) * BIO_MAX_PAGES)) ||
            bio_split_pool_init(&d->bio_split_hook) ||
            !(d->disk = alloc_disk(1))) {
                ida_simple_remove(&bcache_minor, minor);
index 462214eeacbedbd9548e725be2e625723cda0d7e..c57621e49dc002c7b94b7bf34f2a1aa06a3f1b46 100644 (file)
@@ -218,10 +218,10 @@ uint64_t bch_next_delay(struct bch_ratelimit *d, uint64_t done)
 
 void bch_bio_map(struct bio *bio, void *base)
 {
-       size_t size = bio->bi_size;
+       size_t size = bio->bi_iter.bi_size;
        struct bio_vec *bv = bio->bi_io_vec;
 
-       BUG_ON(!bio->bi_size);
+       BUG_ON(!bio->bi_iter.bi_size);
        BUG_ON(bio->bi_vcnt);
 
        bv->bv_offset = base ? ((unsigned long) base) % PAGE_SIZE : 0;
index 99053b1251bea1049c627580f3614d1c18f89b60..04657e93f4fd55e0985797c5813bffd893ca65bc 100644 (file)
@@ -113,7 +113,7 @@ static void dirty_init(struct keybuf_key *w)
        if (!io->dc->writeback_percent)
                bio_set_prio(bio, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0));
 
-       bio->bi_size            = KEY_SIZE(&w->key) << 9;
+       bio->bi_iter.bi_size    = KEY_SIZE(&w->key) << 9;
        bio->bi_max_vecs        = DIV_ROUND_UP(KEY_SIZE(&w->key), PAGE_SECTORS);
        bio->bi_private         = w;
        bio->bi_io_vec          = bio->bi_inline_vecs;
@@ -186,7 +186,7 @@ static void write_dirty(struct closure *cl)
 
        dirty_init(w);
        io->bio.bi_rw           = WRITE;
-       io->bio.bi_sector       = KEY_START(&w->key);
+       io->bio.bi_iter.bi_sector = KEY_START(&w->key);
        io->bio.bi_bdev         = io->dc->bdev;
        io->bio.bi_end_io       = dirty_endio;
 
@@ -255,7 +255,7 @@ static void read_dirty(struct cached_dev *dc)
                io->dc          = dc;
 
                dirty_init(w);
-               io->bio.bi_sector       = PTR_OFFSET(&w->key, 0);
+               io->bio.bi_iter.bi_sector = PTR_OFFSET(&w->key, 0);
                io->bio.bi_bdev         = PTR_CACHE(dc->disk.c,
                                                    &w->key, 0)->bdev;
                io->bio.bi_rw           = READ;
index c9ddcf4614b9300701c9867033c82bc13cadf472..e2f8598937ac41ff5c7577bc5e65aeb39de95386 100644 (file)
@@ -50,7 +50,7 @@ static inline bool should_writeback(struct cached_dev *dc, struct bio *bio,
                return false;
 
        if (dc->partial_stripes_expensive &&
-           bcache_dev_stripe_dirty(dc, bio->bi_sector,
+           bcache_dev_stripe_dirty(dc, bio->bi_iter.bi_sector,
                                    bio_sectors(bio)))
                return true;
 
index 3a8cfa2645c72f6539170f2ab2d3242bb4a6fa58..dd3646111561512f50728aa915b8a279be1c26ac 100644 (file)
  * original bio state.
  */
 
-struct dm_bio_vec_details {
-#if PAGE_SIZE < 65536
-       __u16 bv_len;
-       __u16 bv_offset;
-#else
-       unsigned bv_len;
-       unsigned bv_offset;
-#endif
-};
-
 struct dm_bio_details {
-       sector_t bi_sector;
        struct block_device *bi_bdev;
-       unsigned int bi_size;
-       unsigned short bi_idx;
        unsigned long bi_flags;
-       struct dm_bio_vec_details bi_io_vec[BIO_MAX_PAGES];
+       struct bvec_iter bi_iter;
 };
 
 static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
 {
-       unsigned i;
-
-       bd->bi_sector = bio->bi_sector;
        bd->bi_bdev = bio->bi_bdev;
-       bd->bi_size = bio->bi_size;
-       bd->bi_idx = bio->bi_idx;
        bd->bi_flags = bio->bi_flags;
-
-       for (i = 0; i < bio->bi_vcnt; i++) {
-               bd->bi_io_vec[i].bv_len = bio->bi_io_vec[i].bv_len;
-               bd->bi_io_vec[i].bv_offset = bio->bi_io_vec[i].bv_offset;
-       }
+       bd->bi_iter = bio->bi_iter;
 }
 
 static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
 {
-       unsigned i;
-
-       bio->bi_sector = bd->bi_sector;
        bio->bi_bdev = bd->bi_bdev;
-       bio->bi_size = bd->bi_size;
-       bio->bi_idx = bd->bi_idx;
        bio->bi_flags = bd->bi_flags;
-
-       for (i = 0; i < bio->bi_vcnt; i++) {
-               bio->bi_io_vec[i].bv_len = bd->bi_io_vec[i].bv_len;
-               bio->bi_io_vec[i].bv_offset = bd->bi_io_vec[i].bv_offset;
-       }
+       bio->bi_iter = bd->bi_iter;
 }
 
 #endif
index 173cbb20d10498b21440ada78b27f241b47af2cc..4113b6044b80a2125290888d6da1efa2d4c63c6c 100644 (file)
@@ -538,7 +538,7 @@ static void use_inline_bio(struct dm_buffer *b, int rw, sector_t block,
        bio_init(&b->bio);
        b->bio.bi_io_vec = b->bio_vec;
        b->bio.bi_max_vecs = DM_BUFIO_INLINE_VECS;
-       b->bio.bi_sector = block << b->c->sectors_per_block_bits;
+       b->bio.bi_iter.bi_sector = block << b->c->sectors_per_block_bits;
        b->bio.bi_bdev = b->c->bdev;
        b->bio.bi_end_io = end_io;
 
index 416b7b752a6e0018d4a11800606a8be6b8890e22..5c3e044b67b969efb756367616932ddb5fae2b11 100644 (file)
@@ -72,7 +72,7 @@ static enum io_pattern iot_pattern(struct io_tracker *t)
 
 static void iot_update_stats(struct io_tracker *t, struct bio *bio)
 {
-       if (bio->bi_sector == from_oblock(t->last_end_oblock) + 1)
+       if (bio->bi_iter.bi_sector == from_oblock(t->last_end_oblock) + 1)
                t->nr_seq_samples++;
        else {
                /*
@@ -87,7 +87,7 @@ static void iot_update_stats(struct io_tracker *t, struct bio *bio)
                t->nr_rand_samples++;
        }
 
-       t->last_end_oblock = to_oblock(bio->bi_sector + bio_sectors(bio) - 1);
+       t->last_end_oblock = to_oblock(bio_end_sector(bio) - 1);
 }
 
 static void iot_check_for_pattern_switch(struct io_tracker *t)
@@ -287,9 +287,8 @@ static struct entry *alloc_entry(struct entry_pool *ep)
 static struct entry *alloc_particular_entry(struct entry_pool *ep, dm_cblock_t cblock)
 {
        struct entry *e = ep->entries + from_cblock(cblock);
-       list_del(&e->list);
 
-       INIT_LIST_HEAD(&e->list);
+       list_del_init(&e->list);
        INIT_HLIST_NODE(&e->hlist);
        ep->nr_allocated++;
 
@@ -730,15 +729,18 @@ static int pre_cache_entry_found(struct mq_policy *mq, struct entry *e,
        int r = 0;
        bool updated = updated_this_tick(mq, e);
 
-       requeue_and_update_tick(mq, e);
-
        if ((!discarded_oblock && updated) ||
-           !should_promote(mq, e, discarded_oblock, data_dir))
+           !should_promote(mq, e, discarded_oblock, data_dir)) {
+               requeue_and_update_tick(mq, e);
                result->op = POLICY_MISS;
-       else if (!can_migrate)
+
+       } else if (!can_migrate)
                r = -EWOULDBLOCK;
-       else
+
+       else {
+               requeue_and_update_tick(mq, e);
                r = pre_cache_to_cache(mq, e, result);
+       }
 
        return r;
 }
index 9efcf1059b99e3ae2e6e712eb150c0954646d5d8..bf3a206abd782722be3a17ca6f7469f66e4f9a94 100644 (file)
@@ -664,15 +664,17 @@ static void remap_to_origin(struct cache *cache, struct bio *bio)
 static void remap_to_cache(struct cache *cache, struct bio *bio,
                           dm_cblock_t cblock)
 {
-       sector_t bi_sector = bio->bi_sector;
+       sector_t bi_sector = bio->bi_iter.bi_sector;
 
        bio->bi_bdev = cache->cache_dev->bdev;
        if (!block_size_is_power_of_two(cache))
-               bio->bi_sector = (from_cblock(cblock) * cache->sectors_per_block) +
-                               sector_div(bi_sector, cache->sectors_per_block);
+               bio->bi_iter.bi_sector =
+                       (from_cblock(cblock) * cache->sectors_per_block) +
+                       sector_div(bi_sector, cache->sectors_per_block);
        else
-               bio->bi_sector = (from_cblock(cblock) << cache->sectors_per_block_shift) |
-                               (bi_sector & (cache->sectors_per_block - 1));
+               bio->bi_iter.bi_sector =
+                       (from_cblock(cblock) << cache->sectors_per_block_shift) |
+                       (bi_sector & (cache->sectors_per_block - 1));
 }
 
 static void check_if_tick_bio_needed(struct cache *cache, struct bio *bio)
@@ -712,7 +714,7 @@ static void remap_to_cache_dirty(struct cache *cache, struct bio *bio,
 
 static dm_oblock_t get_bio_block(struct cache *cache, struct bio *bio)
 {
-       sector_t block_nr = bio->bi_sector;
+       sector_t block_nr = bio->bi_iter.bi_sector;
 
        if (!block_size_is_power_of_two(cache))
                (void) sector_div(block_nr, cache->sectors_per_block);
@@ -763,6 +765,12 @@ static void writethrough_endio(struct bio *bio, int err)
 
        dm_unhook_bio(&pb->hook_info, bio);
 
+       /*
+        * Must bump bi_remaining to allow bio to complete with
+        * restored bi_end_io.
+        */
+       atomic_inc(&bio->bi_remaining);
+
        if (err) {
                bio_endio(bio, err);
                return;
@@ -1027,7 +1035,7 @@ static void issue_overwrite(struct dm_cache_migration *mg, struct bio *bio)
 static bool bio_writes_complete_block(struct cache *cache, struct bio *bio)
 {
        return (bio_data_dir(bio) == WRITE) &&
-               (bio->bi_size == (cache->sectors_per_block << SECTOR_SHIFT));
+               (bio->bi_iter.bi_size == (cache->sectors_per_block << SECTOR_SHIFT));
 }
 
 static void avoid_copy(struct dm_cache_migration *mg)
@@ -1252,7 +1260,7 @@ 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);
 
-       BUG_ON(bio->bi_size);
+       BUG_ON(bio->bi_iter.bi_size);
        if (!pb->req_nr)
                remap_to_origin(cache, bio);
        else
@@ -1275,9 +1283,9 @@ static void process_flush_bio(struct cache *cache, struct bio *bio)
  */
 static void process_discard_bio(struct cache *cache, struct bio *bio)
 {
-       dm_block_t start_block = dm_sector_div_up(bio->bi_sector,
+       dm_block_t start_block = dm_sector_div_up(bio->bi_iter.bi_sector,
                                                  cache->discard_block_size);
-       dm_block_t end_block = bio->bi_sector + bio_sectors(bio);
+       dm_block_t end_block = bio_end_sector(bio);
        dm_block_t b;
 
        end_block = block_div(end_block, cache->discard_block_size);
index 81b0fa66045204604a979fdc929e723f6c914a5c..784695d22fde1acaaf11acd78c7263438c04648e 100644 (file)
@@ -39,10 +39,8 @@ struct convert_context {
        struct completion restart;
        struct bio *bio_in;
        struct bio *bio_out;
-       unsigned int offset_in;
-       unsigned int offset_out;
-       unsigned int idx_in;
-       unsigned int idx_out;
+       struct bvec_iter iter_in;
+       struct bvec_iter iter_out;
        sector_t cc_sector;
        atomic_t cc_pending;
 };
@@ -826,10 +824,10 @@ static void crypt_convert_init(struct crypt_config *cc,
 {
        ctx->bio_in = bio_in;
        ctx->bio_out = bio_out;
-       ctx->offset_in = 0;
-       ctx->offset_out = 0;
-       ctx->idx_in = bio_in ? bio_in->bi_idx : 0;
-       ctx->idx_out = bio_out ? bio_out->bi_idx : 0;
+       if (bio_in)
+               ctx->iter_in = bio_in->bi_iter;
+       if (bio_out)
+               ctx->iter_out = bio_out->bi_iter;
        ctx->cc_sector = sector + cc->iv_offset;
        init_completion(&ctx->restart);
 }
@@ -857,8 +855,8 @@ static int crypt_convert_block(struct crypt_config *cc,
                               struct convert_context *ctx,
                               struct ablkcipher_request *req)
 {
-       struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
-       struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
+       struct bio_vec bv_in = bio_iter_iovec(ctx->bio_in, ctx->iter_in);
+       struct bio_vec bv_out = bio_iter_iovec(ctx->bio_out, ctx->iter_out);
        struct dm_crypt_request *dmreq;
        u8 *iv;
        int r;
@@ -869,24 +867,15 @@ static int crypt_convert_block(struct crypt_config *cc,
        dmreq->iv_sector = ctx->cc_sector;
        dmreq->ctx = ctx;
        sg_init_table(&dmreq->sg_in, 1);
-       sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT,
-                   bv_in->bv_offset + ctx->offset_in);
+       sg_set_page(&dmreq->sg_in, bv_in.bv_page, 1 << SECTOR_SHIFT,
+                   bv_in.bv_offset);
 
        sg_init_table(&dmreq->sg_out, 1);
-       sg_set_page(&dmreq->sg_out, bv_out->bv_page, 1 << SECTOR_SHIFT,
-                   bv_out->bv_offset + ctx->offset_out);
+       sg_set_page(&dmreq->sg_out, bv_out.bv_page, 1 << SECTOR_SHIFT,
+                   bv_out.bv_offset);
 
-       ctx->offset_in += 1 << SECTOR_SHIFT;
-       if (ctx->offset_in >= bv_in->bv_len) {
-               ctx->offset_in = 0;
-               ctx->idx_in++;
-       }
-
-       ctx->offset_out += 1 << SECTOR_SHIFT;
-       if (ctx->offset_out >= bv_out->bv_len) {
-               ctx->offset_out = 0;
-               ctx->idx_out++;
-       }
+       bio_advance_iter(ctx->bio_in, &ctx->iter_in, 1 << SECTOR_SHIFT);
+       bio_advance_iter(ctx->bio_out, &ctx->iter_out, 1 << SECTOR_SHIFT);
 
        if (cc->iv_gen_ops) {
                r = cc->iv_gen_ops->generator(cc, iv, dmreq);
@@ -937,8 +926,7 @@ static int crypt_convert(struct crypt_config *cc,
 
        atomic_set(&ctx->cc_pending, 1);
 
-       while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
-             ctx->idx_out < ctx->bio_out->bi_vcnt) {
+       while (ctx->iter_in.bi_size && ctx->iter_out.bi_size) {
 
                crypt_alloc_req(cc, ctx);
 
@@ -1021,7 +1009,7 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size,
                size -= len;
        }
 
-       if (!clone->bi_size) {
+       if (!clone->bi_iter.bi_size) {
                bio_put(clone);
                return NULL;
        }
@@ -1161,7 +1149,7 @@ static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp)
        crypt_inc_pending(io);
 
        clone_init(io, clone);
-       clone->bi_sector = cc->start + io->sector;
+       clone->bi_iter.bi_sector = cc->start + io->sector;
 
        generic_make_request(clone);
        return 0;
@@ -1207,9 +1195,9 @@ static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async)
        }
 
        /* crypt_convert should have filled the clone bio */
-       BUG_ON(io->ctx.idx_out < clone->bi_vcnt);
+       BUG_ON(io->ctx.iter_out.bi_size);
 
-       clone->bi_sector = cc->start + io->sector;
+       clone->bi_iter.bi_sector = cc->start + io->sector;
 
        if (async)
                kcryptd_queue_io(io);
@@ -1224,7 +1212,7 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
        struct dm_crypt_io *new_io;
        int crypt_finished;
        unsigned out_of_pages = 0;
-       unsigned remaining = io->base_bio->bi_size;
+       unsigned remaining = io->base_bio->bi_iter.bi_size;
        sector_t sector = io->sector;
        int r;
 
@@ -1246,9 +1234,9 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
                }
 
                io->ctx.bio_out = clone;
-               io->ctx.idx_out = 0;
+               io->ctx.iter_out = clone->bi_iter;
 
-               remaining -= clone->bi_size;
+               remaining -= clone->bi_iter.bi_size;
                sector += bio_sectors(clone);
 
                crypt_inc_pending(io);
@@ -1290,8 +1278,7 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
                        crypt_inc_pending(new_io);
                        crypt_convert_init(cc, &new_io->ctx, NULL,
                                           io->base_bio, sector);
-                       new_io->ctx.idx_in = io->ctx.idx_in;
-                       new_io->ctx.offset_in = io->ctx.offset_in;
+                       new_io->ctx.iter_in = io->ctx.iter_in;
 
                        /*
                         * Fragments after the first use the base_io
@@ -1869,11 +1856,12 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
        if (unlikely(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) {
                bio->bi_bdev = cc->dev->bdev;
                if (bio_sectors(bio))
-                       bio->bi_sector = cc->start + dm_target_offset(ti, bio->bi_sector);
+                       bio->bi_iter.bi_sector = cc->start +
+                               dm_target_offset(ti, bio->bi_iter.bi_sector);
                return DM_MAPIO_REMAPPED;
        }
 
-       io = crypt_io_alloc(cc, bio, dm_target_offset(ti, bio->bi_sector));
+       io = crypt_io_alloc(cc, bio, dm_target_offset(ti, bio->bi_iter.bi_sector));
 
        if (bio_data_dir(io->base_bio) == READ) {
                if (kcryptd_io_read(io, GFP_NOWAIT))
index 496d5f3646a5df623e6c0a9b22d35ad003c610bc..42c3a27a14cc3a906b5f892a6206de348b6b58ee 100644 (file)
 struct delay_c {
        struct timer_list delay_timer;
        struct mutex timer_lock;
+       struct workqueue_struct *kdelayd_wq;
        struct work_struct flush_expired_bios;
        struct list_head delayed_bios;
        atomic_t may_delay;
-       mempool_t *delayed_pool;
 
        struct dm_dev *dev_read;
        sector_t start_read;
@@ -39,20 +39,16 @@ struct delay_c {
 struct dm_delay_info {
        struct delay_c *context;
        struct list_head list;
-       struct bio *bio;
        unsigned long expires;
 };
 
 static DEFINE_MUTEX(delayed_bios_lock);
 
-static struct workqueue_struct *kdelayd_wq;
-static struct kmem_cache *delayed_cache;
-
 static void handle_delayed_timer(unsigned long data)
 {
        struct delay_c *dc = (struct delay_c *)data;
 
-       queue_work(kdelayd_wq, &dc->flush_expired_bios);
+       queue_work(dc->kdelayd_wq, &dc->flush_expired_bios);
 }
 
 static void queue_timeout(struct delay_c *dc, unsigned long expires)
@@ -87,13 +83,14 @@ static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
        mutex_lock(&delayed_bios_lock);
        list_for_each_entry_safe(delayed, next, &dc->delayed_bios, list) {
                if (flush_all || time_after_eq(jiffies, delayed->expires)) {
+                       struct bio *bio = dm_bio_from_per_bio_data(delayed,
+                                               sizeof(struct dm_delay_info));
                        list_del(&delayed->list);
-                       bio_list_add(&flush_bios, delayed->bio);
-                       if ((bio_data_dir(delayed->bio) == WRITE))
+                       bio_list_add(&flush_bios, bio);
+                       if ((bio_data_dir(bio) == WRITE))
                                delayed->context->writes--;
                        else
                                delayed->context->reads--;
-                       mempool_free(delayed, dc->delayed_pool);
                        continue;
                }
 
@@ -185,10 +182,10 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        }
 
 out:
-       dc->delayed_pool = mempool_create_slab_pool(128, delayed_cache);
-       if (!dc->delayed_pool) {
-               DMERR("Couldn't create delayed bio pool.");
-               goto bad_dev_write;
+       dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
+       if (!dc->kdelayd_wq) {
+               DMERR("Couldn't start kdelayd");
+               goto bad_queue;
        }
 
        setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc);
@@ -200,10 +197,11 @@ out:
 
        ti->num_flush_bios = 1;
        ti->num_discard_bios = 1;
+       ti->per_bio_data_size = sizeof(struct dm_delay_info);
        ti->private = dc;
        return 0;
 
-bad_dev_write:
+bad_queue:
        if (dc->dev_write)
                dm_put_device(ti, dc->dev_write);
 bad_dev_read:
@@ -217,14 +215,13 @@ static void delay_dtr(struct dm_target *ti)
 {
        struct delay_c *dc = ti->private;
 
-       flush_workqueue(kdelayd_wq);
+       destroy_workqueue(dc->kdelayd_wq);
 
        dm_put_device(ti, dc->dev_read);
 
        if (dc->dev_write)
                dm_put_device(ti, dc->dev_write);
 
-       mempool_destroy(dc->delayed_pool);
        kfree(dc);
 }
 
@@ -236,10 +233,9 @@ static int delay_bio(struct delay_c *dc, int delay, struct bio *bio)
        if (!delay || !atomic_read(&dc->may_delay))
                return 1;
 
-       delayed = mempool_alloc(dc->delayed_pool, GFP_NOIO);
+       delayed = dm_per_bio_data(bio, sizeof(struct dm_delay_info));
 
        delayed->context = dc;
-       delayed->bio = bio;
        delayed->expires = expires = jiffies + (delay * HZ / 1000);
 
        mutex_lock(&delayed_bios_lock);
@@ -281,14 +277,15 @@ static int delay_map(struct dm_target *ti, struct bio *bio)
        if ((bio_data_dir(bio) == WRITE) && (dc->dev_write)) {
                bio->bi_bdev = dc->dev_write->bdev;
                if (bio_sectors(bio))
-                       bio->bi_sector = dc->start_write +
-                                        dm_target_offset(ti, bio->bi_sector);
+                       bio->bi_iter.bi_sector = dc->start_write +
+                               dm_target_offset(ti, bio->bi_iter.bi_sector);
 
                return delay_bio(dc, dc->write_delay, bio);
        }
 
        bio->bi_bdev = dc->dev_read->bdev;
-       bio->bi_sector = dc->start_read + dm_target_offset(ti, bio->bi_sector);
+       bio->bi_iter.bi_sector = dc->start_read +
+               dm_target_offset(ti, bio->bi_iter.bi_sector);
 
        return delay_bio(dc, dc->read_delay, bio);
 }
@@ -348,19 +345,7 @@ static struct target_type delay_target = {
 
 static int __init dm_delay_init(void)
 {
-       int r = -ENOMEM;
-
-       kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
-       if (!kdelayd_wq) {
-               DMERR("Couldn't start kdelayd");
-               goto bad_queue;
-       }
-
-       delayed_cache = KMEM_CACHE(dm_delay_info, 0);
-       if (!delayed_cache) {
-               DMERR("Couldn't create delayed bio cache.");
-               goto bad_memcache;
-       }
+       int r;
 
        r = dm_register_target(&delay_target);
        if (r < 0) {
@@ -371,18 +356,12 @@ static int __init dm_delay_init(void)
        return 0;
 
 bad_register:
-       kmem_cache_destroy(delayed_cache);
-bad_memcache:
-       destroy_workqueue(kdelayd_wq);
-bad_queue:
        return r;
 }
 
 static void __exit dm_delay_exit(void)
 {
        dm_unregister_target(&delay_target);
-       kmem_cache_destroy(delayed_cache);
-       destroy_workqueue(kdelayd_wq);
 }
 
 /* Module hooks */
index c80a0ec5f1269b40be7da133c68c6e789c5e5329..b257e46876d357f831bf1c751010d5b16fa125b8 100644 (file)
@@ -248,7 +248,8 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio)
 
        bio->bi_bdev = fc->dev->bdev;
        if (bio_sectors(bio))
-               bio->bi_sector = flakey_map_sector(ti, bio->bi_sector);
+               bio->bi_iter.bi_sector =
+                       flakey_map_sector(ti, bio->bi_iter.bi_sector);
 }
 
 static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)
@@ -265,8 +266,8 @@ static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)
                DMDEBUG("Corrupting data bio=%p by writing %u to byte %u "
                        "(rw=%c bi_rw=%lu bi_sector=%llu cur_bytes=%u)\n",
                        bio, fc->corrupt_bio_value, fc->corrupt_bio_byte,
-                       (bio_data_dir(bio) == WRITE) ? 'w' : 'r',
-                       bio->bi_rw, (unsigned long long)bio->bi_sector, bio_bytes);
+                       (bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_rw,
+                       (unsigned long long)bio->bi_iter.bi_sector, bio_bytes);
        }
 }
 
index 2a20986a2fec9701cd25e443c990f2b7a8479f9f..b2b8a10e842784de5454e2639474f1a208b4b3f1 100644 (file)
@@ -201,26 +201,29 @@ static void list_dp_init(struct dpages *dp, struct page_list *pl, unsigned offse
 /*
  * Functions for getting the pages from a bvec.
  */
-static void bvec_get_page(struct dpages *dp,
+static void bio_get_page(struct dpages *dp,
                  struct page **p, unsigned long *len, unsigned *offset)
 {
-       struct bio_vec *bvec = (struct bio_vec *) dp->context_ptr;
-       *p = bvec->bv_page;
-       *len = bvec->bv_len;
-       *offset = bvec->bv_offset;
+       struct bio *bio = dp->context_ptr;
+       struct bio_vec bvec = bio_iovec(bio);
+       *p = bvec.bv_page;
+       *len = bvec.bv_len;
+       *offset = bvec.bv_offset;
 }
 
-static void bvec_next_page(struct dpages *dp)
+static void bio_next_page(struct dpages *dp)
 {
-       struct bio_vec *bvec = (struct bio_vec *) dp->context_ptr;
-       dp->context_ptr = bvec + 1;
+       struct bio *bio = dp->context_ptr;
+       struct bio_vec bvec = bio_iovec(bio);
+
+       bio_advance(bio, bvec.bv_len);
 }
 
-static void bvec_dp_init(struct dpages *dp, struct bio_vec *bvec)
+static void bio_dp_init(struct dpages *dp, struct bio *bio)
 {
-       dp->get_page = bvec_get_page;
-       dp->next_page = bvec_next_page;
-       dp->context_ptr = bvec;
+       dp->get_page = bio_get_page;
+       dp->next_page = bio_next_page;
+       dp->context_ptr = bio;
 }
 
 /*
@@ -304,14 +307,14 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
                                          dm_sector_div_up(remaining, (PAGE_SIZE >> SECTOR_SHIFT)));
 
                bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
-               bio->bi_sector = where->sector + (where->count - remaining);
+               bio->bi_iter.bi_sector = where->sector + (where->count - remaining);
                bio->bi_bdev = where->bdev;
                bio->bi_end_io = endio;
                store_io_and_region_in_bio(bio, io, region);
 
                if (rw & REQ_DISCARD) {
                        num_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining);
-                       bio->bi_size = num_sectors << SECTOR_SHIFT;
+                       bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT;
                        remaining -= num_sectors;
                } else if (rw & REQ_WRITE_SAME) {
                        /*
@@ -320,7 +323,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
                        dp->get_page(dp, &page, &len, &offset);
                        bio_add_page(bio, page, logical_block_size, offset);
                        num_sectors = min_t(sector_t, q->limits.max_write_same_sectors, remaining);
-                       bio->bi_size = num_sectors << SECTOR_SHIFT;
+                       bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT;
 
                        offset = 0;
                        remaining -= num_sectors;
@@ -457,8 +460,8 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp,
                list_dp_init(dp, io_req->mem.ptr.pl, io_req->mem.offset);
                break;
 
-       case DM_IO_BVEC:
-               bvec_dp_init(dp, io_req->mem.ptr.bvec);
+       case DM_IO_BIO:
+               bio_dp_init(dp, io_req->mem.ptr.bio);
                break;
 
        case DM_IO_VMA:
index 4f99d267340cdb48c3a7b64edcdd4ed9a7fd48ea..53e848c1093936560a9554c9fdacbec2f6dae5bd 100644 (file)
@@ -85,7 +85,8 @@ static void linear_map_bio(struct dm_target *ti, struct bio *bio)
 
        bio->bi_bdev = lc->dev->bdev;
        if (bio_sectors(bio))
-               bio->bi_sector = linear_map_sector(ti, bio->bi_sector);
+               bio->bi_iter.bi_sector =
+                       linear_map_sector(ti, bio->bi_iter.bi_sector);
 }
 
 static int linear_map(struct dm_target *ti, struct bio *bio)
index 9584443c56148608d159ceab1d436fd6bacfda3b..f284e0bfb25fca869855f390f2d8d7a5519a0864 100644 (file)
@@ -432,7 +432,7 @@ static int mirror_available(struct mirror_set *ms, struct bio *bio)
        region_t region = dm_rh_bio_to_region(ms->rh, bio);
 
        if (log->type->in_sync(log, region, 0))
-               return choose_mirror(ms,  bio->bi_sector) ? 1 : 0;
+               return choose_mirror(ms,  bio->bi_iter.bi_sector) ? 1 : 0;
 
        return 0;
 }
@@ -442,15 +442,15 @@ static int mirror_available(struct mirror_set *ms, struct bio *bio)
  */
 static sector_t map_sector(struct mirror *m, struct bio *bio)
 {
-       if (unlikely(!bio->bi_size))
+       if (unlikely(!bio->bi_iter.bi_size))
                return 0;
-       return m->offset + dm_target_offset(m->ms->ti, bio->bi_sector);
+       return m->offset + dm_target_offset(m->ms->ti, bio->bi_iter.bi_sector);
 }
 
 static void map_bio(struct mirror *m, struct bio *bio)
 {
        bio->bi_bdev = m->dev->bdev;
-       bio->bi_sector = map_sector(m, bio);
+       bio->bi_iter.bi_sector = map_sector(m, bio);
 }
 
 static void map_region(struct dm_io_region *io, struct mirror *m,
@@ -526,8 +526,8 @@ static void read_async_bio(struct mirror *m, struct bio *bio)
        struct dm_io_region io;
        struct dm_io_request io_req = {
                .bi_rw = READ,
-               .mem.type = DM_IO_BVEC,
-               .mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx,
+               .mem.type = DM_IO_BIO,
+               .mem.ptr.bio = bio,
                .notify.fn = read_callback,
                .notify.context = bio,
                .client = m->ms->io_client,
@@ -559,7 +559,7 @@ static void do_reads(struct mirror_set *ms, struct bio_list *reads)
                 * We can only read balance if the region is in sync.
                 */
                if (likely(region_in_sync(ms, region, 1)))
-                       m = choose_mirror(ms, bio->bi_sector);
+                       m = choose_mirror(ms, bio->bi_iter.bi_sector);
                else if (m && atomic_read(&m->error_count))
                        m = NULL;
 
@@ -629,8 +629,8 @@ static void do_write(struct mirror_set *ms, struct bio *bio)
        struct mirror *m;
        struct dm_io_request io_req = {
                .bi_rw = WRITE | (bio->bi_rw & WRITE_FLUSH_FUA),
-               .mem.type = DM_IO_BVEC,
-               .mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx,
+               .mem.type = DM_IO_BIO,
+               .mem.ptr.bio = bio,
                .notify.fn = write_callback,
                .notify.context = bio,
                .client = ms->io_client,
@@ -1181,7 +1181,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio)
         * The region is in-sync and we can perform reads directly.
         * Store enough information so we can retry if it fails.
         */
-       m = choose_mirror(ms, bio->bi_sector);
+       m = choose_mirror(ms, bio->bi_iter.bi_sector);
        if (unlikely(!m))
                return -EIO;
 
index 69732e03eb3490d636a0183bd22303742ab65c65..b929fd5f4984bb67fbb62474e24e5af425758770 100644 (file)
@@ -126,7 +126,8 @@ EXPORT_SYMBOL_GPL(dm_rh_region_to_sector);
 
 region_t dm_rh_bio_to_region(struct dm_region_hash *rh, struct bio *bio)
 {
-       return dm_rh_sector_to_region(rh, bio->bi_sector - rh->target_begin);
+       return dm_rh_sector_to_region(rh, bio->bi_iter.bi_sector -
+                                     rh->target_begin);
 }
 EXPORT_SYMBOL_GPL(dm_rh_bio_to_region);
 
index aec57d76db5d616c8e692fa95cee58a8f62a0573..80b5cabbea29d7d6fb2fc3820b505a3028bcfdec 100644 (file)
@@ -1415,6 +1415,7 @@ out:
        if (full_bio) {
                full_bio->bi_end_io = pe->full_bio_end_io;
                full_bio->bi_private = pe->full_bio_private;
+               atomic_inc(&full_bio->bi_remaining);
        }
        free_pending_exception(pe);
 
@@ -1562,11 +1563,10 @@ static void remap_exception(struct dm_snapshot *s, struct dm_exception *e,
                            struct bio *bio, chunk_t chunk)
 {
        bio->bi_bdev = s->cow->bdev;
-       bio->bi_sector = chunk_to_sector(s->store,
-                                        dm_chunk_number(e->new_chunk) +
-                                        (chunk - e->old_chunk)) +
-                                        (bio->bi_sector &
-                                         s->store->chunk_mask);
+       bio->bi_iter.bi_sector =
+               chunk_to_sector(s->store, dm_chunk_number(e->new_chunk) +
+                               (chunk - e->old_chunk)) +
+               (bio->bi_iter.bi_sector & s->store->chunk_mask);
 }
 
 static int snapshot_map(struct dm_target *ti, struct bio *bio)
@@ -1584,7 +1584,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
                return DM_MAPIO_REMAPPED;
        }
 
-       chunk = sector_to_chunk(s->store, bio->bi_sector);
+       chunk = sector_to_chunk(s->store, bio->bi_iter.bi_sector);
 
        /* Full snapshots are not usable */
        /* To get here the table must be live so s->active is always set. */
@@ -1645,7 +1645,8 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
                r = DM_MAPIO_SUBMITTED;
 
                if (!pe->started &&
-                   bio->bi_size == (s->store->chunk_size << SECTOR_SHIFT)) {
+                   bio->bi_iter.bi_size ==
+                   (s->store->chunk_size << SECTOR_SHIFT)) {
                        pe->started = 1;
                        up_write(&s->lock);
                        start_full_bio(pe, bio);
@@ -1701,7 +1702,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
                return DM_MAPIO_REMAPPED;
        }
 
-       chunk = sector_to_chunk(s->store, bio->bi_sector);
+       chunk = sector_to_chunk(s->store, bio->bi_iter.bi_sector);
 
        down_write(&s->lock);
 
@@ -2038,7 +2039,7 @@ static int do_origin(struct dm_dev *origin, struct bio *bio)
        down_read(&_origins_lock);
        o = __lookup_origin(origin->bdev);
        if (o)
-               r = __origin_write(&o->snapshots, bio->bi_sector, bio);
+               r = __origin_write(&o->snapshots, bio->bi_iter.bi_sector, bio);
        up_read(&_origins_lock);
 
        return r;
index 73c1712dad96d09f2760416852dd0cacd22cbd33..d1600d2aa2e2e6983643ef0ef864195f858d4f9d 100644 (file)
@@ -259,13 +259,15 @@ static int stripe_map_range(struct stripe_c *sc, struct bio *bio,
 {
        sector_t begin, end;
 
-       stripe_map_range_sector(sc, bio->bi_sector, target_stripe, &begin);
+       stripe_map_range_sector(sc, bio->bi_iter.bi_sector,
+                               target_stripe, &begin);
        stripe_map_range_sector(sc, bio_end_sector(bio),
                                target_stripe, &end);
        if (begin < end) {
                bio->bi_bdev = sc->stripe[target_stripe].dev->bdev;
-               bio->bi_sector = begin + sc->stripe[target_stripe].physical_start;
-               bio->bi_size = to_bytes(end - begin);
+               bio->bi_iter.bi_sector = begin +
+                       sc->stripe[target_stripe].physical_start;
+               bio->bi_iter.bi_size = to_bytes(end - begin);
                return DM_MAPIO_REMAPPED;
        } else {
                /* The range doesn't map to the target stripe */
@@ -293,9 +295,10 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
                return stripe_map_range(sc, bio, target_bio_nr);
        }
 
-       stripe_map_sector(sc, bio->bi_sector, &stripe, &bio->bi_sector);
+       stripe_map_sector(sc, bio->bi_iter.bi_sector,
+                         &stripe, &bio->bi_iter.bi_sector);
 
-       bio->bi_sector += sc->stripe[stripe].physical_start;
+       bio->bi_iter.bi_sector += sc->stripe[stripe].physical_start;
        bio->bi_bdev = sc->stripe[stripe].dev->bdev;
 
        return DM_MAPIO_REMAPPED;
index ff9ac4be47210839369e233d1d1dfc161cbfb852..09a688b3d48ca1445e136544321a54b112b280e1 100644 (file)
@@ -311,11 +311,11 @@ error:
 static int switch_map(struct dm_target *ti, struct bio *bio)
 {
        struct switch_ctx *sctx = ti->private;
-       sector_t offset = dm_target_offset(ti, bio->bi_sector);
+       sector_t offset = dm_target_offset(ti, bio->bi_iter.bi_sector);
        unsigned path_nr = switch_get_path_nr(sctx, offset);
 
        bio->bi_bdev = sctx->path_list[path_nr].dmdev->bdev;
-       bio->bi_sector = sctx->path_list[path_nr].start + offset;
+       bio->bi_iter.bi_sector = sctx->path_list[path_nr].start + offset;
 
        return DM_MAPIO_REMAPPED;
 }
index 2c0cf511ec2385fa5a558b5d2e1e1ed0c874c9f6..1abb4a24c338e2146274b1d63940d6f3da3b8b4b 100644 (file)
@@ -413,7 +413,7 @@ static bool block_size_is_power_of_two(struct pool *pool)
 static dm_block_t get_bio_block(struct thin_c *tc, struct bio *bio)
 {
        struct pool *pool = tc->pool;
-       sector_t block_nr = bio->bi_sector;
+       sector_t block_nr = bio->bi_iter.bi_sector;
 
        if (block_size_is_power_of_two(pool))
                block_nr >>= pool->sectors_per_block_shift;
@@ -426,14 +426,15 @@ static dm_block_t get_bio_block(struct thin_c *tc, struct bio *bio)
 static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block)
 {
        struct pool *pool = tc->pool;
-       sector_t bi_sector = bio->bi_sector;
+       sector_t bi_sector = bio->bi_iter.bi_sector;
 
        bio->bi_bdev = tc->pool_dev->bdev;
        if (block_size_is_power_of_two(pool))
-               bio->bi_sector = (block << pool->sectors_per_block_shift) |
-                               (bi_sector & (pool->sectors_per_block - 1));
+               bio->bi_iter.bi_sector =
+                       (block << pool->sectors_per_block_shift) |
+                       (bi_sector & (pool->sectors_per_block - 1));
        else
-               bio->bi_sector = (block * pool->sectors_per_block) +
+               bio->bi_iter.bi_sector = (block * pool->sectors_per_block) +
                                 sector_div(bi_sector, pool->sectors_per_block);
 }
 
@@ -610,8 +611,10 @@ static void cell_defer_no_holder(struct thin_c *tc, struct dm_bio_prison_cell *c
 
 static void process_prepared_mapping_fail(struct dm_thin_new_mapping *m)
 {
-       if (m->bio)
+       if (m->bio) {
                m->bio->bi_end_io = m->saved_bi_end_io;
+               atomic_inc(&m->bio->bi_remaining);
+       }
        cell_error(m->tc->pool, m->cell);
        list_del(&m->list);
        mempool_free(m, m->tc->pool->mapping_pool);
@@ -625,8 +628,10 @@ static void process_prepared_mapping(struct dm_thin_new_mapping *m)
        int r;
 
        bio = m->bio;
-       if (bio)
+       if (bio) {
                bio->bi_end_io = m->saved_bi_end_io;
+               atomic_inc(&bio->bi_remaining);
+       }
 
        if (m->err) {
                cell_error(pool, m->cell);
@@ -721,7 +726,8 @@ static void process_prepared(struct pool *pool, struct list_head *head,
  */
 static int io_overlaps_block(struct pool *pool, struct bio *bio)
 {
-       return bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT);
+       return bio->bi_iter.bi_size ==
+               (pool->sectors_per_block << SECTOR_SHIFT);
 }
 
 static int io_overwrites_block(struct pool *pool, struct bio *bio)
@@ -1130,7 +1136,7 @@ static void process_shared_bio(struct thin_c *tc, struct bio *bio,
        if (bio_detain(pool, &key, bio, &cell))
                return;
 
-       if (bio_data_dir(bio) == WRITE && bio->bi_size)
+       if (bio_data_dir(bio) == WRITE && bio->bi_iter.bi_size)
                break_sharing(tc, bio, block, &key, lookup_result, cell);
        else {
                struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
@@ -1153,7 +1159,7 @@ static void provision_block(struct thin_c *tc, struct bio *bio, dm_block_t block
        /*
         * Remap empty bios (flushes) immediately, without provisioning.
         */
-       if (!bio->bi_size) {
+       if (!bio->bi_iter.bi_size) {
                inc_all_io_entry(pool, bio);
                cell_defer_no_holder(tc, cell);
 
@@ -1253,7 +1259,7 @@ static void process_bio_read_only(struct thin_c *tc, struct bio *bio)
        r = dm_thin_find_block(tc->td, block, 1, &lookup_result);
        switch (r) {
        case 0:
-               if (lookup_result.shared && (rw == WRITE) && bio->bi_size)
+               if (lookup_result.shared && (rw == WRITE) && bio->bi_iter.bi_size)
                        bio_io_error(bio);
                else {
                        inc_all_io_entry(tc->pool, bio);
@@ -2867,7 +2873,7 @@ out_unlock:
 
 static int thin_map(struct dm_target *ti, struct bio *bio)
 {
-       bio->bi_sector = dm_target_offset(ti, bio->bi_sector);
+       bio->bi_iter.bi_sector = dm_target_offset(ti, bio->bi_iter.bi_sector);
 
        return thin_bio_map(ti, bio);
 }
index 4b7941db3aff33223481464f24a162d101ab7698..796007a5e0e1a4b6e83b0871c1fca1ef8c0c461f 100644 (file)
@@ -73,15 +73,10 @@ struct dm_verity_io {
        sector_t block;
        unsigned n_blocks;
 
-       /* saved bio vector */
-       struct bio_vec *io_vec;
-       unsigned io_vec_size;
+       struct bvec_iter iter;
 
        struct work_struct work;
 
-       /* A space for short vectors; longer vectors are allocated separately. */
-       struct bio_vec io_vec_inline[DM_VERITY_IO_VEC_INLINE];
-
        /*
         * Three variably-size fields follow this struct:
         *
@@ -284,9 +279,10 @@ release_ret_r:
 static int verity_verify_io(struct dm_verity_io *io)
 {
        struct dm_verity *v = io->v;
+       struct bio *bio = dm_bio_from_per_bio_data(io,
+                                                  v->ti->per_bio_data_size);
        unsigned b;
        int i;
-       unsigned vector = 0, offset = 0;
 
        for (b = 0; b < io->n_blocks; b++) {
                struct shash_desc *desc;
@@ -336,31 +332,22 @@ test_block_hash:
                }
 
                todo = 1 << v->data_dev_block_bits;
-               do {
-                       struct bio_vec *bv;
+               while (io->iter.bi_size) {
                        u8 *page;
-                       unsigned len;
-
-                       BUG_ON(vector >= io->io_vec_size);
-                       bv = &io->io_vec[vector];
-                       page = kmap_atomic(bv->bv_page);
-                       len = bv->bv_len - offset;
-                       if (likely(len >= todo))
-                               len = todo;
-                       r = crypto_shash_update(desc,
-                                       page + bv->bv_offset + offset, len);
+                       struct bio_vec bv = bio_iter_iovec(bio, io->iter);
+
+                       page = kmap_atomic(bv.bv_page);
+                       r = crypto_shash_update(desc, page + bv.bv_offset,
+                                               bv.bv_len);
                        kunmap_atomic(page);
+
                        if (r < 0) {
                                DMERR("crypto_shash_update failed: %d", r);
                                return r;
                        }
-                       offset += len;
-                       if (likely(offset == bv->bv_len)) {
-                               offset = 0;
-                               vector++;
-                       }
-                       todo -= len;
-               } while (todo);
+
+                       bio_advance_iter(bio, &io->iter, bv.bv_len);
+               }
 
                if (!v->version) {
                        r = crypto_shash_update(desc, v->salt, v->salt_size);
@@ -383,8 +370,6 @@ test_block_hash:
                        return -EIO;
                }
        }
-       BUG_ON(vector != io->io_vec_size);
-       BUG_ON(offset);
 
        return 0;
 }
@@ -400,10 +385,7 @@ static void verity_finish_io(struct dm_verity_io *io, int error)
        bio->bi_end_io = io->orig_bi_end_io;
        bio->bi_private = io->orig_bi_private;
 
-       if (io->io_vec != io->io_vec_inline)
-               mempool_free(io->io_vec, v->vec_mempool);
-
-       bio_endio(bio, error);
+       bio_endio_nodec(bio, error);
 }
 
 static void verity_work(struct work_struct *w)
@@ -493,9 +475,9 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
        struct dm_verity_io *io;
 
        bio->bi_bdev = v->data_dev->bdev;
-       bio->bi_sector = verity_map_sector(v, bio->bi_sector);
+       bio->bi_iter.bi_sector = verity_map_sector(v, bio->bi_iter.bi_sector);
 
-       if (((unsigned)bio->bi_sector | bio_sectors(bio)) &
+       if (((unsigned)bio->bi_iter.bi_sector | bio_sectors(bio)) &
            ((1 << (v->data_dev_block_bits - SECTOR_SHIFT)) - 1)) {
                DMERR_LIMIT("unaligned io");
                return -EIO;
@@ -514,18 +496,12 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
        io->v = v;
        io->orig_bi_end_io = bio->bi_end_io;
        io->orig_bi_private = bio->bi_private;
-       io->block = bio->bi_sector >> (v->data_dev_block_bits - SECTOR_SHIFT);
-       io->n_blocks = bio->bi_size >> v->data_dev_block_bits;
+       io->block = bio->bi_iter.bi_sector >> (v->data_dev_block_bits - SECTOR_SHIFT);
+       io->n_blocks = bio->bi_iter.bi_size >> v->data_dev_block_bits;
 
        bio->bi_end_io = verity_end_io;
        bio->bi_private = io;
-       io->io_vec_size = bio_segments(bio);
-       if (io->io_vec_size < DM_VERITY_IO_VEC_INLINE)
-               io->io_vec = io->io_vec_inline;
-       else
-               io->io_vec = mempool_alloc(v->vec_mempool, GFP_NOIO);
-       memcpy(io->io_vec, bio_iovec(bio),
-              io->io_vec_size * sizeof(struct bio_vec));
+       io->iter = bio->bi_iter;
 
        verity_submit_prefetch(v, io);
 
index 0704c523a76b98e41413599aa2707e0f16eeb25a..44a2fa6814ce97cbd05d3e3e34c65672c6dbbebe 100644 (file)
@@ -575,7 +575,7 @@ static void start_io_acct(struct dm_io *io)
                atomic_inc_return(&md->pending[rw]));
 
        if (unlikely(dm_stats_used(&md->stats)))
-               dm_stats_account_io(&md->stats, bio->bi_rw, bio->bi_sector,
+               dm_stats_account_io(&md->stats, bio->bi_rw, bio->bi_iter.bi_sector,
                                    bio_sectors(bio), false, 0, &io->stats_aux);
 }
 
@@ -593,7 +593,7 @@ static void end_io_acct(struct dm_io *io)
        part_stat_unlock();
 
        if (unlikely(dm_stats_used(&md->stats)))
-               dm_stats_account_io(&md->stats, bio->bi_rw, bio->bi_sector,
+               dm_stats_account_io(&md->stats, bio->bi_rw, bio->bi_iter.bi_sector,
                                    bio_sectors(bio), true, duration, &io->stats_aux);
 
        /*
@@ -742,7 +742,7 @@ static void dec_pending(struct dm_io *io, int error)
                if (io_error == DM_ENDIO_REQUEUE)
                        return;
 
-               if ((bio->bi_rw & REQ_FLUSH) && bio->bi_size) {
+               if ((bio->bi_rw & REQ_FLUSH) && bio->bi_iter.bi_size) {
                        /*
                         * Preflush done for flush with data, reissue
                         * without REQ_FLUSH.
@@ -797,7 +797,7 @@ static void end_clone_bio(struct bio *clone, int error)
        struct dm_rq_clone_bio_info *info = clone->bi_private;
        struct dm_rq_target_io *tio = info->tio;
        struct bio *bio = info->orig;
-       unsigned int nr_bytes = info->orig->bi_size;
+       unsigned int nr_bytes = info->orig->bi_iter.bi_size;
 
        bio_put(clone);
 
@@ -1128,7 +1128,7 @@ static void __map_bio(struct dm_target_io *tio)
         * this io.
         */
        atomic_inc(&tio->io->io_count);
-       sector = clone->bi_sector;
+       sector = clone->bi_iter.bi_sector;
        r = ti->type->map(ti, clone);
        if (r == DM_MAPIO_REMAPPED) {
                /* the bio has been remapped so dispatch it */
@@ -1155,76 +1155,32 @@ struct clone_info {
        struct dm_io *io;
        sector_t sector;
        sector_t sector_count;
-       unsigned short idx;
 };
 
 static void bio_setup_sector(struct bio *bio, sector_t sector, sector_t len)
 {
-       bio->bi_sector = sector;
-       bio->bi_size = to_bytes(len);
-}
-
-static void bio_setup_bv(struct bio *bio, unsigned short idx, unsigned short bv_count)
-{
-       bio->bi_idx = idx;
-       bio->bi_vcnt = idx + bv_count;
-       bio->bi_flags &= ~(1 << BIO_SEG_VALID);
-}
-
-static void clone_bio_integrity(struct bio *bio, struct bio *clone,
-                               unsigned short idx, unsigned len, unsigned offset,
-                               unsigned trim)
-{
-       if (!bio_integrity(bio))
-               return;
-
-       bio_integrity_clone(clone, bio, GFP_NOIO);
-
-       if (trim)
-               bio_integrity_trim(clone, bio_sector_offset(bio, idx, offset), len);
-}
-
-/*
- * Creates a little bio that just does part of a bvec.
- */
-static void clone_split_bio(struct dm_target_io *tio, struct bio *bio,
-                           sector_t sector, unsigned short idx,
-                           unsigned offset, unsigned len)
-{
-       struct bio *clone = &tio->clone;
-       struct bio_vec *bv = bio->bi_io_vec + idx;
-
-       *clone->bi_io_vec = *bv;
-
-       bio_setup_sector(clone, sector, len);
-
-       clone->bi_bdev = bio->bi_bdev;
-       clone->bi_rw = bio->bi_rw;
-       clone->bi_vcnt = 1;
-       clone->bi_io_vec->bv_offset = offset;
-       clone->bi_io_vec->bv_len = clone->bi_size;
-       clone->bi_flags |= 1 << BIO_CLONED;
-
-       clone_bio_integrity(bio, clone, idx, len, offset, 1);
+       bio->bi_iter.bi_sector = sector;
+       bio->bi_iter.bi_size = to_bytes(len);
 }
 
 /*
  * Creates a bio that consists of range of complete bvecs.
  */
 static void clone_bio(struct dm_target_io *tio, struct bio *bio,
-                     sector_t sector, unsigned short idx,
-                     unsigned short bv_count, unsigned len)
+                     sector_t sector, unsigned len)
 {
        struct bio *clone = &tio->clone;
-       unsigned trim = 0;
 
-       __bio_clone(clone, bio);
-       bio_setup_sector(clone, sector, len);
-       bio_setup_bv(clone, idx, bv_count);
+       __bio_clone_fast(clone, bio);
+
+       if (bio_integrity(bio))
+               bio_integrity_clone(clone, bio, GFP_NOIO);
+
+       bio_advance(clone, to_bytes(sector - clone->bi_iter.bi_sector));
+       clone->bi_iter.bi_size = to_bytes(len);
 
-       if (idx != bio->bi_idx || clone->bi_size < bio->bi_size)
-               trim = 1;
-       clone_bio_integrity(bio, clone, idx, len, 0, trim);
+       if (bio_integrity(bio))
+               bio_integrity_trim(clone, 0, len);
 }
 
 static struct dm_target_io *alloc_tio(struct clone_info *ci,
@@ -1257,7 +1213,7 @@ static void __clone_and_map_simple_bio(struct clone_info *ci,
         * ci->bio->bi_max_vecs is BIO_INLINE_VECS anyway, for both flush
         * and discard, so no need for concern about wasted bvec allocations.
         */
-        __bio_clone(clone, ci->bio);
+        __bio_clone_fast(clone, ci->bio);
        if (len)
                bio_setup_sector(clone, ci->sector, len);
 
@@ -1286,10 +1242,7 @@ static int __send_empty_flush(struct clone_info *ci)
 }
 
 static void __clone_and_map_data_bio(struct clone_info *ci, struct dm_target *ti,
-                                    sector_t sector, int nr_iovecs,
-                                    unsigned short idx, unsigned short bv_count,
-                                    unsigned offset, unsigned len,
-                                    unsigned split_bvec)
+                                    sector_t sector, unsigned len)
 {
        struct bio *bio = ci->bio;
        struct dm_target_io *tio;
@@ -1303,11 +1256,8 @@ static void __clone_and_map_data_bio(struct clone_info *ci, struct dm_target *ti
                num_target_bios = ti->num_write_bios(ti, bio);
 
        for (target_bio_nr = 0; target_bio_nr < num_target_bios; target_bio_nr++) {
-               tio = alloc_tio(ci, ti, nr_iovecs, target_bio_nr);
-               if (split_bvec)
-                       clone_split_bio(tio, bio, sector, idx, offset, len);
-               else
-                       clone_bio(tio, bio, sector, idx, bv_count, len);
+               tio = alloc_tio(ci, ti, 0, target_bio_nr);
+               clone_bio(tio, bio, sector, len);
                __map_bio(tio);
        }
 }
@@ -1378,60 +1328,6 @@ static int __send_write_same(struct clone_info *ci)
        return __send_changing_extent_only(ci, get_num_write_same_bios, NULL);
 }
 
-/*
- * Find maximum number of sectors / bvecs we can process with a single bio.
- */
-static sector_t __len_within_target(struct clone_info *ci, sector_t max, int *idx)
-{
-       struct bio *bio = ci->bio;
-       sector_t bv_len, total_len = 0;
-
-       for (*idx = ci->idx; max && (*idx < bio->bi_vcnt); (*idx)++) {
-               bv_len = to_sector(bio->bi_io_vec[*idx].bv_len);
-
-               if (bv_len > max)
-                       break;
-
-               max -= bv_len;
-               total_len += bv_len;
-       }
-
-       return total_len;
-}
-
-static int __split_bvec_across_targets(struct clone_info *ci,
-                                      struct dm_target *ti, sector_t max)
-{
-       struct bio *bio = ci->bio;
-       struct bio_vec *bv = bio->bi_io_vec + ci->idx;
-       sector_t remaining = to_sector(bv->bv_len);
-       unsigned offset = 0;
-       sector_t len;
-
-       do {
-               if (offset) {
-                       ti = dm_table_find_target(ci->map, ci->sector);
-                       if (!dm_target_is_valid(ti))
-                               return -EIO;
-
-                       max = max_io_len(ci->sector, ti);
-               }
-
-               len = min(remaining, max);
-
-               __clone_and_map_data_bio(ci, ti, ci->sector, 1, ci->idx, 0,
-                                        bv->bv_offset + offset, len, 1);
-
-               ci->sector += len;
-               ci->sector_count -= len;
-               offset += to_bytes(len);
-       } while (remaining -= len);
-
-       ci->idx++;
-
-       return 0;
-}
-
 /*
  * Select the correct strategy for processing a non-flush bio.
  */
@@ -1439,8 +1335,7 @@ static int __split_and_process_non_flush(struct clone_info *ci)
 {
        struct bio *bio = ci->bio;
        struct dm_target *ti;
-       sector_t len, max;
-       int idx;
+       unsigned len;
 
        if (unlikely(bio->bi_rw & REQ_DISCARD))
                return __send_discard(ci);
@@ -1451,41 +1346,14 @@ static int __split_and_process_non_flush(struct clone_info *ci)
        if (!dm_target_is_valid(ti))
                return -EIO;
 
-       max = max_io_len(ci->sector, ti);
-
-       /*
-        * Optimise for the simple case where we can do all of
-        * the remaining io with a single clone.
-        */
-       if (ci->sector_count <= max) {
-               __clone_and_map_data_bio(ci, ti, ci->sector, bio->bi_max_vecs,
-                                        ci->idx, bio->bi_vcnt - ci->idx, 0,
-                                        ci->sector_count, 0);
-               ci->sector_count = 0;
-               return 0;
-       }
-
-       /*
-        * There are some bvecs that don't span targets.
-        * Do as many of these as possible.
-        */
-       if (to_sector(bio->bi_io_vec[ci->idx].bv_len) <= max) {
-               len = __len_within_target(ci, max, &idx);
-
-               __clone_and_map_data_bio(ci, ti, ci->sector, bio->bi_max_vecs,
-                                        ci->idx, idx - ci->idx, 0, len, 0);
+       len = min_t(sector_t, max_io_len(ci->sector, ti), ci->sector_count);
 
-               ci->sector += len;
-               ci->sector_count -= len;
-               ci->idx = idx;
+       __clone_and_map_data_bio(ci, ti, ci->sector, len);
 
-               return 0;
-       }
+       ci->sector += len;
+       ci->sector_count -= len;
 
-       /*
-        * Handle a bvec that must be split between two or more targets.
-        */
-       return __split_bvec_across_targets(ci, ti, max);
+       return 0;
 }
 
 /*
@@ -1510,8 +1378,7 @@ static void __split_and_process_bio(struct mapped_device *md,
        ci.io->bio = bio;
        ci.io->md = md;
        spin_lock_init(&ci.io->endio_lock);
-       ci.sector = bio->bi_sector;
-       ci.idx = bio->bi_idx;
+       ci.sector = bio->bi_iter.bi_sector;
 
        start_io_acct(ci.io);
 
index 3193aefe982b7b42badf4eba4adc36f89439d70c..e8b4574956c73e500cd634fa0acafad4fad0b93d 100644 (file)
@@ -74,8 +74,8 @@ static void faulty_fail(struct bio *bio, int error)
 {
        struct bio *b = bio->bi_private;
 
-       b->bi_size = bio->bi_size;
-       b->bi_sector = bio->bi_sector;
+       b->bi_iter.bi_size = bio->bi_iter.bi_size;
+       b->bi_iter.bi_sector = bio->bi_iter.bi_sector;
 
        bio_put(bio);
 
@@ -185,26 +185,31 @@ static void make_request(struct mddev *mddev, struct bio *bio)
                        return;
                }
 
-               if (check_sector(conf, bio->bi_sector, bio_end_sector(bio), WRITE))
+               if (check_sector(conf, bio->bi_iter.bi_sector,
+                                bio_end_sector(bio), WRITE))
                        failit = 1;
                if (check_mode(conf, WritePersistent)) {
-                       add_sector(conf, bio->bi_sector, WritePersistent);
+                       add_sector(conf, bio->bi_iter.bi_sector,
+                                  WritePersistent);
                        failit = 1;
                }
                if (check_mode(conf, WriteTransient))
                        failit = 1;
        } else {
                /* read request */
-               if (check_sector(conf, bio->bi_sector, bio_end_sector(bio), READ))
+               if (check_sector(conf, bio->bi_iter.bi_sector,
+                                bio_end_sector(bio), READ))
                        failit = 1;
                if (check_mode(conf, ReadTransient))
                        failit = 1;
                if (check_mode(conf, ReadPersistent)) {
-                       add_sector(conf, bio->bi_sector, ReadPersistent);
+                       add_sector(conf, bio->bi_iter.bi_sector,
+                                  ReadPersistent);
                        failit = 1;
                }
                if (check_mode(conf, ReadFixable)) {
-                       add_sector(conf, bio->bi_sector, ReadFixable);
+                       add_sector(conf, bio->bi_iter.bi_sector,
+                                  ReadFixable);
                        failit = 1;
                }
        }
index f03fabd2b37bacf34a231a0bb034a6d8f2826e68..56f534b4a2d27036b1f820f8bf4bfed56a9b2002 100644 (file)
@@ -288,65 +288,65 @@ static int linear_stop (struct mddev *mddev)
 
 static void linear_make_request(struct mddev *mddev, struct bio *bio)
 {
+       char b[BDEVNAME_SIZE];
        struct dev_info *tmp_dev;
-       sector_t start_sector;
+       struct bio *split;
+       sector_t start_sector, end_sector, data_offset;
 
        if (unlikely(bio->bi_rw & REQ_FLUSH)) {
                md_flush_request(mddev, bio);
                return;
        }
 
-       rcu_read_lock();
-       tmp_dev = which_dev(mddev, bio->bi_sector);
-       start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors;
-
-
-       if (unlikely(bio->bi_sector >= (tmp_dev->end_sector)
-                    || (bio->bi_sector < start_sector))) {
-               char b[BDEVNAME_SIZE];
-
-               printk(KERN_ERR
-                      "md/linear:%s: make_request: Sector %llu out of bounds on "
-                      "dev %s: %llu sectors, offset %llu\n",
-                      mdname(mddev),
-                      (unsigned long long)bio->bi_sector,
-                      bdevname(tmp_dev->rdev->bdev, b),
-                      (unsigned long long)tmp_dev->rdev->sectors,
-                      (unsigned long long)start_sector);
-               rcu_read_unlock();
-               bio_io_error(bio);
-               return;
-       }
-       if (unlikely(bio_end_sector(bio) > tmp_dev->end_sector)) {
-               /* This bio crosses a device boundary, so we have to
-                * split it.
-                */
-               struct bio_pair *bp;
-               sector_t end_sector = tmp_dev->end_sector;
+       do {
+               rcu_read_lock();
 
-               rcu_read_unlock();
-
-               bp = bio_split(bio, end_sector - bio->bi_sector);
+               tmp_dev = which_dev(mddev, bio->bi_iter.bi_sector);
+               start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors;
+               end_sector = tmp_dev->end_sector;
+               data_offset = tmp_dev->rdev->data_offset;
+               bio->bi_bdev = tmp_dev->rdev->bdev;
 
-               linear_make_request(mddev, &bp->bio1);
-               linear_make_request(mddev, &bp->bio2);
-               bio_pair_release(bp);
-               return;
-       }
-                   
-       bio->bi_bdev = tmp_dev->rdev->bdev;
-       bio->bi_sector = bio->bi_sector - start_sector
-               + tmp_dev->rdev->data_offset;
-       rcu_read_unlock();
+               rcu_read_unlock();
 
-       if (unlikely((bio->bi_rw & REQ_DISCARD) &&
-                    !blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) {
-               /* Just ignore it */
-               bio_endio(bio, 0);
-               return;
-       }
+               if (unlikely(bio->bi_iter.bi_sector >= end_sector ||
+                            bio->bi_iter.bi_sector < start_sector))
+                       goto out_of_bounds;
+
+               if (unlikely(bio_end_sector(bio) > end_sector)) {
+                       /* This bio crosses a device boundary, so we have to
+                        * split it.
+                        */
+                       split = bio_split(bio, end_sector -
+                                         bio->bi_iter.bi_sector,
+                                         GFP_NOIO, fs_bio_set);
+                       bio_chain(split, bio);
+               } else {
+                       split = bio;
+               }
 
-       generic_make_request(bio);
+               split->bi_iter.bi_sector = split->bi_iter.bi_sector -
+                       start_sector + data_offset;
+
+               if (unlikely((split->bi_rw & REQ_DISCARD) &&
+                        !blk_queue_discard(bdev_get_queue(split->bi_bdev)))) {
+                       /* Just ignore it */
+                       bio_endio(split, 0);
+               } else
+                       generic_make_request(split);
+       } while (split != bio);
+       return;
+
+out_of_bounds:
+       printk(KERN_ERR
+              "md/linear:%s: make_request: Sector %llu out of bounds on "
+              "dev %s: %llu sectors, offset %llu\n",
+              mdname(mddev),
+              (unsigned long long)bio->bi_iter.bi_sector,
+              bdevname(tmp_dev->rdev->bdev, b),
+              (unsigned long long)tmp_dev->rdev->sectors,
+              (unsigned long long)start_sector);
+       bio_io_error(bio);
 }
 
 static void linear_status (struct seq_file *seq, struct mddev *mddev)
index b6b7a2866c9e99533afd59a0a142712f58febe63..16d84e091e2d199222f3c58203a07f3b696249c9 100644 (file)
@@ -393,7 +393,7 @@ static void md_submit_flush_data(struct work_struct *ws)
        struct mddev *mddev = container_of(ws, struct mddev, flush_work);
        struct bio *bio = mddev->flush_bio;
 
-       if (bio->bi_size == 0)
+       if (bio->bi_iter.bi_size == 0)
                /* an empty barrier - all done */
                bio_endio(bio, 0);
        else {
@@ -754,7 +754,7 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
        struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, mddev);
 
        bio->bi_bdev = rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev;
-       bio->bi_sector = sector;
+       bio->bi_iter.bi_sector = sector;
        bio_add_page(bio, page, size, 0);
        bio->bi_private = rdev;
        bio->bi_end_io = super_written;
@@ -776,36 +776,24 @@ void md_super_wait(struct mddev *mddev)
        finish_wait(&mddev->sb_wait, &wq);
 }
 
-static void bi_complete(struct bio *bio, int error)
-{
-       complete((struct completion*)bio->bi_private);
-}
-
 int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
                 struct page *page, int rw, bool metadata_op)
 {
        struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, rdev->mddev);
-       struct completion event;
        int ret;
 
-       rw |= REQ_SYNC;
-
        bio->bi_bdev = (metadata_op && rdev->meta_bdev) ?
                rdev->meta_bdev : rdev->bdev;
        if (metadata_op)
-               bio->bi_sector = sector + rdev->sb_start;
+               bio->bi_iter.bi_sector = sector + rdev->sb_start;
        else if (rdev->mddev->reshape_position != MaxSector &&
                 (rdev->mddev->reshape_backwards ==
                  (sector >= rdev->mddev->reshape_position)))
-               bio->bi_sector = sector + rdev->new_data_offset;
+               bio->bi_iter.bi_sector = sector + rdev->new_data_offset;
        else
-               bio->bi_sector = sector + rdev->data_offset;
+               bio->bi_iter.bi_sector = sector + rdev->data_offset;
        bio_add_page(bio, page, size, 0);
-       init_completion(&event);
-       bio->bi_private = &event;
-       bio->bi_end_io = bi_complete;
-       submit_bio(rw, bio);
-       wait_for_completion(&event);
+       submit_bio_wait(rw, bio);
 
        ret = test_bit(BIO_UPTODATE, &bio->bi_flags);
        bio_put(bio);
@@ -7777,7 +7765,7 @@ void md_check_recovery(struct mddev *mddev)
        if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
                return;
        if ( ! (
-               (mddev->flags & ~ (1<<MD_CHANGE_PENDING)) ||
+               (mddev->flags & MD_UPDATE_SB_FLAGS & ~ (1<<MD_CHANGE_PENDING)) ||
                test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
                test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
                (mddev->external == 0 && mddev->safemode == 1) ||
index 1642eae75a3335d1282a4bf53751802e1aeb52db..849ad39f547b9c1fbb8d993e118261a33b242134 100644 (file)
@@ -100,7 +100,7 @@ static void multipath_end_request(struct bio *bio, int error)
                md_error (mp_bh->mddev, rdev);
                printk(KERN_ERR "multipath: %s: rescheduling sector %llu\n", 
                       bdevname(rdev->bdev,b), 
-                      (unsigned long long)bio->bi_sector);
+                      (unsigned long long)bio->bi_iter.bi_sector);
                multipath_reschedule_retry(mp_bh);
        } else
                multipath_end_bh_io(mp_bh, error);
@@ -132,7 +132,7 @@ static void multipath_make_request(struct mddev *mddev, struct bio * bio)
        multipath = conf->multipaths + mp_bh->path;
 
        mp_bh->bio = *bio;
-       mp_bh->bio.bi_sector += multipath->rdev->data_offset;
+       mp_bh->bio.bi_iter.bi_sector += multipath->rdev->data_offset;
        mp_bh->bio.bi_bdev = multipath->rdev->bdev;
        mp_bh->bio.bi_rw |= REQ_FAILFAST_TRANSPORT;
        mp_bh->bio.bi_end_io = multipath_end_request;
@@ -355,21 +355,22 @@ static void multipathd(struct md_thread *thread)
                spin_unlock_irqrestore(&conf->device_lock, flags);
 
                bio = &mp_bh->bio;
-               bio->bi_sector = mp_bh->master_bio->bi_sector;
+               bio->bi_iter.bi_sector = mp_bh->master_bio->bi_iter.bi_sector;
                
                if ((mp_bh->path = multipath_map (conf))<0) {
                        printk(KERN_ALERT "multipath: %s: unrecoverable IO read"
                                " error for block %llu\n",
                                bdevname(bio->bi_bdev,b),
-                               (unsigned long long)bio->bi_sector);
+                               (unsigned long long)bio->bi_iter.bi_sector);
                        multipath_end_bh_io(mp_bh, -EIO);
                } else {
                        printk(KERN_ERR "multipath: %s: redirecting sector %llu"
                                " to another IO path\n",
                                bdevname(bio->bi_bdev,b),
-                               (unsigned long long)bio->bi_sector);
+                               (unsigned long long)bio->bi_iter.bi_sector);
                        *bio = *(mp_bh->master_bio);
-                       bio->bi_sector += conf->multipaths[mp_bh->path].rdev->data_offset;
+                       bio->bi_iter.bi_sector +=
+                               conf->multipaths[mp_bh->path].rdev->data_offset;
                        bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev;
                        bio->bi_rw |= REQ_FAILFAST_TRANSPORT;
                        bio->bi_end_io = multipath_end_request;
index c4d420b7d2f43d0804e1c1a94d88ca63484b5ec3..407a99e46f6993a770c21fdfff1972b7f64063b6 100644 (file)
@@ -501,10 +501,11 @@ static inline int is_io_in_chunk_boundary(struct mddev *mddev,
                        unsigned int chunk_sects, struct bio *bio)
 {
        if (likely(is_power_of_2(chunk_sects))) {
-               return chunk_sects >= ((bio->bi_sector & (chunk_sects-1))
+               return chunk_sects >=
+                       ((bio->bi_iter.bi_sector & (chunk_sects-1))
                                        + bio_sectors(bio));
        } else{
-               sector_t sector = bio->bi_sector;
+               sector_t sector = bio->bi_iter.bi_sector;
                return chunk_sects >= (sector_div(sector, chunk_sects)
                                                + bio_sectors(bio));
        }
@@ -512,64 +513,44 @@ static inline int is_io_in_chunk_boundary(struct mddev *mddev,
 
 static void raid0_make_request(struct mddev *mddev, struct bio *bio)
 {
-       unsigned int chunk_sects;
-       sector_t sector_offset;
        struct strip_zone *zone;
        struct md_rdev *tmp_dev;
+       struct bio *split;
 
        if (unlikely(bio->bi_rw & REQ_FLUSH)) {
                md_flush_request(mddev, bio);
                return;
        }
 
-       chunk_sects = mddev->chunk_sectors;
-       if (unlikely(!is_io_in_chunk_boundary(mddev, chunk_sects, bio))) {
-               sector_t sector = bio->bi_sector;
-               struct bio_pair *bp;
-               /* Sanity check -- queue functions should prevent this happening */
-               if (bio_segments(bio) > 1)
-                       goto bad_map;
-               /* This is a one page bio that upper layers
-                * refuse to split for us, so we need to split it.
-                */
-               if (likely(is_power_of_2(chunk_sects)))
-                       bp = bio_split(bio, chunk_sects - (sector &
-                                                          (chunk_sects-1)));
-               else
-                       bp = bio_split(bio, chunk_sects -
-                                      sector_div(sector, chunk_sects));
-               raid0_make_request(mddev, &bp->bio1);
-               raid0_make_request(mddev, &bp->bio2);
-               bio_pair_release(bp);
-               return;
-       }
+       do {
+               sector_t sector = bio->bi_iter.bi_sector;
+               unsigned chunk_sects = mddev->chunk_sectors;
 
-       sector_offset = bio->bi_sector;
-       zone = find_zone(mddev->private, &sector_offset);
-       tmp_dev = map_sector(mddev, zone, bio->bi_sector,
-                            &sector_offset);
-       bio->bi_bdev = tmp_dev->bdev;
-       bio->bi_sector = sector_offset + zone->dev_start +
-               tmp_dev->data_offset;
-
-       if (unlikely((bio->bi_rw & REQ_DISCARD) &&
-                    !blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) {
-               /* Just ignore it */
-               bio_endio(bio, 0);
-               return;
-       }
+               unsigned sectors = chunk_sects -
+                       (likely(is_power_of_2(chunk_sects))
+                        ? (sector & (chunk_sects-1))
+                        : sector_div(sector, chunk_sects));
 
-       generic_make_request(bio);
-       return;
-
-bad_map:
-       printk("md/raid0:%s: make_request bug: can't convert block across chunks"
-              " or bigger than %dk %llu %d\n",
-              mdname(mddev), chunk_sects / 2,
-              (unsigned long long)bio->bi_sector, bio_sectors(bio) / 2);
+               if (sectors < bio_sectors(bio)) {
+                       split = bio_split(bio, sectors, GFP_NOIO, fs_bio_set);
+                       bio_chain(split, bio);
+               } else {
+                       split = bio;
+               }
 
-       bio_io_error(bio);
-       return;
+               zone = find_zone(mddev->private, &sector);
+               tmp_dev = map_sector(mddev, zone, sector, &sector);
+               split->bi_bdev = tmp_dev->bdev;
+               split->bi_iter.bi_sector = sector + zone->dev_start +
+                       tmp_dev->data_offset;
+
+               if (unlikely((split->bi_rw & REQ_DISCARD) &&
+                        !blk_queue_discard(bdev_get_queue(split->bi_bdev)))) {
+                       /* Just ignore it */
+                       bio_endio(split, 0);
+               } else
+                       generic_make_request(split);
+       } while (split != bio);
 }
 
 static void raid0_status(struct seq_file *seq, struct mddev *mddev)
index 1e5a540995e932852df5ff484a96bfcc8636a432..db3b9d7314f1835def74642faaff39af892d1d8c 100644 (file)
@@ -229,7 +229,7 @@ static void call_bio_endio(struct r1bio *r1_bio)
        int done;
        struct r1conf *conf = r1_bio->mddev->private;
        sector_t start_next_window = r1_bio->start_next_window;
-       sector_t bi_sector = bio->bi_sector;
+       sector_t bi_sector = bio->bi_iter.bi_sector;
 
        if (bio->bi_phys_segments) {
                unsigned long flags;
@@ -265,9 +265,8 @@ static void raid_end_bio_io(struct r1bio *r1_bio)
        if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
                pr_debug("raid1: sync end %s on sectors %llu-%llu\n",
                         (bio_data_dir(bio) == WRITE) ? "write" : "read",
-                        (unsigned long long) bio->bi_sector,
-                        (unsigned long long) bio->bi_sector +
-                        bio_sectors(bio) - 1);
+                        (unsigned long long) bio->bi_iter.bi_sector,
+                        (unsigned long long) bio_end_sector(bio) - 1);
 
                call_bio_endio(r1_bio);
        }
@@ -466,9 +465,8 @@ static void raid1_end_write_request(struct bio *bio, int error)
                                struct bio *mbio = r1_bio->master_bio;
                                pr_debug("raid1: behind end write sectors"
                                         " %llu-%llu\n",
-                                        (unsigned long long) mbio->bi_sector,
-                                        (unsigned long long) mbio->bi_sector +
-                                        bio_sectors(mbio) - 1);
+                                        (unsigned long long) mbio->bi_iter.bi_sector,
+                                        (unsigned long long) bio_end_sector(mbio) - 1);
                                call_bio_endio(r1_bio);
                        }
                }
@@ -875,7 +873,7 @@ static bool need_to_wait_for_sync(struct r1conf *conf, struct bio *bio)
                else if ((conf->next_resync - RESYNC_WINDOW_SECTORS
                                >= bio_end_sector(bio)) ||
                         (conf->next_resync + NEXT_NORMALIO_DISTANCE
-                               <= bio->bi_sector))
+                               <= bio->bi_iter.bi_sector))
                        wait = false;
                else
                        wait = true;
@@ -913,19 +911,19 @@ static sector_t wait_barrier(struct r1conf *conf, struct bio *bio)
 
        if (bio && bio_data_dir(bio) == WRITE) {
                if (conf->next_resync + NEXT_NORMALIO_DISTANCE
-                   <= bio->bi_sector) {
+                   <= bio->bi_iter.bi_sector) {
                        if (conf->start_next_window == MaxSector)
                                conf->start_next_window =
                                        conf->next_resync +
                                        NEXT_NORMALIO_DISTANCE;
 
                        if ((conf->start_next_window + NEXT_NORMALIO_DISTANCE)
-                           <= bio->bi_sector)
+                           <= bio->bi_iter.bi_sector)
                                conf->next_window_requests++;
                        else
                                conf->current_window_requests++;
                }
-               if (bio->bi_sector >= conf->start_next_window)
+               if (bio->bi_iter.bi_sector >= conf->start_next_window)
                        sector = conf->start_next_window;
        }
 
@@ -1028,7 +1026,8 @@ do_sync_io:
                if (bvecs[i].bv_page)
                        put_page(bvecs[i].bv_page);
        kfree(bvecs);
-       pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size);
+       pr_debug("%dB behind alloc failed, doing sync I/O\n",
+                bio->bi_iter.bi_size);
 }
 
 struct raid1_plug_cb {
@@ -1108,7 +1107,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
 
        if (bio_data_dir(bio) == WRITE &&
            bio_end_sector(bio) > mddev->suspend_lo &&
-           bio->bi_sector < mddev->suspend_hi) {
+           bio->bi_iter.bi_sector < mddev->suspend_hi) {
                /* As the suspend_* range is controlled by
                 * userspace, we want an interruptible
                 * wait.
@@ -1119,7 +1118,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
                        prepare_to_wait(&conf->wait_barrier,
                                        &w, TASK_INTERRUPTIBLE);
                        if (bio_end_sector(bio) <= mddev->suspend_lo ||
-                           bio->bi_sector >= mddev->suspend_hi)
+                           bio->bi_iter.bi_sector >= mddev->suspend_hi)
                                break;
                        schedule();
                }
@@ -1141,7 +1140,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
        r1_bio->sectors = bio_sectors(bio);
        r1_bio->state = 0;
        r1_bio->mddev = mddev;
-       r1_bio->sector = bio->bi_sector;
+       r1_bio->sector = bio->bi_iter.bi_sector;
 
        /* We might need to issue multiple reads to different
         * devices if there are bad blocks around, so we keep
@@ -1181,12 +1180,13 @@ read_again:
                r1_bio->read_disk = rdisk;
 
                read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-               bio_trim(read_bio, r1_bio->sector - bio->bi_sector,
+               bio_trim(read_bio, r1_bio->sector - bio->bi_iter.bi_sector,
                         max_sectors);
 
                r1_bio->bios[rdisk] = read_bio;
 
-               read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset;
+               read_bio->bi_iter.bi_sector = r1_bio->sector +
+                       mirror->rdev->data_offset;
                read_bio->bi_bdev = mirror->rdev->bdev;
                read_bio->bi_end_io = raid1_end_read_request;
                read_bio->bi_rw = READ | do_sync;
@@ -1198,7 +1198,7 @@ read_again:
                         */
 
                        sectors_handled = (r1_bio->sector + max_sectors
-                                          - bio->bi_sector);
+                                          - bio->bi_iter.bi_sector);
                        r1_bio->sectors = max_sectors;
                        spin_lock_irq(&conf->device_lock);
                        if (bio->bi_phys_segments == 0)
@@ -1219,7 +1219,8 @@ read_again:
                        r1_bio->sectors = bio_sectors(bio) - sectors_handled;
                        r1_bio->state = 0;
                        r1_bio->mddev = mddev;
-                       r1_bio->sector = bio->bi_sector + sectors_handled;
+                       r1_bio->sector = bio->bi_iter.bi_sector +
+                               sectors_handled;
                        goto read_again;
                } else
                        generic_make_request(read_bio);
@@ -1322,7 +1323,7 @@ read_again:
                        if (r1_bio->bios[j])
                                rdev_dec_pending(conf->mirrors[j].rdev, mddev);
                r1_bio->state = 0;
-               allow_barrier(conf, start_next_window, bio->bi_sector);
+               allow_barrier(conf, start_next_window, bio->bi_iter.bi_sector);
                md_wait_for_blocked_rdev(blocked_rdev, mddev);
                start_next_window = wait_barrier(conf, bio);
                /*
@@ -1349,7 +1350,7 @@ read_again:
                        bio->bi_phys_segments++;
                spin_unlock_irq(&conf->device_lock);
        }
-       sectors_handled = r1_bio->sector + max_sectors - bio->bi_sector;
+       sectors_handled = r1_bio->sector + max_sectors - bio->bi_iter.bi_sector;
 
        atomic_set(&r1_bio->remaining, 1);
        atomic_set(&r1_bio->behind_remaining, 0);
@@ -1361,7 +1362,7 @@ read_again:
                        continue;
 
                mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-               bio_trim(mbio, r1_bio->sector - bio->bi_sector, max_sectors);
+               bio_trim(mbio, r1_bio->sector - bio->bi_iter.bi_sector, max_sectors);
 
                if (first_clone) {
                        /* do behind I/O ?
@@ -1395,7 +1396,7 @@ read_again:
 
                r1_bio->bios[i] = mbio;
 
-               mbio->bi_sector = (r1_bio->sector +
+               mbio->bi_iter.bi_sector = (r1_bio->sector +
                                   conf->mirrors[i].rdev->data_offset);
                mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
                mbio->bi_end_io = raid1_end_write_request;
@@ -1435,7 +1436,7 @@ read_again:
                r1_bio->sectors = bio_sectors(bio) - sectors_handled;
                r1_bio->state = 0;
                r1_bio->mddev = mddev;
-               r1_bio->sector = bio->bi_sector + sectors_handled;
+               r1_bio->sector = bio->bi_iter.bi_sector + sectors_handled;
                goto retry_write;
        }
 
@@ -1959,14 +1960,14 @@ static int process_checks(struct r1bio *r1_bio)
                /* fixup the bio for reuse */
                bio_reset(b);
                b->bi_vcnt = vcnt;
-               b->bi_size = r1_bio->sectors << 9;
-               b->bi_sector = r1_bio->sector +
+               b->bi_iter.bi_size = r1_bio->sectors << 9;
+               b->bi_iter.bi_sector = r1_bio->sector +
                        conf->mirrors[i].rdev->data_offset;
                b->bi_bdev = conf->mirrors[i].rdev->bdev;
                b->bi_end_io = end_sync_read;
                b->bi_private = r1_bio;
 
-               size = b->bi_size;
+               size = b->bi_iter.bi_size;
                for (j = 0; j < vcnt ; j++) {
                        struct bio_vec *bi;
                        bi = &b->bi_io_vec[j];
@@ -2221,11 +2222,11 @@ static int narrow_write_error(struct r1bio *r1_bio, int i)
                }
 
                wbio->bi_rw = WRITE;
-               wbio->bi_sector = r1_bio->sector;
-               wbio->bi_size = r1_bio->sectors << 9;
+               wbio->bi_iter.bi_sector = r1_bio->sector;
+               wbio->bi_iter.bi_size = r1_bio->sectors << 9;
 
                bio_trim(wbio, sector - r1_bio->sector, sectors);
-               wbio->bi_sector += rdev->data_offset;
+               wbio->bi_iter.bi_sector += rdev->data_offset;
                wbio->bi_bdev = rdev->bdev;
                if (submit_bio_wait(WRITE, wbio) == 0)
                        /* failure! */
@@ -2339,7 +2340,8 @@ read_more:
                }
                r1_bio->read_disk = disk;
                bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
-               bio_trim(bio, r1_bio->sector - bio->bi_sector, max_sectors);
+               bio_trim(bio, r1_bio->sector - bio->bi_iter.bi_sector,
+                        max_sectors);
                r1_bio->bios[r1_bio->read_disk] = bio;
                rdev = conf->mirrors[disk].rdev;
                printk_ratelimited(KERN_ERR
@@ -2348,7 +2350,7 @@ read_more:
                                   mdname(mddev),
                                   (unsigned long long)r1_bio->sector,
                                   bdevname(rdev->bdev, b));
-               bio->bi_sector = r1_bio->sector + rdev->data_offset;
+               bio->bi_iter.bi_sector = r1_bio->sector + rdev->data_offset;
                bio->bi_bdev = rdev->bdev;
                bio->bi_end_io = raid1_end_read_request;
                bio->bi_rw = READ | do_sync;
@@ -2357,7 +2359,7 @@ read_more:
                        /* Drat - have to split this up more */
                        struct bio *mbio = r1_bio->master_bio;
                        int sectors_handled = (r1_bio->sector + max_sectors
-                                              - mbio->bi_sector);
+                                              - mbio->bi_iter.bi_sector);
                        r1_bio->sectors = max_sectors;
                        spin_lock_irq(&conf->device_lock);
                        if (mbio->bi_phys_segments == 0)
@@ -2375,7 +2377,8 @@ read_more:
                        r1_bio->state = 0;
                        set_bit(R1BIO_ReadError, &r1_bio->state);
                        r1_bio->mddev = mddev;
-                       r1_bio->sector = mbio->bi_sector + sectors_handled;
+                       r1_bio->sector = mbio->bi_iter.bi_sector +
+                               sectors_handled;
 
                        goto read_more;
                } else
@@ -2599,7 +2602,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp
                }
                if (bio->bi_end_io) {
                        atomic_inc(&rdev->nr_pending);
-                       bio->bi_sector = sector_nr + rdev->data_offset;
+                       bio->bi_iter.bi_sector = sector_nr + rdev->data_offset;
                        bio->bi_bdev = rdev->bdev;
                        bio->bi_private = r1_bio;
                }
@@ -2699,7 +2702,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp
                                                        continue;
                                                /* remove last page from this bio */
                                                bio->bi_vcnt--;
-                                               bio->bi_size -= len;
+                                               bio->bi_iter.bi_size -= len;
                                                bio->bi_flags &= ~(1<< BIO_SEG_VALID);
                                        }
                                        goto bio_full;
index c504e8389e69e3ab9ad717b9f83d0c19c2008d68..6d43d88657aa81982e1f31540878e822ffd44a39 100644 (file)
@@ -1152,14 +1152,12 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
        kfree(plug);
 }
 
-static void make_request(struct mddev *mddev, struct bio * bio)
+static void __make_request(struct mddev *mddev, struct bio *bio)
 {
        struct r10conf *conf = mddev->private;
        struct r10bio *r10_bio;
        struct bio *read_bio;
        int i;
-       sector_t chunk_mask = (conf->geo.chunk_mask & conf->prev.chunk_mask);
-       int chunk_sects = chunk_mask + 1;
        const int rw = bio_data_dir(bio);
        const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
        const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
@@ -1174,88 +1172,27 @@ static void make_request(struct mddev *mddev, struct bio * bio)
        int max_sectors;
        int sectors;
 
-       if (unlikely(bio->bi_rw & REQ_FLUSH)) {
-               md_flush_request(mddev, bio);
-               return;
-       }
-
-       /* If this request crosses a chunk boundary, we need to
-        * split it.  This will only happen for 1 PAGE (or less) requests.
-        */
-       if (unlikely((bio->bi_sector & chunk_mask) + bio_sectors(bio)
-                    > chunk_sects
-                    && (conf->geo.near_copies < conf->geo.raid_disks
-                        || conf->prev.near_copies < conf->prev.raid_disks))) {
-               struct bio_pair *bp;
-               /* Sanity check -- queue functions should prevent this happening */
-               if (bio_segments(bio) > 1)
-                       goto bad_map;
-               /* This is a one page bio that upper layers
-                * refuse to split for us, so we need to split it.
-                */
-               bp = bio_split(bio,
-                              chunk_sects - (bio->bi_sector & (chunk_sects - 1)) );
-
-               /* Each of these 'make_request' calls will call 'wait_barrier'.
-                * If the first succeeds but the second blocks due to the resync
-                * thread raising the barrier, we will deadlock because the
-                * IO to the underlying device will be queued in generic_make_request
-                * and will never complete, so will never reduce nr_pending.
-                * So increment nr_waiting here so no new raise_barriers will
-                * succeed, and so the second wait_barrier cannot block.
-                */
-               spin_lock_irq(&conf->resync_lock);
-               conf->nr_waiting++;
-               spin_unlock_irq(&conf->resync_lock);
-
-               make_request(mddev, &bp->bio1);
-               make_request(mddev, &bp->bio2);
-
-               spin_lock_irq(&conf->resync_lock);
-               conf->nr_waiting--;
-               wake_up(&conf->wait_barrier);
-               spin_unlock_irq(&conf->resync_lock);
-
-               bio_pair_release(bp);
-               return;
-       bad_map:
-               printk("md/raid10:%s: make_request bug: can't convert block across chunks"
-                      " or bigger than %dk %llu %d\n", mdname(mddev), chunk_sects/2,
-                      (unsigned long long)bio->bi_sector, bio_sectors(bio) / 2);
-
-               bio_io_error(bio);
-               return;
-       }
-
-       md_write_start(mddev, bio);
-
-       /*
-        * Register the new request and wait if the reconstruction
-        * thread has put up a bar for new requests.
-        * Continue immediately if no resync is active currently.
-        */
-       wait_barrier(conf);
-
        sectors = bio_sectors(bio);
        while (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
-           bio->bi_sector < conf->reshape_progress &&
-           bio->bi_sector + sectors > conf->reshape_progress) {
+           bio->bi_iter.bi_sector < conf->reshape_progress &&
+           bio->bi_iter.bi_sector + sectors > conf->reshape_progress) {
                /* IO spans the reshape position.  Need to wait for
                 * reshape to pass
                 */
                allow_barrier(conf);
                wait_event(conf->wait_barrier,
-                          conf->reshape_progress <= bio->bi_sector ||
-                          conf->reshape_progress >= bio->bi_sector + sectors);
+                          conf->reshape_progress <= bio->bi_iter.bi_sector ||
+                          conf->reshape_progress >= bio->bi_iter.bi_sector +
+                          sectors);
                wait_barrier(conf);
        }
        if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
            bio_data_dir(bio) == WRITE &&
            (mddev->reshape_backwards
-            ? (bio->bi_sector < conf->reshape_safe &&
-               bio->bi_sector + sectors > conf->reshape_progress)
-            : (bio->bi_sector + sectors > conf->reshape_safe &&
-               bio->bi_sector < conf->reshape_progress))) {
+            ? (bio->bi_iter.bi_sector < conf->reshape_safe &&
+               bio->bi_iter.bi_sector + sectors > conf->reshape_progress)
+            : (bio->bi_iter.bi_sector + sectors > conf->reshape_safe &&
+               bio->bi_iter.bi_sector < conf->reshape_progress))) {
                /* Need to update reshape_position in metadata */
                mddev->reshape_position = conf->reshape_progress;
                set_bit(MD_CHANGE_DEVS, &mddev->flags);
@@ -1273,7 +1210,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
        r10_bio->sectors = sectors;
 
        r10_bio->mddev = mddev;
-       r10_bio->sector = bio->bi_sector;
+       r10_bio->sector = bio->bi_iter.bi_sector;
        r10_bio->state = 0;
 
        /* We might need to issue multiple reads to different
@@ -1302,13 +1239,13 @@ read_again:
                slot = r10_bio->read_slot;
 
                read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-               bio_trim(read_bio, r10_bio->sector - bio->bi_sector,
+               bio_trim(read_bio, r10_bio->sector - bio->bi_iter.bi_sector,
                         max_sectors);
 
                r10_bio->devs[slot].bio = read_bio;
                r10_bio->devs[slot].rdev = rdev;
 
-               read_bio->bi_sector = r10_bio->devs[slot].addr +
+               read_bio->bi_iter.bi_sector = r10_bio->devs[slot].addr +
                        choose_data_offset(r10_bio, rdev);
                read_bio->bi_bdev = rdev->bdev;
                read_bio->bi_end_io = raid10_end_read_request;
@@ -1320,7 +1257,7 @@ read_again:
                         * need another r10_bio.
                         */
                        sectors_handled = (r10_bio->sectors + max_sectors
-                                          - bio->bi_sector);
+                                          - bio->bi_iter.bi_sector);
                        r10_bio->sectors = max_sectors;
                        spin_lock_irq(&conf->device_lock);
                        if (bio->bi_phys_segments == 0)
@@ -1341,7 +1278,8 @@ read_again:
                        r10_bio->sectors = bio_sectors(bio) - sectors_handled;
                        r10_bio->state = 0;
                        r10_bio->mddev = mddev;
-                       r10_bio->sector = bio->bi_sector + sectors_handled;
+                       r10_bio->sector = bio->bi_iter.bi_sector +
+                               sectors_handled;
                        goto read_again;
                } else
                        generic_make_request(read_bio);
@@ -1499,7 +1437,8 @@ retry_write:
                        bio->bi_phys_segments++;
                spin_unlock_irq(&conf->device_lock);
        }
-       sectors_handled = r10_bio->sector + max_sectors - bio->bi_sector;
+       sectors_handled = r10_bio->sector + max_sectors -
+               bio->bi_iter.bi_sector;
 
        atomic_set(&r10_bio->remaining, 1);
        bitmap_startwrite(mddev->bitmap, r10_bio->sector, r10_bio->sectors, 0);
@@ -1510,11 +1449,11 @@ retry_write:
                if (r10_bio->devs[i].bio) {
                        struct md_rdev *rdev = conf->mirrors[d].rdev;
                        mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-                       bio_trim(mbio, r10_bio->sector - bio->bi_sector,
+                       bio_trim(mbio, r10_bio->sector - bio->bi_iter.bi_sector,
                                 max_sectors);
                        r10_bio->devs[i].bio = mbio;
 
-                       mbio->bi_sector = (r10_bio->devs[i].addr+
+                       mbio->bi_iter.bi_sector = (r10_bio->devs[i].addr+
                                           choose_data_offset(r10_bio,
                                                              rdev));
                        mbio->bi_bdev = rdev->bdev;
@@ -1553,11 +1492,11 @@ retry_write:
                                rdev = conf->mirrors[d].rdev;
                        }
                        mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-                       bio_trim(mbio, r10_bio->sector - bio->bi_sector,
+                       bio_trim(mbio, r10_bio->sector - bio->bi_iter.bi_sector,
                                 max_sectors);
                        r10_bio->devs[i].repl_bio = mbio;
 
-                       mbio->bi_sector = (r10_bio->devs[i].addr +
+                       mbio->bi_iter.bi_sector = (r10_bio->devs[i].addr +
                                           choose_data_offset(
                                                   r10_bio, rdev));
                        mbio->bi_bdev = rdev->bdev;
@@ -1591,11 +1530,57 @@ retry_write:
                r10_bio->sectors = bio_sectors(bio) - sectors_handled;
 
                r10_bio->mddev = mddev;
-               r10_bio->sector = bio->bi_sector + sectors_handled;
+               r10_bio->sector = bio->bi_iter.bi_sector + sectors_handled;
                r10_bio->state = 0;
                goto retry_write;
        }
        one_write_done(r10_bio);
+}
+
+static void make_request(struct mddev *mddev, struct bio *bio)
+{
+       struct r10conf *conf = mddev->private;
+       sector_t chunk_mask = (conf->geo.chunk_mask & conf->prev.chunk_mask);
+       int chunk_sects = chunk_mask + 1;
+
+       struct bio *split;
+
+       if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+               md_flush_request(mddev, bio);
+               return;
+       }
+
+       md_write_start(mddev, bio);
+
+       /*
+        * Register the new request and wait if the reconstruction
+        * thread has put up a bar for new requests.
+        * Continue immediately if no resync is active currently.
+        */
+       wait_barrier(conf);
+
+       do {
+
+               /*
+                * If this request crosses a chunk boundary, we need to split
+                * it.
+                */
+               if (unlikely((bio->bi_iter.bi_sector & chunk_mask) +
+                            bio_sectors(bio) > chunk_sects
+                            && (conf->geo.near_copies < conf->geo.raid_disks
+                                || conf->prev.near_copies <
+                                conf->prev.raid_disks))) {
+                       split = bio_split(bio, chunk_sects -
+                                         (bio->bi_iter.bi_sector &
+                                          (chunk_sects - 1)),
+                                         GFP_NOIO, fs_bio_set);
+                       bio_chain(split, bio);
+               } else {
+                       split = bio;
+               }
+
+               __make_request(mddev, split);
+       } while (split != bio);
 
        /* In case raid10d snuck in to freeze_array */
        wake_up(&conf->wait_barrier);
@@ -2124,10 +2109,10 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
                bio_reset(tbio);
 
                tbio->bi_vcnt = vcnt;
-               tbio->bi_size = r10_bio->sectors << 9;
+               tbio->bi_iter.bi_size = r10_bio->sectors << 9;
                tbio->bi_rw = WRITE;
                tbio->bi_private = r10_bio;
-               tbio->bi_sector = r10_bio->devs[i].addr;
+               tbio->bi_iter.bi_sector = r10_bio->devs[i].addr;
 
                for (j=0; j < vcnt ; j++) {
                        tbio->bi_io_vec[j].bv_offset = 0;
@@ -2144,7 +2129,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
                atomic_inc(&r10_bio->remaining);
                md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(tbio));
 
-               tbio->bi_sector += conf->mirrors[d].rdev->data_offset;
+               tbio->bi_iter.bi_sector += conf->mirrors[d].rdev->data_offset;
                tbio->bi_bdev = conf->mirrors[d].rdev->bdev;
                generic_make_request(tbio);
        }
@@ -2614,8 +2599,8 @@ static int narrow_write_error(struct r10bio *r10_bio, int i)
                        sectors = sect_to_write;
                /* Write at 'sector' for 'sectors' */
                wbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-               bio_trim(wbio, sector - bio->bi_sector, sectors);
-               wbio->bi_sector = (r10_bio->devs[i].addr+
+               bio_trim(wbio, sector - bio->bi_iter.bi_sector, sectors);
+               wbio->bi_iter.bi_sector = (r10_bio->devs[i].addr+
                                   choose_data_offset(r10_bio, rdev) +
                                   (sector - r10_bio->sector));
                wbio->bi_bdev = rdev->bdev;
@@ -2687,10 +2672,10 @@ read_more:
                (unsigned long long)r10_bio->sector);
        bio = bio_clone_mddev(r10_bio->master_bio,
                              GFP_NOIO, mddev);
-       bio_trim(bio, r10_bio->sector - bio->bi_sector, max_sectors);
+       bio_trim(bio, r10_bio->sector - bio->bi_iter.bi_sector, max_sectors);
        r10_bio->devs[slot].bio = bio;
        r10_bio->devs[slot].rdev = rdev;
-       bio->bi_sector = r10_bio->devs[slot].addr
+       bio->bi_iter.bi_sector = r10_bio->devs[slot].addr
                + choose_data_offset(r10_bio, rdev);
        bio->bi_bdev = rdev->bdev;
        bio->bi_rw = READ | do_sync;
@@ -2701,7 +2686,7 @@ read_more:
                struct bio *mbio = r10_bio->master_bio;
                int sectors_handled =
                        r10_bio->sector + max_sectors
-                       - mbio->bi_sector;
+                       - mbio->bi_iter.bi_sector;
                r10_bio->sectors = max_sectors;
                spin_lock_irq(&conf->device_lock);
                if (mbio->bi_phys_segments == 0)
@@ -2719,7 +2704,7 @@ read_more:
                set_bit(R10BIO_ReadError,
                        &r10_bio->state);
                r10_bio->mddev = mddev;
-               r10_bio->sector = mbio->bi_sector
+               r10_bio->sector = mbio->bi_iter.bi_sector
                        + sectors_handled;
 
                goto read_more;
@@ -3157,7 +3142,8 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
                                bio->bi_end_io = end_sync_read;
                                bio->bi_rw = READ;
                                from_addr = r10_bio->devs[j].addr;
-                               bio->bi_sector = from_addr + rdev->data_offset;
+                               bio->bi_iter.bi_sector = from_addr +
+                                       rdev->data_offset;
                                bio->bi_bdev = rdev->bdev;
                                atomic_inc(&rdev->nr_pending);
                                /* and we write to 'i' (if not in_sync) */
@@ -3181,7 +3167,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
                                        bio->bi_private = r10_bio;
                                        bio->bi_end_io = end_sync_write;
                                        bio->bi_rw = WRITE;
-                                       bio->bi_sector = to_addr
+                                       bio->bi_iter.bi_sector = to_addr
                                                + rdev->data_offset;
                                        bio->bi_bdev = rdev->bdev;
                                        atomic_inc(&r10_bio->remaining);
@@ -3210,7 +3196,8 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
                                bio->bi_private = r10_bio;
                                bio->bi_end_io = end_sync_write;
                                bio->bi_rw = WRITE;
-                               bio->bi_sector = to_addr + rdev->data_offset;
+                               bio->bi_iter.bi_sector = to_addr +
+                                       rdev->data_offset;
                                bio->bi_bdev = rdev->bdev;
                                atomic_inc(&r10_bio->remaining);
                                break;
@@ -3328,7 +3315,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
                        bio->bi_private = r10_bio;
                        bio->bi_end_io = end_sync_read;
                        bio->bi_rw = READ;
-                       bio->bi_sector = sector +
+                       bio->bi_iter.bi_sector = sector +
                                conf->mirrors[d].rdev->data_offset;
                        bio->bi_bdev = conf->mirrors[d].rdev->bdev;
                        count++;
@@ -3350,7 +3337,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
                        bio->bi_private = r10_bio;
                        bio->bi_end_io = end_sync_write;
                        bio->bi_rw = WRITE;
-                       bio->bi_sector = sector +
+                       bio->bi_iter.bi_sector = sector +
                                conf->mirrors[d].replacement->data_offset;
                        bio->bi_bdev = conf->mirrors[d].replacement->bdev;
                        count++;
@@ -3397,7 +3384,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
                             bio2 = bio2->bi_next) {
                                /* remove last page from this bio */
                                bio2->bi_vcnt--;
-                               bio2->bi_size -= len;
+                               bio2->bi_iter.bi_size -= len;
                                bio2->bi_flags &= ~(1<< BIO_SEG_VALID);
                        }
                        goto bio_full;
@@ -4417,7 +4404,7 @@ read_more:
        read_bio = bio_alloc_mddev(GFP_KERNEL, RESYNC_PAGES, mddev);
 
        read_bio->bi_bdev = rdev->bdev;
-       read_bio->bi_sector = (r10_bio->devs[r10_bio->read_slot].addr
+       read_bio->bi_iter.bi_sector = (r10_bio->devs[r10_bio->read_slot].addr
                               + rdev->data_offset);
        read_bio->bi_private = r10_bio;
        read_bio->bi_end_io = end_sync_read;
@@ -4425,7 +4412,7 @@ read_more:
        read_bio->bi_flags &= ~(BIO_POOL_MASK - 1);
        read_bio->bi_flags |= 1 << BIO_UPTODATE;
        read_bio->bi_vcnt = 0;
-       read_bio->bi_size = 0;
+       read_bio->bi_iter.bi_size = 0;
        r10_bio->master_bio = read_bio;
        r10_bio->read_slot = r10_bio->devs[r10_bio->read_slot].devnum;
 
@@ -4451,7 +4438,8 @@ read_more:
 
                bio_reset(b);
                b->bi_bdev = rdev2->bdev;
-               b->bi_sector = r10_bio->devs[s/2].addr + rdev2->new_data_offset;
+               b->bi_iter.bi_sector = r10_bio->devs[s/2].addr +
+                       rdev2->new_data_offset;
                b->bi_private = r10_bio;
                b->bi_end_io = end_reshape_write;
                b->bi_rw = WRITE;
@@ -4478,7 +4466,7 @@ read_more:
                             bio2 = bio2->bi_next) {
                                /* Remove last page from this bio */
                                bio2->bi_vcnt--;
-                               bio2->bi_size -= len;
+                               bio2->bi_iter.bi_size -= len;
                                bio2->bi_flags &= ~(1<<BIO_SEG_VALID);
                        }
                        goto bio_full;
index 47da0af6322be1bd7930f902c96c57875799a358..eea63372e4d30533b2255159c8b428b2ad90acb3 100644 (file)
@@ -133,7 +133,7 @@ static inline void unlock_all_device_hash_locks_irq(struct r5conf *conf)
 static inline struct bio *r5_next_bio(struct bio *bio, sector_t sector)
 {
        int sectors = bio_sectors(bio);
-       if (bio->bi_sector + sectors < sector + STRIPE_SECTORS)
+       if (bio->bi_iter.bi_sector + sectors < sector + STRIPE_SECTORS)
                return bio->bi_next;
        else
                return NULL;
@@ -225,7 +225,7 @@ static void return_io(struct bio *return_bi)
 
                return_bi = bi->bi_next;
                bi->bi_next = NULL;
-               bi->bi_size = 0;
+               bi->bi_iter.bi_size = 0;
                trace_block_bio_complete(bdev_get_queue(bi->bi_bdev),
                                         bi, 0);
                bio_endio(bi, 0);
@@ -678,26 +678,23 @@ get_active_stripe(struct r5conf *conf, sector_t sector,
                        } else
                                init_stripe(sh, sector, previous);
                } else {
+                       spin_lock(&conf->device_lock);
                        if (atomic_read(&sh->count)) {
                                BUG_ON(!list_empty(&sh->lru)
                                    && !test_bit(STRIPE_EXPANDING, &sh->state)
                                    && !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)
-                                   && !test_bit(STRIPE_ON_RELEASE_LIST, &sh->state));
+                                       );
                        } else {
-                               spin_lock(&conf->device_lock);
                                if (!test_bit(STRIPE_HANDLE, &sh->state))
                                        atomic_inc(&conf->active_stripes);
-                               if (list_empty(&sh->lru) &&
-                                   !test_bit(STRIPE_ON_RELEASE_LIST, &sh->state) &&
-                                   !test_bit(STRIPE_EXPANDING, &sh->state))
-                                       BUG();
+                               BUG_ON(list_empty(&sh->lru));
                                list_del_init(&sh->lru);
                                if (sh->group) {
                                        sh->group->stripes_cnt--;
                                        sh->group = NULL;
                                }
-                               spin_unlock(&conf->device_lock);
                        }
+                       spin_unlock(&conf->device_lock);
                }
        } while (sh == NULL);
 
@@ -854,10 +851,10 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
                                bi->bi_rw, i);
                        atomic_inc(&sh->count);
                        if (use_new_offset(conf, sh))
-                               bi->bi_sector = (sh->sector
+                               bi->bi_iter.bi_sector = (sh->sector
                                                 + rdev->new_data_offset);
                        else
-                               bi->bi_sector = (sh->sector
+                               bi->bi_iter.bi_sector = (sh->sector
                                                 + rdev->data_offset);
                        if (test_bit(R5_ReadNoMerge, &sh->dev[i].flags))
                                bi->bi_rw |= REQ_NOMERGE;
@@ -865,7 +862,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
                        bi->bi_vcnt = 1;
                        bi->bi_io_vec[0].bv_len = STRIPE_SIZE;
                        bi->bi_io_vec[0].bv_offset = 0;
-                       bi->bi_size = STRIPE_SIZE;
+                       bi->bi_iter.bi_size = STRIPE_SIZE;
                        /*
                         * If this is discard request, set bi_vcnt 0. We don't
                         * want to confuse SCSI because SCSI will replace payload
@@ -901,15 +898,15 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
                                rbi->bi_rw, i);
                        atomic_inc(&sh->count);
                        if (use_new_offset(conf, sh))
-                               rbi->bi_sector = (sh->sector
+                               rbi->bi_iter.bi_sector = (sh->sector
                                                  + rrdev->new_data_offset);
                        else
-                               rbi->bi_sector = (sh->sector
+                               rbi->bi_iter.bi_sector = (sh->sector
                                                  + rrdev->data_offset);
                        rbi->bi_vcnt = 1;
                        rbi->bi_io_vec[0].bv_len = STRIPE_SIZE;
                        rbi->bi_io_vec[0].bv_offset = 0;
-                       rbi->bi_size = STRIPE_SIZE;
+                       rbi->bi_iter.bi_size = STRIPE_SIZE;
                        /*
                         * If this is discard request, set bi_vcnt 0. We don't
                         * want to confuse SCSI because SCSI will replace payload
@@ -937,24 +934,24 @@ static struct dma_async_tx_descriptor *
 async_copy_data(int frombio, struct bio *bio, struct page *page,
        sector_t sector, struct dma_async_tx_descriptor *tx)
 {
-       struct bio_vec *bvl;
+       struct bio_vec bvl;
+       struct bvec_iter iter;
        struct page *bio_page;
-       int i;
        int page_offset;
        struct async_submit_ctl submit;
        enum async_tx_flags flags = 0;
 
-       if (bio->bi_sector >= sector)
-               page_offset = (signed)(bio->bi_sector - sector) * 512;
+       if (bio->bi_iter.bi_sector >= sector)
+               page_offset = (signed)(bio->bi_iter.bi_sector - sector) * 512;
        else
-               page_offset = (signed)(sector - bio->bi_sector) * -512;
+               page_offset = (signed)(sector - bio->bi_iter.bi_sector) * -512;
 
        if (frombio)
                flags |= ASYNC_TX_FENCE;
        init_async_submit(&submit, flags, tx, NULL, NULL, NULL);
 
-       bio_for_each_segment(bvl, bio, i) {
-               int len = bvl->bv_len;
+       bio_for_each_segment(bvl, bio, iter) {
+               int len = bvl.bv_len;
                int clen;
                int b_offset = 0;
 
@@ -970,8 +967,8 @@ async_copy_data(int frombio, struct bio *bio, struct page *page,
                        clen = len;
 
                if (clen > 0) {
-                       b_offset += bvl->bv_offset;
-                       bio_page = bvl->bv_page;
+                       b_offset += bvl.bv_offset;
+                       bio_page = bvl.bv_page;
                        if (frombio)
                                tx = async_memcpy(page, bio_page, page_offset,
                                                  b_offset, clen, &submit);
@@ -1014,7 +1011,7 @@ static void ops_complete_biofill(void *stripe_head_ref)
                        BUG_ON(!dev->read);
                        rbi = dev->read;
                        dev->read = NULL;
-                       while (rbi && rbi->bi_sector <
+                       while (rbi && rbi->bi_iter.bi_sector <
                                dev->sector + STRIPE_SECTORS) {
                                rbi2 = r5_next_bio(rbi, dev->sector);
                                if (!raid5_dec_bi_active_stripes(rbi)) {
@@ -1050,7 +1047,7 @@ static void ops_run_biofill(struct stripe_head *sh)
                        dev->read = rbi = dev->toread;
                        dev->toread = NULL;
                        spin_unlock_irq(&sh->stripe_lock);
-                       while (rbi && rbi->bi_sector <
+                       while (rbi && rbi->bi_iter.bi_sector <
                                dev->sector + STRIPE_SECTORS) {
                                tx = async_copy_data(0, rbi, dev->page,
                                        dev->sector, tx);
@@ -1392,7 +1389,7 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
                        wbi = dev->written = chosen;
                        spin_unlock_irq(&sh->stripe_lock);
 
-                       while (wbi && wbi->bi_sector <
+                       while (wbi && wbi->bi_iter.bi_sector <
                                dev->sector + STRIPE_SECTORS) {
                                if (wbi->bi_rw & REQ_FUA)
                                        set_bit(R5_WantFUA, &dev->flags);
@@ -2616,7 +2613,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
        int firstwrite=0;
 
        pr_debug("adding bi b#%llu to stripe s#%llu\n",
-               (unsigned long long)bi->bi_sector,
+               (unsigned long long)bi->bi_iter.bi_sector,
                (unsigned long long)sh->sector);
 
        /*
@@ -2634,12 +2631,12 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
                        firstwrite = 1;
        } else
                bip = &sh->dev[dd_idx].toread;
-       while (*bip && (*bip)->bi_sector < bi->bi_sector) {
-               if (bio_end_sector(*bip) > bi->bi_sector)
+       while (*bip && (*bip)->bi_iter.bi_sector < bi->bi_iter.bi_sector) {
+               if (bio_end_sector(*bip) > bi->bi_iter.bi_sector)
                        goto overlap;
                bip = & (*bip)->bi_next;
        }
-       if (*bip && (*bip)->bi_sector < bio_end_sector(bi))
+       if (*bip && (*bip)->bi_iter.bi_sector < bio_end_sector(bi))
                goto overlap;
 
        BUG_ON(*bip && bi->bi_next && (*bip) != bi->bi_next);
@@ -2653,7 +2650,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
                sector_t sector = sh->dev[dd_idx].sector;
                for (bi=sh->dev[dd_idx].towrite;
                     sector < sh->dev[dd_idx].sector + STRIPE_SECTORS &&
-                            bi && bi->bi_sector <= sector;
+                            bi && bi->bi_iter.bi_sector <= sector;
                     bi = r5_next_bio(bi, sh->dev[dd_idx].sector)) {
                        if (bio_end_sector(bi) >= sector)
                                sector = bio_end_sector(bi);
@@ -2663,7 +2660,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
        }
 
        pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n",
-               (unsigned long long)(*bip)->bi_sector,
+               (unsigned long long)(*bip)->bi_iter.bi_sector,
                (unsigned long long)sh->sector, dd_idx);
        spin_unlock_irq(&sh->stripe_lock);
 
@@ -2738,7 +2735,7 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
                if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
                        wake_up(&conf->wait_for_overlap);
 
-               while (bi && bi->bi_sector <
+               while (bi && bi->bi_iter.bi_sector <
                        sh->dev[i].sector + STRIPE_SECTORS) {
                        struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
                        clear_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -2757,7 +2754,7 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
                bi = sh->dev[i].written;
                sh->dev[i].written = NULL;
                if (bi) bitmap_end = 1;
-               while (bi && bi->bi_sector <
+               while (bi && bi->bi_iter.bi_sector <
                       sh->dev[i].sector + STRIPE_SECTORS) {
                        struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
                        clear_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -2781,7 +2778,7 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
                        spin_unlock_irq(&sh->stripe_lock);
                        if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
                                wake_up(&conf->wait_for_overlap);
-                       while (bi && bi->bi_sector <
+                       while (bi && bi->bi_iter.bi_sector <
                               sh->dev[i].sector + STRIPE_SECTORS) {
                                struct bio *nextbi =
                                        r5_next_bio(bi, sh->dev[i].sector);
@@ -3005,7 +3002,7 @@ static void handle_stripe_clean_event(struct r5conf *conf,
                                        clear_bit(R5_UPTODATE, &dev->flags);
                                wbi = dev->written;
                                dev->written = NULL;
-                               while (wbi && wbi->bi_sector <
+                               while (wbi && wbi->bi_iter.bi_sector <
                                        dev->sector + STRIPE_SECTORS) {
                                        wbi2 = r5_next_bio(wbi, dev->sector);
                                        if (!raid5_dec_bi_active_stripes(wbi)) {
@@ -4097,7 +4094,7 @@ static int raid5_mergeable_bvec(struct request_queue *q,
 
 static int in_chunk_boundary(struct mddev *mddev, struct bio *bio)
 {
-       sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev);
+       sector_t sector = bio->bi_iter.bi_sector + get_start_sect(bio->bi_bdev);
        unsigned int chunk_sectors = mddev->chunk_sectors;
        unsigned int bio_sectors = bio_sectors(bio);
 
@@ -4234,9 +4231,9 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio)
        /*
         *      compute position
         */
-       align_bi->bi_sector =  raid5_compute_sector(conf, raid_bio->bi_sector,
-                                                   0,
-                                                   &dd_idx, NULL);
+       align_bi->bi_iter.bi_sector =
+               raid5_compute_sector(conf, raid_bio->bi_iter.bi_sector,
+                                    0, &dd_idx, NULL);
 
        end_sector = bio_end_sector(align_bi);
        rcu_read_lock();
@@ -4261,7 +4258,8 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio)
                align_bi->bi_flags &= ~(1 << BIO_SEG_VALID);
 
                if (!bio_fits_rdev(align_bi) ||
-                   is_badblock(rdev, align_bi->bi_sector, bio_sectors(align_bi),
+                   is_badblock(rdev, align_bi->bi_iter.bi_sector,
+                               bio_sectors(align_bi),
                                &first_bad, &bad_sectors)) {
                        /* too big in some way, or has a known bad block */
                        bio_put(align_bi);
@@ -4270,7 +4268,7 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio)
                }
 
                /* No reshape active, so we can trust rdev->data_offset */
-               align_bi->bi_sector += rdev->data_offset;
+               align_bi->bi_iter.bi_sector += rdev->data_offset;
 
                spin_lock_irq(&conf->device_lock);
                wait_event_lock_irq(conf->wait_for_stripe,
@@ -4282,7 +4280,7 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio)
                if (mddev->gendisk)
                        trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev),
                                              align_bi, disk_devt(mddev->gendisk),
-                                             raid_bio->bi_sector);
+                                             raid_bio->bi_iter.bi_sector);
                generic_make_request(align_bi);
                return 1;
        } else {
@@ -4465,8 +4463,8 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi)
                /* Skip discard while reshape is happening */
                return;
 
-       logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
-       last_sector = bi->bi_sector + (bi->bi_size>>9);
+       logical_sector = bi->bi_iter.bi_sector & ~((sector_t)STRIPE_SECTORS-1);
+       last_sector = bi->bi_iter.bi_sector + (bi->bi_iter.bi_size>>9);
 
        bi->bi_next = NULL;
        bi->bi_phys_segments = 1; /* over-loaded to count active stripes */
@@ -4570,7 +4568,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
                return;
        }
 
-       logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
+       logical_sector = bi->bi_iter.bi_sector & ~((sector_t)STRIPE_SECTORS-1);
        last_sector = bio_end_sector(bi);
        bi->bi_next = NULL;
        bi->bi_phys_segments = 1;       /* over-loaded to count active stripes */
@@ -5054,7 +5052,8 @@ static int  retry_aligned_read(struct r5conf *conf, struct bio *raid_bio)
        int remaining;
        int handled = 0;
 
-       logical_sector = raid_bio->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
+       logical_sector = raid_bio->bi_iter.bi_sector &
+               ~((sector_t)STRIPE_SECTORS-1);
        sector = raid5_compute_sector(conf, logical_sector,
                                      0, &dd_idx, NULL);
        last_sector = bio_end_sector(raid_bio);
@@ -5471,7 +5470,7 @@ static int alloc_thread_groups(struct r5conf *conf, int cnt,
        for (i = 0; i < *group_cnt; i++) {
                struct r5worker_group *group;
 
-               group = worker_groups[i];
+               group = &(*worker_groups)[i];
                INIT_LIST_HEAD(&group->handle_list);
                group->conf = conf;
                group->workers = workers + i * cnt;
index d0799e32336450d967114938fc610b66d4134070..9c9063cd3208909d5840a7c2cc745d1bf124f542 100644 (file)
@@ -955,7 +955,7 @@ struct sms_rx_stats {
        u32 modem_state;                /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
        s32 SNR;                /* dB */
        u32 ber;                /* Post Viterbi ber [1E-5] */
-       u32 ber_error_count;    /* Number of erronous SYNC bits. */
+       u32 ber_error_count;    /* Number of erroneous SYNC bits. */
        u32 ber_bit_count;      /* Total number of SYNC bits. */
        u32 ts_per;             /* Transport stream PER,
        0xFFFFFFFF indicate N/A */
@@ -981,7 +981,7 @@ struct sms_rx_stats_ex {
        u32 modem_state;                /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
        s32 SNR;                /* dB */
        u32 ber;                /* Post Viterbi ber [1E-5] */
-       u32 ber_error_count;    /* Number of erronous SYNC bits. */
+       u32 ber_error_count;    /* Number of erroneous SYNC bits. */
        u32 ber_bit_count;      /* Total number of SYNC bits. */
        u32 ts_per;             /* Transport stream PER,
        0xFFFFFFFF indicate N/A */
index 92c413ba0c7971386f052e2f4c4c00876062a31d..ae36d0ae0fb1991ae0ee2e16e392796ca12d271f 100644 (file)
@@ -95,7 +95,7 @@ struct RECEPTION_STATISTICS_PER_SLICES_S {
        u32 is_demod_locked;    /* 0 - not locked, 1 - locked */
 
        u32 ber_bit_count;      /* Total number of SYNC bits. */
-       u32 ber_error_count;    /* Number of erronous SYNC bits. */
+       u32 ber_error_count;    /* Number of erroneous SYNC bits. */
 
        s32 MRC_SNR;            /* dB */
        s32 mrc_in_band_pwr;    /* In band power in dBM */
index 58de4410c5258a7d6009ae47b5becd7e20fa6208..6c7ff0cdcd32ddd44cae9dcf85e98054a7601052 100644 (file)
@@ -435,7 +435,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
                dprintk_tscheck("TEI detected. "
                                "PID=0x%x data1=0x%x\n",
                                pid, buf[1]);
-               /* data in this packet cant be trusted - drop it unless
+               /* data in this packet can't be trusted - drop it unless
                 * module option dvb_demux_feed_err_pkts is set */
                if (!dvb_demux_feed_err_pkts)
                        return;
@@ -1032,8 +1032,13 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
                return -EINVAL;
        }
 
-       if (feed->is_filtering)
+       if (feed->is_filtering) {
+               /* release dvbdmx->mutex as far as it is
+                  acquired by stop_filtering() itself */
+               mutex_unlock(&dvbdmx->mutex);
                feed->stop_filtering(feed);
+               mutex_lock(&dvbdmx->mutex);
+       }
 
        spin_lock_irq(&dvbdmx->lock);
        f = dvbdmxfeed->filter;
index 125a44041011ca0ed17f99999a2bffaa5c1999a1..5c6ab4921bf11d2004ed77e9240b2452fbbb3974 100644 (file)
@@ -78,7 +78,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
 
        num = if_freq / 1000; /* Hz => kHz */
        num *= 0x4000;
-       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
+       if_ctl = 0x4000 - cxd2820r_div_u64_round_closest(num, 41000);
        buf[0] = (if_ctl >> 8) & 0x3f;
        buf[1] = (if_ctl >> 0) & 0xff;
 
index 90536147bf0458c444a59e176b79ddff09471f4f..6dbbee453ee15adb0c4d6b97196beefe6e7d9523 100644 (file)
@@ -3048,7 +3048,7 @@ static int dib8000_tune(struct dvb_frontend *fe)
                        dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
 
                        locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */
-                       /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this lenght to lock */
+                       /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this length to lock */
                        *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON);
                        *tune_state = CT_DEMOD_STEP_5;
                        break;
@@ -3115,7 +3115,7 @@ static int dib8000_tune(struct dvb_frontend *fe)
 
        case CT_DEMOD_STEP_9: /* 39 */
                        if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */
-                               /* defines timeout for mpeg lock depending on interleaver lenght of longest layer */
+                               /* defines timeout for mpeg lock depending on interleaver length of longest layer */
                                for (i = 0; i < 3; i++) {
                                        if (c->layer[i].interleaving >= deeper_interleaver) {
                                                dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving);
index d416c15691dadd69b49eda6f26c70892c3a02652..bf29a3f0e6f0ca440990f7b8b61e71e9bd02674a 100644 (file)
@@ -1191,7 +1191,7 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
                        goto error;
 
                if (state->m_enable_parallel == true) {
-                       /* paralel -> enable MD1 to MD7 */
+                       /* parallel -> enable MD1 to MD7 */
                        status = write16(state, SIO_PDR_MD1_CFG__A,
                                         sio_pdr_mdx_cfg);
                        if (status < 0)
@@ -1428,7 +1428,7 @@ static int mpegts_stop(struct drxk_state *state)
 
        dprintk(1, "\n");
 
-       /* Gracefull shutdown (byte boundaries) */
+       /* Graceful shutdown (byte boundaries) */
        status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
        if (status < 0)
                goto error;
@@ -2021,7 +2021,7 @@ static int mpegts_dto_setup(struct drxk_state *state,
                fec_oc_dto_burst_len = 204;
        }
 
-       /* Check serial or parrallel output */
+       /* Check serial or parallel output */
        fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
        if (state->m_enable_parallel == false) {
                /* MPEG data output is serial -> set ipr_mode[0] */
@@ -2908,7 +2908,7 @@ static int adc_synchronization(struct drxk_state *state)
                goto error;
 
        if (count == 1) {
-               /* Try sampling on a diffrent edge */
+               /* Try sampling on a different edge */
                u16 clk_neg = 0;
 
                status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
@@ -3306,7 +3306,7 @@ static int dvbt_sc_command(struct drxk_state *state,
        if (status < 0)
                goto error;
 
-       /* Retreive results parameters from SC */
+       /* Retrieve results parameters from SC */
        switch (cmd) {
                /* All commands yielding 5 results */
                /* All commands yielding 4 results */
@@ -3849,7 +3849,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
                break;
        }
 #if 0
-       /* No hierachical channels support in BDA */
+       /* No hierarchical channels support in BDA */
        /* Priority (only for hierarchical channels) */
        switch (channel->priority) {
        case DRX_PRIORITY_LOW:
@@ -4081,7 +4081,7 @@ error:
 /*============================================================================*/
 
 /**
-* \brief Retreive lock status .
+* \brief Retrieve lock status .
 * \param demod    Pointer to demodulator instance.
 * \param lockStat Pointer to lock status structure.
 * \return DRXStatus_t.
@@ -6174,7 +6174,7 @@ static int init_drxk(struct drxk_state *state)
                        goto error;
 
                /* Stamp driver version number in SCU data RAM in BCD code
-                       Done to enable field application engineers to retreive drxdriver version
+                       Done to enable field application engineers to retrieve drxdriver version
                        via I2C from SCU RAM.
                        Not using SCU command interface for SCU register access since no
                        microcode may be present.
@@ -6399,7 +6399,7 @@ static int drxk_set_parameters(struct dvb_frontend *fe)
        fe->ops.tuner_ops.get_if_frequency(fe, &IF);
        start(state, 0, IF);
 
-       /* After set_frontend, stats aren't avaliable */
+       /* After set_frontend, stats aren't available */
        p->strength.stat[0].scale = FE_SCALE_RELATIVE;
        p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
        p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
index 4a5b7d211d2f14e3810111a7f6399405e5000935..b253d400e8176a8baa3d1ba6928a1911d74bdb9d 100644 (file)
@@ -52,9 +52,9 @@
 #define ADV7183_VS_FIELD_CTRL_1    0x31 /* Vsync field control 1 */
 #define ADV7183_VS_FIELD_CTRL_2    0x32 /* Vsync field control 2 */
 #define ADV7183_VS_FIELD_CTRL_3    0x33 /* Vsync field control 3 */
-#define ADV7183_HS_POS_CTRL_1      0x34 /* Hsync positon control 1 */
-#define ADV7183_HS_POS_CTRL_2      0x35 /* Hsync positon control 2 */
-#define ADV7183_HS_POS_CTRL_3      0x36 /* Hsync positon control 3 */
+#define ADV7183_HS_POS_CTRL_1      0x34 /* Hsync position control 1 */
+#define ADV7183_HS_POS_CTRL_2      0x35 /* Hsync position control 2 */
+#define ADV7183_HS_POS_CTRL_3      0x36 /* Hsync position control 3 */
 #define ADV7183_POLARITY           0x37 /* Polarity */
 #define ADV7183_NTSC_COMB_CTRL     0x38 /* NTSC comb control */
 #define ADV7183_PAL_COMB_CTRL      0x39 /* PAL comb control */
index fbfdd2fc2a367f5b48c67fc41785395508fc473d..a324106b9f11e985c0637c16578cd3922ee6f58b 100644 (file)
@@ -877,7 +877,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
                break;
        case ADV7604_MODE_HDMI:
                /* set default prim_mode/vid_std for HDMI
-                  accoring to [REF_03, c. 4.2] */
+                  according to [REF_03, c. 4.2] */
                io_write(sd, 0x00, 0x02); /* video std */
                io_write(sd, 0x01, 0x06); /* prim mode */
                break;
index 22f729d66a9696522e18d42932ae383594cbca5f..b154f36740b49151e2b1e0daeaf307c53032f3e7 100644 (file)
@@ -1013,7 +1013,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
                break;
        case ADV7842_MODE_HDMI:
                /* set default prim_mode/vid_std for HDMI
-                  accoring to [REF_03, c. 4.2] */
+                  according to [REF_03, c. 4.2] */
                io_write(sd, 0x00, 0x02); /* video std */
                io_write(sd, 0x01, 0x06); /* prim mode */
                break;
index 82bf5679da3064d5a8ffd9da91c3d9e085d8d8bb..99ee456700f4972ef53888d692aa5f4b19930bce 100644 (file)
@@ -394,7 +394,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
        if (!rc) {
                /*
-                * If platform_data doesn't specify rc_dev, initilize it
+                * If platform_data doesn't specify rc_dev, initialize it
                 * internally
                 */
                rc = rc_allocate_device();
index f34429e452abf4e01dfd71d38ceb690d3c5ab021..a60931e66312e1ff3818ff363c0edd920c0d6c04 100644 (file)
@@ -544,7 +544,7 @@ int m5mols_init_controls(struct v4l2_subdev *sd)
        u16 zoom_step;
        int ret;
 
-       /* Determine the firmware dependant control range and step values */
+       /* Determine the firmware dependent control range and step values */
        ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &exposure_max);
        if (ret < 0)
                return ret;
index 6fec9384d86e4877d5b750a9f9a9ceec53e06bde..e7f555cc827abb4ddc1eba44bb1526e1d32576e4 100644 (file)
@@ -1460,7 +1460,7 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
        mutex_unlock(&state->lock);
 
        v4l2_dbg(1, s5c73m3_dbg, sd, "%s: Booting %s (%d)\n",
-                __func__, ret ? "failed" : "succeded", ret);
+                __func__, ret ? "failed" : "succeeded", ret);
 
        return ret;
 }
index 9d2c0865224609504ab1a9b9302cb99d53086e85..9dfa516f694471660f9de431c948ae279ed07bb9 100644 (file)
@@ -393,7 +393,7 @@ struct s5c73m3 {
 
        /* External master clock frequency */
        u32 mclk_frequency;
-       /* Video bus type - MIPI-CSI2/paralell */
+       /* Video bus type - MIPI-CSI2/parallel */
        enum v4l2_mbus_type bus_type;
 
        const struct s5c73m3_frame_size *sensor_pix_size[2];
index 637d026345271c154f4af2da7a53bde6adbcae94..afdbcb045ceece64685db171dac9699d8a7dfc49 100644 (file)
@@ -1699,7 +1699,7 @@ static void saa711x_write_platform_data(struct saa711x_state *state,
  * the analog demod.
  * If the tuner is not found, it returns -ENODEV.
  * If auto-detection is disabled and the tuner doesn't match what it was
- *     requred, it returns -EINVAL and fills 'name'.
+ *     required, it returns -EINVAL and fills 'name'.
  * If the chip is found, it returns the chip ID and fills 'name'.
  */
 static int saa711x_detect_chip(struct i2c_client *client,
index 0a5c5d4fedd6e375b34a1848f3b646a6577bd97d..d2daa6a8f27245b88f69d832b2f2537ab716b0f9 100644 (file)
@@ -642,7 +642,7 @@ static const struct ov5642_datafmt
 static int reg_read(struct i2c_client *client, u16 reg, u8 *val)
 {
        int ret;
-       /* We have 16-bit i2c addresses - care for endianess */
+       /* We have 16-bit i2c addresses - care for endianness */
        unsigned char data[2] = { reg >> 8, reg & 0xff };
 
        ret = i2c_master_send(client, data, 2);
index 42276d93624cada191b30eb7e3ca7ad40fb923fa..ed9ae8875348b6abdd226e3026e4b1d6f117c12f 100644 (file)
@@ -83,7 +83,8 @@ static int ths7303_write(struct v4l2_subdev *sd, u8 reg, u8 val)
 }
 
 /* following function is used to set ths7303 */
-int ths7303_setval(struct v4l2_subdev *sd, enum ths7303_filter_mode mode)
+static int ths7303_setval(struct v4l2_subdev *sd,
+                         enum ths7303_filter_mode mode)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct ths7303_state *state = to_state(sd);
index 3f584a7d0781b9860aad6b6bb9f6ddef4ad2b449..bee7946faa7cc2ba28a690e219cd0c5dcf89ff3b 100644 (file)
@@ -130,12 +130,10 @@ static int wm8775_s_routing(struct v4l2_subdev *sd,
                return -EINVAL;
        }
        state->input = input;
-       if (!v4l2_ctrl_g_ctrl(state->mute))
+       if (v4l2_ctrl_g_ctrl(state->mute))
                return 0;
        if (!v4l2_ctrl_g_ctrl(state->vol))
                return 0;
-       if (!v4l2_ctrl_g_ctrl(state->bal))
-               return 0;
        wm8775_set_audio(sd, 1);
        return 0;
 }
index a3b1ee9c00d7152405e9ea0e71549f350194692e..92a06fd858652acddff2dd65ce07dee560445df1 100644 (file)
@@ -4182,7 +4182,8 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
        }
        btv->std = V4L2_STD_PAL;
        init_irqreg(btv);
-       v4l2_ctrl_handler_setup(hdl);
+       if (!bttv_tvcards[btv->c.type].no_video)
+               v4l2_ctrl_handler_setup(hdl);
        if (hdl->error) {
                result = hdl->error;
                goto fail2;
index 2767c64df0c87f9c044aca755a63fbfd0c75adf3..57f4688ea55bdf2488eb14dc523d4a4c542a2609 100644 (file)
@@ -262,7 +262,7 @@ struct cx18_options {
 };
 
 /* per-mdl bit flags */
-#define CX18_F_M_NEED_SWAP  0  /* mdl buffer data must be endianess swapped */
+#define CX18_F_M_NEED_SWAP  0  /* mdl buffer data must be endianness swapped */
 
 /* per-stream, s_flags */
 #define CX18_F_S_CLAIMED       3       /* this stream is claimed */
index e3fc2c71808abbd0746cc7d9faabdfc14b9c583f..95666eee7b277026f3c1154a78361212653130b9 100644 (file)
@@ -427,7 +427,7 @@ int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
        cx_write(MC417_RWD, regval);
 
        /* Transition RD to effect read transaction across bus.
-        * Transtion 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)?
+        * Transition 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)?
         * Should it be 0x9000 -> 0xF000 (also why is RDY being set, its
         * input only...)
         */
index 8164d74b46a4590af0db79f56bd8c41bacead624..655d6854a8d7fa165502c711bf6c83a017cc16be 100644 (file)
@@ -401,7 +401,7 @@ static int pluto_hw_init(struct pluto *pluto)
        /* set automatic LED control by FPGA */
        pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED);
 
-       /* set data endianess */
+       /* set data endianness */
 #ifdef __LITTLE_ENDIAN
        pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END);
 #else
index 57ef5456f1e87e9cc042ec8dc05cdb07192bc15d..1bf06970ca3e8e180cb6a2f20d732c983af820b2 100644 (file)
@@ -1354,9 +1354,11 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
                if (fw_debug) {
                        dev->kthread = kthread_run(saa7164_thread_function, dev,
                                "saa7164 debug");
-                       if (!dev->kthread)
+                       if (IS_ERR(dev->kthread)) {
+                               dev->kthread = NULL;
                                printk(KERN_ERR "%s() Failed to create "
                                        "debug kernel thread\n", __func__);
+                       }
                }
 
        } /* != BOARD_UNKNOWN */
index bd72fb97fea5ab05924c4eeb4f5452534f3c3f46..61f3dbcc259f40f8a0f6f2b4bfa9b52ed6bf24ee 100644 (file)
@@ -1434,7 +1434,7 @@ static void coda_buf_queue(struct vb2_buffer *vb)
        if (q_data->fourcc == V4L2_PIX_FMT_H264 &&
            vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
                /*
-                * For backwards compatiblity, queuing an empty buffer marks
+                * For backwards compatibility, queuing an empty buffer marks
                 * the stream end
                 */
                if (vb2_get_plane_payload(vb, 0) == 0)
index 3d66d88ea3a191911ce72a22a8198602d7640e35..f7915695c9073d37ca10da947c29891b8d0e45d5 100644 (file)
@@ -1039,7 +1039,7 @@ static int fimc_runtime_resume(struct device *dev)
 
        dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
 
-       /* Enable clocks and perform basic initalization */
+       /* Enable clocks and perform basic initialization */
        clk_enable(fimc->clock[CLK_GATE]);
        fimc_hw_reset(fimc);
 
index 7a4ee4c0449deea95dc86e82a85af8412a1d5aad..c1bce170df6fbce44d519a498bf6d19694389306 100644 (file)
@@ -759,7 +759,7 @@ static int fimc_md_register_platform_entity(struct fimc_md *fmd,
                goto dev_unlock;
 
        drvdata = dev_get_drvdata(dev);
-       /* Some subdev didn't probe succesfully id drvdata is NULL */
+       /* Some subdev didn't probe successfully id drvdata is NULL */
        if (drvdata) {
                switch (plat_entity) {
                case IDX_FIMC:
index 3458fa0e2fd537916270fd9fbb0908d2b1610821..60589c2b1c66e11cc11c1c0f5d873c01bcf9c079 100644 (file)
@@ -142,12 +142,6 @@ static int mmpcam_power_up(struct mcam_camera *mcam)
        struct mmp_camera *cam = mcam_to_cam(mcam);
        struct mmp_camera_platform_data *pdata;
 
-       if (mcam->bus_type == V4L2_MBUS_CSI2) {
-               cam->mipi_clk = devm_clk_get(mcam->dev, "mipi");
-               if ((IS_ERR(cam->mipi_clk) && mcam->dphy[2] == 0))
-                       return PTR_ERR(cam->mipi_clk);
-       }
-
 /*
  * Turn on power and clocks to the controller.
  */
@@ -186,12 +180,6 @@ static void mmpcam_power_down(struct mcam_camera *mcam)
        gpio_set_value(pdata->sensor_power_gpio, 0);
        gpio_set_value(pdata->sensor_reset_gpio, 0);
 
-       if (mcam->bus_type == V4L2_MBUS_CSI2 && !IS_ERR(cam->mipi_clk)) {
-               if (cam->mipi_clk)
-                       devm_clk_put(mcam->dev, cam->mipi_clk);
-               cam->mipi_clk = NULL;
-       }
-
        mcam_clk_disable(mcam);
 }
 
@@ -292,8 +280,9 @@ void mmpcam_calc_dphy(struct mcam_camera *mcam)
                return;
 
        /* get the escape clk, this is hard coded */
+       clk_prepare_enable(cam->mipi_clk);
        tx_clk_esc = (clk_get_rate(cam->mipi_clk) / 1000000) / 12;
-
+       clk_disable_unprepare(cam->mipi_clk);
        /*
         * dphy[2] - CSI2_DPHY6:
         * bit 0 ~ bit 7: CK Term Enable
@@ -325,19 +314,6 @@ static irqreturn_t mmpcam_irq(int irq, void *data)
        return IRQ_RETVAL(handled);
 }
 
-static void mcam_deinit_clk(struct mcam_camera *mcam)
-{
-       unsigned int i;
-
-       for (i = 0; i < NR_MCAM_CLK; i++) {
-               if (!IS_ERR(mcam->clk[i])) {
-                       if (mcam->clk[i])
-                               devm_clk_put(mcam->dev, mcam->clk[i]);
-               }
-               mcam->clk[i] = NULL;
-       }
-}
-
 static void mcam_init_clk(struct mcam_camera *mcam)
 {
        unsigned int i;
@@ -371,7 +347,6 @@ static int mmpcam_probe(struct platform_device *pdev)
        if (cam == NULL)
                return -ENOMEM;
        cam->pdev = pdev;
-       cam->mipi_clk = NULL;
        INIT_LIST_HEAD(&cam->devlist);
 
        mcam = &cam->mcam;
@@ -387,6 +362,11 @@ static int mmpcam_probe(struct platform_device *pdev)
        mcam->mclk_div = pdata->mclk_div;
        mcam->bus_type = pdata->bus_type;
        mcam->dphy = pdata->dphy;
+       if (mcam->bus_type == V4L2_MBUS_CSI2) {
+               cam->mipi_clk = devm_clk_get(mcam->dev, "mipi");
+               if ((IS_ERR(cam->mipi_clk) && mcam->dphy[2] == 0))
+                       return PTR_ERR(cam->mipi_clk);
+       }
        mcam->mipi_enabled = false;
        mcam->lane = pdata->lane;
        mcam->chip_id = MCAM_ARMADA610;
@@ -444,7 +424,7 @@ static int mmpcam_probe(struct platform_device *pdev)
         */
        ret = mmpcam_power_up(mcam);
        if (ret)
-               goto out_deinit_clk;
+               return ret;
        ret = mccic_register(mcam);
        if (ret)
                goto out_power_down;
@@ -469,8 +449,6 @@ out_unregister:
        mccic_shutdown(mcam);
 out_power_down:
        mmpcam_power_down(mcam);
-out_deinit_clk:
-       mcam_deinit_clk(mcam);
        return ret;
 }
 
@@ -478,18 +456,11 @@ out_deinit_clk:
 static int mmpcam_remove(struct mmp_camera *cam)
 {
        struct mcam_camera *mcam = &cam->mcam;
-       struct mmp_camera_platform_data *pdata;
 
        mmpcam_remove_device(cam);
        mccic_shutdown(mcam);
        mmpcam_power_down(mcam);
-       pdata = cam->pdev->dev.platform_data;
-       gpio_free(pdata->sensor_reset_gpio);
-       gpio_free(pdata->sensor_power_gpio);
        mcam_deinit_clk(mcam);
-       iounmap(cam->power_regs);
-       iounmap(mcam->regs);
-       kfree(cam);
        return 0;
 }
 
index 1c3608039663e281d23541f17aedcbce044c87fb..561bce8ffb1b57c87dd1b45bbae6cbf7c2b479c1 100644 (file)
@@ -1673,7 +1673,7 @@ void omap3isp_print_status(struct isp_device *isp)
  * ISP clocks get disabled in suspend(). Similarly, the clocks are reenabled in
  * resume(), and the the pipelines are restarted in complete().
  *
- * TODO: PM dependencies between the ISP and sensors are not modeled explicitly
+ * TODO: PM dependencies between the ISP and sensors are not modelled explicitly
  * yet.
  */
 static int isp_pm_prepare(struct device *dev)
index 9319e93599ae5731241b58535583bc1a04b77e73..6ccc3f8c122add705d7338d0656ac744331823fb 100644 (file)
 #define S5P_FIMV_R2H_CMD_EDFU_INIT_RET         16
 #define S5P_FIMV_R2H_CMD_ERR_RET               32
 
-/* Dummy definition for MFCv6 compatibilty */
+/* Dummy definition for MFCv6 compatibility */
 #define S5P_FIMV_CODEC_H264_MVC_DEC            -1
 #define S5P_FIMV_R2H_CMD_FIELD_DONE_RET                -1
 #define S5P_FIMV_MFC_RESET                     -1
index 5f2c4ad6c2cb3427835ed2f40ec9ba5432ae3221..e46067a5785307ac7a1381bd8a8babd8e4ec4fc2 100644 (file)
@@ -239,7 +239,7 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
        frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev);
 
        /* Copy timestamp / timecode from decoded src to dst and set
-          appropraite flags */
+          appropriate flags */
        src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
        list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
                if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) {
@@ -428,7 +428,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev,
                case MFCINST_FINISHING:
                case MFCINST_FINISHED:
                case MFCINST_RUNNING:
-                       /* It is higly probable that an error occured
+                       /* It is highly probable that an error occurred
                         * while decoding a frame */
                        clear_work_bit(ctx);
                        ctx->state = MFCINST_ERROR;
@@ -611,7 +611,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
        mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err);
        switch (reason) {
        case S5P_MFC_R2H_CMD_ERR_RET:
-               /* An error has occured */
+               /* An error has occurred */
                if (ctx->state == MFCINST_RUNNING &&
                        s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) >=
                                dev->warn_start)
@@ -840,7 +840,7 @@ static int s5p_mfc_open(struct file *file)
        mutex_unlock(&dev->mfc_mutex);
        mfc_debug_leave();
        return ret;
-       /* Deinit when failure occured */
+       /* Deinit when failure occurred */
 err_queue_init:
        if (dev->num_inst == 1)
                s5p_mfc_deinit_hw(dev);
@@ -881,14 +881,14 @@ static int s5p_mfc_release(struct file *file)
        /* Mark context as idle */
        clear_work_bit_irqsave(ctx);
        /* If instance was initialised then
-        * return instance and free reosurces */
+        * return instance and free resources */
        if (ctx->inst_no != MFC_NO_INSTANCE_SET) {
                mfc_debug(2, "Has to free instance\n");
                ctx->state = MFCINST_RETURN_INST;
                set_work_bit_irqsave(ctx);
                s5p_mfc_clean_ctx_int_flags(ctx);
                s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
-               /* Wait until instance is returned or timeout occured */
+               /* Wait until instance is returned or timeout occurred */
                if (s5p_mfc_wait_for_done_ctx
                    (ctx, S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)) {
                        s5p_mfc_clock_off();
index 7cab6849fb5b73d9463c591b4b24eaffcae48bae..2475a3c9a0a62ab27330a347865530466d209e0d 100644 (file)
@@ -69,7 +69,7 @@ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
 
        } else {
                /* In this case bank2 can point to the same address as bank1.
-                * Firmware will always occupy the beggining of this area so it is
+                * Firmware will always occupy the beginning of this area so it is
                 * impossible having a video frame buffer with zero address. */
                dev->bank2 = dev->bank1;
        }
index 04e6490a45befbae453d55ef0a86be0bb32497d2..fb2acc53112a47201be7ec785057cdb491eabffc 100644 (file)
@@ -65,7 +65,7 @@ struct mxr_format {
        int num_subframes;
        /** specifies to which subframe belong given plane */
        int plane2subframe[MXR_MAX_PLANES];
-       /** internal code, driver dependant */
+       /** internal code, driver dependent */
        unsigned long cookie;
 };
 
index 641b1f071e06a2b74796f030ddfdcdc80644179b..81b97db111d8506a1c28df84a86ce4181f6ddccb 100644 (file)
@@ -528,7 +528,7 @@ static int mxr_s_dv_timings(struct file *file, void *fh,
        mutex_lock(&mdev->mutex);
 
        /* timings change cannot be done while there is an entity
-        * dependant on output configuration
+        * dependent on output configuration
         */
        if (mdev->n_output > 0) {
                mutex_unlock(&mdev->mutex);
@@ -585,7 +585,7 @@ static int mxr_s_std(struct file *file, void *fh, v4l2_std_id norm)
        mutex_lock(&mdev->mutex);
 
        /* standard change cannot be done while there is an entity
-        * dependant on output configuration
+        * dependent on output configuration
         */
        if (mdev->n_output > 0) {
                mutex_unlock(&mdev->mutex);
index 6769193c7c7bbeef27f723e98760f73ece8d0219..74ce8b6b79fa91c80644e0646996397befd325cc 100644 (file)
@@ -1495,7 +1495,7 @@ static int omap1_cam_set_bus_param(struct soc_camera_device *icd)
        if (ctrlclock & LCLK_EN)
                CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
 
-       /* select bus endianess */
+       /* select bus endianness */
        xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
        fmt = xlate->host_fmt;
 
index 1d3f1196519669cca0509c1972bdb320d2d35ad1..2d4e73b45c5e3b05d7e4615f6f6fd0d46bd56656 100644 (file)
@@ -1108,7 +1108,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
        return 0;
 }
 
-/* timeperframe is arbitrary and continous */
+/* timeperframe is arbitrary and continuous */
 static int vidioc_enum_frameintervals(struct file *file, void *priv,
                                             struct v4l2_frmivalenum *fival)
 {
@@ -1125,7 +1125,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
 
        fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
 
-       /* fill in stepwise (step=1.0 is requred by V4L2 spec) */
+       /* fill in stepwise (step=1.0 is required by V4L2 spec) */
        fival->stepwise.min  = tpf_min;
        fival->stepwise.max  = tpf_max;
        fival->stepwise.step = (struct v4l2_fract) {1, 1};
index 1c9e771aa15c7bb40b5a8a1de25d66b2b108c528..d16bf0f41e247bd69e3af1ebdc31e0309861e0fd 100644 (file)
@@ -323,7 +323,7 @@ static void vsp1_clocks_disable(struct vsp1_device *vsp1)
  * Increment the VSP1 reference count and initialize the device if the first
  * reference is taken.
  *
- * Return a pointer to the VSP1 device or NULL if an error occured.
+ * Return a pointer to the VSP1 device or NULL if an error occurred.
  */
 struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1)
 {
index 714c53ef6c11b19d48304405f363f750b26547d2..4b0ac07af662c2bca05c6534ecb52bfc15730c74 100644 (file)
@@ -1026,8 +1026,10 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
 
        /* ... and the buffers queue... */
        video->alloc_ctx = vb2_dma_contig_init_ctx(video->vsp1->dev);
-       if (IS_ERR(video->alloc_ctx))
+       if (IS_ERR(video->alloc_ctx)) {
+               ret = PTR_ERR(video->alloc_ctx);
                goto error;
+       }
 
        video->queue.type = video->type;
        video->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
index 3db8a8cfe1a87f4eb80e9c22950bbcac93b7daed..050b3bb96fecc13a15f05d3f294147200954e8dd 100644 (file)
@@ -271,8 +271,7 @@ static void shark_unregister_leds(struct shark_device *shark)
        cancel_work_sync(&shark->led_work);
 }
 
-#ifdef CONFIG_PM
-static void shark_resume_leds(struct shark_device *shark)
+static inline void shark_resume_leds(struct shark_device *shark)
 {
        if (test_bit(BLUE_IS_PULSE, &shark->brightness_new))
                set_bit(BLUE_PULSE_LED, &shark->brightness_new);
@@ -281,7 +280,6 @@ static void shark_resume_leds(struct shark_device *shark)
        set_bit(RED_LED, &shark->brightness_new);
        schedule_work(&shark->led_work);
 }
-#endif
 #else
 static int shark_register_leds(struct shark_device *shark, struct device *dev)
 {
index d86d90dab8bf880666a05ca0463aa83fc62f77de..8654e0dc5c95376aa7140498e10af342b955d15a 100644 (file)
@@ -237,8 +237,7 @@ static void shark_unregister_leds(struct shark_device *shark)
        cancel_work_sync(&shark->led_work);
 }
 
-#ifdef CONFIG_PM
-static void shark_resume_leds(struct shark_device *shark)
+static inline void shark_resume_leds(struct shark_device *shark)
 {
        int i;
 
@@ -247,7 +246,6 @@ static void shark_resume_leds(struct shark_device *shark)
 
        schedule_work(&shark->led_work);
 }
-#endif
 #else
 static int shark_register_leds(struct shark_device *shark, struct device *dev)
 {
index 9c9084cb99f7dd1fde0800f0325c58584edd9e19..2fd9009f86633e74b4752472f5db2829daf6d9ce 100644 (file)
@@ -268,8 +268,8 @@ struct si476x_radio;
  *
  * @tune_freq: Tune chip to a specific frequency
  * @seek_start: Star station seeking
- * @rsq_status: Get Recieved Signal Quality(RSQ) status
- * @rds_blckcnt: Get recived RDS blocks count
+ * @rsq_status: Get Received Signal Quality(RSQ) status
+ * @rds_blckcnt: Get received RDS blocks count
  * @phase_diversity: Change phase diversity mode of the tuner
  * @phase_div_status: Get phase diversity mode status
  * @acf_status: Get the status of Automatically Controlled
index 036e2f54f4db4b1bc5c6f574e19ccde1960da9b5..3ed1f5669f791b9d3015bb91efd80ba2fa82d0c0 100644 (file)
@@ -356,7 +356,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
                   So we keep it as-is. */
                return -EINVAL;
        }
-       clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
+       freq = clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
        tea5764_power_up(radio);
        tea5764_tune(radio, (freq * 125) / 2);
        return 0;
index 69e3245a58a0cbfcc1d333d390a30aa45e4c70d8..a9319a24c7efe1290efbc5b309bb719584cf7b5f 100644 (file)
@@ -112,7 +112,7 @@ static int tef6862_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequen
        if (f->tuner != 0)
                return -EINVAL;
 
-       clamp(freq, TEF6862_LO_FREQ, TEF6862_HI_FREQ);
+       freq = clamp(freq, TEF6862_LO_FREQ, TEF6862_HI_FREQ);
        pll = 1964 + ((freq - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
        i2cmsg[0] = (MSA_MODE_PRESET << MSA_MODE_SHIFT) | WM_SUB_PLLM;
        i2cmsg[1] = (pll >> 8) & 0xff;
index 72e3fa652481671cff04e2c06a1478d21fb0ffb6..f329485c6629b038ff2aee825edff86c82189328 100644 (file)
@@ -1370,7 +1370,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
         * 0x68nnnnB7 to 0x6AnnnnB7, the left mouse button generates
         * 0x688301b7 and the right one 0x688481b7. All other keys generate
         * 0x2nnnnnnn. Position coordinate is encoded in buf[1] and buf[2] with
-        * reversed endianess. Extract direction from buffer, rotate endianess,
+        * reversed endianness. Extract direction from buffer, rotate endianness,
         * adjust sign and feed the values into stabilize(). The resulting codes
         * will be 0x01008000, 0x01007F00, which match the newer devices.
         */
index 094484fac94cdbe52f7832f140f87895e922e631..a5d4f883d053a7b0ebca0543ac82d29d216ec26a 100644 (file)
@@ -118,7 +118,7 @@ static int debug;
 #define RR3_IR_IO_LENGTH_FUZZ  0x04
 /* Timeout for end of signal detection */
 #define RR3_IR_IO_SIG_TIMEOUT  0x05
-/* Minumum value for pause recognition. */
+/* Minimum value for pause recognition. */
 #define RR3_IR_IO_MIN_PAUSE    0x06
 
 /* Clock freq. of EZ-USB chip */
index 2e1a02e360ff0cd7279fed8ca20b80a3ee0b8ad8..20cca405bf452c46195ebbbadb37c8a535e85d0b 100644 (file)
@@ -1195,7 +1195,7 @@ static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
  *   DNC Output is selected, the other is always off)
  *
  * @state:     ptr to mt2063_state structure
- * @Mode:      desired reciever delivery system
+ * @Mode:      desired receiver delivery system
  *
  * Note: Register cache must be valid for it to work
  */
@@ -2119,7 +2119,7 @@ static int mt2063_set_analog_params(struct dvb_frontend *fe,
 
 /*
  * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
- * So, the amount of the needed bandwith is given by:
+ * So, the amount of the needed bandwidth is given by:
  *     Bw = Symbol_rate * (1 + 0.15)
  * As such, the maximum symbol rate supported by 6 MHz is given by:
  *     max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
index 74dc46a71f64555c07bb67be9ee09facf822ad41..7e4798783db733cc139e557444f12d4bddb820b5 100644 (file)
 #define V4L2_STD_A2            (V4L2_STD_A2_A    | V4L2_STD_A2_B)
 #define V4L2_STD_NICAM         (V4L2_STD_NICAM_A | V4L2_STD_NICAM_B)
 
-/* To preserve backward compatibilty,
+/* To preserve backward compatibility,
    (std & V4L2_STD_AUDIO) = 0 means that ALL audio stds are supported
  */
 
index e9d017bea377069da087751404e75f86b081c7cd..528cce958a82c4a67c91ea0c52841364db36f7d4 100644 (file)
@@ -1412,8 +1412,8 @@ err_v4l2:
        usb_set_intfdata(interface, NULL);
 err_if:
        usb_put_dev(udev);
-       kfree(dev);
        clear_bit(dev->devno, &cx231xx_devused);
+       kfree(dev);
        return retval;
 }
 
index c8fcd78425bd228ca4374daf94fdbf4ed1c0c17a..798565c4bb3e254c35897efd3ed3f895f634a859 100644 (file)
@@ -1534,6 +1534,8 @@ static const struct usb_device_id af9035_id_table[] = {
        /* XXX: that same ID [0ccd:0099] is used by af9015 driver too */
        { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x0099,
                &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05,
+               &af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) },
        { }
 };
 MODULE_DEVICE_TABLE(usb, af9035_id_table);
index 2627553f7de1f90c262f2d234d1d1faa9288f45f..08240e498451a55810e4bd00a75df73d0c1a607e 100644 (file)
@@ -266,7 +266,7 @@ static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
        struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
        int err;
 
-       /* exit if we didnt initialize the driver yet */
+       /* exit if we didn't initialize the driver yet */
        if (!state->chip_id) {
                mxl_debug("driver not yet initialized, exit.");
                goto fail;
@@ -322,7 +322,7 @@ static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
        struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
        int err;
 
-       /* exit if we didnt initialize the driver yet */
+       /* exit if we didn't initialize the driver yet */
        if (!state->chip_id) {
                mxl_debug("driver not yet initialized, exit.");
                goto fail;
index 40832a1aef6c71c0df2eaf51ffdea327bafe18da..98d24aefb640f80e12d6dd720f872273c71e6276 100644 (file)
@@ -102,7 +102,7 @@ static int technisat_usb2_i2c_access(struct usb_device *udev,
        if (rxlen > 62) {
                err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
                                device_addr);
-               txlen = 62;
+               rxlen = 62;
        }
 
        b[0] = I2C_SPEED_100KHZ_BIT;
index fc5d60efd4abe99f19acbafff7b83879da5ff3ac..dd19c9ff76e0f9a159c6630320814c89e9e83d5a 100644 (file)
@@ -1664,8 +1664,8 @@ static int em28xx_v4l2_close(struct file *filp)
 
        em28xx_videodbg("users=%d\n", dev->users);
 
-       mutex_lock(&dev->lock);
        vb2_fop_release(filp);
+       mutex_lock(&dev->lock);
 
        if (dev->users == 1) {
                /* the device is already disconnect,
index cb1e64ca59c9259b59ca1aaaaea036b6bd2c5fa0..cea8d7f51c3cc9430af956066d87b045b453c062 100644 (file)
@@ -438,7 +438,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
        s32 nToSkip =
                sd->swapRB * (gspca_dev->cam.cam_mode[mode].bytesperline + 1);
 
-       /* Test only against 0202h, so endianess does not matter */
+       /* Test only against 0202h, so endianness does not matter */
        switch (*(s16 *) data) {
        case 0x0202:            /* End of frame, start a new one */
                gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
index cd79c180f67b87e84689a8a162b4962bf5691cde..07529e5a0c5605186b3aa619b6b89d06cf98bc45 100644 (file)
@@ -416,7 +416,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 #if IS_ENABLED(CONFIG_INPUT)
 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
                        u8 *data,               /* interrupt packet data */
-                       int len)                /* interrput packet length */
+                       int len)                /* interrupt packet length */
 {
        int ret = -EINVAL;
 
index a9150964356329d93ea136e151c0d7f0aebf8590..2fd1c5e31a0f2692a1d59dd88c72cbee74e61054 100644 (file)
@@ -874,7 +874,7 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
 #if IS_ENABLED(CONFIG_INPUT)
 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
                        u8 *data,               /* interrupt packet data */
-                       int len)                /* interrput packet length */
+                       int len)                /* interrupt packet length */
 {
        int ret = -EINVAL;
        u8 data0, data1;
index 1fc80af2a18907e57d54eac3f58481ada0f3cda7..48234c9a8b6c3e4b4b927eb654ddb0009aa3d8ba 100644 (file)
@@ -361,6 +361,9 @@ static void stk1135_configure_clock(struct gspca_dev *gspca_dev)
 
        /* set serial interface clock divider (30MHz/0x1f*16+2) = 60240 kHz) */
        reg_w(gspca_dev, STK1135_REG_SICTL + 2, 0x1f);
+
+       /* wait a while for sensor to catch up */
+       udelay(1000);
 }
 
 static void stk1135_camera_disable(struct gspca_dev *gspca_dev)
index 9c0827631b9c105658575ed52e754fd1efa0c740..7f94ec74282e3ea42b0c423130419b038a5e3edd 100644 (file)
@@ -139,7 +139,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
        struct sd *sd = (struct sd *) gspca_dev;
        struct cam *cam = &gspca_dev->cam;
 
-       /* Give the camera some time to settle, otherwise initalization will
+       /* Give the camera some time to settle, otherwise initialization will
           fail on hotplug, and yes it really needs a full second. */
        msleep(1000);
 
index a517d185febed4590bbb5f58306aa4e4a2c4f0f1..46c9f2229a18675c6a1ca39528dab2196937c0c5 100644 (file)
@@ -1027,6 +1027,7 @@ static const struct usb_device_id device_table[] = {
        {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
        {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
        {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
+       {USB_DEVICE(0x06d6, 0x0041), BS(SPCA504B, 0)},
        {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
        {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
        {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
index 7b95d8e88a20240305a8817b72c3459d80a5adc6..d3e1b6d8bf494f79d449c38c96be5d022ab61043 100644 (file)
@@ -6905,7 +6905,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
 #if IS_ENABLED(CONFIG_INPUT)
 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
                        u8 *data,               /* interrupt packet data */
-                       int len)                /* interrput packet length */
+                       int len)                /* interrupt packet length */
 {
        if (len == 8 && data[4] == 1) {
                input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
index 77bbf788965953bbc67f8fa8b3ab18ccbe5806d8..78c9bc8e7f561744364a6de94f4aeaae382dd077 100644 (file)
@@ -1039,7 +1039,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        /* Set the leds off */
        pwc_set_leds(pdev, 0, 0);
 
-       /* Setup intial videomode */
+       /* Setup initial videomode */
        rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
                                V4L2_PIX_FMT_YUV420, 30, &compression, 1);
        if (rc)
index 8a505a90d3189a59876a916507ae50b6e11a0ed9..6222a4ab1e00bfff2d58d7816145bdae58fe4059 100644 (file)
 #define USBTV_ISOC_TRANSFERS   16
 #define USBTV_ISOC_PACKETS     8
 
-#define USBTV_WIDTH            720
-#define USBTV_HEIGHT           480
-
 #define USBTV_CHUNK_SIZE       256
 #define USBTV_CHUNK            240
-#define USBTV_CHUNKS           (USBTV_WIDTH * USBTV_HEIGHT \
-                                       / 4 / USBTV_CHUNK)
 
 /* Chunk header. */
 #define USBTV_MAGIC_OK(chunk)  ((be32_to_cpu(chunk[0]) & 0xff000000) \
 #define USBTV_ODD(chunk)       ((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15)
 #define USBTV_CHUNK_NO(chunk)  (be32_to_cpu(chunk[0]) & 0x00000fff)
 
+#define USBTV_TV_STD  (V4L2_STD_525_60 | V4L2_STD_PAL)
+
+/* parameters for supported TV norms */
+struct usbtv_norm_params {
+       v4l2_std_id norm;
+       int cap_width, cap_height;
+};
+
+static struct usbtv_norm_params norm_params[] = {
+       {
+               .norm = V4L2_STD_525_60,
+               .cap_width = 720,
+               .cap_height = 480,
+       },
+       {
+               .norm = V4L2_STD_PAL,
+               .cap_width = 720,
+               .cap_height = 576,
+       }
+};
+
 /* A single videobuf2 frame buffer. */
 struct usbtv_buf {
        struct vb2_buffer vb;
@@ -94,11 +110,38 @@ struct usbtv {
                USBTV_COMPOSITE_INPUT,
                USBTV_SVIDEO_INPUT,
        } input;
+       v4l2_std_id norm;
+       int width, height;
+       int n_chunks;
        int iso_size;
        unsigned int sequence;
        struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
 };
 
+static int usbtv_configure_for_norm(struct usbtv *usbtv, v4l2_std_id norm)
+{
+       int i, ret = 0;
+       struct usbtv_norm_params *params = NULL;
+
+       for (i = 0; i < ARRAY_SIZE(norm_params); i++) {
+               if (norm_params[i].norm & norm) {
+                       params = &norm_params[i];
+                       break;
+               }
+       }
+
+       if (params) {
+               usbtv->width = params->cap_width;
+               usbtv->height = params->cap_height;
+               usbtv->n_chunks = usbtv->width * usbtv->height
+                                               / 4 / USBTV_CHUNK;
+               usbtv->norm = params->norm;
+       } else
+               ret = -EINVAL;
+
+       return ret;
+}
+
 static int usbtv_set_regs(struct usbtv *usbtv, const u16 regs[][2], int size)
 {
        int ret;
@@ -158,6 +201,57 @@ static int usbtv_select_input(struct usbtv *usbtv, int input)
        return ret;
 }
 
+static int usbtv_select_norm(struct usbtv *usbtv, v4l2_std_id norm)
+{
+       int ret;
+       static const u16 pal[][2] = {
+               { USBTV_BASE + 0x001a, 0x0068 },
+               { USBTV_BASE + 0x010e, 0x0072 },
+               { USBTV_BASE + 0x010f, 0x00a2 },
+               { USBTV_BASE + 0x0112, 0x00b0 },
+               { USBTV_BASE + 0x0117, 0x0001 },
+               { USBTV_BASE + 0x0118, 0x002c },
+               { USBTV_BASE + 0x012d, 0x0010 },
+               { USBTV_BASE + 0x012f, 0x0020 },
+               { USBTV_BASE + 0x024f, 0x0002 },
+               { USBTV_BASE + 0x0254, 0x0059 },
+               { USBTV_BASE + 0x025a, 0x0016 },
+               { USBTV_BASE + 0x025b, 0x0035 },
+               { USBTV_BASE + 0x0263, 0x0017 },
+               { USBTV_BASE + 0x0266, 0x0016 },
+               { USBTV_BASE + 0x0267, 0x0036 }
+       };
+
+       static const u16 ntsc[][2] = {
+               { USBTV_BASE + 0x001a, 0x0079 },
+               { USBTV_BASE + 0x010e, 0x0068 },
+               { USBTV_BASE + 0x010f, 0x009c },
+               { USBTV_BASE + 0x0112, 0x00f0 },
+               { USBTV_BASE + 0x0117, 0x0000 },
+               { USBTV_BASE + 0x0118, 0x00fc },
+               { USBTV_BASE + 0x012d, 0x0004 },
+               { USBTV_BASE + 0x012f, 0x0008 },
+               { USBTV_BASE + 0x024f, 0x0001 },
+               { USBTV_BASE + 0x0254, 0x005f },
+               { USBTV_BASE + 0x025a, 0x0012 },
+               { USBTV_BASE + 0x025b, 0x0001 },
+               { USBTV_BASE + 0x0263, 0x001c },
+               { USBTV_BASE + 0x0266, 0x0011 },
+               { USBTV_BASE + 0x0267, 0x0005 }
+       };
+
+       ret = usbtv_configure_for_norm(usbtv, norm);
+
+       if (!ret) {
+               if (norm & V4L2_STD_525_60)
+                       ret = usbtv_set_regs(usbtv, ntsc, ARRAY_SIZE(ntsc));
+               else if (norm & V4L2_STD_PAL)
+                       ret = usbtv_set_regs(usbtv, pal, ARRAY_SIZE(pal));
+       }
+
+       return ret;
+}
+
 static int usbtv_setup_capture(struct usbtv *usbtv)
 {
        int ret;
@@ -225,26 +319,11 @@ static int usbtv_setup_capture(struct usbtv *usbtv)
 
                { USBTV_BASE + 0x0284, 0x0088 },
                { USBTV_BASE + 0x0003, 0x0004 },
-               { USBTV_BASE + 0x001a, 0x0079 },
                { USBTV_BASE + 0x0100, 0x00d3 },
-               { USBTV_BASE + 0x010e, 0x0068 },
-               { USBTV_BASE + 0x010f, 0x009c },
-               { USBTV_BASE + 0x0112, 0x00f0 },
                { USBTV_BASE + 0x0115, 0x0015 },
-               { USBTV_BASE + 0x0117, 0x0000 },
-               { USBTV_BASE + 0x0118, 0x00fc },
-               { USBTV_BASE + 0x012d, 0x0004 },
-               { USBTV_BASE + 0x012f, 0x0008 },
                { USBTV_BASE + 0x0220, 0x002e },
                { USBTV_BASE + 0x0225, 0x0008 },
                { USBTV_BASE + 0x024e, 0x0002 },
-               { USBTV_BASE + 0x024f, 0x0001 },
-               { USBTV_BASE + 0x0254, 0x005f },
-               { USBTV_BASE + 0x025a, 0x0012 },
-               { USBTV_BASE + 0x025b, 0x0001 },
-               { USBTV_BASE + 0x0263, 0x001c },
-               { USBTV_BASE + 0x0266, 0x0011 },
-               { USBTV_BASE + 0x0267, 0x0005 },
                { USBTV_BASE + 0x024e, 0x0002 },
                { USBTV_BASE + 0x024f, 0x0002 },
        };
@@ -253,6 +332,10 @@ static int usbtv_setup_capture(struct usbtv *usbtv)
        if (ret)
                return ret;
 
+       ret = usbtv_select_norm(usbtv, usbtv->norm);
+       if (ret)
+               return ret;
+
        ret = usbtv_select_input(usbtv, usbtv->input);
        if (ret)
                return ret;
@@ -296,7 +379,7 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
        frame_id = USBTV_FRAME_ID(chunk);
        odd = USBTV_ODD(chunk);
        chunk_no = USBTV_CHUNK_NO(chunk);
-       if (chunk_no >= USBTV_CHUNKS)
+       if (chunk_no >= usbtv->n_chunks)
                return;
 
        /* Beginning of a frame. */
@@ -324,10 +407,10 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
        usbtv->chunks_done++;
 
        /* Last chunk in a frame, signalling an end */
-       if (odd && chunk_no == USBTV_CHUNKS-1) {
+       if (odd && chunk_no == usbtv->n_chunks-1) {
                int size = vb2_plane_size(&buf->vb, 0);
                enum vb2_buffer_state state = usbtv->chunks_done ==
-                                               USBTV_CHUNKS ?
+                                               usbtv->n_chunks ?
                                                VB2_BUF_STATE_DONE :
                                                VB2_BUF_STATE_ERROR;
 
@@ -500,6 +583,8 @@ static int usbtv_querycap(struct file *file, void *priv,
 static int usbtv_enum_input(struct file *file, void *priv,
                                        struct v4l2_input *i)
 {
+       struct usbtv *dev = video_drvdata(file);
+
        switch (i->index) {
        case USBTV_COMPOSITE_INPUT:
                strlcpy(i->name, "Composite", sizeof(i->name));
@@ -512,7 +597,7 @@ static int usbtv_enum_input(struct file *file, void *priv,
        }
 
        i->type = V4L2_INPUT_TYPE_CAMERA;
-       i->std = V4L2_STD_525_60;
+       i->std = dev->vdev.tvnorms;
        return 0;
 }
 
@@ -531,23 +616,37 @@ static int usbtv_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int usbtv_fmt_vid_cap(struct file *file, void *priv,
                                        struct v4l2_format *f)
 {
-       f->fmt.pix.width = USBTV_WIDTH;
-       f->fmt.pix.height = USBTV_HEIGHT;
+       struct usbtv *usbtv = video_drvdata(file);
+
+       f->fmt.pix.width = usbtv->width;
+       f->fmt.pix.height = usbtv->height;
        f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
        f->fmt.pix.field = V4L2_FIELD_INTERLACED;
-       f->fmt.pix.bytesperline = USBTV_WIDTH * 2;
+       f->fmt.pix.bytesperline = usbtv->width * 2;
        f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height);
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.priv = 0;
+
        return 0;
 }
 
 static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm)
 {
-       *norm = V4L2_STD_525_60;
+       struct usbtv *usbtv = video_drvdata(file);
+       *norm = usbtv->norm;
        return 0;
 }
 
+static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)
+{
+       int ret = -EINVAL;
+       struct usbtv *usbtv = video_drvdata(file);
+
+       if ((norm & V4L2_STD_525_60) || (norm & V4L2_STD_PAL))
+               ret = usbtv_select_norm(usbtv, norm);
+
+       return ret;
+}
+
 static int usbtv_g_input(struct file *file, void *priv, unsigned int *i)
 {
        struct usbtv *usbtv = video_drvdata(file);
@@ -561,13 +660,6 @@ static int usbtv_s_input(struct file *file, void *priv, unsigned int i)
        return usbtv_select_input(usbtv, i);
 }
 
-static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)
-{
-       if (norm & V4L2_STD_525_60)
-               return 0;
-       return -EINVAL;
-}
-
 struct v4l2_ioctl_ops usbtv_ioctl_ops = {
        .vidioc_querycap = usbtv_querycap,
        .vidioc_enum_input = usbtv_enum_input,
@@ -604,10 +696,12 @@ static int usbtv_queue_setup(struct vb2_queue *vq,
        const struct v4l2_format *v4l_fmt, unsigned int *nbuffers,
        unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
 {
+       struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
        if (*nbuffers < 2)
                *nbuffers = 2;
        *nplanes = 1;
-       sizes[0] = USBTV_WIDTH * USBTV_HEIGHT / 2 * sizeof(u32);
+       sizes[0] = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32);
 
        return 0;
 }
@@ -690,7 +784,11 @@ static int usbtv_probe(struct usb_interface *intf,
                return -ENOMEM;
        usbtv->dev = dev;
        usbtv->udev = usb_get_dev(interface_to_usbdev(intf));
+
        usbtv->iso_size = size;
+
+       (void)usbtv_configure_for_norm(usbtv, V4L2_STD_525_60);
+
        spin_lock_init(&usbtv->buflock);
        mutex_init(&usbtv->v4l2_lock);
        mutex_init(&usbtv->vb2q_lock);
@@ -727,7 +825,7 @@ static int usbtv_probe(struct usb_interface *intf,
        usbtv->vdev.release = video_device_release_empty;
        usbtv->vdev.fops = &usbtv_fops;
        usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops;
-       usbtv->vdev.tvnorms = V4L2_STD_525_60;
+       usbtv->vdev.tvnorms = USBTV_TV_STD;
        usbtv->vdev.queue = &usbtv->vb2q;
        usbtv->vdev.lock = &usbtv->v4l2_lock;
        set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags);
index 899cb6d1c4a4a74a68cae01dbea51de5befc821e..898c208889cd2d55dd5a22522a2d06340eb0891d 100644 (file)
@@ -556,7 +556,7 @@ static u16 uvc_video_clock_host_sof(const struct uvc_clock_sample *sample)
  *
  * SOF = ((SOF2 - SOF1) * PTS + SOF1 * STC2 - SOF2 * STC1) / (STC2 - STC1)   (1)
  *
- * to avoid loosing precision in the division. Similarly, the host timestamp is
+ * to avoid losing precision in the division. Similarly, the host timestamp is
  * computed with
  *
  * TS = ((TS2 - TS1) * PTS + TS1 * SOF2 - TS2 * SOF1) / (SOF2 - SOF1)       (2)
index 60dcc0f3b32e7b445352b455d377f5b2b794b4fb..fb46790d0eca795d5e411c54bf7129d96e61d3e9 100644 (file)
@@ -420,7 +420,7 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
                "Advanced Simple",
                "Core",
                "Simple Scalable",
-               "Advanced Coding Efficency",
+               "Advanced Coding Efficiency",
                NULL,
        };
 
index b19b306c8f7f533d3112db441f692e57bd76638d..57ba131f08ad9f19d899870f8d7ecf8998170f8a 100644 (file)
@@ -1824,8 +1824,8 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
                return -EINVAL;
        }
 
-       if (eb->flags & ~O_CLOEXEC) {
-               dprintk(1, "Queue does support only O_CLOEXEC flag\n");
+       if (eb->flags & ~(O_CLOEXEC | O_ACCMODE)) {
+               dprintk(1, "Queue does support only O_CLOEXEC and access mode flags\n");
                return -EINVAL;
        }
 
@@ -1848,14 +1848,14 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
 
        vb_plane = &vb->planes[eb->plane];
 
-       dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+       dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE);
        if (IS_ERR_OR_NULL(dbuf)) {
                dprintk(1, "Failed to export buffer %d, plane %d\n",
                        eb->index, eb->plane);
                return -EINVAL;
        }
 
-       ret = dma_buf_fd(dbuf, eb->flags);
+       ret = dma_buf_fd(dbuf, eb->flags & ~O_ACCMODE);
        if (ret < 0) {
                dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
                        eb->index, eb->plane, ret);
index 646f08f4f504c05ae37dd95cbc1fe8333705e658..33d3871d1e131dce9a2f1d8392020dce5b8ff799 100644 (file)
@@ -393,7 +393,7 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
        return sgt;
 }
 
-static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
+static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
 {
        struct vb2_dc_buf *buf = buf_priv;
        struct dma_buf *dbuf;
@@ -404,7 +404,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
        if (WARN_ON(!buf->sgt_base))
                return NULL;
 
-       dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, 0);
+       dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, flags);
        if (IS_ERR(dbuf))
                return NULL;
 
index dd239bdbfcb4a0877db2ab49aa3c27a81eec7dd1..00d339c361fc0ecbd0b9b086e8c5756d28983d77 100644 (file)
@@ -2235,10 +2235,10 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        }
 
        /* do we need to support multiple segments? */
-       if (bio_segments(req->bio) > 1 || bio_segments(rsp->bio) > 1) {
-               printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
-                   ioc->name, __func__, bio_segments(req->bio), blk_rq_bytes(req),
-                   bio_segments(rsp->bio), blk_rq_bytes(rsp));
+       if (bio_multiple_segments(req->bio) ||
+           bio_multiple_segments(rsp->bio)) {
+               printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n",
+                   ioc->name, __func__, blk_rq_bytes(req), blk_rq_bytes(rsp));
                return -EINVAL;
        }
 
index a65447d65605fe7d7539082322a70cceae9c18c7..7dca1e640970a0dfb7f28ad8909c1f3e4d7d26e4 100644 (file)
@@ -148,7 +148,7 @@ static struct resource onkey_resources[] = {
         },
 };
 
-static struct mfd_cell onkey_devs[] = {
+static const struct mfd_cell onkey_devs[] = {
        {
         .name = "88pm80x-onkey",
         .num_resources = 1,
@@ -157,7 +157,7 @@ static struct mfd_cell onkey_devs[] = {
         },
 };
 
-static struct mfd_cell regulator_devs[] = {
+static const struct mfd_cell regulator_devs[] = {
        {
         .name = "88pm80x-regulator",
         .id = -1,
index 8a5b6ffb5afb6fbedbd8a1364a879890a6ebfba5..64751c2a1ace8fc2f90e59c1a1ca404776aa04d0 100644 (file)
@@ -77,7 +77,7 @@ static struct resource codec_resources[] = {
         },
 };
 
-static struct mfd_cell codec_devs[] = {
+static const struct mfd_cell codec_devs[] = {
        {
         .name = "88pm80x-codec",
         .num_resources = ARRAY_SIZE(codec_resources),
index 62a60caa5d1fe7eb583cb208fef9b96a5b0dd8f0..e54a6fd2a5bd41634d364b2fd4a74ba5ca288626 100644 (file)
@@ -32,7 +32,7 @@ config MFD_AS3722
        select MFD_CORE
        select REGMAP_I2C
        select REGMAP_IRQ
-       depends on I2C && OF
+       depends on I2C=y && OF
        help
          The ams AS3722 is a compact system PMU suitable for mobile phones,
          tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down
@@ -321,6 +321,19 @@ config MFD_88PM860X
          select individual components like voltage regulators, RTC and
          battery-charger under the corresponding menus.
 
+config MFD_MAX14577
+       bool "Maxim Semiconductor MAX14577 MUIC + Charger Support"
+       depends on I2C=y
+       select MFD_CORE
+       select REGMAP_I2C
+       select IRQ_DOMAIN
+       help
+         Say yes here to support for Maxim Semiconductor MAX14577.
+         This is a Micro-USB IC with Charger controls on chip.
+         This driver provides common support for accessing the device;
+         additional drivers must be enabled in order to use the functionality
+         of the device.
+
 config MFD_MAX77686
        bool "Maxim Semiconductor MAX77686 PMIC Support"
        depends on I2C=y
index 8a28dc90fe785033452a1740973f34883abbe0de..2e18b05017d9cc3029b040ebb48a74f8ef1d9eae 100644 (file)
@@ -110,6 +110,7 @@ obj-$(CONFIG_MFD_DA9055)    += da9055.o
 da9063-objs                    := da9063-core.o da9063-irq.o da9063-i2c.o
 obj-$(CONFIG_MFD_DA9063)       += da9063.o
 
+obj-$(CONFIG_MFD_MAX14577)     += max14577.o
 obj-$(CONFIG_MFD_MAX77686)     += max77686.o max77686-irq.o
 obj-$(CONFIG_MFD_MAX77693)     += max77693.o max77693-irq.o
 obj-$(CONFIG_MFD_MAX8907)      += max8907.o
index b6c2cdc76091aa2ff78b8d1d17e3c7b6e6d1dbd0..6788064ed899d1407978375d03e51a41fa412de9 100644 (file)
@@ -1017,7 +1017,7 @@ static struct resource ab8500_temp_resources[] = {
        },
 };
 
-static struct mfd_cell ab8500_bm_devs[] = {
+static const struct mfd_cell ab8500_bm_devs[] = {
        {
                .name = "ab8500-charger",
                .of_compatible = "stericsson,ab8500-charger",
@@ -1052,7 +1052,7 @@ static struct mfd_cell ab8500_bm_devs[] = {
        },
 };
 
-static struct mfd_cell ab8500_devs[] = {
+static const struct mfd_cell ab8500_devs[] = {
 #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
@@ -1143,7 +1143,7 @@ static struct mfd_cell ab8500_devs[] = {
        },
 };
 
-static struct mfd_cell ab9540_devs[] = {
+static const struct mfd_cell ab9540_devs[] = {
 #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
@@ -1214,7 +1214,7 @@ static struct mfd_cell ab9540_devs[] = {
 };
 
 /* Device list for ab8505  */
-static struct mfd_cell ab8505_devs[] = {
+static const struct mfd_cell ab8505_devs[] = {
 #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
@@ -1275,7 +1275,7 @@ static struct mfd_cell ab8505_devs[] = {
        },
 };
 
-static struct mfd_cell ab8540_devs[] = {
+static const struct mfd_cell ab8540_devs[] = {
 #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
@@ -1339,7 +1339,7 @@ static struct mfd_cell ab8540_devs[] = {
        },
 };
 
-static struct mfd_cell ab8540_cut1_devs[] = {
+static const struct mfd_cell ab8540_cut1_devs[] = {
        {
                .name = "ab8500-rtc",
                .of_compatible = "stericsson,ab8500-rtc",
@@ -1348,7 +1348,7 @@ static struct mfd_cell ab8540_cut1_devs[] = {
        },
 };
 
-static struct mfd_cell ab8540_cut2_devs[] = {
+static const struct mfd_cell ab8540_cut2_devs[] = {
        {
                .name = "ab8540-rtc",
                .of_compatible = "stericsson,ab8540-rtc",
index e33e385af0a29e7930e4277984c640a1cf1db975..d1a22aae2df51cda0936a52dc58e9df66c493f7d 100644 (file)
@@ -1600,7 +1600,6 @@ static int ab8500_interrupts_print(struct seq_file *s, void *p)
 
        for (line = 0; line < num_interrupt_lines; line++) {
                struct irq_desc *desc = irq_to_desc(line + irq_first);
-               struct irqaction *action = desc->action;
 
                seq_printf(s, "%3i:  %6i %4i", line,
                           num_interrupts[line],
@@ -1608,7 +1607,9 @@ static int ab8500_interrupts_print(struct seq_file *s, void *p)
 
                if (desc && desc->name)
                        seq_printf(s, "-%-8s", desc->name);
-               if (action) {
+               if (desc && desc->action) {
+                       struct irqaction *action = desc->action;
+
                        seq_printf(s, "  %s", action->name);
                        while ((action = action->next) != NULL)
                                seq_printf(s, ", %s", action->name);
index 75e180ceecf3fac16f9a432ada482130624dfe01..a45aab9f6bb135e64c0f0a420f75ed2508e17e92 100644 (file)
@@ -565,7 +565,7 @@ static inline int arizona_of_get_core_pdata(struct arizona *arizona)
 }
 #endif
 
-static struct mfd_cell early_devs[] = {
+static const struct mfd_cell early_devs[] = {
        { .name = "arizona-ldo1" },
 };
 
@@ -577,7 +577,7 @@ static const char *wm5102_supplies[] = {
        "SPKVDDR",
 };
 
-static struct mfd_cell wm5102_devs[] = {
+static const struct mfd_cell wm5102_devs[] = {
        { .name = "arizona-micsupp" },
        { .name = "arizona-extcon" },
        { .name = "arizona-gpio" },
@@ -590,7 +590,7 @@ static struct mfd_cell wm5102_devs[] = {
        },
 };
 
-static struct mfd_cell wm5110_devs[] = {
+static const struct mfd_cell wm5110_devs[] = {
        { .name = "arizona-micsupp" },
        { .name = "arizona-extcon" },
        { .name = "arizona-gpio" },
@@ -609,7 +609,7 @@ static const char *wm8997_supplies[] = {
        "SPKVDD",
 };
 
-static struct mfd_cell wm8997_devs[] = {
+static const struct mfd_cell wm8997_devs[] = {
        { .name = "arizona-micsupp" },
        { .name = "arizona-extcon" },
        { .name = "arizona-gpio" },
index f161f2e00df7434ee8970584e76392af68304179..c71ff0af1547e573aacf17c6317e2e02224813f7 100644 (file)
@@ -54,7 +54,7 @@ static const struct resource as3722_adc_resource[] = {
        },
 };
 
-static struct mfd_cell as3722_devs[] = {
+static const struct mfd_cell as3722_devs[] = {
        {
                .name = "as3722-pinctrl",
        },
@@ -74,6 +74,9 @@ static struct mfd_cell as3722_devs[] = {
        {
                .name = "as3722-power-off",
        },
+       {
+               .name = "as3722-wdt",
+       },
 };
 
 static const struct regmap_irq as3722_irqs[] = {
index fa22154c84e49cfb6be58930339ea180b8be77b6..9f6294f2a0708ab6be063d4bfbc0f98ad1062fa5 100644 (file)
@@ -695,7 +695,7 @@ static int ds1wm_disable(struct platform_device *pdev)
        return 0;
 }
 
-static struct mfd_cell asic3_cell_ds1wm = {
+static const struct mfd_cell asic3_cell_ds1wm = {
        .name          = "ds1wm",
        .enable        = ds1wm_enable,
        .disable       = ds1wm_disable,
@@ -797,7 +797,7 @@ static int asic3_mmc_disable(struct platform_device *pdev)
        return 0;
 }
 
-static struct mfd_cell asic3_cell_mmc = {
+static const struct mfd_cell asic3_cell_mmc = {
        .name          = "tmio-mmc",
        .enable        = asic3_mmc_enable,
        .disable       = asic3_mmc_disable,
index 1f36885d674b07741a4f0374089f2cb04ed839e4..783fe2e73e1edd43344d3bb4c3b1fb09daf9cf3d 100644 (file)
@@ -84,7 +84,7 @@ static irqreturn_t ec_irq_thread(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static struct mfd_cell cros_devs[] = {
+static const struct mfd_cell cros_devs[] = {
        {
                .name = "cros-ec-keyb",
                .id = 1,
index 123044608b63dc5997f9cf921003814f9ac53f84..4f71be99a183713810c5d00e7f4eac480e006a58 100644 (file)
@@ -120,7 +120,7 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev,
        return ret;
 }
 
-static int cros_ec_probe_i2c(struct i2c_client *client,
+static int cros_ec_i2c_probe(struct i2c_client *client,
                             const struct i2c_device_id *dev_id)
 {
        struct device *dev = &client->dev;
@@ -150,7 +150,7 @@ static int cros_ec_probe_i2c(struct i2c_client *client,
        return 0;
 }
 
-static int cros_ec_remove_i2c(struct i2c_client *client)
+static int cros_ec_i2c_remove(struct i2c_client *client)
 {
        struct cros_ec_device *ec_dev = i2c_get_clientdata(client);
 
@@ -190,8 +190,8 @@ static struct i2c_driver cros_ec_driver = {
                .owner  = THIS_MODULE,
                .pm     = &cros_ec_i2c_pm_ops,
        },
-       .probe          = cros_ec_probe_i2c,
-       .remove         = cros_ec_remove_i2c,
+       .probe          = cros_ec_i2c_probe,
+       .remove         = cros_ec_i2c_remove,
        .id_table       = cros_ec_i2c_id,
 };
 
index 367ccb58ecb15a1954cf39e936c46bc5a4bf3498..5658ec48838f2603bd41be28d885b682848928cc 100644 (file)
 /*
   * Time between raising the SPI chip select (for the end of a
   * transaction) and dropping it again (for the next transaction).
-  * If we go too fast, the EC will miss the transaction. It seems
-  * that 50us is enough with the 16MHz STM32 EC.
+  * If we go too fast, the EC will miss the transaction. We know that we
+  * need at least 70 us with the 16 MHz STM32 EC, so go with 200 us to be
+  * safe.
   */
-#define EC_SPI_RECOVERY_TIME_NS        (50 * 1000)
+#define EC_SPI_RECOVERY_TIME_NS        (200 * 1000)
 
 /**
  * struct cros_ec_spi - information about a SPI-connected EC
@@ -75,7 +76,9 @@ static void debug_packet(struct device *dev, const char *name, u8 *ptr,
 
        dev_dbg(dev, "%s: ", name);
        for (i = 0; i < len; i++)
-               dev_cont(dev, " %02x", ptr[i]);
+               pr_cont(" %02x", ptr[i]);
+
+       pr_cont("\n");
 #endif
 }
 
@@ -281,7 +284,7 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
        return 0;
 }
 
-static int cros_ec_probe_spi(struct spi_device *spi)
+static int cros_ec_spi_probe(struct spi_device *spi)
 {
        struct device *dev = &spi->dev;
        struct cros_ec_device *ec_dev;
@@ -323,7 +326,7 @@ static int cros_ec_probe_spi(struct spi_device *spi)
        return 0;
 }
 
-static int cros_ec_remove_spi(struct spi_device *spi)
+static int cros_ec_spi_remove(struct spi_device *spi)
 {
        struct cros_ec_device *ec_dev;
 
@@ -364,8 +367,8 @@ static struct spi_driver cros_ec_driver_spi = {
                .owner  = THIS_MODULE,
                .pm     = &cros_ec_spi_pm_ops,
        },
-       .probe          = cros_ec_probe_spi,
-       .remove         = cros_ec_remove_spi,
+       .probe          = cros_ec_spi_probe,
+       .remove         = cros_ec_spi_remove,
        .id_table       = cros_ec_spi_id,
 };
 
index ea28a33576e45cd3c3df406a09264bd69a5c3298..25838f10b35b2d08c295e18b27ecf4155bb5f4ce 100644 (file)
@@ -427,7 +427,7 @@ int da9052_adc_read_temp(struct da9052 *da9052)
 }
 EXPORT_SYMBOL_GPL(da9052_adc_read_temp);
 
-static struct mfd_cell da9052_subdev_info[] = {
+static const struct mfd_cell da9052_subdev_info[] = {
        {
                .name = "da9052-regulator",
                .id = 1,
index d3670cd3c3c6c0e025c80ec940851ee5599037b1..caf8dcffd0ad403d6b239f9f0c3442ac1651aa2c 100644 (file)
@@ -294,7 +294,7 @@ static struct resource da9055_ld05_6_resource = {
        .flags = IORESOURCE_IRQ,
 };
 
-static struct mfd_cell da9055_devs[] = {
+static const struct mfd_cell da9055_devs[] = {
        {
                .of_compatible = "dialog,da9055-gpio",
                .name = "da9055-gpio",
index c9cf8d988406ff8ed4d01c23d5acd6793e3d06e4..26937cd010714b7c1c9e98877603616390b6e952 100644 (file)
@@ -75,7 +75,7 @@ static struct resource da9063_hwmon_resources[] = {
 };
 
 
-static struct mfd_cell da9063_devs[] = {
+static const struct mfd_cell da9063_devs[] = {
        {
                .name           = DA9063_DRVNAME_REGULATORS,
                .num_resources  = ARRAY_SIZE(da9063_regulators_resources),
index b9ce60c301de026bba38daf276e83773c44379ec..e43e6e821117a01aac56b8e4086fe783056977cd 100644 (file)
@@ -3070,7 +3070,7 @@ static struct db8500_thsens_platform_data db8500_thsens_data = {
        .num_trips = 4,
 };
 
-static struct mfd_cell common_prcmu_devs[] = {
+static const struct mfd_cell common_prcmu_devs[] = {
        {
                .name = "ux500_wdt",
                .platform_data = &db8500_wdt_pdata,
@@ -3079,7 +3079,7 @@ static struct mfd_cell common_prcmu_devs[] = {
        },
 };
 
-static struct mfd_cell db8500_prcmu_devs[] = {
+static const struct mfd_cell db8500_prcmu_devs[] = {
        {
                .name = "db8500-prcmu-regulators",
                .of_compatible = "stericsson,db8500-prcmu-regulator",
index 6bf92a507b9546b911e258037c2dba3ac391851b..e88d4f6fef4cb80b76bdea85498056e6b272874a 100644 (file)
@@ -114,7 +114,7 @@ static struct resource ds1wm_resources[] __initdata = {
        },
 };
 
-static struct mfd_cell ds1wm_cell __initdata = {
+static const struct mfd_cell ds1wm_cell __initconst = {
        .name          = "ds1wm",
        .enable        = ds1wm_enable,
        .disable       = ds1wm_disable,
index 9203d47cdbb1b4106e87ba91e4571cea54c55543..049fd23af54a58f85a51ae564ae2bdc49e3bcdd0 100644 (file)
@@ -178,7 +178,7 @@ static struct mfd_cell msic_devs[] = {
  * These devices appear only after the MSIC driver itself is initialized so
  * we can guarantee that the SCU IPC interface is ready.
  */
-static struct mfd_cell msic_other_devs[] = {
+static const struct mfd_cell msic_other_devs[] = {
        /* Audio codec in the MSIC */
        {
                .id                     = -1,
index 3c0e8cf6916bd0f9cdb040548b7b7919d3f49753..7a51c0d0d4f1f5ec23b323550424cec4ff6386a7 100644 (file)
@@ -181,7 +181,7 @@ static struct resource jz4740_battery_resources[] = {
        },
 };
 
-static struct mfd_cell jz4740_adc_cells[] = {
+static const struct mfd_cell jz4740_adc_cells[] = {
        {
                .id = 0,
                .name = "jz4740-hwmon",
index 0f1221911018b6d4fd4e558ff0df4996a4b70a10..a30bc15fe5ba5ac6a5b2a04a23a3a518ae2d2ba5 100644 (file)
@@ -71,7 +71,7 @@ static struct resource rtc_irqs[] = {
        },
 };
 
-static struct mfd_cell lp8788_devs[] = {
+static const struct mfd_cell lp8788_devs[] = {
        /* 4 bucks */
        MFD_DEV_WITH_ID(BUCK, 1),
        MFD_DEV_WITH_ID(BUCK, 2),
index da1c6566d93d2f755878d358a018835bd7cd1454..37edf9e989b066cbb1a8a667001ce4e655ac7c1c 100644 (file)
@@ -506,7 +506,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
                .iTCO_version = 2,
        },
        [LPC_WPT_LP] = {
-               .name = "Lynx Point_LP",
+               .name = "Wildcat Point_LP",
                .iTCO_version = 2,
        },
 };
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
new file mode 100644 (file)
index 0000000..1337c45
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * max14577.c - mfd core driver for the Maxim 14577
+ *
+ * Copyright (C) 2013 Samsung Electrnoics
+ * Chanwoo Choi <cw00.choi@samsung.com>
+ * Krzysztof Kozlowski <k.kozlowski@samsung.com>
+ *
+ * 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.
+ *
+ * This driver is based on max8997.c
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/max14577.h>
+#include <linux/mfd/max14577-private.h>
+
+static struct mfd_cell max14577_devs[] = {
+       { .name = "max14577-muic", },
+       {
+               .name = "max14577-regulator",
+               .of_compatible = "maxim,max14577-regulator",
+       },
+       { .name = "max14577-charger", },
+};
+
+static bool max14577_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case MAX14577_REG_INT1 ... MAX14577_REG_STATUS3:
+               return true;
+       default:
+               break;
+       }
+       return false;
+}
+
+static const struct regmap_config max14577_regmap_config = {
+       .reg_bits       = 8,
+       .val_bits       = 8,
+       .volatile_reg   = max14577_volatile_reg,
+       .max_register   = MAX14577_REG_END,
+};
+
+static const struct regmap_irq max14577_irqs[] = {
+       /* INT1 interrupts */
+       { .reg_offset = 0, .mask = INT1_ADC_MASK, },
+       { .reg_offset = 0, .mask = INT1_ADCLOW_MASK, },
+       { .reg_offset = 0, .mask = INT1_ADCERR_MASK, },
+       /* INT2 interrupts */
+       { .reg_offset = 1, .mask = INT2_CHGTYP_MASK, },
+       { .reg_offset = 1, .mask = INT2_CHGDETRUN_MASK, },
+       { .reg_offset = 1, .mask = INT2_DCDTMR_MASK, },
+       { .reg_offset = 1, .mask = INT2_DBCHG_MASK, },
+       { .reg_offset = 1, .mask = INT2_VBVOLT_MASK, },
+       /* INT3 interrupts */
+       { .reg_offset = 2, .mask = INT3_EOC_MASK, },
+       { .reg_offset = 2, .mask = INT3_CGMBC_MASK, },
+       { .reg_offset = 2, .mask = INT3_OVP_MASK, },
+       { .reg_offset = 2, .mask = INT3_MBCCHGERR_MASK, },
+};
+
+static const struct regmap_irq_chip max14577_irq_chip = {
+       .name                   = "max14577",
+       .status_base            = MAX14577_REG_INT1,
+       .mask_base              = MAX14577_REG_INTMASK1,
+       .mask_invert            = 1,
+       .num_regs               = 3,
+       .irqs                   = max14577_irqs,
+       .num_irqs               = ARRAY_SIZE(max14577_irqs),
+};
+
+static int max14577_i2c_probe(struct i2c_client *i2c,
+                             const struct i2c_device_id *id)
+{
+       struct max14577 *max14577;
+       struct max14577_platform_data *pdata = dev_get_platdata(&i2c->dev);
+       struct device_node *np = i2c->dev.of_node;
+       u8 reg_data;
+       int ret = 0;
+
+       if (np) {
+               pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+               if (!pdata)
+                       return -ENOMEM;
+               i2c->dev.platform_data = pdata;
+       }
+
+       if (!pdata) {
+               dev_err(&i2c->dev, "No platform data found: %ld\n",
+                               PTR_ERR(pdata));
+               return -EINVAL;
+       }
+
+       max14577 = devm_kzalloc(&i2c->dev, sizeof(*max14577), GFP_KERNEL);
+       if (!max14577)
+               return -ENOMEM;
+
+       i2c_set_clientdata(i2c, max14577);
+       max14577->dev = &i2c->dev;
+       max14577->i2c = i2c;
+       max14577->irq = i2c->irq;
+
+       max14577->regmap = devm_regmap_init_i2c(i2c, &max14577_regmap_config);
+       if (IS_ERR(max14577->regmap)) {
+               ret = PTR_ERR(max14577->regmap);
+               dev_err(max14577->dev, "Failed to allocate register map: %d\n",
+                               ret);
+               return ret;
+       }
+
+       ret = max14577_read_reg(max14577->regmap, MAX14577_REG_DEVICEID,
+                       &reg_data);
+       if (ret) {
+               dev_err(max14577->dev, "Device not found on this channel: %d\n",
+                               ret);
+               return ret;
+       }
+       max14577->vendor_id = ((reg_data & DEVID_VENDORID_MASK) >>
+                               DEVID_VENDORID_SHIFT);
+       max14577->device_id = ((reg_data & DEVID_DEVICEID_MASK) >>
+                               DEVID_DEVICEID_SHIFT);
+       dev_info(max14577->dev, "Device ID: 0x%x, vendor: 0x%x\n",
+                       max14577->device_id, max14577->vendor_id);
+
+       ret = regmap_add_irq_chip(max14577->regmap, max14577->irq,
+                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0,
+                                 &max14577_irq_chip,
+                                 &max14577->irq_data);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
+                               max14577->irq, ret);
+               return ret;
+       }
+
+       ret = mfd_add_devices(max14577->dev, -1, max14577_devs,
+                       ARRAY_SIZE(max14577_devs), NULL, 0,
+                       regmap_irq_get_domain(max14577->irq_data));
+       if (ret < 0)
+               goto err_mfd;
+
+       device_init_wakeup(max14577->dev, 1);
+
+       return 0;
+
+err_mfd:
+       regmap_del_irq_chip(max14577->irq, max14577->irq_data);
+
+       return ret;
+}
+
+static int max14577_i2c_remove(struct i2c_client *i2c)
+{
+       struct max14577 *max14577 = i2c_get_clientdata(i2c);
+
+       mfd_remove_devices(max14577->dev);
+       regmap_del_irq_chip(max14577->irq, max14577->irq_data);
+
+       return 0;
+}
+
+static const struct i2c_device_id max14577_i2c_id[] = {
+       { "max14577", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, max14577_i2c_id);
+
+static int max14577_suspend(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct max14577 *max14577 = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev)) {
+               enable_irq_wake(max14577->irq);
+               /*
+                * MUIC IRQ must be disabled during suspend if this is
+                * a wake up source because it will be handled before
+                * resuming I2C.
+                *
+                * When device is woken up from suspend (e.g. by ADC change),
+                * an interrupt occurs before resuming I2C bus controller.
+                * Interrupt handler tries to read registers but this read
+                * will fail because I2C is still suspended.
+                */
+               disable_irq(max14577->irq);
+       }
+
+       return 0;
+}
+
+static int max14577_resume(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct max14577 *max14577 = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev)) {
+               disable_irq_wake(max14577->irq);
+               enable_irq(max14577->irq);
+       }
+
+       return 0;
+}
+
+static struct of_device_id max14577_dt_match[] = {
+       { .compatible = "maxim,max14577", },
+       {},
+};
+
+static SIMPLE_DEV_PM_OPS(max14577_pm, max14577_suspend, max14577_resume);
+
+static struct i2c_driver max14577_i2c_driver = {
+       .driver = {
+               .name = "max14577",
+               .owner = THIS_MODULE,
+               .pm = &max14577_pm,
+               .of_match_table = of_match_ptr(max14577_dt_match),
+       },
+       .probe = max14577_i2c_probe,
+       .remove = max14577_i2c_remove,
+       .id_table = max14577_i2c_id,
+};
+
+static int __init max14577_i2c_init(void)
+{
+       return i2c_add_driver(&max14577_i2c_driver);
+}
+subsys_initcall(max14577_i2c_init);
+
+static void __exit max14577_i2c_exit(void)
+{
+       i2c_del_driver(&max14577_i2c_driver);
+}
+module_exit(max14577_i2c_exit);
+
+MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <k.kozlowski@samsung.com>");
+MODULE_DESCRIPTION("MAXIM 14577 multi-function core driver");
+MODULE_LICENSE("GPL");
index 34520cbe8afbd6e9f0daca77f4bbde41b93697a6..fb0848544b768ab3a0943ddfe984b29cfeca4b53 100644 (file)
@@ -35,7 +35,7 @@
 
 #define I2C_ADDR_RTC   (0x0C >> 1)
 
-static struct mfd_cell max77686_devs[] = {
+static const struct mfd_cell max77686_devs[] = {
        { .name = "max77686-pmic", },
        { .name = "max77686-rtc", },
        { .name = "max77686-clk", },
index 9f92463f4f7ecaca1b005a14e6cd59f7d38deb4a..a0093a839d4b6fcb397f474248ee7962b2952b5d 100644 (file)
@@ -41,7 +41,7 @@
 #define I2C_ADDR_MUIC  (0x4A >> 1)
 #define I2C_ADDR_HAPTIC        (0x90 >> 1)
 
-static struct mfd_cell max77693_devs[] = {
+static const struct mfd_cell max77693_devs[] = {
        { .name = "max77693-pmic", },
        { .name = "max77693-charger", },
        { .name = "max77693-flash", },
index 3bbfedc07f41c8e24d866120b64423374c629fa3..07740314b29d03acc8068dcc56addd989abca5d1 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
-static struct mfd_cell max8907_cells[] = {
+static const struct mfd_cell max8907_cells[] = {
        { .name = "max8907-regulator", },
        { .name = "max8907-rtc", },
 };
index f0cc40296d8ccc50fab35f0805023bdab6ebc54f..f3faf0c45dddf36d09d4b2d05641145a7ebe13f6 100644 (file)
@@ -45,7 +45,7 @@ static struct resource touch_resources[] = {
        },
 };
 
-static struct mfd_cell touch_devs[] = {
+static const struct mfd_cell touch_devs[] = {
        {
                .name           = "max8925-touch",
                .num_resources  = 1,
@@ -63,7 +63,7 @@ static struct resource power_supply_resources[] = {
        },
 };
 
-static struct mfd_cell power_devs[] = {
+static const struct mfd_cell power_devs[] = {
        {
                .name           = "max8925-power",
                .num_resources  = 1,
@@ -81,7 +81,7 @@ static struct resource rtc_resources[] = {
        },
 };
 
-static struct mfd_cell rtc_devs[] = {
+static const struct mfd_cell rtc_devs[] = {
        {
                .name           = "max8925-rtc",
                .num_resources  = 1,
@@ -104,7 +104,7 @@ static struct resource onkey_resources[] = {
        },
 };
 
-static struct mfd_cell onkey_devs[] = {
+static const struct mfd_cell onkey_devs[] = {
        {
                .name           = "max8925-onkey",
                .num_resources  = 2,
index 791aea3e96ce27622032a0c0fd1bc52ecd69203e..1b80e51c2e73622b11769c6ddec449be50cd9044 100644 (file)
@@ -40,7 +40,7 @@
 #define I2C_ADDR_RTC   (0x0C >> 1)
 #define I2C_ADDR_HAPTIC        (0x90 >> 1)
 
-static struct mfd_cell max8997_devs[] = {
+static const struct mfd_cell max8997_devs[] = {
        { .name = "max8997-pmic", },
        { .name = "max8997-rtc", },
        { .name = "max8997-battery", },
index fe6332dcabee891a27daed80e3ed2525e3b1caa8..f47eaa70eae076f172f4e72977f98dfe26e680da 100644 (file)
@@ -37,7 +37,7 @@
 
 #define RTC_I2C_ADDR           (0x0c >> 1)
 
-static struct mfd_cell max8998_devs[] = {
+static const struct mfd_cell max8998_devs[] = {
        {
                .name = "max8998-pmic",
        }, {
@@ -47,7 +47,7 @@ static struct mfd_cell max8998_devs[] = {
        },
 };
 
-static struct mfd_cell lp3974_devs[] = {
+static const struct mfd_cell lp3974_devs[] = {
        {
                .name = "lp3974-pmic",
        }, {
index 5f14ef6693c22abd073b62ea6114dab2b09d76b8..cbcc86d9b6e7f88045c287516ba68fa67c453bb6 100644 (file)
@@ -149,7 +149,6 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
                ret = PTR_ERR(mc13xxx->regmap);
                dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n",
                                ret);
-               spi_set_drvdata(spi, NULL);
                return ret;
        }
 
index 142650fdc0582e1d25f99480e4a2fb13e1e9bd23..90b630ccc8bc65fa7381439cd190274834c50153 100644 (file)
@@ -121,22 +121,22 @@ static u64 usbhs_dmamask = DMA_BIT_MASK(32);
 
 static inline void usbhs_write(void __iomem *base, u32 reg, u32 val)
 {
-       __raw_writel(val, base + reg);
+       writel_relaxed(val, base + reg);
 }
 
 static inline u32 usbhs_read(void __iomem *base, u32 reg)
 {
-       return __raw_readl(base + reg);
+       return readl_relaxed(base + reg);
 }
 
 static inline void usbhs_writeb(void __iomem *base, u8 reg, u8 val)
 {
-       __raw_writeb(val, base + reg);
+       writeb_relaxed(val, base + reg);
 }
 
 static inline u8 usbhs_readb(void __iomem *base, u8 reg)
 {
-       return __raw_readb(base + reg);
+       return readb_relaxed(base + reg);
 }
 
 /*-------------------------------------------------------------------------*/
index 0d946ae14453380e4abca019a09519627309c5b6..ee7468c1cb60e8ebbbeb0499fb7edc8f5958fe06 100644 (file)
@@ -121,22 +121,22 @@ static DEFINE_SPINLOCK(tll_lock); /* serialize access to tll_dev */
 
 static inline void usbtll_write(void __iomem *base, u32 reg, u32 val)
 {
-       __raw_writel(val, base + reg);
+       writel_relaxed(val, base + reg);
 }
 
 static inline u32 usbtll_read(void __iomem *base, u32 reg)
 {
-       return __raw_readl(base + reg);
+       return readl_relaxed(base + reg);
 }
 
 static inline void usbtll_writeb(void __iomem *base, u8 reg, u8 val)
 {
-       __raw_writeb(val, base + reg);
+       writeb_relaxed(val, base + reg);
 }
 
 static inline u8 usbtll_readb(void __iomem *base, u8 reg)
 {
-       return __raw_readb(base + reg);
+       return readb_relaxed(base + reg);
 }
 
 /*-------------------------------------------------------------------------*/
index 346330176afcd81ba9f6a294420db761e60ab908..df276ad9f40bfb32639c78b28ad7f2155e1f749f 100644 (file)
@@ -74,7 +74,7 @@ static struct deepsleep_control_data deepsleep_data[] = {
 #define EXT_PWR_REQ            \
        (RC5T583_EXT_PWRREQ1_CONTROL | RC5T583_EXT_PWRREQ2_CONTROL)
 
-static struct mfd_cell rc5t583_subdevs[] = {
+static const struct mfd_cell rc5t583_subdevs[] = {
        {.name = "rc5t583-gpio",},
        {.name = "rc5t583-regulator",},
        {.name = "rc5t583-rtc",      },
index 21b7bef73507cc969ae49074873f47b64b3ebe99..aab63ee043e3d7f623ab12fc2bd31c2def0f95cd 100644 (file)
@@ -56,7 +56,7 @@ static struct resource rdc321x_gpio_resources[] = {
        }
 };
 
-static struct mfd_cell rdc321x_sb_cells[] = {
+static const struct mfd_cell rdc321x_sb_cells[] = {
        {
                .name           = "rdc321x-wdt",
                .resources      = rdc321x_wdt_resource,
index a1830986eeb71006b9c693e0aab1bb5e25d98e81..c8f345f7e9a2b574c69d5c2d47fa3dbcf1390993 100644 (file)
@@ -55,7 +55,7 @@ static struct resource retu_pwrbutton_res[] = {
        },
 };
 
-static struct mfd_cell retu_devs[] = {
+static const struct mfd_cell retu_devs[] = {
        {
                .name           = "retu-wdt"
        },
@@ -94,7 +94,7 @@ static struct resource tahvo_usb_res[] = {
        },
 };
 
-static struct mfd_cell tahvo_devs[] = {
+static const struct mfd_cell tahvo_devs[] = {
        {
                .name           = "tahvo-usb",
                .resources      = tahvo_usb_res,
@@ -122,7 +122,7 @@ static const struct retu_data {
        char                    *chip_name;
        char                    *companion_name;
        struct regmap_irq_chip  *irq_chip;
-       struct mfd_cell         *children;
+       const struct mfd_cell   *children;
        int                     nchildren;
 } retu_data[] = {
        [0] = {
index 34c18fb8c0896b46f49de48b4d5631a5d780a811..3a20b47d065b30bbff41cc722dffd2fa730e2bf0 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/mfd/samsung/s5m8767.h>
 #include <linux/regmap.h>
 
-static struct mfd_cell s5m8751_devs[] = {
+static const struct mfd_cell s5m8751_devs[] = {
        {
                .name = "s5m8751-pmic",
        }, {
@@ -41,7 +41,7 @@ static struct mfd_cell s5m8751_devs[] = {
        },
 };
 
-static struct mfd_cell s5m8763_devs[] = {
+static const struct mfd_cell s5m8763_devs[] = {
        {
                .name = "s5m8763-pmic",
        }, {
@@ -51,7 +51,7 @@ static struct mfd_cell s5m8763_devs[] = {
        },
 };
 
-static struct mfd_cell s5m8767_devs[] = {
+static const struct mfd_cell s5m8767_devs[] = {
        {
                .name = "s5m8767-pmic",
        }, {
@@ -59,7 +59,7 @@ static struct mfd_cell s5m8767_devs[] = {
        },
 };
 
-static struct mfd_cell s2mps11_devs[] = {
+static const struct mfd_cell s2mps11_devs[] = {
        {
                .name = "s2mps11-pmic",
        }, {
@@ -134,12 +134,12 @@ static bool s5m8763_volatile(struct device *dev, unsigned int reg)
        }
 }
 
-static struct regmap_config sec_regmap_config = {
+static const struct regmap_config sec_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 };
 
-static struct regmap_config s2mps11_regmap_config = {
+static const struct regmap_config s2mps11_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 
@@ -148,7 +148,7 @@ static struct regmap_config s2mps11_regmap_config = {
        .cache_type = REGCACHE_FLAT,
 };
 
-static struct regmap_config s5m8763_regmap_config = {
+static const struct regmap_config s5m8763_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 
@@ -157,7 +157,7 @@ static struct regmap_config s5m8763_regmap_config = {
        .cache_type = REGCACHE_FLAT,
 };
 
-static struct regmap_config s5m8767_regmap_config = {
+static const struct regmap_config s5m8767_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 
@@ -309,6 +309,8 @@ static int sec_pmic_probe(struct i2c_client *i2c,
        if (ret)
                goto err;
 
+       device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
+
        return ret;
 
 err:
@@ -327,6 +329,43 @@ static int sec_pmic_remove(struct i2c_client *i2c)
        return 0;
 }
 
+static int sec_pmic_suspend(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev)) {
+               enable_irq_wake(sec_pmic->irq);
+               /*
+                * PMIC IRQ must be disabled during suspend for RTC alarm
+                * to work properly.
+                * When device is woken up from suspend by RTC Alarm, an
+                * interrupt occurs before resuming I2C bus controller.
+                * The interrupt is handled by regmap_irq_thread which tries
+                * to read RTC registers. This read fails (I2C is still
+                * suspended) and RTC Alarm interrupt is disabled.
+                */
+               disable_irq(sec_pmic->irq);
+       }
+
+       return 0;
+}
+
+static int sec_pmic_resume(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev)) {
+               disable_irq_wake(sec_pmic->irq);
+               enable_irq(sec_pmic->irq);
+       }
+
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
+
 static const struct i2c_device_id sec_pmic_id[] = {
        { "sec_pmic", 0 },
        { }
@@ -337,6 +376,7 @@ static struct i2c_driver sec_pmic_driver = {
        .driver = {
                   .name = "sec_pmic",
                   .owner = THIS_MODULE,
+                  .pm = &sec_pmic_pm_ops,
                   .of_match_table = of_match_ptr(sec_dt_match),
        },
        .probe = sec_pmic_probe,
index 0dd84e99081e9d30539ab96cccc255591a18be82..f3699748f04ec83f07493465e64e439b41c7ca51 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/mfd/samsung/s5m8763.h>
 #include <linux/mfd/samsung/s5m8767.h>
 
-static struct regmap_irq s2mps11_irqs[] = {
+static const struct regmap_irq s2mps11_irqs[] = {
        [S2MPS11_IRQ_PWRONF] = {
                .reg_offset = 0,
                .mask = S2MPS11_IRQ_PWRONF_MASK,
@@ -90,7 +90,7 @@ static struct regmap_irq s2mps11_irqs[] = {
 };
 
 
-static struct regmap_irq s5m8767_irqs[] = {
+static const struct regmap_irq s5m8767_irqs[] = {
        [S5M8767_IRQ_PWRR] = {
                .reg_offset = 0,
                .mask = S5M8767_IRQ_PWRR_MASK,
@@ -161,7 +161,7 @@ static struct regmap_irq s5m8767_irqs[] = {
        },
 };
 
-static struct regmap_irq s5m8763_irqs[] = {
+static const struct regmap_irq s5m8763_irqs[] = {
        [S5M8763_IRQ_DCINF] = {
                .reg_offset = 0,
                .mask = S5M8763_IRQ_DCINF_MASK,
@@ -236,7 +236,7 @@ static struct regmap_irq s5m8763_irqs[] = {
        },
 };
 
-static struct regmap_irq_chip s2mps11_irq_chip = {
+static const struct regmap_irq_chip s2mps11_irq_chip = {
        .name = "s2mps11",
        .irqs = s2mps11_irqs,
        .num_irqs = ARRAY_SIZE(s2mps11_irqs),
@@ -246,7 +246,7 @@ static struct regmap_irq_chip s2mps11_irq_chip = {
        .ack_base = S2MPS11_REG_INT1,
 };
 
-static struct regmap_irq_chip s5m8767_irq_chip = {
+static const struct regmap_irq_chip s5m8767_irq_chip = {
        .name = "s5m8767",
        .irqs = s5m8767_irqs,
        .num_irqs = ARRAY_SIZE(s5m8767_irqs),
@@ -256,7 +256,7 @@ static struct regmap_irq_chip s5m8767_irq_chip = {
        .ack_base = S5M8767_REG_INT1,
 };
 
-static struct regmap_irq_chip s5m8763_irq_chip = {
+static const struct regmap_irq_chip s5m8763_irq_chip = {
        .name = "s5m8763",
        .irqs = s5m8763_irqs,
        .num_irqs = ARRAY_SIZE(s5m8763_irqs),
index fff63a41862cf6bbb4acfac38496447a4137ad0a..42ccd05445133444e52be15c4d380de7b4915539 100644 (file)
@@ -297,14 +297,14 @@ static struct resource stmpe_gpio_resources[] = {
        },
 };
 
-static struct mfd_cell stmpe_gpio_cell = {
+static const struct mfd_cell stmpe_gpio_cell = {
        .name           = "stmpe-gpio",
        .of_compatible  = "st,stmpe-gpio",
        .resources      = stmpe_gpio_resources,
        .num_resources  = ARRAY_SIZE(stmpe_gpio_resources),
 };
 
-static struct mfd_cell stmpe_gpio_cell_noirq = {
+static const struct mfd_cell stmpe_gpio_cell_noirq = {
        .name           = "stmpe-gpio",
        .of_compatible  = "st,stmpe-gpio",
        /* gpio cell resources consist of an irq only so no resources here */
@@ -325,7 +325,7 @@ static struct resource stmpe_keypad_resources[] = {
        },
 };
 
-static struct mfd_cell stmpe_keypad_cell = {
+static const struct mfd_cell stmpe_keypad_cell = {
        .name           = "stmpe-keypad",
        .of_compatible  = "st,stmpe-keypad",
        .resources      = stmpe_keypad_resources,
@@ -409,7 +409,7 @@ static struct resource stmpe_ts_resources[] = {
        },
 };
 
-static struct mfd_cell stmpe_ts_cell = {
+static const struct mfd_cell stmpe_ts_cell = {
        .name           = "stmpe-ts",
        .of_compatible  = "st,stmpe-ts",
        .resources      = stmpe_ts_resources,
@@ -1064,7 +1064,7 @@ static int stmpe_chip_init(struct stmpe *stmpe)
        return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr);
 }
 
-static int stmpe_add_device(struct stmpe *stmpe, struct mfd_cell *cell)
+static int stmpe_add_device(struct stmpe *stmpe, const struct mfd_cell *cell)
 {
        return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
                               NULL, stmpe->irq_base, stmpe->domain);
index ff2b09ba8797cfc214d36fada42efe1f1b64a807..6639f1b0fef50525a6292a9cce9984dd7c05c836 100644 (file)
@@ -38,7 +38,7 @@ static inline void stmpe_dump_bytes(const char *str, const void *buf,
  *             enable and altfunc callbacks
  */
 struct stmpe_variant_block {
-       struct mfd_cell         *cell;
+       const struct mfd_cell   *cell;
        int                     irq;
        enum stmpe_block        block;
 };
index 87ea51dc6234a243021bce1682a213856c49128b..2cf636c267d9413f77e39d787b6a47496ce1859e 100644 (file)
@@ -155,7 +155,7 @@ static struct resource keypad_resources[] = {
        },
 };
 
-static struct mfd_cell tc3589x_dev_gpio[] = {
+static const struct mfd_cell tc3589x_dev_gpio[] = {
        {
                .name           = "tc3589x-gpio",
                .num_resources  = ARRAY_SIZE(gpio_resources),
@@ -164,7 +164,7 @@ static struct mfd_cell tc3589x_dev_gpio[] = {
        },
 };
 
-static struct mfd_cell tc3589x_dev_keypad[] = {
+static const struct mfd_cell tc3589x_dev_keypad[] = {
        {
                .name           = "tc3589x-keypad",
                .num_resources  = ARRAY_SIZE(keypad_resources),
index acd0f3a41044a5171cc0cfde9d03ad693fa9f48c..591a331d8d83b147fbc10fa23351d61a05aeaf9e 100644 (file)
@@ -126,7 +126,7 @@ static struct tmio_mmc_data tc6387xb_mmc_data = {
 
 /*--------------------------------------------------------------------------*/
 
-static struct mfd_cell tc6387xb_cells[] = {
+static const struct mfd_cell tc6387xb_cells[] = {
        [TC6387XB_CELL_MMC] = {
                .name = "tmio-mmc",
                .enable = tc6387xb_mmc_enable,
index 71e3e0c5bf730c7e8f3423619d9a2e2acc6fa27d..a5424579679cfcd7e0b835964557ea1188c58eaa 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/sched.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/ti_ssp.h>
 
@@ -409,7 +410,6 @@ static int ti_ssp_probe(struct platform_device *pdev)
                cells[id].id            = id;
                cells[id].name          = data->dev_name;
                cells[id].platform_data = data->pdata;
-               cells[id].data_size     = data->pdata_size;
        }
 
        error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL);
index dbb34f94e5e3fce2e0df7f18097930558069af2f..c6668ac70af3c0ff6e107e10ca8346202032b217 100644 (file)
@@ -374,7 +374,7 @@ static const struct resource timberdale_dma_resources[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar0_cfg0[] = {
+static const struct mfd_cell timberdale_cells_bar0_cfg0[] = {
        {
                .name = "timb-dma",
                .num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -431,7 +431,7 @@ static struct mfd_cell timberdale_cells_bar0_cfg0[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar0_cfg1[] = {
+static const struct mfd_cell timberdale_cells_bar0_cfg1[] = {
        {
                .name = "timb-dma",
                .num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -498,7 +498,7 @@ static struct mfd_cell timberdale_cells_bar0_cfg1[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar0_cfg2[] = {
+static const struct mfd_cell timberdale_cells_bar0_cfg2[] = {
        {
                .name = "timb-dma",
                .num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -548,7 +548,7 @@ static struct mfd_cell timberdale_cells_bar0_cfg2[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar0_cfg3[] = {
+static const struct mfd_cell timberdale_cells_bar0_cfg3[] = {
        {
                .name = "timb-dma",
                .num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -619,7 +619,7 @@ static const struct resource timberdale_sdhc_resources[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar1[] = {
+static const struct mfd_cell timberdale_cells_bar1[] = {
        {
                .name = "sdhci",
                .num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
@@ -627,7 +627,7 @@ static struct mfd_cell timberdale_cells_bar1[] = {
        },
 };
 
-static struct mfd_cell timberdale_cells_bar2[] = {
+static const struct mfd_cell timberdale_cells_bar2[] = {
        {
                .name = "sdhci",
                .num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
index a081b925d10b2debf94e28ea2c5c500081262309..3b27482a174fd14bae949ee284f76f4ac504a6fe 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps6507x.h>
 
-static struct mfd_cell tps6507x_devs[] = {
+static const struct mfd_cell tps6507x_devs[] = {
        {
                .name = "tps6507x-pmic",
        },
index e6f03a733879b063d670ecc2bd074ea28063ec18..ba1a25d758c12ed61d82aaea82501272fc34081a 100644 (file)
@@ -64,7 +64,7 @@ static struct resource charger_resources[] = {
        }
 };
 
-static struct mfd_cell tps65090s[] = {
+static const struct mfd_cell tps65090s[] = {
        {
                .name = "tps65090-pmic",
        },
index b7be0b29557599ab94c30ba4f16534c88eff030b..6939ae56c2e168d390a504af22767198b222b9f1 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps65217.h>
 
-static struct mfd_cell tps65217s[] = {
+static const struct mfd_cell tps65217s[] = {
        {
                .name = "tps65217-pmic",
        },
index ee61fd7c198da714c2dd56ba7be2bfe6da5a068d..d0e57934370f348241222d18781fe58df56b78c6 100644 (file)
@@ -103,7 +103,7 @@ static struct resource tps6586x_rtc_resources[] = {
        },
 };
 
-static struct mfd_cell tps6586x_cell[] = {
+static const struct mfd_cell tps6586x_cell[] = {
        {
                .name = "tps6586x-gpio",
        },
index c0f608e3ca9e5fc1fc0706666b8fcc4f89778567..1f142d76cbbc6fc03f44ead367c01a9b75f24c86 100644 (file)
@@ -36,7 +36,7 @@ static struct resource rtc_resources[] = {
        }
 };
 
-static struct mfd_cell tps65910s[] = {
+static const struct mfd_cell tps65910s[] = {
        {
                .name = "tps65910-gpio",
        },
index 925a044cbdf61740e3c54e0a481a9774587c652b..27a518e0eec6d04db1310e86f7ed678b4a762065 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps65912.h>
 
-static struct mfd_cell tps65912s[] = {
+static const struct mfd_cell tps65912s[] = {
        {
                .name = "tps65912-pmic",
        },
index f15ee6d5cfbf96fb97ef6f169528c624b09a2aba..ed6c5b0956e2387f09b213eba64879e2fc656fc7 100644 (file)
@@ -44,7 +44,7 @@ static struct resource tps80031_rtc_resources[] = {
 };
 
 /* TPS80031 sub mfd devices */
-static struct mfd_cell tps80031_cell[] = {
+static const struct mfd_cell tps80031_cell[] = {
        {
                .name = "tps80031-pmic",
        },
index af2a6703f34fa89d6a6c68397c91104ab768f6fe..e00f5340ed872089d31998ff39d6bb57842e731a 100644 (file)
@@ -37,7 +37,7 @@ static const struct usb_device_id vprbrd_table[] = {
 
 MODULE_DEVICE_TABLE(usb, vprbrd_table);
 
-static struct mfd_cell vprbrd_devs[] = {
+static const struct mfd_cell vprbrd_devs[] = {
        {
                .name = "viperboard-gpio",
        },
index 757ecc63338c19a7d7d75c85e4a185459fb3d3a0..5cd5661158bc6f4716fce4de4cb4e3b781c4a3e9 100644 (file)
@@ -60,7 +60,7 @@ static struct resource vx855_gpio_resources[] = {
        },
 };
 
-static struct mfd_cell vx855_cells[] = {
+static const struct mfd_cell vx855_cells[] = {
        {
                .name = "vx855_gpio",
                .num_resources = ARRAY_SIZE(vx855_gpio_resources),
index bf8b3b5ad1fe65d03eb067881599c5cbc1418a32..c24eff39184187f2cdd62000f29cce390da01091 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/mfd/arizona/core.h>
 #include <linux/mfd/arizona/registers.h>
+#include <linux/device.h>
 
 #include "arizona.h"
 
@@ -504,7 +505,7 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x000001AA, 0x0004 },    /* R426   - FLL2 GPIO Clock */
        { 0x00000200, 0x0006 },    /* R512   - Mic Charge Pump 1 */
        { 0x00000210, 0x0184 },    /* R528   - LDO1 Control 1 */
-       { 0x00000213, 0x0344 },    /* R531   - LDO2 Control 1 */
+       { 0x00000213, 0x03E4 },    /* R531   - LDO2 Control 1 */
        { 0x00000218, 0x01A6 },    /* R536   - Mic Bias Ctrl 1 */
        { 0x00000219, 0x01A6 },    /* R537   - Mic Bias Ctrl 2 */
        { 0x0000021A, 0x01A6 },    /* R538   - Mic Bias Ctrl 3 */
@@ -524,6 +525,7 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x00000300, 0x0000 },    /* R768   - Input Enables */
        { 0x00000308, 0x0000 },    /* R776   - Input Rate */
        { 0x00000309, 0x0022 },    /* R777   - Input Volume Ramp */
+       { 0x0000030C, 0x0002 },    /* R780   - HPF Control */
        { 0x00000310, 0x2080 },    /* R784   - IN1L Control */
        { 0x00000311, 0x0180 },    /* R785   - ADC Digital Volume 1L */
        { 0x00000312, 0x0000 },    /* R786   - DMIC1L Control */
@@ -545,6 +547,7 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x00000328, 0x2000 },    /* R808   - IN4L Control */
        { 0x00000329, 0x0180 },    /* R809   - ADC Digital Volume 4L */
        { 0x0000032A, 0x0000 },    /* R810   - DMIC4L Control */
+       { 0x0000032C, 0x0000 },    /* R812   - IN4R Control */
        { 0x0000032D, 0x0180 },    /* R813   - ADC Digital Volume 4R */
        { 0x0000032E, 0x0000 },    /* R814   - DMIC4R Control */
        { 0x00000400, 0x0000 },    /* R1024  - Output Enables 1 */
@@ -882,6 +885,38 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x0000074D, 0x0080 },    /* R1869  - AIF2TX2MIX Input 3 Volume */
        { 0x0000074E, 0x0000 },    /* R1870  - AIF2TX2MIX Input 4 Source */
        { 0x0000074F, 0x0080 },    /* R1871  - AIF2TX2MIX Input 4 Volume */
+       { 0x00000750, 0x0000 },    /* R1872  - AIF2TX3MIX Input 1 Source */
+       { 0x00000751, 0x0080 },    /* R1873  - AIF2TX3MIX Input 1 Volume */
+       { 0x00000752, 0x0000 },    /* R1874  - AIF2TX3MIX Input 2 Source */
+       { 0x00000753, 0x0080 },    /* R1875  - AIF2TX3MIX Input 2 Volume */
+       { 0x00000754, 0x0000 },    /* R1876  - AIF2TX3MIX Input 3 Source */
+       { 0x00000755, 0x0080 },    /* R1877  - AIF2TX3MIX Input 3 Volume */
+       { 0x00000756, 0x0000 },    /* R1878  - AIF2TX3MIX Input 4 Source */
+       { 0x00000757, 0x0080 },    /* R1879  - AIF2TX3MIX Input 4 Volume */
+       { 0x00000758, 0x0000 },    /* R1880  - AIF2TX4MIX Input 1 Source */
+       { 0x00000759, 0x0080 },    /* R1881  - AIF2TX4MIX Input 1 Volume */
+       { 0x0000075A, 0x0000 },    /* R1882  - AIF2TX4MIX Input 2 Source */
+       { 0x0000075B, 0x0080 },    /* R1883  - AIF2TX4MIX Input 2 Volume */
+       { 0x0000075C, 0x0000 },    /* R1884  - AIF2TX4MIX Input 3 Source */
+       { 0x0000075D, 0x0080 },    /* R1885  - AIF2TX4MIX Input 3 Volume */
+       { 0x0000075E, 0x0000 },    /* R1886  - AIF2TX4MIX Input 4 Source */
+       { 0x0000075F, 0x0080 },    /* R1887  - AIF2TX4MIX Input 4 Volume */
+       { 0x00000760, 0x0000 },    /* R1888  - AIF2TX5MIX Input 1 Source */
+       { 0x00000761, 0x0080 },    /* R1889  - AIF2TX5MIX Input 1 Volume */
+       { 0x00000762, 0x0000 },    /* R1890  - AIF2TX5MIX Input 2 Source */
+       { 0x00000763, 0x0080 },    /* R1891  - AIF2TX5MIX Input 2 Volume */
+       { 0x00000764, 0x0000 },    /* R1892  - AIF2TX5MIX Input 3 Source */
+       { 0x00000765, 0x0080 },    /* R1893  - AIF2TX5MIX Input 3 Volume */
+       { 0x00000766, 0x0000 },    /* R1894  - AIF2TX5MIX Input 4 Source */
+       { 0x00000767, 0x0080 },    /* R1895  - AIF2TX5MIX Input 4 Volume */
+       { 0x00000768, 0x0000 },    /* R1896  - AIF2TX6MIX Input 1 Source */
+       { 0x00000769, 0x0080 },    /* R1897  - AIF2TX6MIX Input 1 Volume */
+       { 0x0000076A, 0x0000 },    /* R1898  - AIF2TX6MIX Input 2 Source */
+       { 0x0000076B, 0x0080 },    /* R1899  - AIF2TX6MIX Input 2 Volume */
+       { 0x0000076C, 0x0000 },    /* R1900  - AIF2TX6MIX Input 3 Source */
+       { 0x0000076D, 0x0080 },    /* R1901  - AIF2TX6MIX Input 3 Volume */
+       { 0x0000076E, 0x0000 },    /* R1902  - AIF2TX6MIX Input 4 Source */
+       { 0x0000076F, 0x0080 },    /* R1903  - AIF2TX6MIX Input 4 Volume */
        { 0x00000780, 0x0000 },    /* R1920  - AIF3TX1MIX Input 1 Source */
        { 0x00000781, 0x0080 },    /* R1921  - AIF3TX1MIX Input 1 Volume */
        { 0x00000782, 0x0000 },    /* R1922  - AIF3TX1MIX Input 2 Source */
@@ -1342,6 +1377,64 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x00001404, 0x0000 },    /* R5124  - DSP4 Status 1 */
 };
 
+static bool wm5110_is_rev_b_adsp_memory(unsigned int reg)
+{
+       if ((reg >= 0x100000 && reg < 0x103000) ||
+           (reg >= 0x180000 && reg < 0x181000) ||
+           (reg >= 0x190000 && reg < 0x192000) ||
+           (reg >= 0x1a8000 && reg < 0x1a9000) ||
+           (reg >= 0x200000 && reg < 0x209000) ||
+           (reg >= 0x280000 && reg < 0x281000) ||
+           (reg >= 0x290000 && reg < 0x29a000) ||
+           (reg >= 0x2a8000 && reg < 0x2aa000) ||
+           (reg >= 0x300000 && reg < 0x30f000) ||
+           (reg >= 0x380000 && reg < 0x382000) ||
+           (reg >= 0x390000 && reg < 0x39e000) ||
+           (reg >= 0x3a8000 && reg < 0x3b6000) ||
+           (reg >= 0x400000 && reg < 0x403000) ||
+           (reg >= 0x480000 && reg < 0x481000) ||
+           (reg >= 0x490000 && reg < 0x492000) ||
+           (reg >= 0x4a8000 && reg < 0x4a9000))
+               return true;
+       else
+               return false;
+}
+
+static bool wm5110_is_rev_d_adsp_memory(unsigned int reg)
+{
+       if ((reg >= 0x100000 && reg < 0x106000) ||
+           (reg >= 0x180000 && reg < 0x182000) ||
+           (reg >= 0x190000 && reg < 0x198000) ||
+           (reg >= 0x1a8000 && reg < 0x1aa000) ||
+           (reg >= 0x200000 && reg < 0x20f000) ||
+           (reg >= 0x280000 && reg < 0x282000) ||
+           (reg >= 0x290000 && reg < 0x29c000) ||
+           (reg >= 0x2a6000 && reg < 0x2b4000) ||
+           (reg >= 0x300000 && reg < 0x30f000) ||
+           (reg >= 0x380000 && reg < 0x382000) ||
+           (reg >= 0x390000 && reg < 0x3a2000) ||
+           (reg >= 0x3a6000 && reg < 0x3b4000) ||
+           (reg >= 0x400000 && reg < 0x406000) ||
+           (reg >= 0x480000 && reg < 0x482000) ||
+           (reg >= 0x490000 && reg < 0x498000) ||
+           (reg >= 0x4a8000 && reg < 0x4aa000))
+               return true;
+       else
+               return false;
+}
+
+static bool wm5110_is_adsp_memory(struct device *dev, unsigned int reg)
+{
+       struct arizona *arizona = dev_get_drvdata(dev);
+
+       switch (arizona->rev) {
+       case 0 ... 2:
+               return wm5110_is_rev_b_adsp_memory(reg);
+       default:
+               return wm5110_is_rev_d_adsp_memory(reg);
+       }
+}
+
 static bool wm5110_readable_register(struct device *dev, unsigned int reg)
 {
        switch (reg) {
@@ -1460,6 +1553,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_INPUT_ENABLES_STATUS:
        case ARIZONA_INPUT_RATE:
        case ARIZONA_INPUT_VOLUME_RAMP:
+       case ARIZONA_HPF_CONTROL:
        case ARIZONA_IN1L_CONTROL:
        case ARIZONA_ADC_DIGITAL_VOLUME_1L:
        case ARIZONA_DMIC1L_CONTROL:
@@ -1481,6 +1575,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_IN4L_CONTROL:
        case ARIZONA_ADC_DIGITAL_VOLUME_4L:
        case ARIZONA_DMIC4L_CONTROL:
+       case ARIZONA_IN4R_CONTROL:
        case ARIZONA_ADC_DIGITAL_VOLUME_4R:
        case ARIZONA_DMIC4R_CONTROL:
        case ARIZONA_OUTPUT_ENABLES_1:
@@ -1820,6 +1915,38 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_AIF2TX2MIX_INPUT_3_VOLUME:
        case ARIZONA_AIF2TX2MIX_INPUT_4_SOURCE:
        case ARIZONA_AIF2TX2MIX_INPUT_4_VOLUME:
+       case ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE:
+       case ARIZONA_AIF2TX3MIX_INPUT_1_VOLUME:
+       case ARIZONA_AIF2TX3MIX_INPUT_2_SOURCE:
+       case ARIZONA_AIF2TX3MIX_INPUT_2_VOLUME:
+       case ARIZONA_AIF2TX3MIX_INPUT_3_SOURCE:
+       case ARIZONA_AIF2TX3MIX_INPUT_3_VOLUME:
+       case ARIZONA_AIF2TX3MIX_INPUT_4_SOURCE:
+       case ARIZONA_AIF2TX3MIX_INPUT_4_VOLUME:
+       case ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE:
+       case ARIZONA_AIF2TX4MIX_INPUT_1_VOLUME:
+       case ARIZONA_AIF2TX4MIX_INPUT_2_SOURCE:
+       case ARIZONA_AIF2TX4MIX_INPUT_2_VOLUME:
+       case ARIZONA_AIF2TX4MIX_INPUT_3_SOURCE:
+       case ARIZONA_AIF2TX4MIX_INPUT_3_VOLUME:
+       case ARIZONA_AIF2TX4MIX_INPUT_4_SOURCE:
+       case ARIZONA_AIF2TX4MIX_INPUT_4_VOLUME:
+       case ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE:
+       case ARIZONA_AIF2TX5MIX_INPUT_1_VOLUME:
+       case ARIZONA_AIF2TX5MIX_INPUT_2_SOURCE:
+       case ARIZONA_AIF2TX5MIX_INPUT_2_VOLUME:
+       case ARIZONA_AIF2TX5MIX_INPUT_3_SOURCE:
+       case ARIZONA_AIF2TX5MIX_INPUT_3_VOLUME:
+       case ARIZONA_AIF2TX5MIX_INPUT_4_SOURCE:
+       case ARIZONA_AIF2TX5MIX_INPUT_4_VOLUME:
+       case ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE:
+       case ARIZONA_AIF2TX6MIX_INPUT_1_VOLUME:
+       case ARIZONA_AIF2TX6MIX_INPUT_2_SOURCE:
+       case ARIZONA_AIF2TX6MIX_INPUT_2_VOLUME:
+       case ARIZONA_AIF2TX6MIX_INPUT_3_SOURCE:
+       case ARIZONA_AIF2TX6MIX_INPUT_3_VOLUME:
+       case ARIZONA_AIF2TX6MIX_INPUT_4_SOURCE:
+       case ARIZONA_AIF2TX6MIX_INPUT_4_VOLUME:
        case ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE:
        case ARIZONA_AIF3TX1MIX_INPUT_1_VOLUME:
        case ARIZONA_AIF3TX1MIX_INPUT_2_SOURCE:
@@ -2331,7 +2458,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP4_SCRATCH_3:
                return true;
        default:
-               return false;
+               return wm5110_is_adsp_memory(dev, reg);
        }
 }
 
@@ -2407,16 +2534,18 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP4_SCRATCH_3:
                return true;
        default:
-               return false;
+               return wm5110_is_adsp_memory(dev, reg);
        }
 }
 
+#define WM5110_MAX_REGISTER 0x4a9fff
+
 const struct regmap_config wm5110_spi_regmap = {
        .reg_bits = 32,
        .pad_bits = 16,
        .val_bits = 16,
 
-       .max_register = ARIZONA_DSP1_STATUS_2,
+       .max_register = WM5110_MAX_REGISTER,
        .readable_reg = wm5110_readable_register,
        .volatile_reg = wm5110_volatile_register,
 
@@ -2430,7 +2559,7 @@ const struct regmap_config wm5110_i2c_regmap = {
        .reg_bits = 32,
        .val_bits = 16,
 
-       .max_register = ARIZONA_DSP1_STATUS_2,
+       .max_register = WM5110_MAX_REGISTER,
        .readable_reg = wm5110_readable_register,
        .volatile_reg = wm5110_volatile_register,
 
index 5c459f469224a61719d3258e948c0f0f3ecef856..28366a90e1adfbec14b5679244676b1077c9926e 100644 (file)
@@ -1011,7 +1011,7 @@ static struct resource wm831x_wdt_resources[] = {
        },
 };
 
-static struct mfd_cell wm8310_devs[] = {
+static const struct mfd_cell wm8310_devs[] = {
        {
                .name = "wm831x-backup",
        },
@@ -1165,7 +1165,7 @@ static struct mfd_cell wm8310_devs[] = {
        },
 };
 
-static struct mfd_cell wm8311_devs[] = {
+static const struct mfd_cell wm8311_devs[] = {
        {
                .name = "wm831x-backup",
        },
@@ -1295,7 +1295,7 @@ static struct mfd_cell wm8311_devs[] = {
        },
 };
 
-static struct mfd_cell wm8312_devs[] = {
+static const struct mfd_cell wm8312_devs[] = {
        {
                .name = "wm831x-backup",
        },
@@ -1449,7 +1449,7 @@ static struct mfd_cell wm8312_devs[] = {
        },
 };
 
-static struct mfd_cell wm8320_devs[] = {
+static const struct mfd_cell wm8320_devs[] = {
        {
                .name = "wm831x-backup",
        },
@@ -1578,7 +1578,7 @@ static struct mfd_cell wm8320_devs[] = {
        },
 };
 
-static struct mfd_cell touch_devs[] = {
+static const struct mfd_cell touch_devs[] = {
        {
                .name = "wm831x-touch",
                .num_resources = ARRAY_SIZE(wm831x_touch_resources),
@@ -1586,7 +1586,7 @@ static struct mfd_cell touch_devs[] = {
        },
 };
 
-static struct mfd_cell rtc_devs[] = {
+static const struct mfd_cell rtc_devs[] = {
        {
                .name = "wm831x-rtc",
                .num_resources = ARRAY_SIZE(wm831x_rtc_resources),
@@ -1594,7 +1594,7 @@ static struct mfd_cell rtc_devs[] = {
        },
 };
 
-static struct mfd_cell backlight_devs[] = {
+static const struct mfd_cell backlight_devs[] = {
        {
                .name = "wm831x-backlight",
        },
index 0308275116672c2b15ab2d91b334c561dadbcf46..ba04f1bc70eb52988ce27b5f4e45195e8b216b82 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "wm8994.h"
 
-static struct mfd_cell wm8994_regulator_devs[] = {
+static const struct mfd_cell wm8994_regulator_devs[] = {
        {
                .name = "wm8994-ldo",
                .id = 1,
@@ -62,7 +62,7 @@ static struct resource wm8994_gpio_resources[] = {
        },
 };
 
-static struct mfd_cell wm8994_devs[] = {
+static const struct mfd_cell wm8994_devs[] = {
        {
                .name = "wm8994-codec",
                .num_resources = ARRAY_SIZE(wm8994_codec_resources),
index 87c96e4669e2c50fd9bb5889c813f3a35ce64b1f..6184e854ae1e19856b6ad9ed00744d199f604cb7 100644 (file)
@@ -344,8 +344,6 @@ int mei_cl_unlink(struct mei_cl *cl)
 
        cl->state = MEI_FILE_INITIALIZING;
 
-       list_del_init(&cl->link);
-
        return 0;
 }
 
index f7f3abbe12b6e2a8cc7058397ce77dc0c3cc7029..83c879bf9967be34e21ca6ebe87c789509de2e21 100644 (file)
@@ -131,6 +131,15 @@ err:
 }
 EXPORT_SYMBOL_GPL(mei_start);
 
+
+void mei_cancel_work(struct mei_device *dev)
+{
+       cancel_work_sync(&dev->init_work);
+
+       cancel_delayed_work(&dev->timer_work);
+}
+EXPORT_SYMBOL_GPL(mei_cancel_work);
+
 /**
  * mei_reset - resets host and fw.
  *
@@ -215,16 +224,14 @@ void mei_stop(struct mei_device *dev)
 {
        dev_dbg(&dev->pdev->dev, "stopping the device.\n");
 
-       flush_scheduled_work();
+       mei_cancel_work(dev);
 
-       mutex_lock(&dev->device_lock);
+       mei_nfc_host_exit(dev);
 
-       cancel_delayed_work(&dev->timer_work);
+       mutex_lock(&dev->device_lock);
 
        mei_wd_stop(dev);
 
-       mei_nfc_host_exit();
-
        dev->dev_state = MEI_DEV_POWER_DOWN;
        mei_reset(dev, 0);
 
index 7a95c07e59a6d675a4cc37a41c70fbd3e95961d7..9c8225b945c32276b720a2603df018a13dbc1a3d 100644 (file)
@@ -301,13 +301,11 @@ int mei_irq_read_handler(struct mei_device *dev,
                struct mei_cl_cb *cmpl_list, s32 *slots)
 {
        struct mei_msg_hdr *mei_hdr;
-       struct mei_cl *cl_pos = NULL;
-       struct mei_cl *cl_next = NULL;
-       int ret = 0;
+       struct mei_cl *cl;
+       int ret;
 
        if (!dev->rd_msg_hdr) {
                dev->rd_msg_hdr = mei_read_hdr(dev);
-               dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
                (*slots)--;
                dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
        }
@@ -315,61 +313,64 @@ int mei_irq_read_handler(struct mei_device *dev,
        dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
 
        if (mei_hdr->reserved || !dev->rd_msg_hdr) {
-               dev_dbg(&dev->pdev->dev, "corrupted message header.\n");
+               dev_err(&dev->pdev->dev, "corrupted message header 0x%08X\n",
+                               dev->rd_msg_hdr);
                ret = -EBADMSG;
                goto end;
        }
 
-       if (mei_hdr->host_addr || mei_hdr->me_addr) {
-               list_for_each_entry_safe(cl_pos, cl_next,
-                                       &dev->file_list, link) {
-                       dev_dbg(&dev->pdev->dev,
-                                       "list_for_each_entry_safe read host"
-                                       " 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))
-                               break;
-               }
-
-               if (&cl_pos->link == &dev->file_list) {
-                       dev_dbg(&dev->pdev->dev, "corrupted message header\n");
-                       ret = -EBADMSG;
-                       goto end;
-               }
-       }
-       if (((*slots) * sizeof(u32)) < mei_hdr->length) {
-               dev_err(&dev->pdev->dev,
-                               "we can't read the message slots =%08x.\n",
+       if (mei_slots2data(*slots) < mei_hdr->length) {
+               dev_err(&dev->pdev->dev, "less data available than length=%08x.\n",
                                *slots);
                /* we can't read the message */
                ret = -ERANGE;
                goto end;
        }
 
-       /* decide where to read the message too */
-       if (!mei_hdr->host_addr) {
-               dev_dbg(&dev->pdev->dev, "call mei_hbm_dispatch.\n");
+       /*  HBM message */
+       if (mei_hdr->host_addr == 0 && mei_hdr->me_addr == 0) {
                mei_hbm_dispatch(dev, mei_hdr);
-               dev_dbg(&dev->pdev->dev, "end mei_hbm_dispatch.\n");
-       } 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)) {
+               ret = 0;
+               dev_dbg(&dev->pdev->dev, "mei_hbm_dispatch.\n");
+               goto reset_slots;
+       }
 
-               dev_dbg(&dev->pdev->dev, "call mei_amthif_irq_read_msg.\n");
-               dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
+       /* find recepient cl */
+       list_for_each_entry(cl, &dev->file_list, link) {
+               if (mei_cl_hbm_equal(cl, mei_hdr)) {
+                       cl_dbg(dev, cl, "got a message\n");
+                       break;
+               }
+       }
+
+       /* if no recepient cl was found we assume corrupted header\n */
+       if (&cl->link == &dev->file_list) {
+               dev_err(&dev->pdev->dev, "no destination client found 0x%08X\n",
+                               dev->rd_msg_hdr);
+               ret = -EBADMSG;
+               goto end;
+       }
+
+       if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
+           MEI_FILE_CONNECTED == dev->iamthif_cl.state &&
+           dev->iamthif_state == MEI_IAMTHIF_READING) {
 
                ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list);
-               if (ret)
+               if (ret) {
+                       dev_err(&dev->pdev->dev, "mei_amthif_irq_read_msg failed = %d\n",
+                                       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);
-               if (ret)
+               if (ret) {
+                       dev_err(&dev->pdev->dev, "mei_cl_irq_read_msg failed = %d\n",
+                                       ret);
                        goto end;
+               }
        }
 
+reset_slots:
        /* reset the number of slots and header */
        *slots = mei_count_full_read_slots(dev);
        dev->rd_msg_hdr = 0;
index 406f68e05b4ed4ccdbc6d9f886386a5d110e307b..4a7ee815fab1ffccce421024400386262aabb448 100644 (file)
@@ -456,6 +456,16 @@ static inline u32 mei_data2slots(size_t length)
        return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
 }
 
+/**
+ * mei_slots2data- get data in slots - bytes from slots
+ * @slots -  number of available slots
+ * returns  - number of bytes in slots
+ */
+static inline u32 mei_slots2data(int slots)
+{
+       return slots * 4;
+}
+
 /*
  * mei init function prototypes
  */
@@ -463,6 +473,7 @@ 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);
+void mei_cancel_work(struct mei_device *dev);
 
 /*
  *  MEI interrupt functions prototype
@@ -510,7 +521,7 @@ 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);
+void mei_nfc_host_exit(struct mei_device *dev);
 
 /*
  * NFC Client UUID
index 994ca4aff1a37ecf1b6fc53a2b44e1f446b710dd..0a892205ce7e6314fa53f8b9046f8a6d7e57206a 100644 (file)
@@ -547,12 +547,16 @@ err:
        return ret;
 }
 
-void mei_nfc_host_exit(void)
+void mei_nfc_host_exit(struct mei_device *dev)
 {
        struct mei_nfc_dev *ndev = &nfc_dev;
 
+       cancel_work_sync(&ndev->init_work);
+
+       mutex_lock(&dev->device_lock);
        if (ndev->cl && ndev->cl->device)
                mei_cl_remove_device(ndev->cl->device);
 
        mei_nfc_free(ndev);
+       mutex_unlock(&dev->device_lock);
 }
index b96205aece0c781d267ef9c2ac198cc154145080..3bfae3843d9573e176f2b916ad430c96dfaf8d3d 100644 (file)
@@ -195,8 +195,8 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        return 0;
 
 release_irq:
+       mei_cancel_work(dev);
        mei_disable_interrupts(dev);
-       flush_scheduled_work();
        free_irq(pdev->irq, dev);
 disable_msi:
        pci_disable_msi(pdev);
index 8aa42e738acc6dde99a716535f8b27efcd9d0988..653799b96bfae0dd709367fa20a3a74bc296033d 100644 (file)
@@ -154,14 +154,14 @@ static void mic_reset_inform_host(struct virtio_device *vdev)
 {
        struct mic_vdev *mvdev = to_micvdev(vdev);
        struct mic_device_ctrl __iomem *dc = mvdev->dc;
-       int retry = 100, i;
+       int retry;
 
        iowrite8(0, &dc->host_ack);
        iowrite8(1, &dc->vdev_reset);
        mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
 
        /* Wait till host completes all card accesses and acks the reset */
-       for (i = retry; i--;) {
+       for (retry = 100; retry--;) {
                if (ioread8(&dc->host_ack))
                        break;
                msleep(100);
@@ -187,11 +187,12 @@ static void mic_reset(struct virtio_device *vdev)
 /*
  * The virtio_ring code calls this API when it wants to notify the Host.
  */
-static void mic_notify(struct virtqueue *vq)
+static bool mic_notify(struct virtqueue *vq)
 {
        struct mic_vdev *mvdev = vq->priv;
 
        mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
+       return true;
 }
 
 static void mic_del_vq(struct virtqueue *vq, int n)
@@ -247,17 +248,17 @@ static struct virtqueue *mic_find_vq(struct virtio_device *vdev,
        /* First assign the vring's allocated in host memory */
        vqconfig = mic_vq_config(mvdev->desc) + index;
        memcpy_fromio(&config, vqconfig, sizeof(config));
-       _vr_size = vring_size(config.num, MIC_VIRTIO_RING_ALIGN);
+       _vr_size = vring_size(le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN);
        vr_size = PAGE_ALIGN(_vr_size + sizeof(struct _mic_vring_info));
-       va = mic_card_map(mvdev->mdev, config.address, vr_size);
+       va = mic_card_map(mvdev->mdev, le64_to_cpu(config.address), vr_size);
        if (!va)
                return ERR_PTR(-ENOMEM);
        mvdev->vr[index] = va;
        memset_io(va, 0x0, _vr_size);
-       vq = vring_new_virtqueue(index,
-                               config.num, MIC_VIRTIO_RING_ALIGN, vdev,
-                               false,
-                               va, mic_notify, callback, name);
+       vq = vring_new_virtqueue(index, le16_to_cpu(config.num),
+                                MIC_VIRTIO_RING_ALIGN, vdev, false,
+                                (void __force *)va, mic_notify, callback,
+                                name);
        if (!vq) {
                err = -ENOMEM;
                goto unmap;
@@ -272,7 +273,8 @@ static struct virtqueue *mic_find_vq(struct virtio_device *vdev,
 
        /* Allocate and reassign used ring now */
        mvdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 +
-                       sizeof(struct vring_used_elem) * config.num);
+                                            sizeof(struct vring_used_elem) *
+                                            le16_to_cpu(config.num));
        used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
                                        get_order(mvdev->used_size[index]));
        if (!used) {
@@ -309,7 +311,7 @@ static int mic_find_vqs(struct virtio_device *vdev, unsigned nvqs,
 {
        struct mic_vdev *mvdev = to_micvdev(vdev);
        struct mic_device_ctrl __iomem *dc = mvdev->dc;
-       int i, err, retry = 100;
+       int i, err, retry;
 
        /* We must have this many virtqueues. */
        if (nvqs > ioread8(&mvdev->desc->num_vq))
@@ -331,7 +333,7 @@ static int mic_find_vqs(struct virtio_device *vdev, unsigned nvqs,
         * rings have been re-assigned.
         */
        mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
-       for (i = retry; i--;) {
+       for (retry = 100; retry--;) {
                if (!ioread8(&dc->used_address_updated))
                        break;
                msleep(100);
@@ -519,8 +521,8 @@ static void mic_scan_devices(struct mic_driver *mdrv, bool remove)
        struct device *dev;
        int ret;
 
-       for (i = mic_aligned_size(struct mic_bootparam);
-               i < MIC_DP_SIZE; i += mic_total_desc_size(d)) {
+       for (i = sizeof(struct mic_bootparam); i < MIC_DP_SIZE;
+               i += mic_total_desc_size(d)) {
                d = mdrv->dp + i;
                dc = (void __iomem *)d + mic_aligned_desc_size(d);
                /*
@@ -539,7 +541,8 @@ static void mic_scan_devices(struct mic_driver *mdrv, bool remove)
                        continue;
 
                /* device already exists */
-               dev = device_find_child(mdrv->dev, d, mic_match_desc);
+               dev = device_find_child(mdrv->dev, (void __force *)d,
+                                       mic_match_desc);
                if (dev) {
                        if (remove)
                                iowrite8(MIC_VIRTIO_PARAM_DEV_REMOVE,
index 2c5c22c93ba8e787a1666e74d1b2256c4f894a27..d0407ba53bb7e81b45ecc2b6cfeb6af60ef747b8 100644 (file)
@@ -42,8 +42,8 @@
 
 static inline unsigned mic_desc_size(struct mic_device_desc __iomem *desc)
 {
-       return mic_aligned_size(*desc)
-               + ioread8(&desc->num_vq) * mic_aligned_size(struct mic_vqconfig)
+       return sizeof(*desc)
+               + ioread8(&desc->num_vq) * sizeof(struct mic_vqconfig)
                + ioread8(&desc->feature_len) * 2
                + ioread8(&desc->config_len);
 }
@@ -67,8 +67,7 @@ mic_vq_configspace(struct mic_device_desc __iomem *desc)
 }
 static inline unsigned mic_total_desc_size(struct mic_device_desc __iomem *desc)
 {
-       return mic_aligned_desc_size(desc) +
-               mic_aligned_size(struct mic_device_ctrl);
+       return mic_aligned_desc_size(desc) + sizeof(struct mic_device_ctrl);
 }
 
 int mic_devices_init(struct mic_driver *mdrv);
index 7558d91864380ae849d90a24deee4e31985850eb..b75c6b5cc20fc7a908944291add52a5cada071ff 100644 (file)
@@ -62,7 +62,7 @@ void mic_bootparam_init(struct mic_device *mdev)
 {
        struct mic_bootparam *bootparam = mdev->dp;
 
-       bootparam->magic = MIC_MAGIC;
+       bootparam->magic = cpu_to_le32(MIC_MAGIC);
        bootparam->c2h_shutdown_db = mdev->shutdown_db;
        bootparam->h2c_shutdown_db = -1;
        bootparam->h2c_config_db = -1;
index 5b8494bd1e003ff9cb53d49fa7ffd22798893912..e04bb4fe68235a7de2ac7e5c09c7c027776cb39c 100644 (file)
@@ -41,7 +41,7 @@ static int mic_virtio_copy_to_user(struct mic_vdev *mvdev,
         * We are copying from IO below an should ideally use something
         * like copy_to_user_fromio(..) if it existed.
         */
-       if (copy_to_user(ubuf, dbuf, len)) {
+       if (copy_to_user(ubuf, (void __force *)dbuf, len)) {
                err = -EFAULT;
                dev_err(mic_dev(mvdev), "%s %d err %d\n",
                        __func__, __LINE__, err);
@@ -66,7 +66,7 @@ static int mic_virtio_copy_from_user(struct mic_vdev *mvdev,
         * We are copying to IO below and should ideally use something
         * like copy_from_user_toio(..) if it existed.
         */
-       if (copy_from_user(dbuf, ubuf, len)) {
+       if (copy_from_user((void __force *)dbuf, ubuf, len)) {
                err = -EFAULT;
                dev_err(mic_dev(mvdev), "%s %d err %d\n",
                        __func__, __LINE__, err);
@@ -293,7 +293,7 @@ static void mic_virtio_init_post(struct mic_vdev *mvdev)
                        continue;
                }
                mvdev->mvr[i].vrh.vring.used =
-                       mvdev->mdev->aper.va +
+                       (void __force *)mvdev->mdev->aper.va +
                        le64_to_cpu(vqconfig[i].used_address);
        }
 
@@ -378,7 +378,7 @@ int mic_virtio_config_change(struct mic_vdev *mvdev,
                        void __user *argp)
 {
        DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
-       int ret = 0, retry = 100, i;
+       int ret = 0, retry, i;
        struct mic_bootparam *bootparam = mvdev->mdev->dp;
        s8 db = bootparam->h2c_config_db;
 
@@ -401,7 +401,7 @@ int mic_virtio_config_change(struct mic_vdev *mvdev,
        mvdev->dc->config_change = MIC_VIRTIO_PARAM_CONFIG_CHANGED;
        mvdev->mdev->ops->send_intr(mvdev->mdev, db);
 
-       for (i = retry; i--;) {
+       for (retry = 100; retry--;) {
                ret = wait_event_timeout(wake,
                        mvdev->dc->guest_ack, msecs_to_jiffies(100));
                if (ret)
@@ -467,7 +467,7 @@ static int mic_copy_dp_entry(struct mic_vdev *mvdev,
        }
 
        /* Find the first free device page entry */
-       for (i = mic_aligned_size(struct mic_bootparam);
+       for (i = sizeof(struct mic_bootparam);
                i < MIC_DP_SIZE - mic_total_desc_size(dd_config);
                i += mic_total_desc_size(devp)) {
                devp = mdev->dp + i;
@@ -525,6 +525,7 @@ int mic_virtio_add_device(struct mic_vdev *mvdev,
        char irqname[10];
        struct mic_bootparam *bootparam = mdev->dp;
        u16 num;
+       dma_addr_t vr_addr;
 
        mutex_lock(&mdev->mic_mutex);
 
@@ -559,17 +560,16 @@ int mic_virtio_add_device(struct mic_vdev *mvdev,
                }
                vr->len = vr_size;
                vr->info = vr->va + vring_size(num, MIC_VIRTIO_RING_ALIGN);
-               vr->info->magic = MIC_MAGIC + mvdev->virtio_id + i;
-               vqconfig[i].address = mic_map_single(mdev,
-                       vr->va, vr_size);
-               if (mic_map_error(vqconfig[i].address)) {
+               vr->info->magic = cpu_to_le32(MIC_MAGIC + mvdev->virtio_id + i);
+               vr_addr = mic_map_single(mdev, vr->va, vr_size);
+               if (mic_map_error(vr_addr)) {
                        free_pages((unsigned long)vr->va, get_order(vr_size));
                        ret = -ENOMEM;
                        dev_err(mic_dev(mvdev), "%s %d err %d\n",
                                __func__, __LINE__, ret);
                        goto err;
                }
-               vqconfig[i].address = cpu_to_le64(vqconfig[i].address);
+               vqconfig[i].address = cpu_to_le64(vr_addr);
 
                vring_init(&vr->vr, num, vr->va, MIC_VIRTIO_RING_ALIGN);
                ret = vringh_init_kern(&mvr->vrh,
@@ -639,7 +639,7 @@ void mic_virtio_del_device(struct mic_vdev *mvdev)
        struct mic_vdev *tmp_mvdev;
        struct mic_device *mdev = mvdev->mdev;
        DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
-       int i, ret, retry = 100;
+       int i, ret, retry;
        struct mic_vqconfig *vqconfig;
        struct mic_bootparam *bootparam = mdev->dp;
        s8 db;
@@ -652,16 +652,16 @@ void mic_virtio_del_device(struct mic_vdev *mvdev)
                "Requesting hot remove id %d\n", mvdev->virtio_id);
        mvdev->dc->config_change = MIC_VIRTIO_PARAM_DEV_REMOVE;
        mdev->ops->send_intr(mdev, db);
-       for (i = retry; i--;) {
+       for (retry = 100; retry--;) {
                ret = wait_event_timeout(wake,
                        mvdev->dc->guest_ack, msecs_to_jiffies(100));
                if (ret)
                        break;
        }
        dev_dbg(mdev->sdev->parent,
-               "Device id %d config_change %d guest_ack %d\n",
+               "Device id %d config_change %d guest_ack %d retry %d\n",
                mvdev->virtio_id, mvdev->dc->config_change,
-               mvdev->dc->guest_ack);
+               mvdev->dc->guest_ack, retry);
        mvdev->dc->config_change = 0;
        mvdev->dc->guest_ack = 0;
 skip_hot_remove:
index 81e9541b784c3a4d46bbd352c2aa26faf70c2877..0dfa8a81436e80ebd325d1722caa791d5193936e 100644 (file)
@@ -397,8 +397,8 @@ mic_x100_load_ramdisk(struct mic_device *mdev)
         * so copy over the ramdisk @ 128M.
         */
        memcpy_toio(mdev->aper.va + (mdev->bootaddr << 1), fw->data, fw->size);
-       iowrite32(cpu_to_le32(mdev->bootaddr << 1), &bp->hdr.ramdisk_image);
-       iowrite32(cpu_to_le32(fw->size), &bp->hdr.ramdisk_size);
+       iowrite32(mdev->bootaddr << 1, &bp->hdr.ramdisk_image);
+       iowrite32(fw->size, &bp->hdr.ramdisk_size);
        release_firmware(fw);
 error:
        return rc;
index 157b570ba343e4648b796e7330e7b75bc052d00a..92d1ba8e8153ab9849ab51037804747cd37df7f1 100644 (file)
@@ -308,7 +308,7 @@ static void sdio_acpi_set_handle(struct sdio_func *func)
        struct mmc_host *host = func->card->host;
        u64 addr = (host->slotno << 16) | func->num;
 
-       acpi_preset_companion(&func->dev, ACPI_HANDLE(host->parent), addr);
+       acpi_preset_companion(&func->dev, ACPI_COMPANION(host->parent), addr);
 }
 #else
 static inline void sdio_acpi_set_handle(struct sdio_func *func) {}
index f32057972dd77fe9a7487f74aa2ab727c2126db6..b931226365317b6b64ed2462c1beeb25b7857d16 100644 (file)
@@ -1683,8 +1683,6 @@ static int mmci_remove(struct amba_device *dev)
 {
        struct mmc_host *mmc = amba_get_drvdata(dev);
 
-       amba_set_drvdata(dev, NULL);
-
        if (mmc) {
                struct mmci_host *host = mmc_priv(mmc);
 
index 0b10a9030f4e2a85029ea4bab3afcdb8102899be..98b6b6ef7e5c9d737a749e9a3ddf631f5d92c1c0 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
+#include <linux/of.h>
 #include <linux/omap-dma.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #define OMAP_MMC_CMDTYPE_AC    2
 #define OMAP_MMC_CMDTYPE_ADTC  3
 
-#define OMAP_DMA_MMC_TX                21
-#define OMAP_DMA_MMC_RX                22
-#define OMAP_DMA_MMC2_TX       54
-#define OMAP_DMA_MMC2_RX       55
-
-#define OMAP24XX_DMA_MMC2_TX   47
-#define OMAP24XX_DMA_MMC2_RX   48
-#define OMAP24XX_DMA_MMC1_TX   61
-#define OMAP24XX_DMA_MMC1_RX   62
-
-
 #define DRIVER_NAME "mmci-omap"
 
 /* Specifies how often in millisecs to poll for card status changes
@@ -1330,7 +1320,7 @@ static int mmc_omap_probe(struct platform_device *pdev)
        struct mmc_omap_host *host = NULL;
        struct resource *res;
        dma_cap_mask_t mask;
-       unsigned sig;
+       unsigned sig = 0;
        int i, ret = 0;
        int irq;
 
@@ -1340,7 +1330,7 @@ static int mmc_omap_probe(struct platform_device *pdev)
        }
        if (pdata->nr_slots == 0) {
                dev_err(&pdev->dev, "no slots\n");
-               return -ENXIO;
+               return -EPROBE_DEFER;
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1407,19 +1397,20 @@ static int mmc_omap_probe(struct platform_device *pdev)
        host->dma_tx_burst = -1;
        host->dma_rx_burst = -1;
 
-       if (mmc_omap2())
-               sig = host->id == 0 ? OMAP24XX_DMA_MMC1_TX : OMAP24XX_DMA_MMC2_TX;
-       else
-               sig = host->id == 0 ? OMAP_DMA_MMC_TX : OMAP_DMA_MMC2_TX;
-       host->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+       if (res)
+               sig = res->start;
+       host->dma_tx = dma_request_slave_channel_compat(mask,
+                               omap_dma_filter_fn, &sig, &pdev->dev, "tx");
        if (!host->dma_tx)
                dev_warn(host->dev, "unable to obtain TX DMA engine channel %u\n",
                        sig);
-       if (mmc_omap2())
-               sig = host->id == 0 ? OMAP24XX_DMA_MMC1_RX : OMAP24XX_DMA_MMC2_RX;
-       else
-               sig = host->id == 0 ? OMAP_DMA_MMC_RX : OMAP_DMA_MMC2_RX;
-       host->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+       if (res)
+               sig = res->start;
+       host->dma_rx = dma_request_slave_channel_compat(mask,
+                               omap_dma_filter_fn, &sig, &pdev->dev, "rx");
        if (!host->dma_rx)
                dev_warn(host->dev, "unable to obtain RX DMA engine channel %u\n",
                        sig);
@@ -1512,12 +1503,20 @@ static int mmc_omap_remove(struct platform_device *pdev)
        return 0;
 }
 
+#if IS_BUILTIN(CONFIG_OF)
+static const struct of_device_id mmc_omap_match[] = {
+       { .compatible = "ti,omap2420-mmc", },
+       { },
+};
+#endif
+
 static struct platform_driver mmc_omap_driver = {
        .probe          = mmc_omap_probe,
        .remove         = mmc_omap_remove,
        .driver         = {
                .name   = DRIVER_NAME,
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(mmc_omap_match),
        },
 };
 
index 7eda71dbc183b7aa456e60a41f0490c882d94331..7dc2c147720aba6fa30dd17fef26f3593d53895b 100644 (file)
@@ -41,6 +41,7 @@
 #define        OPCODE_WRSR             0x01    /* Write status register 1 byte */
 #define        OPCODE_NORM_READ        0x03    /* Read data bytes (low frequency) */
 #define        OPCODE_FAST_READ        0x0b    /* Read data bytes (high frequency) */
+#define        OPCODE_QUAD_READ        0x6b    /* Read data bytes */
 #define        OPCODE_PP               0x02    /* Page program (up to 256 bytes) */
 #define        OPCODE_BE_4K            0x20    /* Erase 4KiB block */
 #define        OPCODE_BE_4K_PMC        0xd7    /* Erase 4KiB block on PMC chips */
 #define        OPCODE_CHIP_ERASE       0xc7    /* Erase whole flash chip */
 #define        OPCODE_SE               0xd8    /* Sector erase (usually 64KiB) */
 #define        OPCODE_RDID             0x9f    /* Read JEDEC ID */
+#define        OPCODE_RDCR             0x35    /* Read configuration register */
 
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define        OPCODE_NORM_READ_4B     0x13    /* Read data bytes (low frequency) */
 #define        OPCODE_FAST_READ_4B     0x0c    /* Read data bytes (high frequency) */
+#define        OPCODE_QUAD_READ_4B     0x6c    /* Read data bytes */
 #define        OPCODE_PP_4B            0x12    /* Page program (up to 256 bytes) */
 #define        OPCODE_SE_4B            0xdc    /* Sector erase (usually 64KiB) */
 
 #define        SR_BP2                  0x10    /* Block protect 2 */
 #define        SR_SRWD                 0x80    /* SR write protect */
 
+#define SR_QUAD_EN_MX           0x40    /* Macronix Quad I/O */
+
+/* Configuration Register bits. */
+#define CR_QUAD_EN_SPAN                0x2     /* Spansion Quad I/O */
+
 /* Define max times to check status register before we give up. */
 #define        MAX_READY_WAIT_JIFFIES  (40 * HZ)       /* M25P16 specs 40s max chip erase */
 #define        MAX_CMD_SIZE            6
 
 /****************************************************************************/
 
+enum read_type {
+       M25P80_NORMAL = 0,
+       M25P80_FAST,
+       M25P80_QUAD,
+};
+
 struct m25p {
        struct spi_device       *spi;
        struct mutex            lock;
@@ -94,7 +108,7 @@ struct m25p {
        u8                      read_opcode;
        u8                      program_opcode;
        u8                      *command;
-       bool                    fast_read;
+       enum read_type          flash_read;
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -130,6 +144,26 @@ static int read_sr(struct m25p *flash)
        return val;
 }
 
+/*
+ * Read configuration register, returning its value in the
+ * location. Return the configuration register value.
+ * Returns negative if error occured.
+ */
+static int read_cr(struct m25p *flash)
+{
+       u8 code = OPCODE_RDCR;
+       int ret;
+       u8 val;
+
+       ret = spi_write_then_read(flash->spi, &code, 1, &val, 1);
+       if (ret < 0) {
+               dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
+               return ret;
+       }
+
+       return val;
+}
+
 /*
  * Write status register 1 byte
  * Returns negative if error occurred.
@@ -219,6 +253,93 @@ static int wait_till_ready(struct m25p *flash)
        return 1;
 }
 
+/*
+ * Write status Register and configuration register with 2 bytes
+ * The first byte will be written to the status register, while the
+ * second byte will be written to the configuration register.
+ * Return negative if error occured.
+ */
+static int write_sr_cr(struct m25p *flash, u16 val)
+{
+       flash->command[0] = OPCODE_WRSR;
+       flash->command[1] = val & 0xff;
+       flash->command[2] = (val >> 8);
+
+       return spi_write(flash->spi, flash->command, 3);
+}
+
+static int macronix_quad_enable(struct m25p *flash)
+{
+       int ret, val;
+       u8 cmd[2];
+       cmd[0] = OPCODE_WRSR;
+
+       val = read_sr(flash);
+       cmd[1] = val | SR_QUAD_EN_MX;
+       write_enable(flash);
+
+       spi_write(flash->spi, &cmd, 2);
+
+       if (wait_till_ready(flash))
+               return 1;
+
+       ret = read_sr(flash);
+       if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
+               dev_err(&flash->spi->dev, "Macronix Quad bit not set\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int spansion_quad_enable(struct m25p *flash)
+{
+       int ret;
+       int quad_en = CR_QUAD_EN_SPAN << 8;
+
+       write_enable(flash);
+
+       ret = write_sr_cr(flash, quad_en);
+       if (ret < 0) {
+               dev_err(&flash->spi->dev,
+                       "error while writing configuration register\n");
+               return -EINVAL;
+       }
+
+       /* read back and check it */
+       ret = read_cr(flash);
+       if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+               dev_err(&flash->spi->dev, "Spansion Quad bit not set\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int set_quad_mode(struct m25p *flash, u32 jedec_id)
+{
+       int status;
+
+       switch (JEDEC_MFR(jedec_id)) {
+       case CFI_MFR_MACRONIX:
+               status = macronix_quad_enable(flash);
+               if (status) {
+                       dev_err(&flash->spi->dev,
+                               "Macronix quad-read not enabled\n");
+                       return -EINVAL;
+               }
+               return status;
+       default:
+               status = spansion_quad_enable(flash);
+               if (status) {
+                       dev_err(&flash->spi->dev,
+                               "Spansion quad-read not enabled\n");
+                       return -EINVAL;
+               }
+               return status;
+       }
+}
+
 /*
  * Erase the whole flash memory
  *
@@ -349,6 +470,25 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
        return 0;
 }
 
+/*
+ * Dummy Cycle calculation for different type of read.
+ * It can be used to support more commands with
+ * different dummy cycle requirements.
+ */
+static inline int m25p80_dummy_cycles_read(struct m25p *flash)
+{
+       switch (flash->flash_read) {
+       case M25P80_FAST:
+       case M25P80_QUAD:
+               return 1;
+       case M25P80_NORMAL:
+               return 0;
+       default:
+               dev_err(&flash->spi->dev, "No valid read type supported\n");
+               return -1;
+       }
+}
+
 /*
  * Read an address range from the flash chip.  The address range
  * may be any size provided it is within the physical boundaries.
@@ -360,6 +500,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
        struct spi_transfer t[2];
        struct spi_message m;
        uint8_t opcode;
+       int dummy;
 
        pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
                        __func__, (u32)from, len);
@@ -367,8 +508,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
        spi_message_init(&m);
        memset(t, 0, (sizeof t));
 
+       dummy =  m25p80_dummy_cycles_read(flash);
+       if (dummy < 0) {
+               dev_err(&flash->spi->dev, "No valid read command supported\n");
+               return -EINVAL;
+       }
+
        t[0].tx_buf = flash->command;
-       t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
+       t[0].len = m25p_cmdsz(flash) + dummy;
        spi_message_add_tail(&t[0], &m);
 
        t[1].rx_buf = buf;
@@ -391,8 +538,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 
        spi_sync(flash->spi, &m);
 
-       *retlen = m.actual_length - m25p_cmdsz(flash) -
-                       (flash->fast_read ? 1 : 0);
+       *retlen = m.actual_length - m25p_cmdsz(flash) - dummy;
 
        mutex_unlock(&flash->lock);
 
@@ -698,6 +844,7 @@ struct flash_info {
 #define        SST_WRITE       0x04            /* use SST byte programming */
 #define        M25P_NO_FR      0x08            /* Can't do fastread */
 #define        SECT_4K_PMC     0x10            /* OPCODE_BE_4K_PMC works uniformly */
+#define        M25P80_QUAD_READ        0x20    /* Flash supports Quad Read */
 };
 
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)     \
@@ -775,7 +922,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
        { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
        { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
+       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) },
 
        /* Micron */
        { "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
@@ -795,7 +942,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
        { "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
        { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
+       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, M25P80_QUAD_READ) },
        { "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
        { "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
        { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
@@ -937,6 +1084,7 @@ static int m25p_probe(struct spi_device *spi)
        unsigned                        i;
        struct mtd_part_parser_data     ppdata;
        struct device_node *np = spi->dev.of_node;
+       int ret;
 
        /* Platform data helps sort out which chip type we have, as
         * well as how this board partitions it.  If we don't have
@@ -1051,22 +1199,44 @@ static int m25p_probe(struct spi_device *spi)
        flash->page_size = info->page_size;
        flash->mtd.writebufsize = flash->page_size;
 
-       if (np)
+       if (np) {
                /* If we were instantiated by DT, use it */
-               flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
-       else
+               if (of_property_read_bool(np, "m25p,fast-read"))
+                       flash->flash_read = M25P80_FAST;
+       } else {
                /* If we weren't instantiated by DT, default to fast-read */
-               flash->fast_read = true;
+               flash->flash_read = M25P80_FAST;
+       }
 
        /* Some devices cannot do fast-read, no matter what DT tells us */
        if (info->flags & M25P_NO_FR)
-               flash->fast_read = false;
+               flash->flash_read = M25P80_NORMAL;
+
+       /* Quad-read mode takes precedence over fast/normal */
+       if (spi->mode & SPI_RX_QUAD && info->flags & M25P80_QUAD_READ) {
+               ret = set_quad_mode(flash, info->jedec_id);
+               if (ret) {
+                       dev_err(&flash->spi->dev, "quad mode not supported\n");
+                       return ret;
+               }
+               flash->flash_read = M25P80_QUAD;
+       }
 
        /* Default commands */
-       if (flash->fast_read)
+       switch (flash->flash_read) {
+       case M25P80_QUAD:
+               flash->read_opcode = OPCODE_QUAD_READ;
+               break;
+       case M25P80_FAST:
                flash->read_opcode = OPCODE_FAST_READ;
-       else
+               break;
+       case M25P80_NORMAL:
                flash->read_opcode = OPCODE_NORM_READ;
+               break;
+       default:
+               dev_err(&flash->spi->dev, "No Read opcode defined\n");
+               return -EINVAL;
+       }
 
        flash->program_opcode = OPCODE_PP;
 
@@ -1077,9 +1247,17 @@ static int m25p_probe(struct spi_device *spi)
                flash->addr_width = 4;
                if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
                        /* Dedicated 4-byte command set */
-                       flash->read_opcode = flash->fast_read ?
-                               OPCODE_FAST_READ_4B :
-                               OPCODE_NORM_READ_4B;
+                       switch (flash->flash_read) {
+                       case M25P80_QUAD:
+                               flash->read_opcode = OPCODE_QUAD_READ;
+                               break;
+                       case M25P80_FAST:
+                               flash->read_opcode = OPCODE_FAST_READ_4B;
+                               break;
+                       case M25P80_NORMAL:
+                               flash->read_opcode = OPCODE_NORM_READ_4B;
+                               break;
+                       }
                        flash->program_opcode = OPCODE_PP_4B;
                        /* No small sector erase for 4-byte command set */
                        flash->erase_opcode = OPCODE_SE_4B;
index 182849d39c61acb34c40a79ab6bf04e30162da79..5c8b322ba904b1691bf204efc3f4523106dc8f67 100644 (file)
@@ -205,7 +205,7 @@ static int __init ms02nv_init_one(ulong addr)
        mtd->type = MTD_RAM;
        mtd->flags = MTD_CAP_RAM;
        mtd->size = fixsize;
-       mtd->name = (char *)ms02nv_name;
+       mtd->name = ms02nv_name;
        mtd->owner = THIS_MODULE;
        mtd->_read = ms02nv_read;
        mtd->_write = ms02nv_write;
index 4a47b0266d4e587761a2db5c1cd2e1613fc710bc..624069de4f28c067260fc4fec75c35b713fc5c84 100644 (file)
@@ -669,7 +669,6 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages,
        if (!err)
                return 0;
 
-       spi_set_drvdata(spi, NULL);
        kfree(priv);
        return err;
 }
@@ -899,10 +898,8 @@ static int dataflash_remove(struct spi_device *spi)
        pr_debug("%s: remove\n", dev_name(&spi->dev));
 
        status = mtd_device_unregister(&flash->mtd);
-       if (status == 0) {
-               spi_set_drvdata(spi, NULL);
+       if (status == 0)
                kfree(flash);
-       }
        return status;
 }
 
index d210d131fef255da97e7d277574ac80f01a66341..9aad854fe9121aaa821181bffe64e819ec0e8498 100644 (file)
@@ -61,7 +61,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
        if (!info)
                return -ENOMEM;
 
-       info->map.name = (char *) flash->name;
+       info->map.name = flash->name;
        info->map.bankwidth = flash->width;
        info->map.phys = res->start;
        info->map.size = resource_size(res);
@@ -73,7 +73,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
        info->map.cached =
-               ioremap_cached(info->map.phys, info->map.size);
+               ioremap_cache(info->map.phys, info->map.size);
        if (!info->map.cached)
                printk(KERN_WARNING "Failed to ioremap cached %s\n",
                       info->map.name);
index d467f3b11c96c72ded5f3019cc823eb50fc6bd0b..39cc4181f02538a438b8fc427e00e19c1074fde3 100644 (file)
@@ -75,7 +75,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp)
 
        up->name = of_get_property(dp, "model", NULL);
        if (up->name && 0 < strlen(up->name))
-               up->map.name = (char *)up->name;
+               up->map.name = up->name;
 
        up->map.phys = op->resource[0].start;
 
index 6e732c3820c14bf9d07b693a0c1de9bfff0088f0..67a89bb459435cf2bb782c186bd5feb76e383535 100644 (file)
@@ -534,7 +534,7 @@ out_register:
        return slave;
 }
 
-int mtd_add_partition(struct mtd_info *master, char *name,
+int mtd_add_partition(struct mtd_info *master, const char *name,
                      long long offset, long long length)
 {
        struct mtd_partition part;
index 93ae6a6d94f713d6352abd612efd1fed05f43dfd..691f5a05ecf3e33c6d646bdf54f38535ce287a9f 100644 (file)
@@ -95,7 +95,7 @@ config MTD_NAND_OMAP2
          platforms.
 
 config MTD_NAND_OMAP_BCH
-       depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
+       depends on MTD_NAND_OMAP2
        tristate "Support hardware based BCH error correction"
        default n
        select BCH
@@ -326,11 +326,11 @@ config MTD_NAND_ATMEL
          on Atmel AT91 and AVR32 processors.
 
 config MTD_NAND_PXA3xx
-       tristate "Support for NAND flash devices on PXA3xx"
+       tristate "NAND support on PXA3xx and Armada 370/XP"
        depends on PXA3xx || ARCH_MMP || PLAT_ORION
        help
          This enables the driver for the NAND flash device found on
-         PXA3xx processors
+         PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2).
 
 config MTD_NAND_SLC_LPC32XX
        tristate "NXP LPC32xx SLC Controller"
index b68a4959f700af3e2768af69e6dd9afd0f94c8e1..0afafa049ea139672136ef4fd929edc740261c70 100644 (file)
@@ -1440,10 +1440,13 @@ static int __init doc_probe(unsigned long physadr)
        int reg, len, numchips;
        int ret = 0;
 
+       if (!request_mem_region(physadr, DOC_IOREMAP_LEN, NULL))
+               return -EBUSY;
        virtadr = ioremap(physadr, DOC_IOREMAP_LEN);
        if (!virtadr) {
                printk(KERN_ERR "Diskonchip ioremap failed: 0x%x bytes at 0x%lx\n", DOC_IOREMAP_LEN, physadr);
-               return -EIO;
+               ret = -EIO;
+               goto error_ioremap;
        }
 
        /* It's not possible to cleanly detect the DiskOnChip - the
@@ -1629,6 +1632,10 @@ static int __init doc_probe(unsigned long physadr)
        WriteDOC(save_control, virtadr, DOCControl);
  fail:
        iounmap(virtadr);
+
+error_ioremap:
+       release_mem_region(physadr, DOC_IOREMAP_LEN);
+
        return ret;
 }
 
@@ -1645,6 +1652,7 @@ static void release_nanddoc(void)
                nextmtd = doc->nextdoc;
                nand_release(mtd);
                iounmap(doc->virtadr);
+               release_mem_region(doc->physadr, DOC_IOREMAP_LEN);
                kfree(mtd);
        }
 }
index aaced29727fb0437f6a0c142253b04cbc0ca82d0..dd1df605a1d61ec8a43ffb5515ea50ce2f3c9b69 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include "gpmi-nand.h"
 #include "gpmi-regs.h"
@@ -207,30 +208,41 @@ void gpmi_dump_info(struct gpmi_nand_data *this)
        u32 reg;
        int i;
 
-       pr_err("Show GPMI registers :\n");
+       dev_err(this->dev, "Show GPMI registers :\n");
        for (i = 0; i <= HW_GPMI_DEBUG / 0x10 + 1; i++) {
                reg = readl(r->gpmi_regs + i * 0x10);
-               pr_err("offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
+               dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
        }
 
        /* start to print out the BCH info */
-       pr_err("Show BCH registers :\n");
+       dev_err(this->dev, "Show BCH registers :\n");
        for (i = 0; i <= HW_BCH_VERSION / 0x10 + 1; i++) {
                reg = readl(r->bch_regs + i * 0x10);
-               pr_err("offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
+               dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
        }
-       pr_err("BCH Geometry :\n");
-       pr_err("GF length              : %u\n", geo->gf_len);
-       pr_err("ECC Strength           : %u\n", geo->ecc_strength);
-       pr_err("Page Size in Bytes     : %u\n", geo->page_size);
-       pr_err("Metadata Size in Bytes : %u\n", geo->metadata_size);
-       pr_err("ECC Chunk Size in Bytes: %u\n", geo->ecc_chunk_size);
-       pr_err("ECC Chunk Count        : %u\n", geo->ecc_chunk_count);
-       pr_err("Payload Size in Bytes  : %u\n", geo->payload_size);
-       pr_err("Auxiliary Size in Bytes: %u\n", geo->auxiliary_size);
-       pr_err("Auxiliary Status Offset: %u\n", geo->auxiliary_status_offset);
-       pr_err("Block Mark Byte Offset : %u\n", geo->block_mark_byte_offset);
-       pr_err("Block Mark Bit Offset  : %u\n", geo->block_mark_bit_offset);
+       dev_err(this->dev, "BCH Geometry :\n"
+               "GF length              : %u\n"
+               "ECC Strength           : %u\n"
+               "Page Size in Bytes     : %u\n"
+               "Metadata Size in Bytes : %u\n"
+               "ECC Chunk Size in Bytes: %u\n"
+               "ECC Chunk Count        : %u\n"
+               "Payload Size in Bytes  : %u\n"
+               "Auxiliary Size in Bytes: %u\n"
+               "Auxiliary Status Offset: %u\n"
+               "Block Mark Byte Offset : %u\n"
+               "Block Mark Bit Offset  : %u\n",
+               geo->gf_len,
+               geo->ecc_strength,
+               geo->page_size,
+               geo->metadata_size,
+               geo->ecc_chunk_size,
+               geo->ecc_chunk_count,
+               geo->payload_size,
+               geo->auxiliary_size,
+               geo->auxiliary_status_offset,
+               geo->block_mark_byte_offset,
+               geo->block_mark_bit_offset);
 }
 
 /* Configures the geometry for BCH.  */
@@ -265,8 +277,8 @@ int bch_set_geometry(struct gpmi_nand_data *this)
        * chip, otherwise it will lock up. So we skip resetting BCH on the MX23.
        * On the other hand, the MX28 needs the reset, because one case has been
        * seen where the BCH produced ECC errors constantly after 10000
-       * consecutive reboots. The latter case has not been seen on the MX23 yet,
-       * still we don't know if it could happen there as well.
+       * consecutive reboots. The latter case has not been seen on the MX23
+       * yet, still we don't know if it could happen there as well.
        */
        ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
        if (ret)
@@ -353,7 +365,7 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
        improved_timing_is_available =
                (target.tREA_in_ns  >= 0) &&
                (target.tRLOH_in_ns >= 0) &&
-               (target.tRHOH_in_ns >= 0) ;
+               (target.tRHOH_in_ns >= 0);
 
        /* Inspect the clock. */
        nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]);
@@ -911,10 +923,14 @@ static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
        struct resources  *r = &this->resources;
        struct nand_chip *nand = &this->nand;
        struct mtd_info  *mtd = &this->mtd;
-       uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
+       uint8_t *feature;
        unsigned long rate;
        int ret;
 
+       feature = kzalloc(ONFI_SUBFEATURE_PARAM_LEN, GFP_KERNEL);
+       if (!feature)
+               return -ENOMEM;
+
        nand->select_chip(mtd, 0);
 
        /* [1] send SET FEATURE commond to NAND */
@@ -942,11 +958,13 @@ static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
 
        this->flags |= GPMI_ASYNC_EDO_ENABLED;
        this->timing_mode = mode;
+       kfree(feature);
        dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode);
        return 0;
 
 err_out:
        nand->select_chip(mtd, -1);
+       kfree(feature);
        dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode);
        return -EINVAL;
 }
@@ -986,7 +1004,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
        /* Enable the clock. */
        ret = gpmi_enable_clk(this);
        if (ret) {
-               pr_err("We failed in enable the clk\n");
+               dev_err(this->dev, "We failed in enable the clk\n");
                goto err_out;
        }
 
@@ -1003,7 +1021,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
        /* [1] Set HW_GPMI_TIMING0 */
        reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
                BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles)         |
-               BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles)       ;
+               BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles);
 
        writel(reg, gpmi_regs + HW_GPMI_TIMING0);
 
@@ -1090,7 +1108,7 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
                mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip);
                reg = readl(r->gpmi_regs + HW_GPMI_STAT);
        } else
-               pr_err("unknow arch.\n");
+               dev_err(this->dev, "unknow arch.\n");
        return reg & mask;
 }
 
@@ -1121,10 +1139,8 @@ int gpmi_send_command(struct gpmi_nand_data *this)
        desc = dmaengine_prep_slave_sg(channel,
                                        (struct scatterlist *)pio,
                                        ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
-       if (!desc) {
-               pr_err("step 1 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
 
        /* [2] send out the COMMAND + ADDRESS string stored in @buffer */
        sgl = &this->cmd_sgl;
@@ -1134,11 +1150,8 @@ int gpmi_send_command(struct gpmi_nand_data *this)
        desc = dmaengine_prep_slave_sg(channel,
                                sgl, 1, DMA_MEM_TO_DEV,
                                DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-
-       if (!desc) {
-               pr_err("step 2 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
 
        /* [3] submit the DMA */
        set_dma_type(this, DMA_FOR_COMMAND);
@@ -1167,20 +1180,17 @@ int gpmi_send_data(struct gpmi_nand_data *this)
        pio[1] = 0;
        desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio,
                                        ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
-       if (!desc) {
-               pr_err("step 1 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
 
        /* [2] send DMA request */
        prepare_data_dma(this, DMA_TO_DEVICE);
        desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
                                        1, DMA_MEM_TO_DEV,
                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-       if (!desc) {
-               pr_err("step 2 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
+
        /* [3] submit the DMA */
        set_dma_type(this, DMA_FOR_WRITE_DATA);
        return start_dma_without_bch_irq(this, desc);
@@ -1204,20 +1214,16 @@ int gpmi_read_data(struct gpmi_nand_data *this)
        desc = dmaengine_prep_slave_sg(channel,
                                        (struct scatterlist *)pio,
                                        ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
-       if (!desc) {
-               pr_err("step 1 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
 
        /* [2] : send DMA request */
        prepare_data_dma(this, DMA_FROM_DEVICE);
        desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
                                        1, DMA_DEV_TO_MEM,
                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-       if (!desc) {
-               pr_err("step 2 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
 
        /* [3] : submit the DMA */
        set_dma_type(this, DMA_FOR_READ_DATA);
@@ -1262,10 +1268,9 @@ int gpmi_send_page(struct gpmi_nand_data *this,
                                        (struct scatterlist *)pio,
                                        ARRAY_SIZE(pio), DMA_TRANS_NONE,
                                        DMA_CTRL_ACK);
-       if (!desc) {
-               pr_err("step 2 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
+
        set_dma_type(this, DMA_FOR_WRITE_ECC_PAGE);
        return start_dma_with_bch_irq(this, desc);
 }
@@ -1297,10 +1302,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
        desc = dmaengine_prep_slave_sg(channel,
                                (struct scatterlist *)pio, 2,
                                DMA_TRANS_NONE, 0);
-       if (!desc) {
-               pr_err("step 1 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
 
        /* [2] Enable the BCH block and read. */
        command_mode = BV_GPMI_CTRL0_COMMAND_MODE__READ;
@@ -1327,10 +1330,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
                                        (struct scatterlist *)pio,
                                        ARRAY_SIZE(pio), DMA_TRANS_NONE,
                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-       if (!desc) {
-               pr_err("step 2 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
 
        /* [3] Disable the BCH block */
        command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY;
@@ -1348,10 +1349,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
                                (struct scatterlist *)pio, 3,
                                DMA_TRANS_NONE,
                                DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-       if (!desc) {
-               pr_err("step 3 error\n");
-               return -1;
-       }
+       if (!desc)
+               return -EINVAL;
 
        /* [4] submit the DMA */
        set_dma_type(this, DMA_FOR_READ_ECC_PAGE);
index dabbc14db5630d8592268012fc067559179aa0f8..e2f58207c779313c1c254d60b2c515b8963421c2 100644 (file)
@@ -18,9 +18,6 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/clk.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
@@ -352,6 +349,9 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
 
 int common_nfc_set_geometry(struct gpmi_nand_data *this)
 {
+       if (of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc")
+               && set_geometry_by_ecc_info(this))
+               return 0;
        return legacy_set_geometry(this);
 }
 
@@ -382,7 +382,7 @@ void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr)
 
                ret = dma_map_sg(this->dev, sgl, 1, dr);
                if (ret == 0)
-                       pr_err("DMA mapping failed.\n");
+                       dev_err(this->dev, "DMA mapping failed.\n");
 
                this->direct_dma_map_ok = false;
        }
@@ -416,7 +416,7 @@ static void dma_irq_callback(void *param)
                break;
 
        default:
-               pr_err("in wrong DMA operation.\n");
+               dev_err(this->dev, "in wrong DMA operation.\n");
        }
 
        complete(dma_c);
@@ -438,7 +438,8 @@ int start_dma_without_bch_irq(struct gpmi_nand_data *this,
        /* Wait for the interrupt from the DMA block. */
        err = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000));
        if (!err) {
-               pr_err("DMA timeout, last DMA :%d\n", this->last_dma_type);
+               dev_err(this->dev, "DMA timeout, last DMA :%d\n",
+                       this->last_dma_type);
                gpmi_dump_info(this);
                return -ETIMEDOUT;
        }
@@ -467,7 +468,8 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *this,
        /* Wait for the interrupt from the BCH block. */
        err = wait_for_completion_timeout(bch_c, msecs_to_jiffies(1000));
        if (!err) {
-               pr_err("BCH timeout, last DMA :%d\n", this->last_dma_type);
+               dev_err(this->dev, "BCH timeout, last DMA :%d\n",
+                       this->last_dma_type);
                gpmi_dump_info(this);
                return -ETIMEDOUT;
        }
@@ -483,70 +485,38 @@ static int acquire_register_block(struct gpmi_nand_data *this,
        void __iomem *p;
 
        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
-       if (!r) {
-               pr_err("Can't get resource for %s\n", res_name);
-               return -ENODEV;
-       }
-
-       p = ioremap(r->start, resource_size(r));
-       if (!p) {
-               pr_err("Can't remap %s\n", res_name);
-               return -ENOMEM;
-       }
+       p = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
 
        if (!strcmp(res_name, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME))
                res->gpmi_regs = p;
        else if (!strcmp(res_name, GPMI_NAND_BCH_REGS_ADDR_RES_NAME))
                res->bch_regs = p;
        else
-               pr_err("unknown resource name : %s\n", res_name);
+               dev_err(this->dev, "unknown resource name : %s\n", res_name);
 
        return 0;
 }
 
-static void release_register_block(struct gpmi_nand_data *this)
-{
-       struct resources *res = &this->resources;
-       if (res->gpmi_regs)
-               iounmap(res->gpmi_regs);
-       if (res->bch_regs)
-               iounmap(res->bch_regs);
-       res->gpmi_regs = NULL;
-       res->bch_regs = NULL;
-}
-
 static int acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h)
 {
        struct platform_device *pdev = this->pdev;
-       struct resources *res = &this->resources;
        const char *res_name = GPMI_NAND_BCH_INTERRUPT_RES_NAME;
        struct resource *r;
        int err;
 
        r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
        if (!r) {
-               pr_err("Can't get resource for %s\n", res_name);
+               dev_err(this->dev, "Can't get resource for %s\n", res_name);
                return -ENODEV;
        }
 
-       err = request_irq(r->start, irq_h, 0, res_name, this);
-       if (err) {
-               pr_err("Can't own %s\n", res_name);
-               return err;
-       }
-
-       res->bch_low_interrupt = r->start;
-       res->bch_high_interrupt = r->end;
-       return 0;
-}
+       err = devm_request_irq(this->dev, r->start, irq_h, 0, res_name, this);
+       if (err)
+               dev_err(this->dev, "error requesting BCH IRQ\n");
 
-static void release_bch_irq(struct gpmi_nand_data *this)
-{
-       struct resources *res = &this->resources;
-       int i = res->bch_low_interrupt;
-
-       for (; i <= res->bch_high_interrupt; i++)
-               free_irq(i, this);
+       return err;
 }
 
 static void release_dma_channels(struct gpmi_nand_data *this)
@@ -567,7 +537,7 @@ static int acquire_dma_channels(struct gpmi_nand_data *this)
        /* request dma channel */
        dma_chan = dma_request_slave_channel(&pdev->dev, "rx-tx");
        if (!dma_chan) {
-               pr_err("Failed to request DMA channel.\n");
+               dev_err(this->dev, "Failed to request DMA channel.\n");
                goto acquire_err;
        }
 
@@ -579,21 +549,6 @@ acquire_err:
        return -EINVAL;
 }
 
-static void gpmi_put_clks(struct gpmi_nand_data *this)
-{
-       struct resources *r = &this->resources;
-       struct clk *clk;
-       int i;
-
-       for (i = 0; i < GPMI_CLK_MAX; i++) {
-               clk = r->clock[i];
-               if (clk) {
-                       clk_put(clk);
-                       r->clock[i] = NULL;
-               }
-       }
-}
-
 static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = {
        "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch",
 };
@@ -606,7 +561,7 @@ static int gpmi_get_clks(struct gpmi_nand_data *this)
        int err, i;
 
        /* The main clock is stored in the first. */
-       r->clock[0] = clk_get(this->dev, "gpmi_io");
+       r->clock[0] = devm_clk_get(this->dev, "gpmi_io");
        if (IS_ERR(r->clock[0])) {
                err = PTR_ERR(r->clock[0]);
                goto err_clock;
@@ -622,7 +577,7 @@ static int gpmi_get_clks(struct gpmi_nand_data *this)
                if (extra_clks[i - 1] == NULL)
                        break;
 
-               clk = clk_get(this->dev, extra_clks[i - 1]);
+               clk = devm_clk_get(this->dev, extra_clks[i - 1]);
                if (IS_ERR(clk)) {
                        err = PTR_ERR(clk);
                        goto err_clock;
@@ -644,7 +599,6 @@ static int gpmi_get_clks(struct gpmi_nand_data *this)
 
 err_clock:
        dev_dbg(this->dev, "failed in finding the clocks.\n");
-       gpmi_put_clks(this);
        return err;
 }
 
@@ -666,7 +620,7 @@ static int acquire_resources(struct gpmi_nand_data *this)
 
        ret = acquire_dma_channels(this);
        if (ret)
-               goto exit_dma_channels;
+               goto exit_regs;
 
        ret = gpmi_get_clks(this);
        if (ret)
@@ -675,18 +629,12 @@ static int acquire_resources(struct gpmi_nand_data *this)
 
 exit_clock:
        release_dma_channels(this);
-exit_dma_channels:
-       release_bch_irq(this);
 exit_regs:
-       release_register_block(this);
        return ret;
 }
 
 static void release_resources(struct gpmi_nand_data *this)
 {
-       gpmi_put_clks(this);
-       release_register_block(this);
-       release_bch_irq(this);
        release_dma_channels(this);
 }
 
@@ -732,8 +680,7 @@ static int read_page_prepare(struct gpmi_nand_data *this,
                                                length, DMA_FROM_DEVICE);
                if (dma_mapping_error(dev, dest_phys)) {
                        if (alt_size < length) {
-                               pr_err("%s, Alternate buffer is too small\n",
-                                       __func__);
+                               dev_err(dev, "Alternate buffer is too small\n");
                                return -ENOMEM;
                        }
                        goto map_failed;
@@ -783,8 +730,7 @@ static int send_page_prepare(struct gpmi_nand_data *this,
                                                DMA_TO_DEVICE);
                if (dma_mapping_error(dev, source_phys)) {
                        if (alt_size < length) {
-                               pr_err("%s, Alternate buffer is too small\n",
-                                       __func__);
+                               dev_err(dev, "Alternate buffer is too small\n");
                                return -ENOMEM;
                        }
                        goto map_failed;
@@ -872,7 +818,6 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this)
 
 error_alloc:
        gpmi_free_dma_buffer(this);
-       pr_err("Error allocating DMA buffers!\n");
        return -ENOMEM;
 }
 
@@ -904,7 +849,8 @@ static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl)
 
        ret = gpmi_send_command(this);
        if (ret)
-               pr_err("Chip: %u, Error %d\n", this->current_chip, ret);
+               dev_err(this->dev, "Chip: %u, Error %d\n",
+                       this->current_chip, ret);
 
        this->command_length = 0;
 }
@@ -935,7 +881,7 @@ static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
        struct nand_chip *chip = mtd->priv;
        struct gpmi_nand_data *this = chip->priv;
 
-       pr_debug("len is %d\n", len);
+       dev_dbg(this->dev, "len is %d\n", len);
        this->upper_buf = buf;
        this->upper_len = len;
 
@@ -947,7 +893,7 @@ static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
        struct nand_chip *chip = mtd->priv;
        struct gpmi_nand_data *this = chip->priv;
 
-       pr_debug("len is %d\n", len);
+       dev_dbg(this->dev, "len is %d\n", len);
        this->upper_buf = (uint8_t *)buf;
        this->upper_len = len;
 
@@ -1026,13 +972,13 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
        unsigned int  max_bitflips = 0;
        int           ret;
 
-       pr_debug("page number is : %d\n", page);
+       dev_dbg(this->dev, "page number is : %d\n", page);
        ret = read_page_prepare(this, buf, mtd->writesize,
                                        this->payload_virt, this->payload_phys,
                                        nfc_geo->payload_size,
                                        &payload_virt, &payload_phys);
        if (ret) {
-               pr_err("Inadequate DMA buffer\n");
+               dev_err(this->dev, "Inadequate DMA buffer\n");
                ret = -ENOMEM;
                return ret;
        }
@@ -1046,7 +992,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
                        nfc_geo->payload_size,
                        payload_virt, payload_phys);
        if (ret) {
-               pr_err("Error in ECC-based read: %d\n", ret);
+               dev_err(this->dev, "Error in ECC-based read: %d\n", ret);
                return ret;
        }
 
@@ -1102,7 +1048,7 @@ static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
        dma_addr_t auxiliary_phys;
        int        ret;
 
-       pr_debug("ecc write page.\n");
+       dev_dbg(this->dev, "ecc write page.\n");
        if (this->swap_block_mark) {
                /*
                 * If control arrives here, we're doing block mark swapping.
@@ -1132,7 +1078,7 @@ static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                                nfc_geo->payload_size,
                                &payload_virt, &payload_phys);
                if (ret) {
-                       pr_err("Inadequate payload DMA buffer\n");
+                       dev_err(this->dev, "Inadequate payload DMA buffer\n");
                        return 0;
                }
 
@@ -1142,7 +1088,7 @@ static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                                nfc_geo->auxiliary_size,
                                &auxiliary_virt, &auxiliary_phys);
                if (ret) {
-                       pr_err("Inadequate auxiliary DMA buffer\n");
+                       dev_err(this->dev, "Inadequate auxiliary DMA buffer\n");
                        goto exit_auxiliary;
                }
        }
@@ -1150,7 +1096,7 @@ static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
        /* Ask the NFC. */
        ret = gpmi_send_page(this, payload_phys, auxiliary_phys);
        if (ret)
-               pr_err("Error in ECC-based write: %d\n", ret);
+               dev_err(this->dev, "Error in ECC-based write: %d\n", ret);
 
        if (!this->swap_block_mark) {
                send_page_end(this, chip->oob_poi, mtd->oobsize,
@@ -1240,7 +1186,7 @@ static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 {
        struct gpmi_nand_data *this = chip->priv;
 
-       pr_debug("page number is %d\n", page);
+       dev_dbg(this->dev, "page number is %d\n", page);
        /* clear the OOB buffer */
        memset(chip->oob_poi, ~0, mtd->oobsize);
 
@@ -1453,7 +1399,6 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)
 
        /* Write the NCB fingerprint into the page buffer. */
        memset(buffer, ~0, mtd->writesize);
-       memset(chip->oob_poi, ~0, mtd->oobsize);
        memcpy(buffer + 12, fingerprint, strlen(fingerprint));
 
        /* Loop through the first search area, writing NCB fingerprints. */
@@ -1568,7 +1513,7 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this)
        /* Set up the NFC geometry which is used by BCH. */
        ret = bch_set_geometry(this);
        if (ret) {
-               pr_err("Error setting BCH geometry : %d\n", ret);
+               dev_err(this->dev, "Error setting BCH geometry : %d\n", ret);
                return ret;
        }
 
@@ -1576,20 +1521,7 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this)
        return gpmi_alloc_dma_buffer(this);
 }
 
-static int gpmi_pre_bbt_scan(struct gpmi_nand_data  *this)
-{
-       /* Set up swap_block_mark, must be set before the gpmi_set_geometry() */
-       if (GPMI_IS_MX23(this))
-               this->swap_block_mark = false;
-       else
-               this->swap_block_mark = true;
-
-       /* Set up the medium geometry */
-       return gpmi_set_geometry(this);
-
-}
-
-static void gpmi_nfc_exit(struct gpmi_nand_data *this)
+static void gpmi_nand_exit(struct gpmi_nand_data *this)
 {
        nand_release(&this->mtd);
        gpmi_free_dma_buffer(this);
@@ -1603,8 +1535,11 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
        struct bch_geometry *bch_geo = &this->bch_geometry;
        int ret;
 
-       /* Prepare for the BBT scan. */
-       ret = gpmi_pre_bbt_scan(this);
+       /* Set up swap_block_mark, must be set before the gpmi_set_geometry() */
+       this->swap_block_mark = !GPMI_IS_MX23(this);
+
+       /* Set up the medium geometry */
+       ret = gpmi_set_geometry(this);
        if (ret)
                return ret;
 
@@ -1629,7 +1564,7 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
        return 0;
 }
 
-static int gpmi_nfc_init(struct gpmi_nand_data *this)
+static int gpmi_nand_init(struct gpmi_nand_data *this)
 {
        struct mtd_info  *mtd = &this->mtd;
        struct nand_chip *chip = &this->nand;
@@ -1693,7 +1628,7 @@ static int gpmi_nfc_init(struct gpmi_nand_data *this)
        return 0;
 
 err_out:
-       gpmi_nfc_exit(this);
+       gpmi_nand_exit(this);
        return ret;
 }
 
@@ -1728,15 +1663,13 @@ static int gpmi_nand_probe(struct platform_device *pdev)
        if (of_id) {
                pdev->id_entry = of_id->data;
        } else {
-               pr_err("Failed to find the right device id.\n");
+               dev_err(&pdev->dev, "Failed to find the right device id.\n");
                return -ENODEV;
        }
 
        this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL);
-       if (!this) {
-               pr_err("Failed to allocate per-device memory\n");
+       if (!this)
                return -ENOMEM;
-       }
 
        platform_set_drvdata(pdev, this);
        this->pdev  = pdev;
@@ -1750,7 +1683,7 @@ static int gpmi_nand_probe(struct platform_device *pdev)
        if (ret)
                goto exit_nfc_init;
 
-       ret = gpmi_nfc_init(this);
+       ret = gpmi_nand_init(this);
        if (ret)
                goto exit_nfc_init;
 
@@ -1770,7 +1703,7 @@ static int gpmi_nand_remove(struct platform_device *pdev)
 {
        struct gpmi_nand_data *this = platform_get_drvdata(pdev);
 
-       gpmi_nfc_exit(this);
+       gpmi_nand_exit(this);
        release_resources(this);
        return 0;
 }
index a7685e3a87486b86713fef19da82e9bbad3c6253..4c801fa1872530e681e801d2adaee333d4acffb4 100644 (file)
@@ -26,8 +26,6 @@
 struct resources {
        void __iomem  *gpmi_regs;
        void __iomem  *bch_regs;
-       unsigned int  bch_low_interrupt;
-       unsigned int  bch_high_interrupt;
        unsigned int  dma_low_channel;
        unsigned int  dma_high_channel;
        struct clk    *clock[GPMI_CLK_MAX];
index 439bc389641841dc05f79ab638f7010e4a9cd053..d744cf7989785e64f64145fa58fed379412b285e 100644 (file)
@@ -786,7 +786,6 @@ static int mpc5121_nfc_probe(struct platform_device *op)
        /* Detect NAND chips */
        if (nand_scan(mtd, be32_to_cpup(chips_no))) {
                dev_err(dev, "NAND Flash not found !\n");
-               devm_free_irq(dev, prv->irq, mtd);
                retval = -ENXIO;
                goto error;
        }
@@ -811,7 +810,6 @@ static int mpc5121_nfc_probe(struct platform_device *op)
 
        default:
                dev_err(dev, "Unsupported NAND flash!\n");
-               devm_free_irq(dev, prv->irq, mtd);
                retval = -ENXIO;
                goto error;
        }
@@ -822,7 +820,6 @@ static int mpc5121_nfc_probe(struct platform_device *op)
        retval = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
        if (retval) {
                dev_err(dev, "Error adding MTD device!\n");
-               devm_free_irq(dev, prv->irq, mtd);
                goto error;
        }
 
@@ -836,11 +833,8 @@ static int mpc5121_nfc_remove(struct platform_device *op)
 {
        struct device *dev = &op->dev;
        struct mtd_info *mtd = dev_get_drvdata(dev);
-       struct nand_chip *chip = mtd->priv;
-       struct mpc5121_nfc_prv *prv = chip->priv;
 
        nand_release(mtd);
-       devm_free_irq(dev, prv->irq, mtd);
        mpc5121_nfc_free(dev, mtd);
 
        return 0;
index 4d174366a0f09ec2ebecd99fc8241fc978a05caa..90f871acb0efec737c918532bbdd350ca7969220 100644 (file)
@@ -223,7 +223,7 @@ MODULE_DEVICE_TABLE(of, pasemi_nand_match);
 static struct platform_driver pasemi_nand_driver =
 {
        .driver = {
-               .name = (char*)driver_name,
+               .name = driver_name,
                .owner = THIS_MODULE,
                .of_match_table = pasemi_nand_match,
        },
index 4cabdc9fda9076ceff440af42e028fb1073f9ed7..3d143fec2c0ce4f563060054ca88e41c712c52a5 100644 (file)
@@ -7,6 +7,8 @@
  * 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.
+ *
+ * See Documentation/mtd/nand/pxa3xx-nand.txt for more details.
  */
 
 #include <linux/kernel.h>
@@ -24,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_mtd.h>
 
 #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
 #define ARCH_HAS_DMA
@@ -35,6 +38,7 @@
 
 #include <linux/platform_data/mtd-nand-pxa3xx.h>
 
+#define NAND_DEV_READY_TIMEOUT  50
 #define        CHIP_DELAY_TIMEOUT      (2 * HZ/10)
 #define NAND_STOP_DELAY                (2 * HZ/50)
 #define PAGE_CHUNK_SIZE                (2048)
@@ -54,6 +58,7 @@
 #define NDPCR          (0x18) /* Page Count Register */
 #define NDBDR0         (0x1C) /* Bad Block Register 0 */
 #define NDBDR1         (0x20) /* Bad Block Register 1 */
+#define NDECCCTRL      (0x28) /* ECC control */
 #define NDDB           (0x40) /* Data Buffer */
 #define NDCB0          (0x48) /* Command Buffer0 */
 #define NDCB1          (0x4C) /* Command Buffer1 */
@@ -80,6 +85,9 @@
 #define NDCR_INT_MASK           (0xFFF)
 
 #define NDSR_MASK              (0xfff)
+#define NDSR_ERR_CNT_OFF       (16)
+#define NDSR_ERR_CNT_MASK       (0x1f)
+#define NDSR_ERR_CNT(sr)       ((sr >> NDSR_ERR_CNT_OFF) & NDSR_ERR_CNT_MASK)
 #define NDSR_RDY                (0x1 << 12)
 #define NDSR_FLASH_RDY          (0x1 << 11)
 #define NDSR_CS0_PAGED         (0x1 << 10)
@@ -88,8 +96,8 @@
 #define NDSR_CS1_CMDD          (0x1 << 7)
 #define NDSR_CS0_BBD           (0x1 << 6)
 #define NDSR_CS1_BBD           (0x1 << 5)
-#define NDSR_DBERR             (0x1 << 4)
-#define NDSR_SBERR             (0x1 << 3)
+#define NDSR_UNCORERR          (0x1 << 4)
+#define NDSR_CORERR            (0x1 << 3)
 #define NDSR_WRDREQ            (0x1 << 2)
 #define NDSR_RDDREQ            (0x1 << 1)
 #define NDSR_WRCMDREQ          (0x1)
 #define NDCB0_ST_ROW_EN         (0x1 << 26)
 #define NDCB0_AUTO_RS          (0x1 << 25)
 #define NDCB0_CSEL             (0x1 << 24)
+#define NDCB0_EXT_CMD_TYPE_MASK        (0x7 << 29)
+#define NDCB0_EXT_CMD_TYPE(x)  (((x) << 29) & NDCB0_EXT_CMD_TYPE_MASK)
 #define NDCB0_CMD_TYPE_MASK    (0x7 << 21)
 #define NDCB0_CMD_TYPE(x)      (((x) << 21) & NDCB0_CMD_TYPE_MASK)
 #define NDCB0_NC               (0x1 << 20)
 #define NDCB0_CMD1_MASK                (0xff)
 #define NDCB0_ADDR_CYC_SHIFT   (16)
 
+#define EXT_CMD_TYPE_DISPATCH  6 /* Command dispatch */
+#define EXT_CMD_TYPE_NAKED_RW  5 /* Naked read or Naked write */
+#define EXT_CMD_TYPE_READ      4 /* Read */
+#define EXT_CMD_TYPE_DISP_WR   4 /* Command dispatch with write */
+#define EXT_CMD_TYPE_FINAL     3 /* Final command */
+#define EXT_CMD_TYPE_LAST_RW   1 /* Last naked read/write */
+#define EXT_CMD_TYPE_MONO      0 /* Monolithic read/write */
+
 /* macros for registers read/write */
 #define nand_writel(info, off, val)    \
        __raw_writel((val), (info)->mmio_base + (off))
@@ -120,9 +138,9 @@ enum {
        ERR_NONE        = 0,
        ERR_DMABUSERR   = -1,
        ERR_SENDCMD     = -2,
-       ERR_DBERR       = -3,
+       ERR_UNCORERR    = -3,
        ERR_BBERR       = -4,
-       ERR_SBERR       = -5,
+       ERR_CORERR      = -5,
 };
 
 enum {
@@ -149,7 +167,6 @@ struct pxa3xx_nand_host {
        void                    *info_data;
 
        /* page size of attached chip */
-       unsigned int            page_size;
        int                     use_ecc;
        int                     cs;
 
@@ -167,11 +184,13 @@ struct pxa3xx_nand_info {
        struct clk              *clk;
        void __iomem            *mmio_base;
        unsigned long           mmio_phys;
-       struct completion       cmd_complete;
+       struct completion       cmd_complete, dev_ready;
 
        unsigned int            buf_start;
        unsigned int            buf_count;
        unsigned int            buf_size;
+       unsigned int            data_buff_pos;
+       unsigned int            oob_buff_pos;
 
        /* DMA information */
        int                     drcmr_dat;
@@ -195,13 +214,18 @@ struct pxa3xx_nand_info {
 
        int                     cs;
        int                     use_ecc;        /* use HW ECC ? */
+       int                     ecc_bch;        /* using BCH ECC? */
        int                     use_dma;        /* use DMA ? */
        int                     use_spare;      /* use spare ? */
-       int                     is_ready;
+       int                     need_wait;
 
-       unsigned int            page_size;      /* page size of attached chip */
-       unsigned int            data_size;      /* data size in FIFO */
+       unsigned int            data_size;      /* data to be read from FIFO */
+       unsigned int            chunk_size;     /* split commands chunk size */
        unsigned int            oob_size;
+       unsigned int            spare_size;
+       unsigned int            ecc_size;
+       unsigned int            ecc_err_cnt;
+       unsigned int            max_bitflips;
        int                     retcode;
 
        /* cached register value */
@@ -239,6 +263,54 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
 { "256MiB 16-bit", 0xba20,  64, 2048, 16, 16, 2048, &timing[3] },
 };
 
+static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
+static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+               | NAND_BBT_2BIT | NAND_BBT_VERSION,
+       .offs = 8,
+       .len = 6,
+       .veroffs = 14,
+       .maxblocks = 8,         /* Last 8 blocks in each chip */
+       .pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+               | NAND_BBT_2BIT | NAND_BBT_VERSION,
+       .offs = 8,
+       .len = 6,
+       .veroffs = 14,
+       .maxblocks = 8,         /* Last 8 blocks in each chip */
+       .pattern = bbt_mirror_pattern
+};
+
+static struct nand_ecclayout ecc_layout_4KB_bch4bit = {
+       .eccbytes = 64,
+       .eccpos = {
+               32,  33,  34,  35,  36,  37,  38,  39,
+               40,  41,  42,  43,  44,  45,  46,  47,
+               48,  49,  50,  51,  52,  53,  54,  55,
+               56,  57,  58,  59,  60,  61,  62,  63,
+               96,  97,  98,  99,  100, 101, 102, 103,
+               104, 105, 106, 107, 108, 109, 110, 111,
+               112, 113, 114, 115, 116, 117, 118, 119,
+               120, 121, 122, 123, 124, 125, 126, 127},
+       /* Bootrom looks in bytes 0 & 5 for bad blocks */
+       .oobfree = { {6, 26}, { 64, 32} }
+};
+
+static struct nand_ecclayout ecc_layout_4KB_bch8bit = {
+       .eccbytes = 128,
+       .eccpos = {
+               32,  33,  34,  35,  36,  37,  38,  39,
+               40,  41,  42,  43,  44,  45,  46,  47,
+               48,  49,  50,  51,  52,  53,  54,  55,
+               56,  57,  58,  59,  60,  61,  62,  63},
+       .oobfree = { }
+};
+
 /* Define a default flash type setting serve as flash detecting only */
 #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
 
@@ -256,6 +328,29 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
 /* convert nano-seconds to nand flash controller clock cycles */
 #define ns2cycle(ns, clk)      (int)((ns) * (clk / 1000000) / 1000)
 
+static struct of_device_id pxa3xx_nand_dt_ids[] = {
+       {
+               .compatible = "marvell,pxa3xx-nand",
+               .data       = (void *)PXA3XX_NAND_VARIANT_PXA,
+       },
+       {
+               .compatible = "marvell,armada370-nand",
+               .data       = (void *)PXA3XX_NAND_VARIANT_ARMADA370,
+       },
+       {}
+};
+MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
+
+static enum pxa3xx_nand_variant
+pxa3xx_nand_get_variant(struct platform_device *pdev)
+{
+       const struct of_device_id *of_id =
+                       of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
+       if (!of_id)
+               return PXA3XX_NAND_VARIANT_PXA;
+       return (enum pxa3xx_nand_variant)of_id->data;
+}
+
 static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
                                   const struct pxa3xx_nand_timing *t)
 {
@@ -280,25 +375,23 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
        nand_writel(info, NDTR1CS0, ndtr1);
 }
 
-static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
+/*
+ * Set the data and OOB size, depending on the selected
+ * spare and ECC configuration.
+ * Only applicable to READ0, READOOB and PAGEPROG commands.
+ */
+static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info,
+                               struct mtd_info *mtd)
 {
-       struct pxa3xx_nand_host *host = info->host[info->cs];
        int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
 
-       info->data_size = host->page_size;
-       if (!oob_enable) {
-               info->oob_size = 0;
+       info->data_size = mtd->writesize;
+       if (!oob_enable)
                return;
-       }
 
-       switch (host->page_size) {
-       case 2048:
-               info->oob_size = (info->use_ecc) ? 40 : 64;
-               break;
-       case 512:
-               info->oob_size = (info->use_ecc) ? 8 : 16;
-               break;
-       }
+       info->oob_size = info->spare_size;
+       if (!info->use_ecc)
+               info->oob_size += info->ecc_size;
 }
 
 /**
@@ -313,10 +406,15 @@ static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
 
        ndcr = info->reg_ndcr;
 
-       if (info->use_ecc)
+       if (info->use_ecc) {
                ndcr |= NDCR_ECC_EN;
-       else
+               if (info->ecc_bch)
+                       nand_writel(info, NDECCCTRL, 0x1);
+       } else {
                ndcr &= ~NDCR_ECC_EN;
+               if (info->ecc_bch)
+                       nand_writel(info, NDECCCTRL, 0x0);
+       }
 
        if (info->use_dma)
                ndcr |= NDCR_DMA_EN;
@@ -375,26 +473,39 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
 
 static void handle_data_pio(struct pxa3xx_nand_info *info)
 {
+       unsigned int do_bytes = min(info->data_size, info->chunk_size);
+
        switch (info->state) {
        case STATE_PIO_WRITING:
-               __raw_writesl(info->mmio_base + NDDB, info->data_buff,
-                               DIV_ROUND_UP(info->data_size, 4));
+               __raw_writesl(info->mmio_base + NDDB,
+                             info->data_buff + info->data_buff_pos,
+                             DIV_ROUND_UP(do_bytes, 4));
+
                if (info->oob_size > 0)
-                       __raw_writesl(info->mmio_base + NDDB, info->oob_buff,
-                                       DIV_ROUND_UP(info->oob_size, 4));
+                       __raw_writesl(info->mmio_base + NDDB,
+                                     info->oob_buff + info->oob_buff_pos,
+                                     DIV_ROUND_UP(info->oob_size, 4));
                break;
        case STATE_PIO_READING:
-               __raw_readsl(info->mmio_base + NDDB, info->data_buff,
-                               DIV_ROUND_UP(info->data_size, 4));
+               __raw_readsl(info->mmio_base + NDDB,
+                            info->data_buff + info->data_buff_pos,
+                            DIV_ROUND_UP(do_bytes, 4));
+
                if (info->oob_size > 0)
-                       __raw_readsl(info->mmio_base + NDDB, info->oob_buff,
-                                       DIV_ROUND_UP(info->oob_size, 4));
+                       __raw_readsl(info->mmio_base + NDDB,
+                                    info->oob_buff + info->oob_buff_pos,
+                                    DIV_ROUND_UP(info->oob_size, 4));
                break;
        default:
                dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
                                info->state);
                BUG();
        }
+
+       /* Update buffer pointers for multi-page read/write */
+       info->data_buff_pos += do_bytes;
+       info->oob_buff_pos += info->oob_size;
+       info->data_size -= do_bytes;
 }
 
 #ifdef ARCH_HAS_DMA
@@ -452,7 +563,7 @@ static void start_data_dma(struct pxa3xx_nand_info *info)
 static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 {
        struct pxa3xx_nand_info *info = devid;
-       unsigned int status, is_completed = 0;
+       unsigned int status, is_completed = 0, is_ready = 0;
        unsigned int ready, cmd_done;
 
        if (info->cs == 0) {
@@ -465,10 +576,25 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 
        status = nand_readl(info, NDSR);
 
-       if (status & NDSR_DBERR)
-               info->retcode = ERR_DBERR;
-       if (status & NDSR_SBERR)
-               info->retcode = ERR_SBERR;
+       if (status & NDSR_UNCORERR)
+               info->retcode = ERR_UNCORERR;
+       if (status & NDSR_CORERR) {
+               info->retcode = ERR_CORERR;
+               if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 &&
+                   info->ecc_bch)
+                       info->ecc_err_cnt = NDSR_ERR_CNT(status);
+               else
+                       info->ecc_err_cnt = 1;
+
+               /*
+                * Each chunk composing a page is corrected independently,
+                * and we need to store maximum number of corrected bitflips
+                * to return it to the MTD layer in ecc.read_page().
+                */
+               info->max_bitflips = max_t(unsigned int,
+                                          info->max_bitflips,
+                                          info->ecc_err_cnt);
+       }
        if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) {
                /* whether use dma to transfer data */
                if (info->use_dma) {
@@ -488,8 +614,8 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
                is_completed = 1;
        }
        if (status & ready) {
-               info->is_ready = 1;
                info->state = STATE_READY;
+               is_ready = 1;
        }
 
        if (status & NDSR_WRCMDREQ) {
@@ -518,6 +644,8 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
        nand_writel(info, NDSR, status);
        if (is_completed)
                complete(&info->cmd_complete);
+       if (is_ready)
+               complete(&info->dev_ready);
 NORMAL_IRQ_EXIT:
        return IRQ_HANDLED;
 }
@@ -530,51 +658,93 @@ static inline int is_buf_blank(uint8_t *buf, size_t len)
        return 1;
 }
 
-static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
-               uint16_t column, int page_addr)
+static void set_command_address(struct pxa3xx_nand_info *info,
+               unsigned int page_size, uint16_t column, int page_addr)
 {
-       int addr_cycle, exec_cmd;
-       struct pxa3xx_nand_host *host;
-       struct mtd_info *mtd;
+       /* small page addr setting */
+       if (page_size < PAGE_CHUNK_SIZE) {
+               info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
+                               | (column & 0xFF);
 
-       host = info->host[info->cs];
-       mtd = host->mtd;
-       addr_cycle = 0;
-       exec_cmd = 1;
+               info->ndcb2 = 0;
+       } else {
+               info->ndcb1 = ((page_addr & 0xFFFF) << 16)
+                               | (column & 0xFFFF);
+
+               if (page_addr & 0xFF0000)
+                       info->ndcb2 = (page_addr & 0xFF0000) >> 16;
+               else
+                       info->ndcb2 = 0;
+       }
+}
+
+static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
+{
+       struct pxa3xx_nand_host *host = info->host[info->cs];
+       struct mtd_info *mtd = host->mtd;
 
        /* reset data and oob column point to handle data */
        info->buf_start         = 0;
        info->buf_count         = 0;
        info->oob_size          = 0;
+       info->data_buff_pos     = 0;
+       info->oob_buff_pos      = 0;
        info->use_ecc           = 0;
        info->use_spare         = 1;
-       info->is_ready          = 0;
        info->retcode           = ERR_NONE;
-       if (info->cs != 0)
-               info->ndcb0 = NDCB0_CSEL;
-       else
-               info->ndcb0 = 0;
+       info->ecc_err_cnt       = 0;
+       info->ndcb3             = 0;
 
        switch (command) {
        case NAND_CMD_READ0:
        case NAND_CMD_PAGEPROG:
                info->use_ecc = 1;
        case NAND_CMD_READOOB:
-               pxa3xx_set_datasize(info);
+               pxa3xx_set_datasize(info, mtd);
                break;
        case NAND_CMD_PARAM:
                info->use_spare = 0;
                break;
-       case NAND_CMD_SEQIN:
-               exec_cmd = 0;
-               break;
        default:
                info->ndcb1 = 0;
                info->ndcb2 = 0;
-               info->ndcb3 = 0;
                break;
        }
 
+       /*
+        * If we are about to issue a read command, or about to set
+        * the write address, then clean the data buffer.
+        */
+       if (command == NAND_CMD_READ0 ||
+           command == NAND_CMD_READOOB ||
+           command == NAND_CMD_SEQIN) {
+
+               info->buf_count = mtd->writesize + mtd->oobsize;
+               memset(info->data_buff, 0xFF, info->buf_count);
+       }
+
+}
+
+static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
+               int ext_cmd_type, uint16_t column, int page_addr)
+{
+       int addr_cycle, exec_cmd;
+       struct pxa3xx_nand_host *host;
+       struct mtd_info *mtd;
+
+       host = info->host[info->cs];
+       mtd = host->mtd;
+       addr_cycle = 0;
+       exec_cmd = 1;
+
+       if (info->cs != 0)
+               info->ndcb0 = NDCB0_CSEL;
+       else
+               info->ndcb0 = 0;
+
+       if (command == NAND_CMD_SEQIN)
+               exec_cmd = 0;
+
        addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles
                                    + host->col_addr_cycles);
 
@@ -589,30 +759,42 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                if (command == NAND_CMD_READOOB)
                        info->buf_start += mtd->writesize;
 
-               /* Second command setting for large pages */
-               if (host->page_size >= PAGE_CHUNK_SIZE)
+               /*
+                * Multiple page read needs an 'extended command type' field,
+                * which is either naked-read or last-read according to the
+                * state.
+                */
+               if (mtd->writesize == PAGE_CHUNK_SIZE) {
                        info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
+               } else if (mtd->writesize > PAGE_CHUNK_SIZE) {
+                       info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8)
+                                       | NDCB0_LEN_OVRD
+                                       | NDCB0_EXT_CMD_TYPE(ext_cmd_type);
+                       info->ndcb3 = info->chunk_size +
+                                     info->oob_size;
+               }
+
+               set_command_address(info, mtd->writesize, column, page_addr);
+               break;
 
        case NAND_CMD_SEQIN:
-               /* small page addr setting */
-               if (unlikely(host->page_size < PAGE_CHUNK_SIZE)) {
-                       info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
-                                       | (column & 0xFF);
 
-                       info->ndcb2 = 0;
-               } else {
-                       info->ndcb1 = ((page_addr & 0xFFFF) << 16)
-                                       | (column & 0xFFFF);
+               info->buf_start = column;
+               set_command_address(info, mtd->writesize, 0, page_addr);
 
-                       if (page_addr & 0xFF0000)
-                               info->ndcb2 = (page_addr & 0xFF0000) >> 16;
-                       else
-                               info->ndcb2 = 0;
+               /*
+                * Multiple page programming needs to execute the initial
+                * SEQIN command that sets the page address.
+                */
+               if (mtd->writesize > PAGE_CHUNK_SIZE) {
+                       info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
+                               | NDCB0_EXT_CMD_TYPE(ext_cmd_type)
+                               | addr_cycle
+                               | command;
+                       /* No data transfer in this case */
+                       info->data_size = 0;
+                       exec_cmd = 1;
                }
-
-               info->buf_count = mtd->writesize + mtd->oobsize;
-               memset(info->data_buff, 0xFF, info->buf_count);
-
                break;
 
        case NAND_CMD_PAGEPROG:
@@ -622,13 +804,40 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                        break;
                }
 
-               info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
-                               | NDCB0_AUTO_RS
-                               | NDCB0_ST_ROW_EN
-                               | NDCB0_DBC
-                               | (NAND_CMD_PAGEPROG << 8)
-                               | NAND_CMD_SEQIN
-                               | addr_cycle;
+               /* Second command setting for large pages */
+               if (mtd->writesize > PAGE_CHUNK_SIZE) {
+                       /*
+                        * Multiple page write uses the 'extended command'
+                        * field. This can be used to issue a command dispatch
+                        * or a naked-write depending on the current stage.
+                        */
+                       info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
+                                       | NDCB0_LEN_OVRD
+                                       | NDCB0_EXT_CMD_TYPE(ext_cmd_type);
+                       info->ndcb3 = info->chunk_size +
+                                     info->oob_size;
+
+                       /*
+                        * This is the command dispatch that completes a chunked
+                        * page program operation.
+                        */
+                       if (info->data_size == 0) {
+                               info->ndcb0 = NDCB0_CMD_TYPE(0x1)
+                                       | NDCB0_EXT_CMD_TYPE(ext_cmd_type)
+                                       | command;
+                               info->ndcb1 = 0;
+                               info->ndcb2 = 0;
+                               info->ndcb3 = 0;
+                       }
+               } else {
+                       info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
+                                       | NDCB0_AUTO_RS
+                                       | NDCB0_ST_ROW_EN
+                                       | NDCB0_DBC
+                                       | (NAND_CMD_PAGEPROG << 8)
+                                       | NAND_CMD_SEQIN
+                                       | addr_cycle;
+               }
                break;
 
        case NAND_CMD_PARAM:
@@ -717,10 +926,15 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
                nand_writel(info, NDTR1CS0, info->ndtr1cs0);
        }
 
+       prepare_start_command(info, command);
+
        info->state = STATE_PREPARED;
-       exec_cmd = prepare_command_pool(info, command, column, page_addr);
+       exec_cmd = prepare_set_command(info, command, 0, column, page_addr);
+
        if (exec_cmd) {
                init_completion(&info->cmd_complete);
+               init_completion(&info->dev_ready);
+               info->need_wait = 1;
                pxa3xx_nand_start(info);
 
                ret = wait_for_completion_timeout(&info->cmd_complete,
@@ -734,6 +948,117 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
        info->state = STATE_IDLE;
 }
 
+static void armada370_nand_cmdfunc(struct mtd_info *mtd,
+                                  const unsigned command,
+                                  int column, int page_addr)
+{
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
+       int ret, exec_cmd, ext_cmd_type;
+
+       /*
+        * if this is a x16 device then convert the input
+        * "byte" address into a "word" address appropriate
+        * for indexing a word-oriented device
+        */
+       if (info->reg_ndcr & NDCR_DWIDTH_M)
+               column /= 2;
+
+       /*
+        * There may be different NAND chip hooked to
+        * different chip select, so check whether
+        * chip select has been changed, if yes, reset the timing
+        */
+       if (info->cs != host->cs) {
+               info->cs = host->cs;
+               nand_writel(info, NDTR0CS0, info->ndtr0cs0);
+               nand_writel(info, NDTR1CS0, info->ndtr1cs0);
+       }
+
+       /* Select the extended command for the first command */
+       switch (command) {
+       case NAND_CMD_READ0:
+       case NAND_CMD_READOOB:
+               ext_cmd_type = EXT_CMD_TYPE_MONO;
+               break;
+       case NAND_CMD_SEQIN:
+               ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
+               break;
+       case NAND_CMD_PAGEPROG:
+               ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
+               break;
+       default:
+               ext_cmd_type = 0;
+               break;
+       }
+
+       prepare_start_command(info, command);
+
+       /*
+        * Prepare the "is ready" completion before starting a command
+        * transaction sequence. If the command is not executed the
+        * completion will be completed, see below.
+        *
+        * We can do that inside the loop because the command variable
+        * is invariant and thus so is the exec_cmd.
+        */
+       info->need_wait = 1;
+       init_completion(&info->dev_ready);
+       do {
+               info->state = STATE_PREPARED;
+               exec_cmd = prepare_set_command(info, command, ext_cmd_type,
+                                              column, page_addr);
+               if (!exec_cmd) {
+                       info->need_wait = 0;
+                       complete(&info->dev_ready);
+                       break;
+               }
+
+               init_completion(&info->cmd_complete);
+               pxa3xx_nand_start(info);
+
+               ret = wait_for_completion_timeout(&info->cmd_complete,
+                               CHIP_DELAY_TIMEOUT);
+               if (!ret) {
+                       dev_err(&info->pdev->dev, "Wait time out!!!\n");
+                       /* Stop State Machine for next command cycle */
+                       pxa3xx_nand_stop(info);
+                       break;
+               }
+
+               /* Check if the sequence is complete */
+               if (info->data_size == 0 && command != NAND_CMD_PAGEPROG)
+                       break;
+
+               /*
+                * After a splitted program command sequence has issued
+                * the command dispatch, the command sequence is complete.
+                */
+               if (info->data_size == 0 &&
+                   command == NAND_CMD_PAGEPROG &&
+                   ext_cmd_type == EXT_CMD_TYPE_DISPATCH)
+                       break;
+
+               if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) {
+                       /* Last read: issue a 'last naked read' */
+                       if (info->data_size == info->chunk_size)
+                               ext_cmd_type = EXT_CMD_TYPE_LAST_RW;
+                       else
+                               ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
+
+               /*
+                * If a splitted program command has no more data to transfer,
+                * the command dispatch must be issued to complete.
+                */
+               } else if (command == NAND_CMD_PAGEPROG &&
+                          info->data_size == 0) {
+                               ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
+               }
+       } while (1);
+
+       info->state = STATE_IDLE;
+}
+
 static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
                struct nand_chip *chip, const uint8_t *buf, int oob_required)
 {
@@ -753,20 +1078,14 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
        chip->read_buf(mtd, buf, mtd->writesize);
        chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-       if (info->retcode == ERR_SBERR) {
-               switch (info->use_ecc) {
-               case 1:
-                       mtd->ecc_stats.corrected++;
-                       break;
-               case 0:
-               default:
-                       break;
-               }
-       } else if (info->retcode == ERR_DBERR) {
+       if (info->retcode == ERR_CORERR && info->use_ecc) {
+               mtd->ecc_stats.corrected += info->ecc_err_cnt;
+
+       } else if (info->retcode == ERR_UNCORERR) {
                /*
                 * for blank page (all 0xff), HW will calculate its ECC as
                 * 0, which is different from the ECC information within
-                * OOB, ignore such double bit errors
+                * OOB, ignore such uncorrectable errors
                 */
                if (is_buf_blank(buf, mtd->writesize))
                        info->retcode = ERR_NONE;
@@ -774,7 +1093,7 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
                        mtd->ecc_stats.failed++;
        }
 
-       return 0;
+       return info->max_bitflips;
 }
 
 static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
@@ -833,21 +1152,27 @@ static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
 {
        struct pxa3xx_nand_host *host = mtd->priv;
        struct pxa3xx_nand_info *info = host->info_data;
+       int ret;
+
+       if (info->need_wait) {
+               ret = wait_for_completion_timeout(&info->dev_ready,
+                               CHIP_DELAY_TIMEOUT);
+               info->need_wait = 0;
+               if (!ret) {
+                       dev_err(&info->pdev->dev, "Ready time out!!!\n");
+                       return NAND_STATUS_FAIL;
+               }
+       }
 
        /* pxa3xx_nand_send_command has waited for command complete */
        if (this->state == FL_WRITING || this->state == FL_ERASING) {
                if (info->retcode == ERR_NONE)
                        return 0;
-               else {
-                       /*
-                        * any error make it return 0x01 which will tell
-                        * the caller the erase and write fail
-                        */
-                       return 0x01;
-               }
+               else
+                       return NAND_STATUS_FAIL;
        }
 
-       return 0;
+       return NAND_STATUS_READY;
 }
 
 static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
@@ -869,7 +1194,6 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
        }
 
        /* calculate flash information */
-       host->page_size = f->page_size;
        host->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
 
        /* calculate addressing information */
@@ -906,13 +1230,15 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
        uint32_t ndcr = nand_readl(info, NDCR);
 
        if (ndcr & NDCR_PAGE_SZ) {
-               host->page_size = 2048;
+               /* Controller's FIFO size */
+               info->chunk_size = 2048;
                host->read_id_bytes = 4;
        } else {
-               host->page_size = 512;
+               info->chunk_size = 512;
                host->read_id_bytes = 2;
        }
 
+       /* Set an initial chunk size */
        info->reg_ndcr = ndcr & ~NDCR_INT_MASK;
        info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
        info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
@@ -988,18 +1314,89 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
 static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
 {
        struct mtd_info *mtd;
+       struct nand_chip *chip;
        int ret;
+
        mtd = info->host[info->cs]->mtd;
+       chip = mtd->priv;
+
        /* use the common timing to make a try */
        ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]);
        if (ret)
                return ret;
 
-       pxa3xx_nand_cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
-       if (info->is_ready)
-               return 0;
+       chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
+       ret = chip->waitfunc(mtd, chip);
+       if (ret & NAND_STATUS_FAIL)
+               return -ENODEV;
 
-       return -ENODEV;
+       return 0;
+}
+
+static int pxa_ecc_init(struct pxa3xx_nand_info *info,
+                       struct nand_ecc_ctrl *ecc,
+                       int strength, int page_size)
+{
+       /*
+        * We don't use strength here as the PXA variant
+        * is used with non-ONFI compliant devices.
+        */
+       if (page_size == 2048) {
+               info->chunk_size = 2048;
+               info->spare_size = 40;
+               info->ecc_size = 24;
+               ecc->mode = NAND_ECC_HW;
+               ecc->size = 512;
+               ecc->strength = 1;
+               return 1;
+
+       } else if (page_size == 512) {
+               info->chunk_size = 512;
+               info->spare_size = 8;
+               info->ecc_size = 8;
+               ecc->mode = NAND_ECC_HW;
+               ecc->size = 512;
+               ecc->strength = 1;
+               return 1;
+       }
+       return 0;
+}
+
+static int armada370_ecc_init(struct pxa3xx_nand_info *info,
+                             struct nand_ecc_ctrl *ecc,
+                             int strength, int ecc_stepsize, int page_size)
+{
+       /*
+        * Required ECC: 4-bit correction per 512 bytes
+        * Select: 16-bit correction per 2048 bytes
+        */
+       if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) {
+               info->ecc_bch = 1;
+               info->chunk_size = 2048;
+               info->spare_size = 32;
+               info->ecc_size = 32;
+               ecc->mode = NAND_ECC_HW;
+               ecc->size = info->chunk_size;
+               ecc->layout = &ecc_layout_4KB_bch4bit;
+               ecc->strength = 16;
+               return 1;
+
+       /*
+        * Required ECC: 8-bit correction per 512 bytes
+        * Select: 16-bit correction per 1024 bytes
+        */
+       } else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) {
+               info->ecc_bch = 1;
+               info->chunk_size = 1024;
+               info->spare_size = 0;
+               info->ecc_size = 32;
+               ecc->mode = NAND_ECC_HW;
+               ecc->size = info->chunk_size;
+               ecc->layout = &ecc_layout_4KB_bch8bit;
+               ecc->strength = 16;
+               return 1;
+       }
+       return 0;
 }
 
 static int pxa3xx_nand_scan(struct mtd_info *mtd)
@@ -1072,15 +1469,43 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
        pxa3xx_flash_ids[1].name = NULL;
        def = pxa3xx_flash_ids;
 KEEP_CONFIG:
-       chip->ecc.mode = NAND_ECC_HW;
-       chip->ecc.size = host->page_size;
-       chip->ecc.strength = 1;
-
        if (info->reg_ndcr & NDCR_DWIDTH_M)
                chip->options |= NAND_BUSWIDTH_16;
 
+       /* Device detection must be done with ECC disabled */
+       if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+               nand_writel(info, NDECCCTRL, 0x0);
+
        if (nand_scan_ident(mtd, 1, def))
                return -ENODEV;
+
+       if (pdata->flash_bbt) {
+               /*
+                * We'll use a bad block table stored in-flash and don't
+                * allow writing the bad block marker to the flash.
+                */
+               chip->bbt_options |= NAND_BBT_USE_FLASH |
+                                    NAND_BBT_NO_OOB_BBM;
+               chip->bbt_td = &bbt_main_descr;
+               chip->bbt_md = &bbt_mirror_descr;
+       }
+
+       if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+               ret = armada370_ecc_init(info, &chip->ecc,
+                                  chip->ecc_strength_ds,
+                                  chip->ecc_step_ds,
+                                  mtd->writesize);
+       else
+               ret = pxa_ecc_init(info, &chip->ecc,
+                                  chip->ecc_strength_ds,
+                                  mtd->writesize);
+       if (!ret) {
+               dev_err(&info->pdev->dev,
+                       "ECC strength %d at page size %d is not supported\n",
+                       chip->ecc_strength_ds, mtd->writesize);
+               return -ENODEV;
+       }
+
        /* calculate addressing information */
        if (mtd->writesize >= 2048)
                host->col_addr_cycles = 2;
@@ -1121,6 +1546,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
                return -ENOMEM;
 
        info->pdev = pdev;
+       info->variant = pxa3xx_nand_get_variant(pdev);
        for (cs = 0; cs < pdata->num_cs; cs++) {
                mtd = (struct mtd_info *)((unsigned int)&info[1] +
                      (sizeof(*mtd) + sizeof(*host)) * cs);
@@ -1138,11 +1564,16 @@ static int alloc_nand_resource(struct platform_device *pdev)
                chip->controller        = &info->controller;
                chip->waitfunc          = pxa3xx_nand_waitfunc;
                chip->select_chip       = pxa3xx_nand_select_chip;
-               chip->cmdfunc           = pxa3xx_nand_cmdfunc;
                chip->read_word         = pxa3xx_nand_read_word;
                chip->read_byte         = pxa3xx_nand_read_byte;
                chip->read_buf          = pxa3xx_nand_read_buf;
                chip->write_buf         = pxa3xx_nand_write_buf;
+               chip->options           |= NAND_NO_SUBPAGE_WRITE;
+
+               if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+                       chip->cmdfunc = armada370_nand_cmdfunc;
+               else
+                       chip->cmdfunc = pxa3xx_nand_cmdfunc;
        }
 
        spin_lock_init(&chip->controller->lock);
@@ -1254,29 +1685,6 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
        return 0;
 }
 
-static struct of_device_id pxa3xx_nand_dt_ids[] = {
-       {
-               .compatible = "marvell,pxa3xx-nand",
-               .data       = (void *)PXA3XX_NAND_VARIANT_PXA,
-       },
-       {
-               .compatible = "marvell,armada370-nand",
-               .data       = (void *)PXA3XX_NAND_VARIANT_ARMADA370,
-       },
-       {}
-};
-MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
-
-static enum pxa3xx_nand_variant
-pxa3xx_nand_get_variant(struct platform_device *pdev)
-{
-       const struct of_device_id *of_id =
-                       of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
-       if (!of_id)
-               return PXA3XX_NAND_VARIANT_PXA;
-       return (enum pxa3xx_nand_variant)of_id->data;
-}
-
 static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
 {
        struct pxa3xx_nand_platform_data *pdata;
@@ -1296,6 +1704,7 @@ static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
        if (of_get_property(np, "marvell,nand-keep-config", NULL))
                pdata->keep_config = 1;
        of_property_read_u32(np, "num-cs", &pdata->num_cs);
+       pdata->flash_bbt = of_get_nand_on_flash_bbt(np);
 
        pdev->dev.platform_data = pdata;
 
@@ -1333,7 +1742,6 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
        }
 
        info = platform_get_drvdata(pdev);
-       info->variant = pxa3xx_nand_get_variant(pdev);
        probe_success = 0;
        for (cs = 0; cs < pdata->num_cs; cs++) {
                struct mtd_info *mtd = info->host[cs]->mtd;
index d64f8c30945fbcd8e2d09a5b8342e75c081cd343..f0a708bf9b0eec211d7a8f0b2a93cbebdcbaacce 100644 (file)
@@ -81,7 +81,7 @@ static int parse_ofpart_partitions(struct mtd_info *master,
                partname = of_get_property(pp, "label", &len);
                if (!partname)
                        partname = of_get_property(pp, "name", &len);
-               (*pparts)[i].name = (char *)partname;
+               (*pparts)[i].name = partname;
 
                if (of_get_property(pp, "read-only", &len))
                        (*pparts)[i].mask_flags |= MTD_WRITEABLE;
@@ -152,7 +152,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master,
                if (names && (plen > 0)) {
                        int len = strlen(names) + 1;
 
-                       (*pparts)[i].name = (char *)names;
+                       (*pparts)[i].name = names;
                        plen -= len;
                        names += len;
                } else {
index 4dd5ee2a34cc68c4222f4c4115beedaee8b187d2..36eab0c4fb337b502c986d6c9ade7f1801d2a5f8 100644 (file)
@@ -4110,7 +4110,7 @@ static int bond_check_params(struct bond_params *params)
                if (!miimon) {
                        pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n");
                        pr_warning("Forcing miimon to 100msec\n");
-                       miimon = 100;
+                       miimon = BOND_DEFAULT_MIIMON;
                }
        }
 
@@ -4147,7 +4147,7 @@ static int bond_check_params(struct bond_params *params)
                if (!miimon) {
                        pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure and link speed which are essential for TLB/ALB load balancing\n");
                        pr_warning("Forcing miimon to 100msec\n");
-                       miimon = 100;
+                       miimon = BOND_DEFAULT_MIIMON;
                }
        }
 
index 9a5223c7b4d1a14f9b19354cfba6c4ea3dd933d0..ea6f640782b7456228787fa33ab8882b2bd8aa0b 100644 (file)
@@ -45,10 +45,15 @@ int bond_option_mode_set(struct bonding *bond, int mode)
                return -EPERM;
        }
 
-       if (BOND_MODE_IS_LB(mode) && bond->params.arp_interval) {
-               pr_err("%s: %s mode is incompatible with arp monitoring.\n",
-                      bond->dev->name, bond_mode_tbl[mode].modename);
-               return -EINVAL;
+       if (BOND_NO_USES_ARP(mode) && bond->params.arp_interval) {
+               pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n",
+                       bond->dev->name, bond_mode_tbl[mode].modename);
+               /* disable arp monitoring */
+               bond->params.arp_interval = 0;
+               /* set miimon to default value */
+               bond->params.miimon = BOND_DEFAULT_MIIMON;
+               pr_info("%s: Setting MII monitoring interval to %d.\n",
+                       bond->dev->name, bond->params.miimon);
        }
 
        /* don't cache arp_validate between modes */
index 0ec2a7e8c8a9588170c97715856e7b5f34cf7c60..abf5e106edc549c053e4d3ffdecce72c4470742e 100644 (file)
@@ -523,9 +523,7 @@ static ssize_t bonding_store_arp_interval(struct device *d,
                ret = -EINVAL;
                goto out;
        }
-       if (bond->params.mode == BOND_MODE_ALB ||
-           bond->params.mode == BOND_MODE_TLB ||
-           bond->params.mode == BOND_MODE_8023AD) {
+       if (BOND_NO_USES_ARP(bond->params.mode)) {
                pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n",
                        bond->dev->name, bond->dev->name);
                ret = -EINVAL;
index ca31286aa028158341a5847382b75afb74a6ea2f..a9f4f9f4d8ceea321061e94f35164829e1de2f7c 100644 (file)
@@ -35,6 +35,8 @@
 
 #define BOND_MAX_ARP_TARGETS   16
 
+#define BOND_DEFAULT_MIIMON    100
+
 #define IS_UP(dev)                                        \
              ((((dev)->flags & IFF_UP) == IFF_UP)      && \
               netif_running(dev)                       && \
                 ((mode) == BOND_MODE_TLB)          ||  \
                 ((mode) == BOND_MODE_ALB))
 
+#define BOND_NO_USES_ARP(mode)                         \
+               (((mode) == BOND_MODE_8023AD)   ||      \
+                ((mode) == BOND_MODE_TLB)      ||      \
+                ((mode) == BOND_MODE_ALB))
+
 #define TX_QUEUE_OVERRIDE(mode)                                \
                        (((mode) == BOND_MODE_ACTIVEBACKUP) ||  \
                         ((mode) == BOND_MODE_ROUNDROBIN))
index e3fc07cf2f6269e5ccf0ca5dbf42897c191cecd4..77061eebb034f4295258d9b0800fed28865d123a 100644 (file)
@@ -712,22 +712,31 @@ static int c_can_set_mode(struct net_device *dev, enum can_mode mode)
        return 0;
 }
 
-static int c_can_get_berr_counter(const struct net_device *dev,
-                                       struct can_berr_counter *bec)
+static int __c_can_get_berr_counter(const struct net_device *dev,
+                                   struct can_berr_counter *bec)
 {
        unsigned int reg_err_counter;
        struct c_can_priv *priv = netdev_priv(dev);
 
-       c_can_pm_runtime_get_sync(priv);
-
        reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
        bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
                                ERR_CNT_REC_SHIFT;
        bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;
 
+       return 0;
+}
+
+static int c_can_get_berr_counter(const struct net_device *dev,
+                                 struct can_berr_counter *bec)
+{
+       struct c_can_priv *priv = netdev_priv(dev);
+       int err;
+
+       c_can_pm_runtime_get_sync(priv);
+       err = __c_can_get_berr_counter(dev, bec);
        c_can_pm_runtime_put_sync(priv);
 
-       return 0;
+       return err;
 }
 
 /*
@@ -754,6 +763,7 @@ static void c_can_do_tx(struct net_device *dev)
                if (!(val & (1 << (msg_obj_no - 1)))) {
                        can_get_echo_skb(dev,
                                        msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
+                       c_can_object_get(dev, 0, msg_obj_no, IF_COMM_ALL);
                        stats->tx_bytes += priv->read_reg(priv,
                                        C_CAN_IFACE(MSGCTRL_REG, 0))
                                        & IF_MCONT_DLC_MASK;
@@ -872,7 +882,7 @@ static int c_can_handle_state_change(struct net_device *dev,
        if (unlikely(!skb))
                return 0;
 
-       c_can_get_berr_counter(dev, &bec);
+       __c_can_get_berr_counter(dev, &bec);
        reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
        rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >>
                                ERR_CNT_RP_SHIFT;
index ae08cf129ebbb0bda31f4b74893574b9703253f0..aaed97bee4711d1cb2e8b1eb514fc3e343ad21e0 100644 (file)
@@ -1020,13 +1020,13 @@ static int flexcan_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev, "no ipg clock defined\n");
                        return PTR_ERR(clk_ipg);
                }
-               clock_freq = clk_get_rate(clk_ipg);
 
                clk_per = devm_clk_get(&pdev->dev, "per");
                if (IS_ERR(clk_per)) {
                        dev_err(&pdev->dev, "no per clock defined\n");
                        return PTR_ERR(clk_per);
                }
+               clock_freq = clk_get_rate(clk_per);
        }
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
index 7164a999f50ff37e176f9995f21cd04451f17043..f17c3018b7c7ffb3f7d75785c3ddd2218b0f3f79 100644 (file)
@@ -494,20 +494,20 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
        uint8_t isrc, status;
        int n = 0;
 
-       /* Shared interrupts and IRQ off? */
-       if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF)
-               return IRQ_NONE;
-
        if (priv->pre_irq)
                priv->pre_irq(priv);
 
+       /* Shared interrupts and IRQ off? */
+       if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF)
+               goto out;
+
        while ((isrc = priv->read_reg(priv, SJA1000_IR)) &&
               (n < SJA1000_MAX_IRQ)) {
-               n++;
+
                status = priv->read_reg(priv, SJA1000_SR);
                /* check for absent controller due to hw unplug */
                if (status == 0xFF && sja1000_is_absent(priv))
-                       return IRQ_NONE;
+                       goto out;
 
                if (isrc & IRQ_WUI)
                        netdev_warn(dev, "wakeup interrupt\n");
@@ -535,7 +535,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
                                status = priv->read_reg(priv, SJA1000_SR);
                                /* check for absent controller */
                                if (status == 0xFF && sja1000_is_absent(priv))
-                                       return IRQ_NONE;
+                                       goto out;
                        }
                }
                if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
@@ -543,8 +543,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
                        if (sja1000_err(dev, isrc, status))
                                break;
                }
+               n++;
        }
-
+out:
        if (priv->post_irq)
                priv->post_irq(priv);
 
index fb3dd4399cf36e24cd4a1fe809333d140c8419f2..f615fdec0f1b2fb800189d97395554ecd392fa60 100644 (file)
@@ -113,7 +113,7 @@ static const struct net_device_ops hydra_netdev_ops = {
 static int hydra_init(struct zorro_dev *z)
 {
     struct net_device *dev;
-    unsigned long board = ZTWO_VADDR(z->resource.start);
+    unsigned long board = (unsigned long)ZTWO_VADDR(z->resource.start);
     unsigned long ioaddr = board+HYDRA_NIC_BASE;
     const char name[] = "NE2000";
     int start_page, stop_page;
index 85ec4c2d2645582339eb7ecfa796e9b37fee91ad..ae2a12b7db62db6fcc748019af9abca0e2abf051 100644 (file)
@@ -287,7 +287,7 @@ static const struct net_device_ops zorro8390_netdev_ops = {
 };
 
 static int zorro8390_init(struct net_device *dev, unsigned long board,
-                         const char *name, unsigned long ioaddr)
+                         const char *name, void __iomem *ioaddr)
 {
        int i;
        int err;
@@ -354,7 +354,7 @@ static int zorro8390_init(struct net_device *dev, unsigned long board,
        start_page = NESM_START_PG;
        stop_page = NESM_STOP_PG;
 
-       dev->base_addr = ioaddr;
+       dev->base_addr = (unsigned long)ioaddr;
        dev->irq = IRQ_AMIGA_PORTS;
 
        /* Install the Interrupt handler */
index 0866e7627433c1148037b9ade8064351c2819722..56139184b8019c132428654a5af6a4bd4018de14 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/zorro.h>
 #include <linux/bitops.h>
 
+#include <asm/byteorder.h>
 #include <asm/irq.h>
 #include <asm/amigaints.h>
 #include <asm/amigahw.h>
@@ -678,6 +679,7 @@ static int a2065_init_one(struct zorro_dev *z,
        unsigned long base_addr = board + A2065_LANCE;
        unsigned long mem_start = board + A2065_RAM;
        struct resource *r1, *r2;
+       u32 serial;
        int err;
 
        r1 = request_mem_region(base_addr, sizeof(struct lance_regs),
@@ -702,6 +704,7 @@ static int a2065_init_one(struct zorro_dev *z,
        r1->name = dev->name;
        r2->name = dev->name;
 
+       serial = be32_to_cpu(z->rom.er_SerialNumber);
        dev->dev_addr[0] = 0x00;
        if (z->id != ZORRO_PROD_AMERISTAR_A2065) {      /* Commodore */
                dev->dev_addr[1] = 0x80;
@@ -710,11 +713,11 @@ static int a2065_init_one(struct zorro_dev *z,
                dev->dev_addr[1] = 0x00;
                dev->dev_addr[2] = 0x9f;
        }
-       dev->dev_addr[3] = (z->rom.er_SerialNumber >> 16) & 0xff;
-       dev->dev_addr[4] = (z->rom.er_SerialNumber >> 8) & 0xff;
-       dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff;
-       dev->base_addr = ZTWO_VADDR(base_addr);
-       dev->mem_start = ZTWO_VADDR(mem_start);
+       dev->dev_addr[3] = (serial >> 16) & 0xff;
+       dev->dev_addr[4] = (serial >> 8) & 0xff;
+       dev->dev_addr[5] = serial & 0xff;
+       dev->base_addr = (unsigned long)ZTWO_VADDR(base_addr);
+       dev->mem_start = (unsigned long)ZTWO_VADDR(mem_start);
        dev->mem_end = dev->mem_start + A2065_RAM_SIZE;
 
        priv->ll = (volatile struct lance_regs *)dev->base_addr;
index c178eb4c81668ad3a1b033f11c9070b9e63c934d..b08101b31b8bc547ffbfb486f87abc7a18f92686 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/zorro.h>
 #include <linux/bitops.h>
 
+#include <asm/byteorder.h>
 #include <asm/amigaints.h>
 #include <asm/amigahw.h>
 #include <asm/irq.h>
@@ -718,6 +719,7 @@ static int ariadne_init_one(struct zorro_dev *z,
        struct resource *r1, *r2;
        struct net_device *dev;
        struct ariadne_private *priv;
+       u32 serial;
        int err;
 
        r1 = request_mem_region(base_addr, sizeof(struct Am79C960), "Am79C960");
@@ -741,14 +743,15 @@ static int ariadne_init_one(struct zorro_dev *z,
        r1->name = dev->name;
        r2->name = dev->name;
 
+       serial = be32_to_cpu(z->rom.er_SerialNumber);
        dev->dev_addr[0] = 0x00;
        dev->dev_addr[1] = 0x60;
        dev->dev_addr[2] = 0x30;
-       dev->dev_addr[3] = (z->rom.er_SerialNumber >> 16) & 0xff;
-       dev->dev_addr[4] = (z->rom.er_SerialNumber >> 8) & 0xff;
-       dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff;
-       dev->base_addr = ZTWO_VADDR(base_addr);
-       dev->mem_start = ZTWO_VADDR(mem_start);
+       dev->dev_addr[3] = (serial >> 16) & 0xff;
+       dev->dev_addr[4] = (serial >> 8) & 0xff;
+       dev->dev_addr[5] = serial & 0xff;
+       dev->base_addr = (unsigned long)ZTWO_VADDR(base_addr);
+       dev->mem_start = (unsigned long)ZTWO_VADDR(mem_start);
        dev->mem_end = dev->mem_start + ARIADNE_RAM_SIZE;
 
        dev->netdev_ops = &ariadne_netdev_ops;
index a9e068423ba0651414cc0c5b23f0eda6937a6c23..369b736dde0533740a01718fd2d271fa7f10ad60 100644 (file)
@@ -10629,10 +10629,8 @@ static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir)
 static ssize_t tg3_show_temp(struct device *dev,
                             struct device_attribute *devattr, char *buf)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct tg3 *tp = netdev_priv(netdev);
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct tg3 *tp = dev_get_drvdata(dev);
        u32 temperature;
 
        spin_lock_bh(&tp->lock);
@@ -10650,29 +10648,25 @@ static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, tg3_show_temp, NULL,
 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, tg3_show_temp, NULL,
                          TG3_TEMP_MAX_OFFSET);
 
-static struct attribute *tg3_attributes[] = {
+static struct attribute *tg3_attrs[] = {
        &sensor_dev_attr_temp1_input.dev_attr.attr,
        &sensor_dev_attr_temp1_crit.dev_attr.attr,
        &sensor_dev_attr_temp1_max.dev_attr.attr,
        NULL
 };
-
-static const struct attribute_group tg3_group = {
-       .attrs = tg3_attributes,
-};
+ATTRIBUTE_GROUPS(tg3);
 
 static void tg3_hwmon_close(struct tg3 *tp)
 {
        if (tp->hwmon_dev) {
                hwmon_device_unregister(tp->hwmon_dev);
                tp->hwmon_dev = NULL;
-               sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group);
        }
 }
 
 static void tg3_hwmon_open(struct tg3 *tp)
 {
-       int i, err;
+       int i;
        u32 size = 0;
        struct pci_dev *pdev = tp->pdev;
        struct tg3_ocir ocirs[TG3_SD_NUM_RECS];
@@ -10690,18 +10684,11 @@ static void tg3_hwmon_open(struct tg3 *tp)
        if (!size)
                return;
 
-       /* Register hwmon sysfs hooks */
-       err = sysfs_create_group(&pdev->dev.kobj, &tg3_group);
-       if (err) {
-               dev_err(&pdev->dev, "Cannot create sysfs group, aborting\n");
-               return;
-       }
-
-       tp->hwmon_dev = hwmon_device_register(&pdev->dev);
+       tp->hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, "tg3",
+                                                         tp, tg3_groups);
        if (IS_ERR(tp->hwmon_dev)) {
                tp->hwmon_dev = NULL;
                dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n");
-               sysfs_remove_group(&pdev->dev.kobj, &tg3_group);
        }
 }
 
index f4825db5d1792419924bab4f9d08e17abbfd6128..5878df619b531ad0b3ea96167f53e8909ff9fd21 100644 (file)
@@ -503,6 +503,7 @@ struct be_adapter {
 };
 
 #define be_physfn(adapter)             (!adapter->virtfn)
+#define be_virtfn(adapter)             (adapter->virtfn)
 #define        sriov_enabled(adapter)          (adapter->num_vfs > 0)
 #define sriov_want(adapter)             (be_physfn(adapter) && \
                                         (num_vfs || pci_num_vf(adapter->pdev)))
index dbcd5262c0167c1ae0dacf7dd578b5c3a2a43ce5..e0e8bc1ef14c47e93336df2c784d1ff14e6b4143 100644 (file)
@@ -1032,6 +1032,13 @@ int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq,
        } else {
                req->hdr.version = 2;
                req->page_size = 1; /* 1 for 4K */
+
+               /* coalesce-wm field in this cmd is not relevant to Lancer.
+                * Lancer uses COMMON_MODIFY_CQ to set this field
+                */
+               if (!lancer_chip(adapter))
+                       AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
+                                     ctxt, coalesce_wm);
                AMAP_SET_BITS(struct amap_cq_context_v2, nodelay, ctxt,
                                                                no_delay);
                AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
index abde97471636918a6b7e2381634cdc743678d24c..fee64bf10446092fa718caa12819e1be65ba0d6a 100644 (file)
@@ -2658,8 +2658,8 @@ static int be_close(struct net_device *netdev)
 
        be_roce_dev_close(adapter);
 
-       for_all_evt_queues(adapter, eqo, i) {
-               if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
+       if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
+               for_all_evt_queues(adapter, eqo, i) {
                        napi_disable(&eqo->napi);
                        be_disable_busy_poll(eqo);
                }
@@ -3253,12 +3253,10 @@ static int be_mac_setup(struct be_adapter *adapter)
                memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN);
        }
 
-       /* On BE3 VFs this cmd may fail due to lack of privilege.
-        * Ignore the failure as in this case pmac_id is fetched
-        * in the IFACE_CREATE cmd.
-        */
-       be_cmd_pmac_add(adapter, mac, adapter->if_handle,
-                       &adapter->pmac_id[0], 0);
+       /* For BE3-R VFs, the PF programs the initial MAC address */
+       if (!(BEx_chip(adapter) && be_virtfn(adapter)))
+               be_cmd_pmac_add(adapter, mac, adapter->if_handle,
+                               &adapter->pmac_id[0], 0);
        return 0;
 }
 
@@ -4599,6 +4597,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
        if (adapter->wol)
                be_setup_wol(adapter, true);
 
+       be_intr_set(adapter, false);
        cancel_delayed_work_sync(&adapter->func_recovery_work);
 
        netif_device_detach(netdev);
@@ -4634,6 +4633,7 @@ static int be_resume(struct pci_dev *pdev)
        if (status)
                return status;
 
+       be_intr_set(adapter, true);
        /* tell fw we're ready to fire cmds */
        status = be_cmd_fw_init(adapter);
        if (status)
index 58c147271a362e68914d55d97b71b327b194e86b..f9313b36c88716068611b44d3c7a6b182d4277e9 100644 (file)
@@ -83,6 +83,11 @@ struct e1000_adapter;
 
 #define E1000_MAX_INTR                 10
 
+/*
+ * Count for polling __E1000_RESET condition every 10-20msec.
+ */
+#define E1000_CHECK_RESET_COUNT        50
+
 /* TX/RX descriptor defines */
 #define E1000_DEFAULT_TXD              256
 #define E1000_MAX_TXD                  256
@@ -312,8 +317,6 @@ struct e1000_adapter {
        struct delayed_work watchdog_task;
        struct delayed_work fifo_stall_task;
        struct delayed_work phy_info_task;
-
-       struct mutex mutex;
 };
 
 enum e1000_state_t {
index e38622825fa7336ae74f64229f3e5619cb668335..46e6544ed1b7f5c1ba9367dd1dfe444d725cd0e3 100644 (file)
@@ -494,13 +494,20 @@ static void e1000_down_and_stop(struct e1000_adapter *adapter)
 {
        set_bit(__E1000_DOWN, &adapter->flags);
 
-       /* Only kill reset task if adapter is not resetting */
-       if (!test_bit(__E1000_RESETTING, &adapter->flags))
-               cancel_work_sync(&adapter->reset_task);
-
        cancel_delayed_work_sync(&adapter->watchdog_task);
+
+       /*
+        * Since the watchdog task can reschedule other tasks, we should cancel
+        * it first, otherwise we can run into the situation when a work is
+        * still running after the adapter has been turned down.
+        */
+
        cancel_delayed_work_sync(&adapter->phy_info_task);
        cancel_delayed_work_sync(&adapter->fifo_stall_task);
+
+       /* Only kill reset task if adapter is not resetting */
+       if (!test_bit(__E1000_RESETTING, &adapter->flags))
+               cancel_work_sync(&adapter->reset_task);
 }
 
 void e1000_down(struct e1000_adapter *adapter)
@@ -544,21 +551,8 @@ void e1000_down(struct e1000_adapter *adapter)
        e1000_clean_all_rx_rings(adapter);
 }
 
-static void e1000_reinit_safe(struct e1000_adapter *adapter)
-{
-       while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
-               msleep(1);
-       mutex_lock(&adapter->mutex);
-       e1000_down(adapter);
-       e1000_up(adapter);
-       mutex_unlock(&adapter->mutex);
-       clear_bit(__E1000_RESETTING, &adapter->flags);
-}
-
 void e1000_reinit_locked(struct e1000_adapter *adapter)
 {
-       /* if rtnl_lock is not held the call path is bogus */
-       ASSERT_RTNL();
        WARN_ON(in_interrupt());
        while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
                msleep(1);
@@ -1316,7 +1310,6 @@ static int e1000_sw_init(struct e1000_adapter *adapter)
        e1000_irq_disable(adapter);
 
        spin_lock_init(&adapter->stats_lock);
-       mutex_init(&adapter->mutex);
 
        set_bit(__E1000_DOWN, &adapter->flags);
 
@@ -1440,6 +1433,10 @@ static int e1000_close(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
+       int count = E1000_CHECK_RESET_COUNT;
+
+       while (test_bit(__E1000_RESETTING, &adapter->flags) && count--)
+               usleep_range(10000, 20000);
 
        WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
        e1000_down(adapter);
@@ -2325,11 +2322,8 @@ static void e1000_update_phy_info_task(struct work_struct *work)
        struct e1000_adapter *adapter = container_of(work,
                                                     struct e1000_adapter,
                                                     phy_info_task.work);
-       if (test_bit(__E1000_DOWN, &adapter->flags))
-               return;
-       mutex_lock(&adapter->mutex);
+
        e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
-       mutex_unlock(&adapter->mutex);
 }
 
 /**
@@ -2345,9 +2339,6 @@ static void e1000_82547_tx_fifo_stall_task(struct work_struct *work)
        struct net_device *netdev = adapter->netdev;
        u32 tctl;
 
-       if (test_bit(__E1000_DOWN, &adapter->flags))
-               return;
-       mutex_lock(&adapter->mutex);
        if (atomic_read(&adapter->tx_fifo_stall)) {
                if ((er32(TDT) == er32(TDH)) &&
                   (er32(TDFT) == er32(TDFH)) &&
@@ -2368,7 +2359,6 @@ static void e1000_82547_tx_fifo_stall_task(struct work_struct *work)
                        schedule_delayed_work(&adapter->fifo_stall_task, 1);
                }
        }
-       mutex_unlock(&adapter->mutex);
 }
 
 bool e1000_has_link(struct e1000_adapter *adapter)
@@ -2422,10 +2412,6 @@ static void e1000_watchdog(struct work_struct *work)
        struct e1000_tx_ring *txdr = adapter->tx_ring;
        u32 link, tctl;
 
-       if (test_bit(__E1000_DOWN, &adapter->flags))
-               return;
-
-       mutex_lock(&adapter->mutex);
        link = e1000_has_link(adapter);
        if ((netif_carrier_ok(netdev)) && link)
                goto link_up;
@@ -2516,7 +2502,7 @@ link_up:
                        adapter->tx_timeout_count++;
                        schedule_work(&adapter->reset_task);
                        /* exit immediately since reset is imminent */
-                       goto unlock;
+                       return;
                }
        }
 
@@ -2544,9 +2530,6 @@ link_up:
        /* Reschedule the task */
        if (!test_bit(__E1000_DOWN, &adapter->flags))
                schedule_delayed_work(&adapter->watchdog_task, 2 * HZ);
-
-unlock:
-       mutex_unlock(&adapter->mutex);
 }
 
 enum latency_range {
@@ -3495,10 +3478,8 @@ static void e1000_reset_task(struct work_struct *work)
        struct e1000_adapter *adapter =
                container_of(work, struct e1000_adapter, reset_task);
 
-       if (test_bit(__E1000_DOWN, &adapter->flags))
-               return;
        e_err(drv, "Reset adapter\n");
-       e1000_reinit_safe(adapter);
+       e1000_reinit_locked(adapter);
 }
 
 /**
@@ -4963,6 +4944,11 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
        netif_device_detach(netdev);
 
        if (netif_running(netdev)) {
+               int count = E1000_CHECK_RESET_COUNT;
+
+               while (test_bit(__E1000_RESETTING, &adapter->flags) && count--)
+                       usleep_range(10000, 20000);
+
                WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
                e1000_down(adapter);
        }
index b0f3666b1d7f1c669181a9f62534aa8096baeccc..c3143da497c82be85c4f580776290872e647e317 100644 (file)
@@ -2062,14 +2062,15 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
 
-       wol->supported = WAKE_UCAST | WAKE_MCAST |
-                        WAKE_BCAST | WAKE_MAGIC |
-                        WAKE_PHY;
        wol->wolopts = 0;
 
        if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED))
                return;
 
+       wol->supported = WAKE_UCAST | WAKE_MCAST |
+                        WAKE_BCAST | WAKE_MAGIC |
+                        WAKE_PHY;
+
        /* apply any specific unsupported masks here */
        switch (adapter->hw.device_id) {
        default:
index 0c55079ebee37c03d0a5a9a5cbdc6681d78c19a9..cc06854296a379a6f5d1fac21ecf9412d94d477b 100644 (file)
@@ -4251,8 +4251,8 @@ static void ixgbe_disable_fwd_ring(struct ixgbe_fwd_adapter *vadapter,
        rx_ring->l2_accel_priv = NULL;
 }
 
-int ixgbe_fwd_ring_down(struct net_device *vdev,
-                       struct ixgbe_fwd_adapter *accel)
+static int ixgbe_fwd_ring_down(struct net_device *vdev,
+                              struct ixgbe_fwd_adapter *accel)
 {
        struct ixgbe_adapter *adapter = accel->real_adapter;
        unsigned int rxbase = accel->rx_base_queue;
@@ -7986,10 +7986,9 @@ skip_sriov:
                           NETIF_F_TSO |
                           NETIF_F_TSO6 |
                           NETIF_F_RXHASH |
-                          NETIF_F_RXCSUM |
-                          NETIF_F_HW_L2FW_DOFFLOAD;
+                          NETIF_F_RXCSUM;
 
-       netdev->hw_features = netdev->features;
+       netdev->hw_features = netdev->features | NETIF_F_HW_L2FW_DOFFLOAD;
 
        switch (adapter->hw.mac.type) {
        case ixgbe_mac_82599EB:
index e4c676006be97db79d3208607f36bb503bdaecaa..39217e5ff7dcd74ddcfc49c7e33e43ec2633c515 100644 (file)
@@ -46,6 +46,7 @@ static bool ixgbe_get_i2c_data(u32 *i2cctl);
 static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
 static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
 static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
+static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw);
 
 /**
  *  ixgbe_identify_phy_generic - Get physical layer module
@@ -1164,7 +1165,7 @@ err_read_i2c_eeprom:
  *
  * Searches for and identifies the QSFP module and assigns appropriate PHY type
  **/
-s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
+static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
 {
        struct ixgbe_adapter *adapter = hw->back;
        s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
index aae900a256da98601a501a121eed1f14347d3997..fffcbdd2bf0e49ab129abf04cd16a650a4d5cb91 100644 (file)
@@ -145,7 +145,6 @@ s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
 s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw);
 s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw);
 s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
-s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw);
 s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
                                         u16 *list_offset,
                                         u16 *data_offset);
index 346a4e025c34100315b1ca2785d631d3bc5d3408..04b3ec1352f1eb9f532f7a6ab770615441f023fd 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/bitrev.h>
 #include <linux/slab.h>
 
-#include <asm/bootinfo.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/hwtest.h>
index f2a2128165dd98b4c41598fb481c4e4f40417614..737c1a881f781917061d8b39ad43762f62ee7a6e 100644 (file)
@@ -678,9 +678,6 @@ static void cp_tx (struct cp_private *cp)
                                 le32_to_cpu(txd->opts1) & 0xffff,
                                 PCI_DMA_TODEVICE);
 
-               bytes_compl += skb->len;
-               pkts_compl++;
-
                if (status & LastFrag) {
                        if (status & (TxError | TxFIFOUnder)) {
                                netif_dbg(cp, tx_err, cp->dev,
@@ -702,6 +699,8 @@ static void cp_tx (struct cp_private *cp)
                                netif_dbg(cp, tx_done, cp->dev,
                                          "tx done, slot %d\n", tx_tail);
                        }
+                       bytes_compl += skb->len;
+                       pkts_compl++;
                        dev_kfree_skb_irq(skb);
                }
 
index 799387570766b6642ad4fdbc13f917acd358887a..c737f0ea5de751b7de9b1cb710fb101dc170ee41 100644 (file)
@@ -3465,6 +3465,11 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
        rtl_writephy(tp, 0x14, 0x9065);
        rtl_writephy(tp, 0x14, 0x1065);
 
+       /* Check ALDPS bit, disable it if enabled */
+       rtl_writephy(tp, 0x1f, 0x0a43);
+       if (rtl_readphy(tp, 0x10) & 0x0004)
+               rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0004);
+
        rtl_writephy(tp, 0x1f, 0x0000);
 }
 
index 656a3277c2b210e69ffd028d059ce10b809e8db8..15816cacb548161bd4a7299909bb83ccd9c222be 100644 (file)
@@ -75,6 +75,8 @@ struct efx_mcdi_mon {
        unsigned long last_update;
        struct device *device;
        struct efx_mcdi_mon_attribute *attrs;
+       struct attribute_group group;
+       const struct attribute_group *groups[2];
        unsigned int n_attrs;
 };
 
index 4cc5d95b2a5a5ea36869625843bf4daba064e84f..d72ad4fc36172241d5aeccbe883f4a82c8ee2daf 100644 (file)
@@ -139,17 +139,10 @@ static int efx_mcdi_mon_update(struct efx_nic *efx)
        return rc;
 }
 
-static ssize_t efx_mcdi_mon_show_name(struct device *dev,
-                                     struct device_attribute *attr,
-                                     char *buf)
-{
-       return sprintf(buf, "%s\n", KBUILD_MODNAME);
-}
-
 static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index,
                                  efx_dword_t *entry)
 {
-       struct efx_nic *efx = dev_get_drvdata(dev);
+       struct efx_nic *efx = dev_get_drvdata(dev->parent);
        struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
        int rc;
 
@@ -263,7 +256,7 @@ static ssize_t efx_mcdi_mon_show_label(struct device *dev,
                       efx_mcdi_sensor_type[mon_attr->type].label);
 }
 
-static int
+static void
 efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name,
                      ssize_t (*reader)(struct device *,
                                        struct device_attribute *, char *),
@@ -272,7 +265,6 @@ efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name,
 {
        struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
        struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs];
-       int rc;
 
        strlcpy(attr->name, name, sizeof(attr->name));
        attr->index = index;
@@ -286,10 +278,7 @@ efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name,
        attr->dev_attr.attr.name = attr->name;
        attr->dev_attr.attr.mode = S_IRUGO;
        attr->dev_attr.show = reader;
-       rc = device_create_file(&efx->pci_dev->dev, &attr->dev_attr);
-       if (rc == 0)
-               ++hwmon->n_attrs;
-       return rc;
+       hwmon->group.attrs[hwmon->n_attrs++] = &attr->dev_attr.attr;
 }
 
 int efx_mcdi_mon_probe(struct efx_nic *efx)
@@ -338,26 +327,22 @@ int efx_mcdi_mon_probe(struct efx_nic *efx)
        efx_mcdi_mon_update(efx);
 
        /* Allocate space for the maximum possible number of
-        * attributes for this set of sensors: name of the driver plus
+        * attributes for this set of sensors:
         * value, min, max, crit, alarm and label for each sensor.
         */
-       n_attrs = 1 + 6 * n_sensors;
+       n_attrs = 6 * n_sensors;
        hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL);
        if (!hwmon->attrs) {
                rc = -ENOMEM;
                goto fail;
        }
-
-       hwmon->device = hwmon_device_register(&efx->pci_dev->dev);
-       if (IS_ERR(hwmon->device)) {
-               rc = PTR_ERR(hwmon->device);
+       hwmon->group.attrs = kcalloc(n_attrs + 1, sizeof(struct attribute *),
+                                    GFP_KERNEL);
+       if (!hwmon->group.attrs) {
+               rc = -ENOMEM;
                goto fail;
        }
 
-       rc = efx_mcdi_mon_add_attr(efx, "name", efx_mcdi_mon_show_name, 0, 0, 0);
-       if (rc)
-               goto fail;
-
        for (i = 0, j = -1, type = -1; ; i++) {
                enum efx_hwmon_type hwmon_type;
                const char *hwmon_prefix;
@@ -372,7 +357,7 @@ int efx_mcdi_mon_probe(struct efx_nic *efx)
                                page = type / 32;
                                j = -1;
                                if (page == n_pages)
-                                       return 0;
+                                       goto hwmon_register;
 
                                MCDI_SET_DWORD(inbuf, SENSOR_INFO_EXT_IN_PAGE,
                                               page);
@@ -453,28 +438,22 @@ int efx_mcdi_mon_probe(struct efx_nic *efx)
                if (min1 != max1) {
                        snprintf(name, sizeof(name), "%s%u_input",
                                 hwmon_prefix, hwmon_index);
-                       rc = efx_mcdi_mon_add_attr(
+                       efx_mcdi_mon_add_attr(
                                efx, name, efx_mcdi_mon_show_value, i, type, 0);
-                       if (rc)
-                               goto fail;
 
                        if (hwmon_type != EFX_HWMON_POWER) {
                                snprintf(name, sizeof(name), "%s%u_min",
                                         hwmon_prefix, hwmon_index);
-                               rc = efx_mcdi_mon_add_attr(
+                               efx_mcdi_mon_add_attr(
                                        efx, name, efx_mcdi_mon_show_limit,
                                        i, type, min1);
-                               if (rc)
-                                       goto fail;
                        }
 
                        snprintf(name, sizeof(name), "%s%u_max",
                                 hwmon_prefix, hwmon_index);
-                       rc = efx_mcdi_mon_add_attr(
+                       efx_mcdi_mon_add_attr(
                                efx, name, efx_mcdi_mon_show_limit,
                                i, type, max1);
-                       if (rc)
-                               goto fail;
 
                        if (min2 != max2) {
                                /* Assume max2 is critical value.
@@ -482,32 +461,38 @@ int efx_mcdi_mon_probe(struct efx_nic *efx)
                                 */
                                snprintf(name, sizeof(name), "%s%u_crit",
                                         hwmon_prefix, hwmon_index);
-                               rc = efx_mcdi_mon_add_attr(
+                               efx_mcdi_mon_add_attr(
                                        efx, name, efx_mcdi_mon_show_limit,
                                        i, type, max2);
-                               if (rc)
-                                       goto fail;
                        }
                }
 
                snprintf(name, sizeof(name), "%s%u_alarm",
                         hwmon_prefix, hwmon_index);
-               rc = efx_mcdi_mon_add_attr(
+               efx_mcdi_mon_add_attr(
                        efx, name, efx_mcdi_mon_show_alarm, i, type, 0);
-               if (rc)
-                       goto fail;
 
                if (type < ARRAY_SIZE(efx_mcdi_sensor_type) &&
                    efx_mcdi_sensor_type[type].label) {
                        snprintf(name, sizeof(name), "%s%u_label",
                                 hwmon_prefix, hwmon_index);
-                       rc = efx_mcdi_mon_add_attr(
+                       efx_mcdi_mon_add_attr(
                                efx, name, efx_mcdi_mon_show_label, i, type, 0);
-                       if (rc)
-                               goto fail;
                }
        }
 
+hwmon_register:
+       hwmon->groups[0] = &hwmon->group;
+       hwmon->device = hwmon_device_register_with_groups(&efx->pci_dev->dev,
+                                                         KBUILD_MODNAME, NULL,
+                                                         hwmon->groups);
+       if (IS_ERR(hwmon->device)) {
+               rc = PTR_ERR(hwmon->device);
+               goto fail;
+       }
+
+       return 0;
+
 fail:
        efx_mcdi_mon_remove(efx);
        return rc;
@@ -516,14 +501,11 @@ fail:
 void efx_mcdi_mon_remove(struct efx_nic *efx)
 {
        struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
-       unsigned int i;
 
-       for (i = 0; i < hwmon->n_attrs; i++)
-               device_remove_file(&efx->pci_dev->dev,
-                                  &hwmon->attrs[i].dev_attr);
-       kfree(hwmon->attrs);
        if (hwmon->device)
                hwmon_device_unregister(hwmon->device);
+       kfree(hwmon->attrs);
+       kfree(hwmon->group.attrs);
        efx_nic_free_buffer(efx, &hwmon->dma_buf);
 }
 
index c9d4c872e81da1888cf8678ceb2fd7df5381ac03..749654b976bcf85fd07558f175274b9f01551705 100644 (file)
@@ -46,7 +46,8 @@
     defined(CONFIG_MACH_LITTLETON) ||\
     defined(CONFIG_MACH_ZYLONITE2) ||\
     defined(CONFIG_ARCH_VIPER) ||\
-    defined(CONFIG_MACH_STARGATE2)
+    defined(CONFIG_MACH_STARGATE2) ||\
+    defined(CONFIG_ARCH_VERSATILE)
 
 #include <asm/mach-types.h>
 
@@ -154,6 +155,8 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 #define SMC_outl(v, a, r)      writel(v, (a) + (r))
 #define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
 #define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
+#define SMC_insw(a, r, p, l)   readsw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)  writesw((a) + (r), p, l)
 #define SMC_IRQ_FLAGS          (-1)    /* from resource */
 
 /* We actually can't write halfwords properly if not word aligned */
@@ -206,23 +209,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 #define RPC_LSA_DEFAULT                RPC_LED_TX_RX
 #define RPC_LSB_DEFAULT                RPC_LED_100_10
 
-#elif  defined(CONFIG_ARCH_VERSATILE)
-
-#define SMC_CAN_USE_8BIT       1
-#define SMC_CAN_USE_16BIT      1
-#define SMC_CAN_USE_32BIT      1
-#define SMC_NOWAIT             1
-
-#define SMC_inb(a, r)          readb((a) + (r))
-#define SMC_inw(a, r)          readw((a) + (r))
-#define SMC_inl(a, r)          readl((a) + (r))
-#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
-#define SMC_outw(v, a, r)      writew(v, (a) + (r))
-#define SMC_outl(v, a, r)      writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
-#define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
-#define SMC_IRQ_FLAGS          (-1)    /* from resource */
-
 #elif defined(CONFIG_MN10300)
 
 /*
index d022bf936572ea857cbcb9f0fded1899077d5a95..ad61d26a44f31d26fc3b6d96f8430a5264e28e6f 100644 (file)
@@ -2172,16 +2172,13 @@ static int velocity_poll(struct napi_struct *napi, int budget)
        unsigned int rx_done;
        unsigned long flags;
 
-       spin_lock_irqsave(&vptr->lock, flags);
        /*
         * Do rx and tx twice for performance (taken from the VIA
         * out-of-tree driver).
         */
-       rx_done = velocity_rx_srv(vptr, budget / 2);
-       velocity_tx_srv(vptr);
-       rx_done += velocity_rx_srv(vptr, budget - rx_done);
+       rx_done = velocity_rx_srv(vptr, budget);
+       spin_lock_irqsave(&vptr->lock, flags);
        velocity_tx_srv(vptr);
-
        /* If budget not fully consumed, exit the polling mode */
        if (rx_done < budget) {
                napi_complete(napi);
@@ -2342,6 +2339,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
                if (ret < 0)
                        goto out_free_tmp_vptr_1;
 
+               napi_disable(&vptr->napi);
+
                spin_lock_irqsave(&vptr->lock, flags);
 
                netif_stop_queue(dev);
@@ -2362,6 +2361,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
 
                velocity_give_many_rx_descs(vptr);
 
+               napi_enable(&vptr->napi);
+
                mac_enable_int(vptr->mac_regs);
                netif_start_queue(dev);
 
index dc76670c2f2a16c244d0ec58a779a8742d0e6c3e..9093004f9b63004922a0202180d7341343287553 100644 (file)
@@ -744,7 +744,7 @@ err:
        rcu_read_lock();
        vlan = rcu_dereference(q->vlan);
        if (vlan)
-               vlan->dev->stats.tx_dropped++;
+               this_cpu_inc(vlan->pcpu_stats->tx_dropped);
        rcu_read_unlock();
 
        return err;
@@ -767,7 +767,6 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
                                const struct sk_buff *skb,
                                const struct iovec *iv, int len)
 {
-       struct macvlan_dev *vlan;
        int ret;
        int vnet_hdr_len = 0;
        int vlan_offset = 0;
@@ -821,15 +820,6 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
        copied += len;
 
 done:
-       rcu_read_lock();
-       vlan = rcu_dereference(q->vlan);
-       if (vlan) {
-               preempt_disable();
-               macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0);
-               preempt_enable();
-       }
-       rcu_read_unlock();
-
        return ret ? ret : copied;
 }
 
index 508e4359338bc385dc2a0901e24a6351f735f780..14372c65a7e8209b5f97da6416ef80d1f41a522c 100644 (file)
@@ -64,6 +64,7 @@
 
 #define PHY_ID_VSC8234                 0x000fc620
 #define PHY_ID_VSC8244                 0x000fc6c0
+#define PHY_ID_VSC8514                 0x00070670
 #define PHY_ID_VSC8574                 0x000704a0
 #define PHY_ID_VSC8662                 0x00070660
 #define PHY_ID_VSC8221                 0x000fc550
@@ -131,6 +132,7 @@ static int vsc82xx_config_intr(struct phy_device *phydev)
                err = phy_write(phydev, MII_VSC8244_IMASK,
                        (phydev->drv->phy_id == PHY_ID_VSC8234 ||
                         phydev->drv->phy_id == PHY_ID_VSC8244 ||
+                        phydev->drv->phy_id == PHY_ID_VSC8514 ||
                         phydev->drv->phy_id == PHY_ID_VSC8574) ?
                                MII_VSC8244_IMASK_MASK :
                                MII_VSC8221_IMASK_MASK);
@@ -245,6 +247,18 @@ static struct phy_driver vsc82xx_driver[] = {
        .ack_interrupt  = &vsc824x_ack_interrupt,
        .config_intr    = &vsc82xx_config_intr,
        .driver         = { .owner = THIS_MODULE,},
+}, {
+       .phy_id         = PHY_ID_VSC8514,
+       .name           = "Vitesse VSC8514",
+       .phy_id_mask    = 0x000ffff0,
+       .features       = PHY_GBIT_FEATURES,
+       .flags          = PHY_HAS_INTERRUPT,
+       .config_init    = &vsc824x_config_init,
+       .config_aneg    = &vsc82x4_config_aneg,
+       .read_status    = &genphy_read_status,
+       .ack_interrupt  = &vsc824x_ack_interrupt,
+       .config_intr    = &vsc82xx_config_intr,
+       .driver         = { .owner = THIS_MODULE,},
 }, {
        .phy_id         = PHY_ID_VSC8574,
        .name           = "Vitesse VSC8574",
@@ -315,6 +329,7 @@ module_exit(vsc82xx_exit);
 static struct mdio_device_id __maybe_unused vitesse_tbl[] = {
        { PHY_ID_VSC8234, 0x000ffff0 },
        { PHY_ID_VSC8244, 0x000fffc0 },
+       { PHY_ID_VSC8514, 0x000ffff0 },
        { PHY_ID_VSC8574, 0x000ffff0 },
        { PHY_ID_VSC8662, 0x000ffff0 },
        { PHY_ID_VSC8221, 0x000ffff0 },
index 34b0de09d88190a04e30d867e31ad001f35f0e34..736050d6b4516b3de85eb2c214d0464ff690d99f 100644 (file)
@@ -1366,6 +1366,8 @@ static int team_user_linkup_option_get(struct team *team,
        return 0;
 }
 
+static void __team_carrier_check(struct team *team);
+
 static int team_user_linkup_option_set(struct team *team,
                                       struct team_gsetter_ctx *ctx)
 {
@@ -1373,6 +1375,7 @@ static int team_user_linkup_option_set(struct team *team,
 
        port->user.linkup = ctx->data.bool_val;
        team_refresh_port_linkup(port);
+       __team_carrier_check(port->team);
        return 0;
 }
 
@@ -1392,6 +1395,7 @@ static int team_user_linkup_en_option_set(struct team *team,
 
        port->user.linkup_enabled = ctx->data.bool_val;
        team_refresh_port_linkup(port);
+       __team_carrier_check(port->team);
        return 0;
 }
 
index 7bab4de658a91d9fb1231f5e45461a268efc8487..acda66169973413090427ff566cb3bcff0e50288 100644 (file)
@@ -1084,7 +1084,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
                                  VIRTIO_NET_CTRL_MAC_TABLE_SET,
                                  sg, NULL))
-               dev_warn(&dev->dev, "Failed to set MAC fitler table.\n");
+               dev_warn(&dev->dev, "Failed to set MAC filter table.\n");
 
        kfree(buf);
 }
index b00a7e92225f7b928f5a3cf7395f860af27299bd..54e36fcb39542e8361dfdc019134f3ba1538de8f 100644 (file)
@@ -5,6 +5,8 @@ config BRCMSMAC
        tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
        depends on MAC80211
        depends on BCMA
+       select NEW_LEDS if BCMA_DRIVER_GPIO
+       select LEDS_CLASS if BCMA_DRIVER_GPIO
        select BRCMUTIL
        select FW_LOADER
        select CRC_CCITT
index 9df7bc91a26f54c9812718e481c538895aa5b4f8..c72438bb2fafd24b8e59f416d4e4311752dce941 100644 (file)
@@ -383,6 +383,14 @@ struct hwsim_radiotap_hdr {
        __le16 rt_chbitmask;
 } __packed;
 
+struct hwsim_radiotap_ack_hdr {
+       struct ieee80211_radiotap_header hdr;
+       u8 rt_flags;
+       u8 pad;
+       __le16 rt_channel;
+       __le16 rt_chbitmask;
+} __packed;
+
 /* MAC80211_HWSIM netlinf family */
 static struct genl_family hwsim_genl_family = {
        .id = GENL_ID_GENERATE,
@@ -500,7 +508,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
                                       const u8 *addr)
 {
        struct sk_buff *skb;
-       struct hwsim_radiotap_hdr *hdr;
+       struct hwsim_radiotap_ack_hdr *hdr;
        u16 flags;
        struct ieee80211_hdr *hdr11;
 
@@ -511,14 +519,14 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
        if (skb == NULL)
                return;
 
-       hdr = (struct hwsim_radiotap_hdr *) skb_put(skb, sizeof(*hdr));
+       hdr = (struct hwsim_radiotap_ack_hdr *) skb_put(skb, sizeof(*hdr));
        hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION;
        hdr->hdr.it_pad = 0;
        hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
        hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
                                          (1 << IEEE80211_RADIOTAP_CHANNEL));
        hdr->rt_flags = 0;
-       hdr->rt_rate = 0;
+       hdr->pad = 0;
        hdr->rt_channel = cpu_to_le16(chan->center_freq);
        flags = IEEE80211_CHAN_2GHZ;
        hdr->rt_chbitmask = cpu_to_le16(flags);
@@ -1230,7 +1238,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
                                              HRTIMER_MODE_REL);
                } else if (!info->enable_beacon) {
                        unsigned int count = 0;
-                       ieee80211_iterate_active_interfaces(
+                       ieee80211_iterate_active_interfaces_atomic(
                                data->hw, IEEE80211_IFACE_ITER_NORMAL,
                                mac80211_hwsim_bcn_en_iter, &count);
                        wiphy_debug(hw->wiphy, "  beaconing vifs remaining: %u",
index c8e029df770e38cac9a52dccb660666bd8cc9f74..a09398fe9e2a67218f50530af8a0b4616443cbbb 100644 (file)
@@ -319,8 +319,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                if (bss_desc && bss_desc->ssid.ssid_len &&
                    (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor.
                                       ssid, &bss_desc->ssid))) {
-                       kfree(bss_desc);
-                       return 0;
+                       ret = 0;
+                       goto done;
                }
 
                /* Exit Adhoc mode first */
index 919b6509455cfbaf45ba63c7d8b378fa13a8e758..64f0e0d18b8188c1729f525e26a2ca8b88724d8f 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/udp.h>
 
 #include <net/tcp.h>
+#include <net/ip6_checksum.h>
 
 #include <xen/xen.h>
 #include <xen/events.h>
index 1cb6e51e6bda97aadb4ba88bd46123544dcc4140..170e8e60cdb7fe3d47307d4b9146039e3af7f3a8 100644 (file)
@@ -141,6 +141,24 @@ void ntb_unregister_event_callback(struct ntb_device *ndev)
        ndev->event_cb = NULL;
 }
 
+static void ntb_irq_work(unsigned long data)
+{
+       struct ntb_db_cb *db_cb = (struct ntb_db_cb *)data;
+       int rc;
+
+       rc = db_cb->callback(db_cb->data, db_cb->db_num);
+       if (rc)
+               tasklet_schedule(&db_cb->irq_work);
+       else {
+               struct ntb_device *ndev = db_cb->ndev;
+               unsigned long mask;
+
+               mask = readw(ndev->reg_ofs.ldb_mask);
+               clear_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
+               writew(mask, ndev->reg_ofs.ldb_mask);
+       }
+}
+
 /**
  * ntb_register_db_callback() - register a callback for doorbell interrupt
  * @ndev: pointer to ntb_device instance
@@ -155,7 +173,7 @@ void ntb_unregister_event_callback(struct ntb_device *ndev)
  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
  */
 int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx,
-                            void *data, void (*func)(void *data, int db_num))
+                            void *data, int (*func)(void *data, int db_num))
 {
        unsigned long mask;
 
@@ -166,6 +184,10 @@ int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx,
 
        ndev->db_cb[idx].callback = func;
        ndev->db_cb[idx].data = data;
+       ndev->db_cb[idx].ndev = ndev;
+
+       tasklet_init(&ndev->db_cb[idx].irq_work, ntb_irq_work,
+                    (unsigned long) &ndev->db_cb[idx]);
 
        /* unmask interrupt */
        mask = readw(ndev->reg_ofs.ldb_mask);
@@ -194,6 +216,8 @@ void ntb_unregister_db_callback(struct ntb_device *ndev, unsigned int idx)
        set_bit(idx * ndev->bits_per_vector, &mask);
        writew(mask, ndev->reg_ofs.ldb_mask);
 
+       tasklet_disable(&ndev->db_cb[idx].irq_work);
+
        ndev->db_cb[idx].callback = NULL;
 }
 
@@ -678,6 +702,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
                                return -EINVAL;
 
                        ndev->limits.max_mw = SNB_ERRATA_MAX_MW;
+                       ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
                        ndev->reg_ofs.spad_write = ndev->mw[1].vbase +
                                                   SNB_SPAD_OFFSET;
                        ndev->reg_ofs.rdb = ndev->mw[1].vbase +
@@ -688,8 +713,21 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
                         */
                        writeq(ndev->mw[1].bar_sz + 0x1000, ndev->reg_base +
                               SNB_PBAR4LMT_OFFSET);
+                       /* HW errata on the Limit registers.  They can only be
+                        * written when the base register is 4GB aligned and
+                        * < 32bit.  This should already be the case based on the
+                        * driver defaults, but write the Limit registers first
+                        * just in case.
+                        */
                } else {
                        ndev->limits.max_mw = SNB_MAX_MW;
+
+                       /* HW Errata on bit 14 of b2bdoorbell register.  Writes
+                        * will not be mirrored to the remote system.  Shrink
+                        * the number of bits by one, since bit 14 is the last
+                        * bit.
+                        */
+                       ndev->limits.max_db_bits = SNB_MAX_DB_BITS - 1;
                        ndev->reg_ofs.spad_write = ndev->reg_base +
                                                   SNB_B2B_SPAD_OFFSET;
                        ndev->reg_ofs.rdb = ndev->reg_base +
@@ -699,6 +737,12 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
                         * something silly
                         */
                        writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET);
+                       /* HW errata on the Limit registers.  They can only be
+                        * written when the base register is 4GB aligned and
+                        * < 32bit.  This should already be the case based on the
+                        * driver defaults, but write the Limit registers first
+                        * just in case.
+                        */
                }
 
                /* The Xeon errata workaround requires setting SBAR Base
@@ -769,6 +813,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
                 * have an equal amount.
                 */
                ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2;
+               ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
                /* Note: The SDOORBELL is the cause of the errata.  You REALLY
                 * don't want to touch it.
                 */
@@ -793,6 +838,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
                 * have an equal amount.
                 */
                ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2;
+               ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
                ndev->reg_ofs.rdb = ndev->reg_base + SNB_PDOORBELL_OFFSET;
                ndev->reg_ofs.ldb = ndev->reg_base + SNB_SDOORBELL_OFFSET;
                ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_SDBMSK_OFFSET;
@@ -819,7 +865,6 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
        ndev->reg_ofs.lnk_stat = ndev->reg_base + SNB_SLINK_STATUS_OFFSET;
        ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET;
 
-       ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
        ndev->limits.msix_cnt = SNB_MSIX_CNT;
        ndev->bits_per_vector = SNB_DB_BITS_PER_VEC;
 
@@ -934,12 +979,16 @@ static irqreturn_t bwd_callback_msix_irq(int irq, void *data)
 {
        struct ntb_db_cb *db_cb = data;
        struct ntb_device *ndev = db_cb->ndev;
+       unsigned long mask;
 
        dev_dbg(&ndev->pdev->dev, "MSI-X irq %d received for DB %d\n", irq,
                db_cb->db_num);
 
-       if (db_cb->callback)
-               db_cb->callback(db_cb->data, db_cb->db_num);
+       mask = readw(ndev->reg_ofs.ldb_mask);
+       set_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
+       writew(mask, ndev->reg_ofs.ldb_mask);
+
+       tasklet_schedule(&db_cb->irq_work);
 
        /* No need to check for the specific HB irq, any interrupt means
         * we're connected.
@@ -955,12 +1004,16 @@ static irqreturn_t xeon_callback_msix_irq(int irq, void *data)
 {
        struct ntb_db_cb *db_cb = data;
        struct ntb_device *ndev = db_cb->ndev;
+       unsigned long mask;
 
        dev_dbg(&ndev->pdev->dev, "MSI-X irq %d received for DB %d\n", irq,
                db_cb->db_num);
 
-       if (db_cb->callback)
-               db_cb->callback(db_cb->data, db_cb->db_num);
+       mask = readw(ndev->reg_ofs.ldb_mask);
+       set_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
+       writew(mask, ndev->reg_ofs.ldb_mask);
+
+       tasklet_schedule(&db_cb->irq_work);
 
        /* On Sandybridge, there are 16 bits in the interrupt register
         * but only 4 vectors.  So, 5 bits are assigned to the first 3
@@ -986,7 +1039,7 @@ static irqreturn_t xeon_event_msix_irq(int irq, void *dev)
                dev_err(&ndev->pdev->dev, "Error determining link status\n");
 
        /* bit 15 is always the link bit */
-       writew(1 << ndev->limits.max_db_bits, ndev->reg_ofs.ldb);
+       writew(1 << SNB_LINK_DB, ndev->reg_ofs.ldb);
 
        return IRQ_HANDLED;
 }
@@ -1075,6 +1128,10 @@ static int ntb_setup_msix(struct ntb_device *ndev)
                         "Only %d MSI-X vectors.  Limiting the number of queues to that number.\n",
                         rc);
                msix_entries = rc;
+
+               rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries);
+               if (rc)
+                       goto err1;
        }
 
        for (i = 0; i < msix_entries; i++) {
@@ -1176,9 +1233,10 @@ static int ntb_setup_interrupts(struct ntb_device *ndev)
         */
        if (ndev->hw_type == BWD_HW)
                writeq(~0, ndev->reg_ofs.ldb_mask);
-       else
-               writew(~(1 << ndev->limits.max_db_bits),
-                      ndev->reg_ofs.ldb_mask);
+       else {
+               u16 var = 1 << SNB_LINK_DB;
+               writew(~var, ndev->reg_ofs.ldb_mask);
+       }
 
        rc = ntb_setup_msix(ndev);
        if (!rc)
@@ -1286,6 +1344,39 @@ static void ntb_free_debugfs(struct ntb_device *ndev)
        }
 }
 
+static void ntb_hw_link_up(struct ntb_device *ndev)
+{
+       if (ndev->conn_type == NTB_CONN_TRANSPARENT)
+               ntb_link_event(ndev, NTB_LINK_UP);
+       else {
+               u32 ntb_cntl;
+
+               /* Let's bring the NTB link up */
+               ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
+               ntb_cntl &= ~(NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK);
+               ntb_cntl |= NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP;
+               ntb_cntl |= NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP;
+               writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
+       }
+}
+
+static void ntb_hw_link_down(struct ntb_device *ndev)
+{
+       u32 ntb_cntl;
+
+       if (ndev->conn_type == NTB_CONN_TRANSPARENT) {
+               ntb_link_event(ndev, NTB_LINK_DOWN);
+               return;
+       }
+
+       /* Bring NTB link down */
+       ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
+       ntb_cntl &= ~(NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP);
+       ntb_cntl &= ~(NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP);
+       ntb_cntl |= NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK;
+       writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
+}
+
 static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        struct ntb_device *ndev;
@@ -1374,9 +1465,7 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (rc)
                goto err6;
 
-       /* Let's bring the NTB link up */
-       writel(NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP,
-              ndev->reg_ofs.lnk_cntl);
+       ntb_hw_link_up(ndev);
 
        return 0;
 
@@ -1406,12 +1495,8 @@ static void ntb_pci_remove(struct pci_dev *pdev)
 {
        struct ntb_device *ndev = pci_get_drvdata(pdev);
        int i;
-       u32 ntb_cntl;
 
-       /* Bring NTB link down */
-       ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
-       ntb_cntl |= NTB_CNTL_LINK_DISABLE;
-       writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
+       ntb_hw_link_down(ndev);
 
        ntb_transport_free(ndev->ntb_transport);
 
index 0a31cedae7d42f9227d125bfabe97297b47255d9..bbdb7edca10cd8647e4b739dfab29f1ed33fc1e6 100644 (file)
@@ -106,10 +106,11 @@ struct ntb_mw {
 };
 
 struct ntb_db_cb {
-       void (*callback) (void *data, int db_num);
+       int (*callback)(void *data, int db_num);
        unsigned int db_num;
        void *data;
        struct ntb_device *ndev;
+       struct tasklet_struct irq_work;
 };
 
 struct ntb_device {
@@ -228,8 +229,8 @@ struct ntb_device *ntb_register_transport(struct pci_dev *pdev,
 void ntb_unregister_transport(struct ntb_device *ndev);
 void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr);
 int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx,
-                            void *data, void (*db_cb_func) (void *data,
-                                                            int db_num));
+                            void *data, int (*db_cb_func)(void *data,
+                                                          int db_num));
 void ntb_unregister_db_callback(struct ntb_device *ndev, unsigned int idx);
 int ntb_register_event_callback(struct ntb_device *ndev,
                                void (*event_cb_func) (void *handle,
index aa4bdd393c58ee2c4cf40105b1644afdcb19913c..9774506419d75ba1a5dc08a5f0e4d52e90d33ad7 100644 (file)
@@ -55,6 +55,7 @@
 #define SNB_MAX_COMPAT_SPADS   16
 /* Reserve the uppermost bit for link interrupt */
 #define SNB_MAX_DB_BITS                15
+#define SNB_LINK_DB            15
 #define SNB_DB_BITS_PER_VEC    5
 #define SNB_MAX_MW             2
 #define SNB_ERRATA_MAX_MW      1
@@ -75,9 +76,6 @@
 #define SNB_SBAR2XLAT_OFFSET   0x0030
 #define SNB_SBAR4XLAT_OFFSET   0x0038
 #define SNB_SBAR0BASE_OFFSET   0x0040
-#define SNB_SBAR0BASE_OFFSET   0x0040
-#define SNB_SBAR2BASE_OFFSET   0x0048
-#define SNB_SBAR4BASE_OFFSET   0x0050
 #define SNB_SBAR2BASE_OFFSET   0x0048
 #define SNB_SBAR4BASE_OFFSET   0x0050
 #define SNB_NTBCNTL_OFFSET     0x0058
 #define BWD_LTSSMSTATEJMP_FORCEDETECT  (1 << 2)
 #define BWD_IBIST_ERR_OFLOW    0x7FFF7FFF
 
-#define NTB_CNTL_CFG_LOCK      (1 << 0)
-#define NTB_CNTL_LINK_DISABLE  (1 << 1)
-#define NTB_CNTL_BAR23_SNOOP   (1 << 2)
-#define NTB_CNTL_BAR45_SNOOP   (1 << 6)
-#define BWD_CNTL_LINK_DOWN     (1 << 16)
+#define NTB_CNTL_CFG_LOCK              (1 << 0)
+#define NTB_CNTL_LINK_DISABLE          (1 << 1)
+#define NTB_CNTL_S2P_BAR23_SNOOP       (1 << 2)
+#define NTB_CNTL_P2S_BAR23_SNOOP       (1 << 4)
+#define NTB_CNTL_S2P_BAR45_SNOOP       (1 << 6)
+#define NTB_CNTL_P2S_BAR45_SNOOP       (1 << 8)
+#define BWD_CNTL_LINK_DOWN             (1 << 16)
 
 #define NTB_PPD_OFFSET         0x00D4
 #define SNB_PPD_CONN_TYPE      0x0003
index d0222f13d154808f3cfa4ed3cab26cd1a7b899ee..3217f394d45b106051b282f824be1413b5efa65d 100644 (file)
@@ -119,7 +119,6 @@ struct ntb_transport_qp {
 
        void (*rx_handler) (struct ntb_transport_qp *qp, void *qp_data,
                            void *data, int len);
-       struct tasklet_struct rx_work;
        struct list_head rx_pend_q;
        struct list_head rx_free_q;
        spinlock_t ntb_rx_pend_q_lock;
@@ -584,11 +583,8 @@ static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size)
        return 0;
 }
 
-static void ntb_qp_link_cleanup(struct work_struct *work)
+static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
 {
-       struct ntb_transport_qp *qp = container_of(work,
-                                                  struct ntb_transport_qp,
-                                                  link_cleanup);
        struct ntb_transport *nt = qp->transport;
        struct pci_dev *pdev = ntb_query_pdev(nt->ndev);
 
@@ -602,6 +598,16 @@ static void ntb_qp_link_cleanup(struct work_struct *work)
 
        dev_info(&pdev->dev, "qp %d: Link Down\n", qp->qp_num);
        qp->qp_link = NTB_LINK_DOWN;
+}
+
+static void ntb_qp_link_cleanup_work(struct work_struct *work)
+{
+       struct ntb_transport_qp *qp = container_of(work,
+                                                  struct ntb_transport_qp,
+                                                  link_cleanup);
+       struct ntb_transport *nt = qp->transport;
+
+       ntb_qp_link_cleanup(qp);
 
        if (nt->transport_link == NTB_LINK_UP)
                schedule_delayed_work(&qp->link_work,
@@ -613,22 +619,20 @@ static void ntb_qp_link_down(struct ntb_transport_qp *qp)
        schedule_work(&qp->link_cleanup);
 }
 
-static void ntb_transport_link_cleanup(struct work_struct *work)
+static void ntb_transport_link_cleanup(struct ntb_transport *nt)
 {
-       struct ntb_transport *nt = container_of(work, struct ntb_transport,
-                                               link_cleanup);
        int i;
 
+       /* Pass along the info to any clients */
+       for (i = 0; i < nt->max_qps; i++)
+               if (!test_bit(i, &nt->qp_bitmap))
+                       ntb_qp_link_cleanup(&nt->qps[i]);
+
        if (nt->transport_link == NTB_LINK_DOWN)
                cancel_delayed_work_sync(&nt->link_work);
        else
                nt->transport_link = NTB_LINK_DOWN;
 
-       /* Pass along the info to any clients */
-       for (i = 0; i < nt->max_qps; i++)
-               if (!test_bit(i, &nt->qp_bitmap))
-                       ntb_qp_link_down(&nt->qps[i]);
-
        /* The scratchpad registers keep the values if the remote side
         * goes down, blast them now to give them a sane value the next
         * time they are accessed
@@ -637,6 +641,14 @@ static void ntb_transport_link_cleanup(struct work_struct *work)
                ntb_write_local_spad(nt->ndev, i, 0);
 }
 
+static void ntb_transport_link_cleanup_work(struct work_struct *work)
+{
+       struct ntb_transport *nt = container_of(work, struct ntb_transport,
+                                               link_cleanup);
+
+       ntb_transport_link_cleanup(nt);
+}
+
 static void ntb_transport_event_callback(void *data, enum ntb_hw_event event)
 {
        struct ntb_transport *nt = data;
@@ -880,7 +892,7 @@ static int ntb_transport_init_queue(struct ntb_transport *nt,
        }
 
        INIT_DELAYED_WORK(&qp->link_work, ntb_qp_link_work);
-       INIT_WORK(&qp->link_cleanup, ntb_qp_link_cleanup);
+       INIT_WORK(&qp->link_cleanup, ntb_qp_link_cleanup_work);
 
        spin_lock_init(&qp->ntb_rx_pend_q_lock);
        spin_lock_init(&qp->ntb_rx_free_q_lock);
@@ -936,7 +948,7 @@ int ntb_transport_init(struct pci_dev *pdev)
        }
 
        INIT_DELAYED_WORK(&nt->link_work, ntb_transport_link_work);
-       INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup);
+       INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup_work);
 
        rc = ntb_register_event_callback(nt->ndev,
                                         ntb_transport_event_callback);
@@ -972,7 +984,7 @@ void ntb_transport_free(void *transport)
        struct ntb_device *ndev = nt->ndev;
        int i;
 
-       nt->transport_link = NTB_LINK_DOWN;
+       ntb_transport_link_cleanup(nt);
 
        /* verify that all the qp's are freed */
        for (i = 0; i < nt->max_qps; i++) {
@@ -1188,11 +1200,14 @@ err:
        goto out;
 }
 
-static void ntb_transport_rx(unsigned long data)
+static int ntb_transport_rxc_db(void *data, int db_num)
 {
-       struct ntb_transport_qp *qp = (struct ntb_transport_qp *)data;
+       struct ntb_transport_qp *qp = data;
        int rc, i;
 
+       dev_dbg(&ntb_query_pdev(qp->ndev)->dev, "%s: doorbell %d received\n",
+               __func__, db_num);
+
        /* Limit the number of packets processed in a single interrupt to
         * provide fairness to others
         */
@@ -1204,16 +1219,8 @@ static void ntb_transport_rx(unsigned long data)
 
        if (qp->dma_chan)
                dma_async_issue_pending(qp->dma_chan);
-}
-
-static void ntb_transport_rxc_db(void *data, int db_num)
-{
-       struct ntb_transport_qp *qp = data;
-
-       dev_dbg(&ntb_query_pdev(qp->ndev)->dev, "%s: doorbell %d received\n",
-               __func__, db_num);
 
-       tasklet_schedule(&qp->rx_work);
+       return i;
 }
 
 static void ntb_tx_copy_callback(void *data)
@@ -1432,11 +1439,12 @@ ntb_transport_create_queue(void *data, struct pci_dev *pdev,
        qp->tx_handler = handlers->tx_handler;
        qp->event_handler = handlers->event_handler;
 
+       dmaengine_get();
        qp->dma_chan = dma_find_channel(DMA_MEMCPY);
-       if (!qp->dma_chan)
+       if (!qp->dma_chan) {
+               dmaengine_put();
                dev_info(&pdev->dev, "Unable to allocate DMA channel, using CPU instead\n");
-       else
-               dmaengine_get();
+       }
 
        for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) {
                entry = kzalloc(sizeof(struct ntb_queue_entry), GFP_ATOMIC);
@@ -1458,25 +1466,23 @@ ntb_transport_create_queue(void *data, struct pci_dev *pdev,
                             &qp->tx_free_q);
        }
 
-       tasklet_init(&qp->rx_work, ntb_transport_rx, (unsigned long) qp);
-
        rc = ntb_register_db_callback(qp->ndev, free_queue, qp,
                                      ntb_transport_rxc_db);
        if (rc)
-               goto err3;
+               goto err2;
 
        dev_info(&pdev->dev, "NTB Transport QP %d created\n", qp->qp_num);
 
        return qp;
 
-err3:
-       tasklet_disable(&qp->rx_work);
 err2:
        while ((entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q)))
                kfree(entry);
 err1:
        while ((entry = ntb_list_rm(&qp->ntb_rx_free_q_lock, &qp->rx_free_q)))
                kfree(entry);
+       if (qp->dma_chan)
+               dmaengine_put();
        set_bit(free_queue, &nt->qp_bitmap);
 err:
        return NULL;
@@ -1515,7 +1521,6 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp)
        }
 
        ntb_unregister_db_callback(qp->ndev, qp->qp_num);
-       tasklet_disable(&qp->rx_work);
 
        cancel_delayed_work_sync(&qp->link_work);
 
index 7578d79b368831085dc5ee70850fd6578ee13357..2f650f68af14e4ec9e37e2c837db3fd55408b9ff 100644 (file)
@@ -300,7 +300,7 @@ static int __init parport_mfc3_init(void)
                if (!request_mem_region(piabase, sizeof(struct pia), "PIA"))
                        continue;
 
-               pp = (struct pia *)ZTWO_VADDR(piabase);
+               pp = ZTWO_VADDR(piabase);
                pp->crb = 0;
                pp->pddrb = 255; /* all data pins output */
                pp->crb = PIA_DDR|32|8;
index 1cf605f6767357947e9a097981caa7d7869ca2f0..ec4ddae1fb54a68641bf4e4b90e6cbec2def6814 100644 (file)
@@ -279,7 +279,9 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
 
        status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
        if (ACPI_FAILURE(status)) {
-               acpi_handle_warn(handle, "can't evaluate _ADR (%#x)\n", status);
+               if (status != AE_NOT_FOUND)
+                       acpi_handle_warn(handle,
+                               "can't evaluate _ADR (%#x)\n", status);
                return AE_OK;
        }
 
@@ -489,7 +491,7 @@ static void acpiphp_bus_add(acpi_handle handle)
 
        acpi_bus_scan(handle);
        acpi_bus_get_device(handle, &adev);
-       if (adev)
+       if (acpi_device_enumerated(adev))
                acpi_device_set_power(adev, ACPI_STATE_D0);
 }
 
index ecfac7e72d91ae29a3ec8a5b6e8d159d0f7b7178..8dcccffd6e216b8529da5530019fe557e0f61ff1 100644 (file)
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <acpi/acpi_bus.h>
 #include <linux/sysfs.h>
 #include <linux/kobject.h>
-#include <asm/uaccess.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
+#include <asm/uaccess.h>
 
 #include "acpiphp.h"
 #include "../pci.h"
index 21e865ded1dce01fde77bb29312e2a653be6b4fa..24e147cae667e33dd46346dddeb994e96e868f4e 100644 (file)
@@ -163,8 +163,6 @@ static inline const char *slot_name(struct slot *slot)
 }
 
 #ifdef CONFIG_ACPI
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
 #include <linux/pci-acpi.h>
 
 void __init pciehp_acpi_slot_detection_init(void);
index 50ce6809829836c38d4aedfa58aeb642b126d9df..2122b2bf006f37576d5bb2e3a22190c5ccacba00 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/module.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
-#include <acpi/acpi_bus.h>
 
 struct ioapic {
        acpi_handle     handle;
index 577074efbe62f93f39ac00c6f5c4963d53bd2b0d..ce31eb0cdca7396ad64a9891d5cee74056887f9e 100644 (file)
@@ -12,9 +12,6 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/pci-aspm.h>
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
-
 #include <linux/pci-acpi.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_qos.h>
@@ -306,10 +303,10 @@ void acpi_pci_remove_bus(struct pci_bus *bus)
 }
 
 /* ACPI bus type */
-static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
+static struct acpi_device *acpi_pci_find_companion(struct device *dev)
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
-       bool is_bridge;
+       bool check_children;
        u64 addr;
 
        /*
@@ -317,14 +314,12 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
         * is set only after acpi_pci_find_device() has been called for the
         * given device.
         */
-       is_bridge = pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE
+       check_children = pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE
                        || pci_dev->hdr_type == PCI_HEADER_TYPE_CARDBUS;
        /* Please ref to ACPI spec for the syntax of _ADR */
        addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
-       *handle = acpi_find_child(ACPI_HANDLE(dev->parent), addr, is_bridge);
-       if (!*handle)
-               return -ENODEV;
-       return 0;
+       return acpi_find_child_device(ACPI_COMPANION(dev->parent), addr,
+                                     check_children);
 }
 
 static void pci_acpi_setup(struct device *dev)
@@ -364,7 +359,7 @@ static bool pci_acpi_bus_match(struct device *dev)
 static struct acpi_bus_type acpi_pci_bus = {
        .name = "PCI",
        .match = pci_acpi_bus_match,
-       .find_device = acpi_pci_find_device,
+       .find_companion = acpi_pci_find_companion,
        .setup = pci_acpi_setup,
        .cleanup = pci_acpi_cleanup,
 };
index 9042fdbd724405bc96808ed699a1d543fcf17c17..7edd5c307446298994bd0b3660f9ffac6de4bd6d 100644 (file)
@@ -288,12 +288,27 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
        int error, node;
        struct drv_dev_and_id ddi = { drv, dev, id };
 
-       /* Execute driver initialization on node where the device's
-          bus is attached to.  This way the driver likely allocates
-          its local memory on the right node without any need to
-          change it. */
+       /*
+        * Execute driver initialization on node where the device is
+        * attached.  This way the driver likely allocates its local memory
+        * on the right node.
+        */
        node = dev_to_node(&dev->dev);
-       if (node >= 0) {
+
+       /*
+        * On NUMA systems, we are likely to call a PF probe function using
+        * work_on_cpu().  If that probe calls pci_enable_sriov() (which
+        * adds the VF devices via pci_bus_add_device()), we may re-enter
+        * this function to call the VF probe function.  Calling
+        * work_on_cpu() again will cause a lockdep warning.  Since VFs are
+        * always on the same node as the PF, we can work around this by
+        * avoiding work_on_cpu() when we're already on the correct node.
+        *
+        * Preemption is enabled, so it's theoretically unsafe to use
+        * numa_node_id(), but even if we run the probe function on the
+        * wrong node, it should be functionally correct.
+        */
+       if (node >= 0 && node != numa_node_id()) {
                int cpu;
 
                get_online_cpus();
@@ -305,6 +320,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
                put_online_cpus();
        } else
                error = local_pci_probe(&ddi);
+
        return error;
 }
 
index d51f45aa669e5ff9184daab1df72776e8165aa84..dbafcc8ef67396da56ce21568d1fb89fe5c8778d 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/nls.h>
 #include <linux/acpi.h>
 #include <linux/pci-acpi.h>
-#include <acpi/acpi_bus.h>
 #include "pci.h"
 
 #define        DEVICE_LABEL_DSM        0x07
index b3b1b9aa8863817e16812fdb65a26cb6dd1c27fd..3a02717473adc7dfb775a543d6c8f786ddb91ff4 100644 (file)
@@ -9,10 +9,6 @@
  *
  *  Init/reset quirks for USB host controllers should be in the
  *  USB quirks file, where their drivers can access reuse it.
- *
- *  The bridge optimization stuff has been removed. If you really
- *  have a silly BIOS which is unable to set your host bridge right,
- *  use the PowerTweak utility (see http://powertweak.sourceforge.net).
  */
 
 #include <linux/types.h>
index 1576851028db700be2413b01e815cc8387b3cd47..cc9337a71529180eaebc7beb991dfb7c9e186ea8 100644 (file)
@@ -24,7 +24,7 @@ static void pci_stop_dev(struct pci_dev *dev)
        if (dev->is_added) {
                pci_proc_detach_device(dev);
                pci_remove_sysfs_dev_files(dev);
-               device_del(&dev->dev);
+               device_release_driver(&dev->dev);
                dev->is_added = 0;
        }
 
@@ -34,6 +34,8 @@ static void pci_stop_dev(struct pci_dev *dev)
 
 static void pci_destroy_dev(struct pci_dev *dev)
 {
+       device_del(&dev->dev);
+
        down_write(&pci_bus_sem);
        list_del(&dev->bus_list);
        up_write(&pci_bus_sem);
index 2832576d8b12ee7c99e24896c3fe333dd8cffadc..114f5ef4b73abdbcd02e524a1a34f84aeeb5b7cb 100644 (file)
@@ -512,6 +512,7 @@ static const struct dev_pm_ops byt_gpio_pm_ops = {
 
 static const struct acpi_device_id byt_gpio_acpi_match[] = {
        { "INT33B2", 0 },
+       { "INT33FC", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
index 69616aeaa966218efa16eb3858324107e816e7bf..09fde58b12e0fa1e2446d56218fa644f32aeeef1 100644 (file)
@@ -5,3 +5,4 @@ if GOLDFISH
 source "drivers/platform/goldfish/Kconfig"
 endif
 
+source "drivers/platform/chrome/Kconfig"
index 8a44a4cd6d1efc30789d5da4cc392447695d68ae..3656b7b17b99ee8ecc806fd21f3fa493873ff122 100644 (file)
@@ -5,3 +5,4 @@
 obj-$(CONFIG_X86)              += x86/
 obj-$(CONFIG_OLPC)             += olpc/
 obj-$(CONFIG_GOLDFISH)         += goldfish/
+obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
new file mode 100644 (file)
index 0000000..440ed77
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# Platform support for Chrome OS hardware (Chromebooks and Chromeboxes)
+#
+
+menuconfig CHROME_PLATFORMS
+       bool "Platform support for Chrome hardware"
+       depends on X86
+       ---help---
+         Say Y here to get to see options for platform support for
+         various Chromebooks and Chromeboxes. This option alone does
+         not add any kernel code.
+
+         If you say N, all options in this submenu will be skipped and disabled.
+
+if CHROME_PLATFORMS
+
+config CHROMEOS_LAPTOP
+       tristate "Chrome OS Laptop"
+       depends on I2C
+       depends on DMI
+       ---help---
+         This driver instantiates i2c and smbus devices such as
+         light sensors and touchpads.
+
+         If you have a supported Chromebook, choose Y or M here.
+         The module will be called chromeos_laptop.
+
+config CHROMEOS_PSTORE
+       tristate "Chrome OS pstore support"
+       ---help---
+         This module instantiates the persistent storage on x86 ChromeOS
+         devices. It can be used to store away console logs and crash
+         information across reboots.
+
+         The range of memory used is 0xf00000-0x1000000, traditionally
+         the memory used to back VGA controller memory.
+
+         If you have a supported Chromebook, choose Y or M here.
+         The module will be called chromeos_pstore.
+
+
+endif # CHROMEOS_PLATFORMS
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile
new file mode 100644 (file)
index 0000000..2b860ca
--- /dev/null
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_CHROMEOS_LAPTOP)  += chromeos_laptop.o
+obj-$(CONFIG_CHROMEOS_PSTORE)  += chromeos_pstore.o
similarity index 57%
rename from drivers/platform/x86/chromeos_laptop.c
rename to drivers/platform/chrome/chromeos_laptop.c
index 3e5b4497a1d02010b4c63bdc939f67127bb19976..7f3aad0e115c49f4c2ea85c149dace0e901620ce 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 
 #define ATMEL_TP_I2C_ADDR      0x4b
 #define ATMEL_TP_I2C_BL_ADDR   0x25
@@ -40,7 +41,7 @@ static struct i2c_client *als;
 static struct i2c_client *tp;
 static struct i2c_client *ts;
 
-const char *i2c_adapter_names[] = {
+static const char *i2c_adapter_names[] = {
        "SMBus I801 adapter",
        "i915 gmbus vga",
        "i915 gmbus panel",
@@ -53,20 +54,33 @@ enum i2c_adapter_type {
        I2C_ADAPTER_PANEL,
 };
 
-static struct i2c_board_info __initdata cyapa_device = {
+struct i2c_peripheral {
+       int (*add)(enum i2c_adapter_type type);
+       enum i2c_adapter_type type;
+};
+
+#define MAX_I2C_PERIPHERALS 3
+
+struct chromeos_laptop {
+       struct i2c_peripheral i2c_peripherals[MAX_I2C_PERIPHERALS];
+};
+
+static struct chromeos_laptop *cros_laptop;
+
+static struct i2c_board_info cyapa_device = {
        I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR),
        .flags          = I2C_CLIENT_WAKE,
 };
 
-static struct i2c_board_info __initdata isl_als_device = {
+static struct i2c_board_info isl_als_device = {
        I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR),
 };
 
-static struct i2c_board_info __initdata tsl2583_als_device = {
+static struct i2c_board_info tsl2583_als_device = {
        I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR),
 };
 
-static struct i2c_board_info __initdata tsl2563_als_device = {
+static struct i2c_board_info tsl2563_als_device = {
        I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR),
 };
 
@@ -89,7 +103,7 @@ static struct mxt_platform_data atmel_224s_tp_platform_data = {
        .config_length          = 0,
 };
 
-static struct i2c_board_info __initdata atmel_224s_tp_device = {
+static struct i2c_board_info atmel_224s_tp_device = {
        I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR),
        .platform_data = &atmel_224s_tp_platform_data,
        .flags          = I2C_CLIENT_WAKE,
@@ -110,13 +124,13 @@ static struct mxt_platform_data atmel_1664s_platform_data = {
        .config_length          = 0,
 };
 
-static struct i2c_board_info __initdata atmel_1664s_device = {
+static struct i2c_board_info atmel_1664s_device = {
        I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR),
        .platform_data = &atmel_1664s_platform_data,
        .flags          = I2C_CLIENT_WAKE,
 };
 
-static struct i2c_client __init *__add_probed_i2c_device(
+static struct i2c_client *__add_probed_i2c_device(
                const char *name,
                int bus,
                struct i2c_board_info *info,
@@ -169,7 +183,7 @@ static struct i2c_client __init *__add_probed_i2c_device(
        return client;
 }
 
-static int __init __find_i2c_adap(struct device *dev, void *data)
+static int __find_i2c_adap(struct device *dev, void *data)
 {
        const char *name = data;
        static const char *prefix = "i2c-";
@@ -180,7 +194,7 @@ static int __init __find_i2c_adap(struct device *dev, void *data)
        return (strncmp(adapter->name, name, strlen(name)) == 0);
 }
 
-static int __init find_i2c_adapter_num(enum i2c_adapter_type type)
+static int find_i2c_adapter_num(enum i2c_adapter_type type)
 {
        struct device *dev = NULL;
        struct i2c_adapter *adapter;
@@ -189,8 +203,9 @@ static int __init find_i2c_adapter_num(enum i2c_adapter_type type)
        dev = bus_find_device(&i2c_bus_type, NULL, (void *)name,
                              __find_i2c_adap);
        if (!dev) {
-               pr_err("%s: i2c adapter %s not found on system.\n", __func__,
-                      name);
+               /* Adapters may appear later. Deferred probing will retry */
+               pr_notice("%s: i2c adapter %s not found on system.\n", __func__,
+                         name);
                return -ENODEV;
        }
        adapter = to_i2c_adapter(dev);
@@ -205,7 +220,7 @@ static int __init find_i2c_adapter_num(enum i2c_adapter_type type)
  * Returns NULL if no devices found.
  * See Documentation/i2c/instantiating-devices for more information.
  */
-static __init struct i2c_client *add_probed_i2c_device(
+static struct i2c_client *add_probed_i2c_device(
                const char *name,
                enum i2c_adapter_type type,
                struct i2c_board_info *info,
@@ -222,7 +237,7 @@ static __init struct i2c_client *add_probed_i2c_device(
  * info->addr.
  * Returns NULL if no device found.
  */
-static __init struct i2c_client *add_i2c_device(const char *name,
+static struct i2c_client *add_i2c_device(const char *name,
                                                enum i2c_adapter_type type,
                                                struct i2c_board_info *info)
 {
@@ -233,161 +248,259 @@ static __init struct i2c_client *add_i2c_device(const char *name,
                                       addr_list);
 }
 
-
-static struct i2c_client __init *add_smbus_device(const char *name,
-                                                 struct i2c_board_info *info)
+static int setup_cyapa_tp(enum i2c_adapter_type type)
 {
-       return add_i2c_device(name, I2C_ADAPTER_SMBUS, info);
-}
+       if (tp)
+               return 0;
 
-static int __init setup_cyapa_smbus_tp(const struct dmi_system_id *id)
-{
-       /* add cyapa touchpad on smbus */
-       tp = add_smbus_device("trackpad", &cyapa_device);
-       return 0;
+       /* add cyapa touchpad */
+       tp = add_i2c_device("trackpad", type, &cyapa_device);
+       return (!tp) ? -EAGAIN : 0;
 }
 
-static int __init setup_atmel_224s_tp(const struct dmi_system_id *id)
+static int setup_atmel_224s_tp(enum i2c_adapter_type type)
 {
        const unsigned short addr_list[] = { ATMEL_TP_I2C_BL_ADDR,
                                             ATMEL_TP_I2C_ADDR,
                                             I2C_CLIENT_END };
+       if (tp)
+               return 0;
 
-       /* add atmel mxt touchpad on VGA DDC GMBus */
-       tp = add_probed_i2c_device("trackpad", I2C_ADAPTER_VGADDC,
+       /* add atmel mxt touchpad */
+       tp = add_probed_i2c_device("trackpad", type,
                                   &atmel_224s_tp_device, addr_list);
-       return 0;
+       return (!tp) ? -EAGAIN : 0;
 }
 
-static int __init setup_atmel_1664s_ts(const struct dmi_system_id *id)
+static int setup_atmel_1664s_ts(enum i2c_adapter_type type)
 {
        const unsigned short addr_list[] = { ATMEL_TS_I2C_BL_ADDR,
                                             ATMEL_TS_I2C_ADDR,
                                             I2C_CLIENT_END };
+       if (ts)
+               return 0;
 
-       /* add atmel mxt touch device on PANEL GMBus */
-       ts = add_probed_i2c_device("touchscreen", I2C_ADAPTER_PANEL,
+       /* add atmel mxt touch device */
+       ts = add_probed_i2c_device("touchscreen", type,
                                   &atmel_1664s_device, addr_list);
-       return 0;
+       return (!ts) ? -EAGAIN : 0;
 }
 
-
-static int __init setup_isl29018_als(const struct dmi_system_id *id)
+static int setup_isl29018_als(enum i2c_adapter_type type)
 {
+       if (als)
+               return 0;
+
        /* add isl29018 light sensor */
-       als = add_smbus_device("lightsensor", &isl_als_device);
-       return 0;
+       als = add_i2c_device("lightsensor", type, &isl_als_device);
+       return (!als) ? -EAGAIN : 0;
 }
 
-static int __init setup_isl29023_als(const struct dmi_system_id *id)
+static int setup_tsl2583_als(enum i2c_adapter_type type)
 {
-       /* add isl29023 light sensor on Panel GMBus */
-       als = add_i2c_device("lightsensor", I2C_ADAPTER_PANEL,
-                            &isl_als_device);
-       return 0;
+       if (als)
+               return 0;
+
+       /* add tsl2583 light sensor */
+       als = add_i2c_device(NULL, type, &tsl2583_als_device);
+       return (!als) ? -EAGAIN : 0;
 }
 
-static int __init setup_tsl2583_als(const struct dmi_system_id *id)
+static int setup_tsl2563_als(enum i2c_adapter_type type)
 {
-       /* add tsl2583 light sensor on smbus */
-       als = add_smbus_device(NULL, &tsl2583_als_device);
-       return 0;
+       if (als)
+               return 0;
+
+       /* add tsl2563 light sensor */
+       als = add_i2c_device(NULL, type, &tsl2563_als_device);
+       return (!als) ? -EAGAIN : 0;
 }
 
-static int __init setup_tsl2563_als(const struct dmi_system_id *id)
+static int __init chromeos_laptop_dmi_matched(const struct dmi_system_id *id)
 {
-       /* add tsl2563 light sensor on smbus */
-       als = add_smbus_device(NULL, &tsl2563_als_device);
-       return 0;
+       cros_laptop = (void *)id->driver_data;
+       pr_debug("DMI Matched %s.\n", id->ident);
+
+       /* Indicate to dmi_scan that processing is done. */
+       return 1;
 }
 
-static struct dmi_system_id __initdata chromeos_laptop_dmi_table[] = {
-       {
-               .ident = "Samsung Series 5 550 - Touchpad",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Lumpy"),
-               },
-               .callback = setup_cyapa_smbus_tp,
+static int chromeos_laptop_probe(struct platform_device *pdev)
+{
+       int i;
+       int ret = 0;
+
+       for (i = 0; i < MAX_I2C_PERIPHERALS; i++) {
+               struct i2c_peripheral *i2c_dev;
+
+               i2c_dev = &cros_laptop->i2c_peripherals[i];
+
+               /* No more peripherals. */
+               if (i2c_dev->add == NULL)
+                       break;
+
+               /* Add the device. Set -EPROBE_DEFER on any failure */
+               if (i2c_dev->add(i2c_dev->type))
+                       ret = -EPROBE_DEFER;
+       }
+
+       return ret;
+}
+
+static struct chromeos_laptop samsung_series_5_550 = {
+       .i2c_peripherals = {
+               /* Touchpad. */
+               { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS },
+               /* Light Sensor. */
+               { .add = setup_isl29018_als, I2C_ADAPTER_SMBUS },
        },
-       {
-               .ident = "Chromebook Pixel - Touchscreen",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Link"),
-               },
-               .callback = setup_atmel_1664s_ts,
+};
+
+static struct chromeos_laptop samsung_series_5 = {
+       .i2c_peripherals = {
+               /* Light Sensor. */
+               { .add = setup_tsl2583_als, I2C_ADAPTER_SMBUS },
+       },
+};
+
+static struct chromeos_laptop chromebook_pixel = {
+       .i2c_peripherals = {
+               /* Touch Screen. */
+               { .add = setup_atmel_1664s_ts, I2C_ADAPTER_PANEL },
+               /* Touchpad. */
+               { .add = setup_atmel_224s_tp, I2C_ADAPTER_VGADDC },
+               /* Light Sensor. */
+               { .add = setup_isl29018_als, I2C_ADAPTER_PANEL },
+       },
+};
+
+static struct chromeos_laptop acer_c7_chromebook = {
+       .i2c_peripherals = {
+               /* Touchpad. */
+               { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS },
+       },
+};
+
+static struct chromeos_laptop acer_ac700 = {
+       .i2c_peripherals = {
+               /* Light Sensor. */
+               { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS },
        },
+};
+
+static struct chromeos_laptop hp_pavilion_14_chromebook = {
+       .i2c_peripherals = {
+               /* Touchpad. */
+               { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS },
+       },
+};
+
+static struct chromeos_laptop cr48 = {
+       .i2c_peripherals = {
+               /* Light Sensor. */
+               { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS },
+       },
+};
+
+#define _CBDD(board_) \
+       .callback = chromeos_laptop_dmi_matched, \
+       .driver_data = (void *)&board_
+
+static struct dmi_system_id chromeos_laptop_dmi_table[] __initdata = {
        {
-               .ident = "Chromebook Pixel - Touchpad",
+               .ident = "Samsung Series 5 550",
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Link"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Lumpy"),
                },
-               .callback = setup_atmel_224s_tp,
+               _CBDD(samsung_series_5_550),
        },
        {
-               .ident = "Samsung Series 5 550 - Light Sensor",
+               .ident = "Samsung Series 5",
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Lumpy"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Alex"),
                },
-               .callback = setup_isl29018_als,
+               _CBDD(samsung_series_5),
        },
        {
-               .ident = "Chromebook Pixel - Light Sensor",
+               .ident = "Chromebook Pixel",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "Link"),
                },
-               .callback = setup_isl29023_als,
+               _CBDD(chromebook_pixel),
        },
        {
-               .ident = "Acer C7 Chromebook - Touchpad",
+               .ident = "Acer C7 Chromebook",
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Parrot"),
                },
-               .callback = setup_cyapa_smbus_tp,
+               _CBDD(acer_c7_chromebook),
        },
        {
-               .ident = "HP Pavilion 14 Chromebook - Touchpad",
+               .ident = "Acer AC700",
                .matches = {
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
                },
-               .callback = setup_cyapa_smbus_tp,
+               _CBDD(acer_ac700),
        },
        {
-               .ident = "Samsung Series 5 - Light Sensor",
+               .ident = "HP Pavilion 14 Chromebook",
                .matches = {
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Alex"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"),
                },
-               .callback = setup_tsl2583_als,
+               _CBDD(hp_pavilion_14_chromebook),
        },
        {
-               .ident = "Cr-48 - Light Sensor",
+               .ident = "Cr-48",
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Mario"),
                },
-               .callback = setup_tsl2563_als,
-       },
-       {
-               .ident = "Acer AC700 - Light Sensor",
-               .matches = {
-                       DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
-               },
-               .callback = setup_tsl2563_als,
+               _CBDD(cr48),
        },
        { }
 };
 MODULE_DEVICE_TABLE(dmi, chromeos_laptop_dmi_table);
 
+static struct platform_device *cros_platform_device;
+
+static struct platform_driver cros_platform_driver = {
+       .driver = {
+               .name = "chromeos_laptop",
+               .owner = THIS_MODULE,
+       },
+       .probe = chromeos_laptop_probe,
+};
+
 static int __init chromeos_laptop_init(void)
 {
+       int ret;
        if (!dmi_check_system(chromeos_laptop_dmi_table)) {
                pr_debug("%s unsupported system.\n", __func__);
                return -ENODEV;
        }
+
+       ret = platform_driver_register(&cros_platform_driver);
+       if (ret)
+               return ret;
+
+       cros_platform_device = platform_device_alloc("chromeos_laptop", -1);
+       if (!cros_platform_device) {
+               ret = -ENOMEM;
+               goto fail_platform_device1;
+       }
+
+       ret = platform_device_add(cros_platform_device);
+       if (ret)
+               goto fail_platform_device2;
+
        return 0;
+
+fail_platform_device2:
+       platform_device_put(cros_platform_device);
+fail_platform_device1:
+       platform_driver_unregister(&cros_platform_driver);
+       return ret;
 }
 
 static void __exit chromeos_laptop_exit(void)
@@ -398,6 +511,9 @@ static void __exit chromeos_laptop_exit(void)
                i2c_unregister_device(tp);
        if (ts)
                i2c_unregister_device(ts);
+
+       platform_device_unregister(cros_platform_device);
+       platform_driver_unregister(&cros_platform_driver);
 }
 
 module_init(chromeos_laptop_init);
diff --git a/drivers/platform/chrome/chromeos_pstore.c b/drivers/platform/chrome/chromeos_pstore.c
new file mode 100644 (file)
index 0000000..e0e0e65
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *  chromeos_pstore.c - Driver to instantiate Chromebook ramoops device
+ *
+ *  Copyright (C) 2013 Google, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, version 2 of the License.
+ */
+
+#include <linux/dmi.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pstore_ram.h>
+
+static struct dmi_system_id chromeos_pstore_dmi_table[] __initdata = {
+       {
+               /*
+                * Today all Chromebooks/boxes ship with GOOGLE as vendor and
+                * coreboot as bios vendor. No other systems with this
+                * combination are known to date.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+                       DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
+               },
+       },
+       {
+               /*
+                * The first Samsung Chromebox and Chromebook Series 5 550 use
+                * coreboot but with Samsung as the system vendor.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"),
+                       DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
+               },
+       },
+       {
+               /* x86-alex, the first Samsung Chromebook. */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Alex"),
+               },
+       },
+       {
+               /* x86-mario, the Cr-48 pilot device from Google. */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "IEC"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Mario"),
+               },
+       },
+       {
+               /* x86-zgb, the first Acer Chromebook. */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
+               },
+       },
+       { }
+};
+MODULE_DEVICE_TABLE(dmi, chromeos_pstore_dmi_table);
+
+/*
+ * On x86 chromebooks/boxes, the firmware will keep the legacy VGA memory
+ * range untouched across reboots, so we use that to store our pstore
+ * contents for panic logs, etc.
+ */
+static struct ramoops_platform_data chromeos_ramoops_data = {
+       .mem_size       = 0x100000,
+       .mem_address    = 0xf00000,
+       .record_size    = 0x20000,
+       .console_size   = 0x20000,
+       .ftrace_size    = 0x20000,
+       .dump_oops      = 1,
+};
+
+static struct platform_device chromeos_ramoops = {
+       .name = "ramoops",
+       .dev = {
+               .platform_data = &chromeos_ramoops_data,
+       },
+};
+
+static int __init chromeos_pstore_init(void)
+{
+       if (dmi_check_system(chromeos_pstore_dmi_table))
+               return platform_device_register(&chromeos_ramoops);
+
+       return -ENODEV;
+}
+
+static void __exit chromeos_pstore_exit(void)
+{
+       platform_device_unregister(&chromeos_ramoops);
+}
+
+module_init(chromeos_pstore_init);
+module_exit(chromeos_pstore_exit);
+
+MODULE_DESCRIPTION("Chrome OS pstore module");
+MODULE_LICENSE("GPL");
index b51a7460cc49bc03b4c055e8f46bfe2fedf718ff..d9dcd37b5a521e86baf54702ff96f91657037aff 100644 (file)
@@ -79,17 +79,6 @@ config ASUS_LAPTOP
 
          If you have an ACPI-compatible ASUS laptop, say Y or M here.
 
-config CHROMEOS_LAPTOP
-       tristate "Chrome OS Laptop"
-       depends on I2C
-       depends on DMI
-       ---help---
-         This driver instantiates i2c and smbus devices such as
-         light sensors and touchpads.
-
-         If you have a supported Chromebook, choose Y or M here.
-         The module will be called chromeos_laptop.
-
 config DELL_LAPTOP
        tristate "Dell Laptop Extras"
        depends on X86
index 5dbe193243510a94db296ba690ded6fa1af768e5..f0e6aa407ffb9ee8786e7aa71f5c76ed00ec6d81 100644 (file)
@@ -50,7 +50,6 @@ obj-$(CONFIG_INTEL_MID_POWER_BUTTON)  += intel_mid_powerbtn.o
 obj-$(CONFIG_INTEL_OAKTRAIL)   += intel_oaktrail.o
 obj-$(CONFIG_SAMSUNG_Q10)      += samsung-q10.o
 obj-$(CONFIG_APPLE_GMUX)       += apple-gmux.o
-obj-$(CONFIG_CHROMEOS_LAPTOP)  += chromeos_laptop.o
 obj-$(CONFIG_INTEL_RST)                += intel-rst.o
 obj-$(CONFIG_INTEL_SMARTCONNECT)       += intel-smartconnect.o
 
index c9076bdaf2c18fc9a34c3d3f906cd333971f57e5..c91f69b39db4b8c637d5182eb5f8f85aed1bf79b 100644 (file)
@@ -41,8 +41,6 @@
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
-
-#include <acpi/acpi_drivers.h>
 #include <acpi/video.h>
 
 MODULE_AUTHOR("Carlos Corbacho");
index 0e9c169b42f82a782b1166b2c05880ad4e1ad0da..7f4dc6f51f8afdf9df7984818585e10bf2047280 100644 (file)
@@ -53,8 +53,7 @@
 #include <linux/rfkill.h>
 #include <linux/slab.h>
 #include <linux/dmi.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
+#include <linux/acpi.h>
 
 #define ASUS_LAPTOP_VERSION    "0.42"
 
@@ -1494,10 +1493,9 @@ static int asus_input_init(struct asus_laptop *asus)
        int error;
 
        input = input_allocate_device();
-       if (!input) {
-               pr_warn("Unable to allocate input device\n");
+       if (!input)
                return -ENOMEM;
-       }
+
        input->name = "Asus Laptop extra buttons";
        input->phys = ASUS_LAPTOP_FILE "/input0";
        input->id.bustype = BUS_HOST;
index 19c313b056c334c771e678b05146ee7676e7edac..df7ecb9ecd9d7c95b66cdbc79f4f17bfaf4bf49c 100644 (file)
@@ -45,8 +45,7 @@
 #include <linux/seq_file.h>
 #include <linux/platform_device.h>
 #include <linux/thermal.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <acpi/video.h>
 
 #include "asus-wmi.h"
index 6dfa8d3b4eec22dfd826e6d7de7cc811d565340b..70d355a9ae2cc2f7cdc2efb04941a2c76688139f 100644 (file)
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <linux/backlight.h>
 #include <linux/input.h>
 #include <linux/rfkill.h>
 
 MODULE_LICENSE("GPL");
 
-
 struct cmpc_accel {
        int sensitivity;
        int g_select;
index bb77e18b3dd4d5a8ce882f883dddbd98a28e037f..c608b1d33f4a60893a3bdc87b52773f872259f6d 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/err.h>
 #include <linux/dmi.h>
 #include <linux/io.h>
+#include <linux/rfkill.h>
 #include <linux/power_supply.h>
 #include <linux/acpi.h>
 #include <linux/mm.h>
@@ -89,6 +90,13 @@ static struct platform_driver platform_driver = {
 
 static struct platform_device *platform_device;
 static struct backlight_device *dell_backlight_device;
+static struct rfkill *wifi_rfkill;
+static struct rfkill *bluetooth_rfkill;
+static struct rfkill *wwan_rfkill;
+static bool force_rfkill;
+
+module_param(force_rfkill, bool, 0444);
+MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");
 
 static const struct dmi_system_id dell_device_table[] __initconst = {
        {
@@ -355,6 +363,108 @@ dell_send_request(struct calling_interface_buffer *buffer, int class,
        return buffer;
 }
 
+/* Derived from information in DellWirelessCtl.cpp:
+   Class 17, select 11 is radio control. It returns an array of 32-bit values.
+
+   Input byte 0 = 0: Wireless information
+
+   result[0]: return code
+   result[1]:
+     Bit 0:      Hardware switch supported
+     Bit 1:      Wifi locator supported
+     Bit 2:      Wifi is supported
+     Bit 3:      Bluetooth is supported
+     Bit 4:      WWAN is supported
+     Bit 5:      Wireless keyboard supported
+     Bits 6-7:   Reserved
+     Bit 8:      Wifi is installed
+     Bit 9:      Bluetooth is installed
+     Bit 10:     WWAN is installed
+     Bits 11-15: Reserved
+     Bit 16:     Hardware switch is on
+     Bit 17:     Wifi is blocked
+     Bit 18:     Bluetooth is blocked
+     Bit 19:     WWAN is blocked
+     Bits 20-31: Reserved
+   result[2]: NVRAM size in bytes
+   result[3]: NVRAM format version number
+
+   Input byte 0 = 2: Wireless switch configuration
+   result[0]: return code
+   result[1]:
+     Bit 0:      Wifi controlled by switch
+     Bit 1:      Bluetooth controlled by switch
+     Bit 2:      WWAN controlled by switch
+     Bits 3-6:   Reserved
+     Bit 7:      Wireless switch config locked
+     Bit 8:      Wifi locator enabled
+     Bits 9-14:  Reserved
+     Bit 15:     Wifi locator setting locked
+     Bits 16-31: Reserved
+*/
+
+static int dell_rfkill_set(void *data, bool blocked)
+{
+       int disable = blocked ? 1 : 0;
+       unsigned long radio = (unsigned long)data;
+       int hwswitch_bit = (unsigned long)data - 1;
+
+       get_buffer();
+       dell_send_request(buffer, 17, 11);
+
+       /* If the hardware switch controls this radio, and the hardware
+          switch is disabled, always disable the radio */
+       if ((hwswitch_state & BIT(hwswitch_bit)) &&
+           !(buffer->output[1] & BIT(16)))
+               disable = 1;
+
+       buffer->input[0] = (1 | (radio<<8) | (disable << 16));
+       dell_send_request(buffer, 17, 11);
+
+       release_buffer();
+       return 0;
+}
+
+/* Must be called with the buffer held */
+static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
+                                       int status)
+{
+       if (status & BIT(0)) {
+               /* Has hw-switch, sync sw_state to BIOS */
+               int block = rfkill_blocked(rfkill);
+               buffer->input[0] = (1 | (radio << 8) | (block << 16));
+               dell_send_request(buffer, 17, 11);
+       } else {
+               /* No hw-switch, sync BIOS state to sw_state */
+               rfkill_set_sw_state(rfkill, !!(status & BIT(radio + 16)));
+       }
+}
+
+static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio,
+                                       int status)
+{
+       if (hwswitch_state & (BIT(radio - 1)))
+               rfkill_set_hw_state(rfkill, !(status & BIT(16)));
+}
+
+static void dell_rfkill_query(struct rfkill *rfkill, void *data)
+{
+       int status;
+
+       get_buffer();
+       dell_send_request(buffer, 17, 11);
+       status = buffer->output[1];
+
+       dell_rfkill_update_hw_state(rfkill, (unsigned long)data, status);
+
+       release_buffer();
+}
+
+static const struct rfkill_ops dell_rfkill_ops = {
+       .set_block = dell_rfkill_set,
+       .query = dell_rfkill_query,
+};
+
 static struct dentry *dell_laptop_dir;
 
 static int dell_debugfs_show(struct seq_file *s, void *data)
@@ -424,6 +534,136 @@ static const struct file_operations dell_debugfs_fops = {
        .release = single_release,
 };
 
+static void dell_update_rfkill(struct work_struct *ignored)
+{
+       int status;
+
+       get_buffer();
+       dell_send_request(buffer, 17, 11);
+       status = buffer->output[1];
+
+       if (wifi_rfkill) {
+               dell_rfkill_update_hw_state(wifi_rfkill, 1, status);
+               dell_rfkill_update_sw_state(wifi_rfkill, 1, status);
+       }
+       if (bluetooth_rfkill) {
+               dell_rfkill_update_hw_state(bluetooth_rfkill, 2, status);
+               dell_rfkill_update_sw_state(bluetooth_rfkill, 2, status);
+       }
+       if (wwan_rfkill) {
+               dell_rfkill_update_hw_state(wwan_rfkill, 3, status);
+               dell_rfkill_update_sw_state(wwan_rfkill, 3, status);
+       }
+
+       release_buffer();
+}
+static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill);
+
+
+static int __init dell_setup_rfkill(void)
+{
+       int status;
+       int ret;
+       const char *product;
+
+       /*
+        * rfkill causes trouble on various non Latitudes, according to Dell
+        * actually testing the rfkill functionality is only done on Latitudes.
+        */
+       product = dmi_get_system_info(DMI_PRODUCT_NAME);
+       if (!force_rfkill && (!product || strncmp(product, "Latitude", 8)))
+               return 0;
+
+       get_buffer();
+       dell_send_request(buffer, 17, 11);
+       status = buffer->output[1];
+       buffer->input[0] = 0x2;
+       dell_send_request(buffer, 17, 11);
+       hwswitch_state = buffer->output[1];
+       release_buffer();
+
+       if (!(status & BIT(0))) {
+               if (force_rfkill) {
+                       /* No hwsitch, clear all hw-controlled bits */
+                       hwswitch_state &= ~7;
+               } else {
+                       /* rfkill is only tested on laptops with a hwswitch */
+                       return 0;
+               }
+       }
+
+       if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
+               wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev,
+                                          RFKILL_TYPE_WLAN,
+                                          &dell_rfkill_ops, (void *) 1);
+               if (!wifi_rfkill) {
+                       ret = -ENOMEM;
+                       goto err_wifi;
+               }
+               ret = rfkill_register(wifi_rfkill);
+               if (ret)
+                       goto err_wifi;
+       }
+
+       if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
+               bluetooth_rfkill = rfkill_alloc("dell-bluetooth",
+                                               &platform_device->dev,
+                                               RFKILL_TYPE_BLUETOOTH,
+                                               &dell_rfkill_ops, (void *) 2);
+               if (!bluetooth_rfkill) {
+                       ret = -ENOMEM;
+                       goto err_bluetooth;
+               }
+               ret = rfkill_register(bluetooth_rfkill);
+               if (ret)
+                       goto err_bluetooth;
+       }
+
+       if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
+               wwan_rfkill = rfkill_alloc("dell-wwan",
+                                          &platform_device->dev,
+                                          RFKILL_TYPE_WWAN,
+                                          &dell_rfkill_ops, (void *) 3);
+               if (!wwan_rfkill) {
+                       ret = -ENOMEM;
+                       goto err_wwan;
+               }
+               ret = rfkill_register(wwan_rfkill);
+               if (ret)
+                       goto err_wwan;
+       }
+
+       return 0;
+err_wwan:
+       rfkill_destroy(wwan_rfkill);
+       if (bluetooth_rfkill)
+               rfkill_unregister(bluetooth_rfkill);
+err_bluetooth:
+       rfkill_destroy(bluetooth_rfkill);
+       if (wifi_rfkill)
+               rfkill_unregister(wifi_rfkill);
+err_wifi:
+       rfkill_destroy(wifi_rfkill);
+
+       return ret;
+}
+
+static void dell_cleanup_rfkill(void)
+{
+       if (wifi_rfkill) {
+               rfkill_unregister(wifi_rfkill);
+               rfkill_destroy(wifi_rfkill);
+       }
+       if (bluetooth_rfkill) {
+               rfkill_unregister(bluetooth_rfkill);
+               rfkill_destroy(bluetooth_rfkill);
+       }
+       if (wwan_rfkill) {
+               rfkill_unregister(wwan_rfkill);
+               rfkill_destroy(wwan_rfkill);
+       }
+}
+
 static int dell_send_intensity(struct backlight_device *bd)
 {
        int ret = 0;
@@ -515,6 +755,30 @@ static void touchpad_led_exit(void)
        led_classdev_unregister(&touchpad_led);
 }
 
+static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
+                             struct serio *port)
+{
+       static bool extended;
+
+       if (str & 0x20)
+               return false;
+
+       if (unlikely(data == 0xe0)) {
+               extended = true;
+               return false;
+       } else if (unlikely(extended)) {
+               switch (data) {
+               case 0x8:
+                       schedule_delayed_work(&dell_rfkill_work,
+                                             round_jiffies_relative(HZ / 4));
+                       break;
+               }
+               extended = false;
+       }
+
+       return false;
+}
+
 static int __init dell_init(void)
 {
        int max_intensity = 0;
@@ -557,10 +821,26 @@ static int __init dell_init(void)
        }
        buffer = page_address(bufferpage);
 
+       ret = dell_setup_rfkill();
+
+       if (ret) {
+               pr_warn("Unable to setup rfkill\n");
+               goto fail_rfkill;
+       }
+
+       ret = i8042_install_filter(dell_laptop_i8042_filter);
+       if (ret) {
+               pr_warn("Unable to install key filter\n");
+               goto fail_filter;
+       }
+
        if (quirks && quirks->touchpad_led)
                touchpad_led_init(&platform_device->dev);
 
        dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL);
+       if (dell_laptop_dir != NULL)
+               debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL,
+                                   &dell_debugfs_fops);
 
 #ifdef CONFIG_ACPI
        /* In the event of an ACPI backlight being available, don't
@@ -603,6 +883,11 @@ static int __init dell_init(void)
        return 0;
 
 fail_backlight:
+       i8042_remove_filter(dell_laptop_i8042_filter);
+       cancel_delayed_work_sync(&dell_rfkill_work);
+fail_filter:
+       dell_cleanup_rfkill();
+fail_rfkill:
        free_page((unsigned long)bufferpage);
 fail_buffer:
        platform_device_del(platform_device);
@@ -620,7 +905,10 @@ static void __exit dell_exit(void)
        debugfs_remove_recursive(dell_laptop_dir);
        if (quirks && quirks->touchpad_led)
                touchpad_led_exit();
+       i8042_remove_filter(dell_laptop_i8042_filter);
+       cancel_delayed_work_sync(&dell_rfkill_work);
        backlight_device_unregister(dell_backlight_device);
+       dell_cleanup_rfkill();
        if (platform_device) {
                platform_device_unregister(platform_device);
                platform_driver_unregister(&platform_driver);
index bcf8cc6b5537cca1a1c3ad016d700ca3f30104a4..dbc97a33bbc8ea2cbd61590590f533c13680a3a4 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/types.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
-#include <acpi/acpi_drivers.h>
 #include <linux/acpi.h>
 #include <linux/string.h>
 
index fa9a2171cc134b733c837f89a4f1b80aeb0989ea..390e8e33d5e31b77d67c7d7a1a8c659ead20e791 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/types.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
-#include <acpi/acpi_drivers.h>
 #include <linux/acpi.h>
 #include <linux/string.h>
 #include <linux/dmi.h>
@@ -130,7 +129,8 @@ static const u16 bios_to_linux_keycode[256] __initconst = {
        KEY_BRIGHTNESSUP,       KEY_UNKNOWN,    KEY_KBDILLUMTOGGLE,
        KEY_UNKNOWN,    KEY_SWITCHVIDEOMODE,    KEY_UNKNOWN, KEY_UNKNOWN,
        KEY_SWITCHVIDEOMODE,    KEY_UNKNOWN,    KEY_UNKNOWN, KEY_PROG2,
-       KEY_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       KEY_UNKNOWN,    KEY_UNKNOWN,    KEY_UNKNOWN,    KEY_UNKNOWN,
+       KEY_UNKNOWN,    KEY_UNKNOWN,    KEY_UNKNOWN,    KEY_MICMUTE,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -139,8 +139,8 @@ static const u16 bios_to_linux_keycode[256] __initconst = {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       KEY_PROG3
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_PROG3
 };
 
 static struct input_dev *dell_wmi_input_dev;
index aefcc32e563479d2b22404fdd75ceb7072423d16..bcde1ea02dd36ecb7024292cf03187edeab1fdd6 100644 (file)
@@ -28,8 +28,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/slab.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
+#include <linux/acpi.h>
 #include <linux/uaccess.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
@@ -1203,10 +1202,8 @@ static int eeepc_input_init(struct eeepc_laptop *eeepc)
        int error;
 
        input = input_allocate_device();
-       if (!input) {
-               pr_info("Unable to allocate input device\n");
+       if (!input)
                return -ENOMEM;
-       }
 
        input->name = "Asus EeePC extra buttons";
        input->phys = EEEPC_LAPTOP_FILE "/input0";
index af67e6e56ebbf3165d6c315daf6e88b155328d8f..6112933f627834cc1c4561feb68a3edc28492e5e 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/input/sparse-keymap.h>
 #include <linux/dmi.h>
 #include <linux/fb.h>
-#include <acpi/acpi_bus.h>
+#include <linux/acpi.h>
 
 #include "asus-wmi.h"
 
index 1c86fa0857c8eb73dfb64ec90ee9e7f7e50404c3..8ba8956b5a48f7f1fccc37df42cdaf4772892209 100644 (file)
@@ -54,6 +54,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
 #define HPWMI_HARDWARE_QUERY 0x4
 #define HPWMI_WIRELESS_QUERY 0x5
 #define HPWMI_HOTKEY_QUERY 0xc
+#define HPWMI_FEATURE_QUERY 0xd
 #define HPWMI_WIRELESS2_QUERY 0x1b
 #define HPWMI_POSTCODEERROR_QUERY 0x2a
 
@@ -292,6 +293,17 @@ static int hp_wmi_tablet_state(void)
        return (state & 0x4) ? 1 : 0;
 }
 
+static int hp_wmi_bios_2009_later(void)
+{
+       int state = 0;
+       int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, 0, &state,
+                                      sizeof(state), sizeof(state));
+       if (ret)
+               return ret;
+
+       return (state & 0x10) ? 1 : 0;
+}
+
 static int hp_wmi_set_block(void *data, bool blocked)
 {
        enum hp_wmi_radio r = (enum hp_wmi_radio) data;
@@ -871,7 +883,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
        gps_rfkill = NULL;
        rfkill2_count = 0;
 
-       if (hp_wmi_rfkill_setup(device))
+       if (hp_wmi_bios_2009_later() || hp_wmi_rfkill_setup(device))
                hp_wmi_rfkill2_setup(device);
 
        err = device_create_file(&device->dev, &dev_attr_display);
index a8e43cf70fac96309d7b689265b7c2b6ba2a19db..aff4d0670edfec733e131c0137fd82f70e0d2206 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/uaccess.h>
 #include <linux/leds.h>
 #include <linux/atomic.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include "../../misc/lis3lv02d/lis3lv02d.h"
 
 #define DRIVER_NAME     "hp_accel"
index 6788acc22ab97f01b410240eef0a5b2082c98550..6dd060a0bb65293d47a2d02669a62785403b8ae0 100644 (file)
@@ -26,8 +26,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <linux/rfkill.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
@@ -570,10 +569,8 @@ static int ideapad_input_init(struct ideapad_private *priv)
        int error;
 
        inputdev = input_allocate_device();
-       if (!inputdev) {
-               pr_info("Unable to allocate input device\n");
+       if (!inputdev)
                return -ENOMEM;
-       }
 
        inputdev->name = "Ideapad extra buttons";
        inputdev->phys = "ideapad/input0";
index a2083a9e5662d660fd95cbb297815aa0570c8268..d45bca34bf1b3bc935f5dc9b729fd87219cf4825 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 MODULE_LICENSE("GPL");
 
index 1838400dc0360615f799fac64a82b51f7efb9c17..04cf5dffdfd9152436719e69955df00afe30e144 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 MODULE_LICENSE("GPL");
 
index 11244f8703c402c876fb34b0e107383781661416..e8b46d2c468c963b37f338534b40aad814ac8792 100644 (file)
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
-
 #include <linux/thermal.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 MODULE_AUTHOR("Thomas Sujith");
 MODULE_AUTHOR("Zhang Rui");
index 6b18aba82cfae450bde3cad8fd2b2d01f20b3d03..8d6775266d66263bac3bdd45d7a5f580e598731e 100644 (file)
@@ -66,10 +66,8 @@ static int mfld_pb_probe(struct platform_device *pdev)
                return -EINVAL;
 
        input = input_allocate_device();
-       if (!input) {
-               dev_err(&pdev->dev, "Input device allocation error\n");
+       if (!input)
                return -ENOMEM;
-       }
 
        input->name = pdev->name;
        input->phys = "power-button/input0";
index f6f18cde0f11c70f035e88c1da80f96506e0b3ab..4bc96041678573ec89eed8cf8c0e185f7e53d864 100644 (file)
@@ -50,9 +50,6 @@
 #include <linux/platform_device.h>
 #include <linux/dmi.h>
 #include <linux/rfkill.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-
 
 #define DRIVER_NAME    "intel_oaktrail"
 #define DRIVER_VERSION "0.4ac1"
index d654f831410de9621df488aadbca2d6c6d174721..60ea476a91305c8f357f1950064cee54e92f0f29 100644 (file)
  *    message handler is called within firmware.
  */
 
-#define IPC_BASE_ADDR     0xFF11C000   /* IPC1 base register address */
-#define IPC_MAX_ADDR      0x100                /* Maximum IPC regisers */
 #define IPC_WWBUF_SIZE    20           /* IPC Write buffer Size */
 #define IPC_RWBUF_SIZE    20           /* IPC Read buffer Size */
-#define IPC_I2C_BASE      0xFF12B000   /* I2C control register base address */
-#define IPC_I2C_MAX_ADDR  0x10         /* Maximum I2C regisers */
+#define IPC_IOC                  0x100         /* IPC command register IOC bit */
+
+enum {
+       SCU_IPC_LINCROFT,
+       SCU_IPC_PENWELL,
+       SCU_IPC_CLOVERVIEW,
+       SCU_IPC_TANGIER,
+};
+
+/* intel scu ipc driver data*/
+struct intel_scu_ipc_pdata_t {
+       u32 ipc_base;
+       u32 i2c_base;
+       u32 ipc_len;
+       u32 i2c_len;
+       u8 irq_mode;
+};
+
+static struct intel_scu_ipc_pdata_t intel_scu_ipc_pdata[] = {
+       [SCU_IPC_LINCROFT] = {
+               .ipc_base = 0xff11c000,
+               .i2c_base = 0xff12b000,
+               .ipc_len = 0x100,
+               .i2c_len = 0x10,
+               .irq_mode = 0,
+       },
+       [SCU_IPC_PENWELL] = {
+               .ipc_base = 0xff11c000,
+               .i2c_base = 0xff12b000,
+               .ipc_len = 0x100,
+               .i2c_len = 0x10,
+               .irq_mode = 1,
+       },
+       [SCU_IPC_CLOVERVIEW] = {
+               .ipc_base = 0xff11c000,
+               .i2c_base = 0xff12b000,
+               .ipc_len = 0x100,
+               .i2c_len = 0x10,
+               .irq_mode = 1,
+       },
+       [SCU_IPC_TANGIER] = {
+               .ipc_base = 0xff009000,
+               .i2c_base  = 0xff00d000,
+               .ipc_len  = 0x100,
+               .i2c_len = 0x10,
+               .irq_mode = 0,
+       },
+};
 
 static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id);
 static void ipc_remove(struct pci_dev *pdev);
@@ -72,6 +116,8 @@ struct intel_scu_ipc_dev {
        struct pci_dev *pdev;
        void __iomem *ipc_base;
        void __iomem *i2c_base;
+       struct completion cmd_complete;
+       u8 irq_mode;
 };
 
 static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
@@ -98,6 +144,10 @@ static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
  */
 static inline void ipc_command(u32 cmd) /* Send ipc command */
 {
+       if (ipcdev.irq_mode) {
+               reinit_completion(&ipcdev.cmd_complete);
+               writel(cmd | IPC_IOC, ipcdev.ipc_base);
+       }
        writel(cmd, ipcdev.ipc_base);
 }
 
@@ -156,6 +206,30 @@ static inline int busy_loop(void) /* Wait till scu status is busy */
        return 0;
 }
 
+/* Wait till ipc ioc interrupt is received or timeout in 3 HZ */
+static inline int ipc_wait_for_interrupt(void)
+{
+       int status;
+
+       if (!wait_for_completion_timeout(&ipcdev.cmd_complete, 3 * HZ)) {
+               struct device *dev = &ipcdev.pdev->dev;
+               dev_err(dev, "IPC timed out\n");
+               return -ETIMEDOUT;
+       }
+
+       status = ipc_read_status();
+
+       if ((status >> 1) & 1)
+               return -EIO;
+
+       return 0;
+}
+
+int intel_scu_ipc_check_status(void)
+{
+       return ipcdev.irq_mode ? ipc_wait_for_interrupt() : busy_loop();
+}
+
 /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
 static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
 {
@@ -196,8 +270,8 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
                ipc_command(4 << 16 |  id << 12 | 0 << 8 | op);
        }
 
-       err = busy_loop();
-       if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
+       err = intel_scu_ipc_check_status();
+       if (!err && id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
                /* Workaround: values are read as 0 without memcpy_fromio */
                memcpy_fromio(cbuf, ipcdev.ipc_base + 0x90, 16);
                for (nc = 0; nc < count; nc++)
@@ -391,7 +465,7 @@ int intel_scu_ipc_simple_command(int cmd, int sub)
                return -ENODEV;
        }
        ipc_command(sub << 12 | cmd);
-       err = busy_loop();
+       err = intel_scu_ipc_check_status();
        mutex_unlock(&ipclock);
        return err;
 }
@@ -425,10 +499,12 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
                ipc_data_writel(*in++, 4 * i);
 
        ipc_command((inlen << 16) | (sub << 12) | cmd);
-       err = busy_loop();
+       err = intel_scu_ipc_check_status();
 
-       for (i = 0; i < outlen; i++)
-               *out++ = ipc_data_readl(4 * i);
+       if (!err) {
+               for (i = 0; i < outlen; i++)
+                       *out++ = ipc_data_readl(4 * i);
+       }
 
        mutex_unlock(&ipclock);
        return err;
@@ -491,6 +567,9 @@ EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
  */
 static irqreturn_t ioc(int irq, void *dev_id)
 {
+       if (ipcdev.irq_mode)
+               complete(&ipcdev.cmd_complete);
+
        return IRQ_HANDLED;
 }
 
@@ -504,13 +583,18 @@ static irqreturn_t ioc(int irq, void *dev_id)
  */
 static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       int err;
+       int err, pid;
+       struct intel_scu_ipc_pdata_t *pdata;
        resource_size_t pci_resource;
 
        if (ipcdev.pdev)                /* We support only one SCU */
                return -EBUSY;
 
+       pid = id->driver_data;
+       pdata = &intel_scu_ipc_pdata[pid];
+
        ipcdev.pdev = pci_dev_get(dev);
+       ipcdev.irq_mode = pdata->irq_mode;
 
        err = pci_enable_device(dev);
        if (err)
@@ -524,14 +608,16 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id)
        if (!pci_resource)
                return -ENOMEM;
 
+       init_completion(&ipcdev.cmd_complete);
+
        if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev))
                return -EBUSY;
 
-       ipcdev.ipc_base = ioremap_nocache(IPC_BASE_ADDR, IPC_MAX_ADDR);
+       ipcdev.ipc_base = ioremap_nocache(pdata->ipc_base, pdata->ipc_len);
        if (!ipcdev.ipc_base)
                return -ENOMEM;
 
-       ipcdev.i2c_base = ioremap_nocache(IPC_I2C_BASE, IPC_I2C_MAX_ADDR);
+       ipcdev.i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len);
        if (!ipcdev.i2c_base) {
                iounmap(ipcdev.ipc_base);
                return -ENOMEM;
@@ -564,7 +650,10 @@ static void ipc_remove(struct pci_dev *pdev)
 }
 
 static DEFINE_PCI_DEVICE_TABLE(pci_ids) = {
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x082a)},
+       {PCI_VDEVICE(INTEL, 0x082a), SCU_IPC_LINCROFT},
+       {PCI_VDEVICE(INTEL, 0x080e), SCU_IPC_PENWELL},
+       {PCI_VDEVICE(INTEL, 0x08ea), SCU_IPC_CLOVERVIEW},
+       {PCI_VDEVICE(INTEL, 0x11a0), SCU_IPC_TANGIER},
        { 0,}
 };
 MODULE_DEVICE_TABLE(pci, pci_ids);
index 0aea63b3729a4481ece3bc5d1c8dfb041fe0f2bc..3c59c0a3ee0f0f2d57a895f853d6915c37d39822 100644 (file)
@@ -20,8 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 MODULE_AUTHOR("Dave Airlie");
 MODULE_DESCRIPTION("MXM WMI Driver");
index 10d12b221601ddae853fe3b0e8554d99d0c5ef06..609d38779b2680175660557b1093fa1026c91aad 100644 (file)
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
 
-
 #ifndef ACPI_HOTKEY_COMPONENT
 #define ACPI_HOTKEY_COMPONENT  0x10000000
 #endif
@@ -490,11 +488,8 @@ static int acpi_pcc_init_input(struct pcc_acpi *pcc)
        int error;
 
        input_dev = input_allocate_device();
-       if (!input_dev) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                 "Couldn't allocate input device for hotkey"));
+       if (!input_dev)
                return -ENOMEM;
-       }
 
        input_dev->name = ACPI_PCC_DRIVER_NAME;
        input_dev->phys = ACPI_PCC_INPUT_PHYS;
index 47ae0c47d4b5ccf67749cc110f86788e7c74753f..c9f6e511daa639f9656f6e96de7603be944e934b 100644 (file)
@@ -24,8 +24,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>");
 MODULE_DESCRIPTION("pvpanic device driver");
index cae7098e9b0d70adf271eb9c31a1e833919a54b1..5413f62d2e6136b62327abdd0d32c8f000b3c531 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/backlight.h>
 #include <linux/dmi.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 #define SAMSUNGQ10_BL_MAX_INTENSITY 7
 
index 47caab0ea7a14faa1051b35eafe1ff8e53703ee0..563e4f595f836c1d1ad966688d61c33e4a8d33d5 100644 (file)
@@ -61,9 +61,6 @@
 #include <linux/workqueue.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
-#include <asm/uaccess.h>
 #include <linux/sonypi.h>
 #include <linux/sony-laptop.h>
 #include <linux/rfkill.h>
@@ -71,6 +68,7 @@
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
 #endif
+#include <asm/uaccess.h>
 
 #define dprintk(fmt, ...)                      \
 do {                                           \
@@ -140,12 +138,12 @@ MODULE_PARM_DESC(kbd_backlight_timeout,
                 "on the model (default: no change from current value)");
 
 #ifdef CONFIG_PM_SLEEP
-static void sony_nc_kbd_backlight_resume(void);
 static void sony_nc_thermal_resume(void);
 #endif
 static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
                unsigned int handle);
-static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd);
+static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd,
+               unsigned int handle);
 
 static int sony_nc_battery_care_setup(struct platform_device *pd,
                unsigned int handle);
@@ -304,8 +302,8 @@ static int sony_laptop_input_keycode_map[] = {
        KEY_FN_F10,     /* 14 SONYPI_EVENT_FNKEY_F10 */
        KEY_FN_F11,     /* 15 SONYPI_EVENT_FNKEY_F11 */
        KEY_FN_F12,     /* 16 SONYPI_EVENT_FNKEY_F12 */
-       KEY_FN_F1,      /* 17 SONYPI_EVENT_FNKEY_1 */
-       KEY_FN_F2,      /* 18 SONYPI_EVENT_FNKEY_2 */
+       KEY_FN_1,       /* 17 SONYPI_EVENT_FNKEY_1 */
+       KEY_FN_2,       /* 18 SONYPI_EVENT_FNKEY_2 */
        KEY_FN_D,       /* 19 SONYPI_EVENT_FNKEY_D */
        KEY_FN_E,       /* 20 SONYPI_EVENT_FNKEY_E */
        KEY_FN_F,       /* 21 SONYPI_EVENT_FNKEY_F */
@@ -1444,7 +1442,7 @@ static void sony_nc_function_cleanup(struct platform_device *pd)
                case 0x014b:
                case 0x014c:
                case 0x0163:
-                       sony_nc_kbd_backlight_cleanup(pd);
+                       sony_nc_kbd_backlight_cleanup(pd, handle);
                        break;
                default:
                        continue;
@@ -1486,13 +1484,6 @@ static void sony_nc_function_resume(void)
                case 0x0135:
                        sony_nc_rfkill_update();
                        break;
-               case 0x0137:
-               case 0x0143:
-               case 0x014b:
-               case 0x014c:
-               case 0x0163:
-                       sony_nc_kbd_backlight_resume();
-                       break;
                default:
                        continue;
                }
@@ -1822,6 +1813,12 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
        int result;
        int ret = 0;
 
+       if (kbdbl_ctl) {
+               pr_warn("handle 0x%.4x: keyboard backlight setup already done for 0x%.4x\n",
+                               handle, kbdbl_ctl->handle);
+               return -EBUSY;
+       }
+
        /* verify the kbd backlight presence, these handles are not used for
         * keyboard backlight only
         */
@@ -1881,9 +1878,10 @@ outkzalloc:
        return ret;
 }
 
-static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
+static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd,
+               unsigned int handle)
 {
-       if (kbdbl_ctl) {
+       if (kbdbl_ctl && handle == kbdbl_ctl->handle) {
                device_remove_file(&pd->dev, &kbdbl_ctl->mode_attr);
                device_remove_file(&pd->dev, &kbdbl_ctl->timeout_attr);
                kfree(kbdbl_ctl);
@@ -1891,25 +1889,6 @@ static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
        }
 }
 
-#ifdef CONFIG_PM_SLEEP
-static void sony_nc_kbd_backlight_resume(void)
-{
-       int ignore = 0;
-
-       if (!kbdbl_ctl)
-               return;
-
-       if (kbdbl_ctl->mode == 0)
-               sony_call_snc_handle(kbdbl_ctl->handle, kbdbl_ctl->base,
-                               &ignore);
-
-       if (kbdbl_ctl->timeout != 0)
-               sony_call_snc_handle(kbdbl_ctl->handle,
-                               (kbdbl_ctl->base + 0x200) |
-                               (kbdbl_ctl->timeout << 0x10), &ignore);
-}
-#endif
-
 struct battery_care_control {
        struct device_attribute attrs[2];
        unsigned int handle;
index 9b93fdb61ed7c03733ead31aaa7f0ef632a6bd00..6a6ea28a7e51df054ff2f514fde39d7d9f10b264 100644 (file)
@@ -32,9 +32,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <linux/platform_device.h>
 
 #define GUID "C364AC71-36DB-495A-8494-B439D472A505"
index 05e046aa5e314be112b0e165f93fd82c6ab16fe5..defb6afc1409cc7fff0863d6829c5c26478b6a4a 100644 (file)
@@ -61,7 +61,6 @@
 #include <linux/freezer.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-
 #include <linux/nvram.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/input.h>
 #include <linux/leds.h>
 #include <linux/rfkill.h>
-#include <asm/uaccess.h>
-
 #include <linux/dmi.h>
 #include <linux/jiffies.h>
 #include <linux/workqueue.h>
-
+#include <linux/acpi.h>
+#include <linux/pci_ids.h>
+#include <linux/thinkpad_acpi.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/initval.h>
-
-#include <acpi/acpi_drivers.h>
-
-#include <linux/pci_ids.h>
-
-#include <linux/thinkpad_acpi.h>
+#include <asm/uaccess.h>
 
 /* ThinkPad CMOS commands */
 #define TP_CMOS_VOLUME_DOWN    0
@@ -6438,7 +6432,12 @@ static struct ibm_struct brightness_driver_data = {
 #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"
 #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME
 
-static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */
+#if SNDRV_CARDS <= 32
+#define DEFAULT_ALSA_IDX               ~((1 << (SNDRV_CARDS - 3)) - 1)
+#else
+#define DEFAULT_ALSA_IDX               ~((1 << (32 - 3)) - 1)
+#endif
+static int alsa_index = DEFAULT_ALSA_IDX; /* last three slots */
 static char *alsa_id = "ThinkPadEC";
 static bool alsa_enable = SNDRV_DEFAULT_ENABLE1;
 
@@ -9163,7 +9162,6 @@ static int __init thinkpad_acpi_module_init(void)
        mutex_init(&tpacpi_inputdev_send_mutex);
        tpacpi_inputdev = input_allocate_device();
        if (!tpacpi_inputdev) {
-               pr_err("unable to allocate input device\n");
                thinkpad_acpi_module_exit();
                return -ENOMEM;
        } else {
index 67897c8740ba58ea3c93cf54b0a2a3e74a1e3a84..e597de05e6c27badfe97ea533ddb2f7a6c41d3b5 100644 (file)
@@ -97,10 +97,8 @@ static int acpi_topstar_init_hkey(struct topstar_hkey *hkey)
        int error;
 
        input = input_allocate_device();
-       if (!input) {
-               pr_err("Unable to allocate input device\n");
+       if (!input)
                return -ENOMEM;
-       }
 
        input->name = "Topstar Laptop extra buttons";
        input->phys = "topstar/input0";
index 0cfadb65f7c639597abce1d1bcb81ba3a04ff1d3..7ad1ed091f9225fc572a1b70fde9ecf622d06ad1 100644 (file)
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/i8042.h>
-
+#include <linux/acpi.h>
 #include <asm/uaccess.h>
 
-#include <acpi/acpi_drivers.h>
-
 MODULE_AUTHOR("John Belmonte");
 MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver");
 MODULE_LICENSE("GPL");
@@ -975,10 +973,8 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
        u32 hci_result;
 
        dev->hotkey_dev = input_allocate_device();
-       if (!dev->hotkey_dev) {
-               pr_info("Unable to register input device\n");
+       if (!dev->hotkey_dev)
                return -ENOMEM;
-       }
 
        dev->hotkey_dev->name = "Toshiba input device";
        dev->hotkey_dev->phys = "toshiba_acpi/input0";
index 74dd01ae343b01f5f5a9827c5ec02f11ceee61b5..2cb1ea62b4a7f9ac7b268adadb251105be279923 100644 (file)
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>");
 MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver");
 MODULE_LICENSE("GPL");
 
-
 static int toshiba_bt_rfkill_add(struct acpi_device *device);
 static int toshiba_bt_rfkill_remove(struct acpi_device *device);
 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event);
index 62e8c221d01ea10a5f105a0a44b2d2d8277d7878..43d13295e63d53a50b62dae995d3a63b7e112a3a 100644 (file)
@@ -37,8 +37,6 @@
 #include <linux/acpi.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 
 ACPI_MODULE_NAME("wmi");
 MODULE_AUTHOR("Carlos Corbacho");
@@ -672,8 +670,10 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
        struct wmi_block *wblock;
 
        wblock = dev_get_drvdata(dev);
-       if (!wblock)
-               return -ENOMEM;
+       if (!wblock) {
+               strcat(buf, "\n");
+               return strlen(buf);
+       }
 
        wmi_gtoa(wblock->gblock.guid, guid_string);
 
index 4b1377bd59446a50405e00414418adf9ac8f8381..49cbccec6e2de1ecffa260348c3582e609ba1507 100644 (file)
@@ -18,8 +18,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/input.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 
 #define MODULE_NAME "xo15-ebook"
 
index 14655a0f0431b35bd9a0988b669c510a162155e3..156d14e2587e1ede2cfb0e6c93266a9d1735be73 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/pnp.h>
 #include <linux/slab.h>
 #include <linux/mod_devicetable.h>
-#include <acpi/acpi_bus.h>
 
 #include "../base.h"
 #include "pnpacpi.h"
@@ -329,20 +328,15 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp)
            && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
 }
 
-static int __init acpi_pnp_find_device(struct device *dev, acpi_handle * handle)
+static struct acpi_device * __init acpi_pnp_find_companion(struct device *dev)
 {
-       struct device *adev;
-       struct acpi_device *acpi;
-
-       adev = bus_find_device(&acpi_bus_type, NULL,
-                              to_pnp_dev(dev), acpi_pnp_match);
-       if (!adev)
-               return -ENODEV;
+       dev = bus_find_device(&acpi_bus_type, NULL, to_pnp_dev(dev),
+                             acpi_pnp_match);
+       if (!dev)
+               return NULL;
 
-       acpi = to_acpi_device(adev);
-       *handle = acpi->handle;
-       put_device(adev);
-       return 0;
+       put_device(dev);
+       return to_acpi_device(dev);
 }
 
 /* complete initialization of a PNPACPI device includes having
@@ -356,7 +350,7 @@ static bool acpi_pnp_bus_match(struct device *dev)
 static struct acpi_bus_type __initdata acpi_pnp_bus = {
        .name        = "PNP",
        .match       = acpi_pnp_bus_match,
-       .find_device = acpi_pnp_find_device,
+       .find_companion = acpi_pnp_find_companion,
 };
 
 int pnpacpi_disabled __initdata;
index 3e60225b0227b2d6ff8f0c2ad863f195256c4b2e..051ef9699777519951c2c87b2e39c6dc5b69d27c 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef ACPI_PNP_H
 #define ACPI_PNP_H
 
-#include <acpi/acpi_bus.h>
 #include <linux/acpi.h>
 #include <linux/pnp.h>
 
index 5e2054afe840e9d6412a28c5250f34d1017aa7b2..85ad58c6da17233a9503650500b69579887c84bb 100644 (file)
@@ -196,6 +196,7 @@ config BATTERY_MAX17040
 config BATTERY_MAX17042
        tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
        depends on I2C
+       select REGMAP_I2C
        help
          MAX17042 is fuel-gauge systems for lithium-ion (Li+) batteries
          in handheld and portable equipment. The MAX17042 is configured
index 00e6672963601754262ced9e842f31c27e07c69e..6aac23cc65663ada046958869dc6d5b8b32e9648 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/notifier.h>
 #include <linux/err.h>
 #include <linux/power_supply.h>
 #include <linux/thermal.h>
@@ -24,6 +25,9 @@
 struct class *power_supply_class;
 EXPORT_SYMBOL_GPL(power_supply_class);
 
+ATOMIC_NOTIFIER_HEAD(power_supply_notifier);
+EXPORT_SYMBOL_GPL(power_supply_notifier);
+
 static struct device_type power_supply_dev_type;
 
 static bool __power_supply_is_supplied_by(struct power_supply *supplier,
@@ -80,6 +84,8 @@ static void power_supply_changed_work(struct work_struct *work)
                class_for_each_device(power_supply_class, NULL, psy,
                                      __power_supply_changed_work);
                power_supply_update_leds(psy);
+               atomic_notifier_call_chain(&power_supply_notifier,
+                               PSY_EVENT_PROP_CHANGED, psy);
                kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE);
                spin_lock_irqsave(&psy->changed_lock, flags);
        }
@@ -347,6 +353,18 @@ static void power_supply_dev_release(struct device *dev)
        kfree(dev);
 }
 
+int power_supply_reg_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_register(&power_supply_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(power_supply_reg_notifier);
+
+void power_supply_unreg_notifier(struct notifier_block *nb)
+{
+       atomic_notifier_chain_unregister(&power_supply_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(power_supply_unreg_notifier);
+
 #ifdef CONFIG_THERMAL
 static int power_supply_read_temp(struct thermal_zone_device *tzd,
                unsigned long *temp)
@@ -511,6 +529,10 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
        dev_set_drvdata(dev, psy);
        psy->dev = dev;
 
+       rc = dev_set_name(dev, "%s", psy->name);
+       if (rc)
+               goto dev_set_name_failed;
+
        INIT_WORK(&psy->changed_work, power_supply_changed_work);
 
        rc = power_supply_check_supplies(psy);
@@ -524,10 +546,6 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
        if (rc)
                goto wakeup_init_failed;
 
-       rc = kobject_set_name(&dev->kobj, "%s", psy->name);
-       if (rc)
-               goto kobject_set_name_failed;
-
        rc = device_add(dev);
        if (rc)
                goto device_add_failed;
@@ -553,11 +571,11 @@ create_triggers_failed:
 register_cooler_failed:
        psy_unregister_thermal(psy);
 register_thermal_failed:
-wakeup_init_failed:
        device_del(dev);
-kobject_set_name_failed:
 device_add_failed:
+wakeup_init_failed:
 check_supplies_failed:
+dev_set_name_failed:
        put_device(dev);
 success:
        return rc;
index 724706a97dc40c5cf7e21d89f7c58bc2385f6226..034ece7070838991a59d45f88f0e0ace95c6abba 100644 (file)
@@ -28,8 +28,6 @@
 #include <linux/mfd/arizona/pdata.h>
 #include <linux/mfd/arizona/registers.h>
 
-#define ARIZONA_MICSUPP_MAX_SELECTOR 0x1f
-
 struct arizona_micsupp {
        struct regulator_dev *regulator;
        struct arizona *arizona;
@@ -40,42 +38,6 @@ struct arizona_micsupp {
        struct work_struct check_cp_work;
 };
 
-static int arizona_micsupp_list_voltage(struct regulator_dev *rdev,
-                                       unsigned int selector)
-{
-       if (selector > ARIZONA_MICSUPP_MAX_SELECTOR)
-               return -EINVAL;
-
-       if (selector == ARIZONA_MICSUPP_MAX_SELECTOR)
-               return 3300000;
-       else
-               return (selector * 50000) + 1700000;
-}
-
-static int arizona_micsupp_map_voltage(struct regulator_dev *rdev,
-                                      int min_uV, int max_uV)
-{
-       unsigned int voltage;
-       int selector;
-
-       if (min_uV < 1700000)
-               min_uV = 1700000;
-
-       if (min_uV > 3200000)
-               selector = ARIZONA_MICSUPP_MAX_SELECTOR;
-       else
-               selector = DIV_ROUND_UP(min_uV - 1700000, 50000);
-
-       if (selector < 0)
-               return -EINVAL;
-
-       voltage = arizona_micsupp_list_voltage(rdev, selector);
-       if (voltage < min_uV || voltage > max_uV)
-               return -EINVAL;
-
-       return selector;
-}
-
 static void arizona_micsupp_check_cp(struct work_struct *work)
 {
        struct arizona_micsupp *micsupp =
@@ -145,8 +107,8 @@ static struct regulator_ops arizona_micsupp_ops = {
        .disable = arizona_micsupp_disable,
        .is_enabled = regulator_is_enabled_regmap,
 
-       .list_voltage = arizona_micsupp_list_voltage,
-       .map_voltage = arizona_micsupp_map_voltage,
+       .list_voltage = regulator_list_voltage_linear_range,
+       .map_voltage = regulator_map_voltage_linear_range,
 
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
@@ -155,11 +117,43 @@ static struct regulator_ops arizona_micsupp_ops = {
        .set_bypass = arizona_micsupp_set_bypass,
 };
 
+static const struct regulator_linear_range arizona_micsupp_ranges[] = {
+       REGULATOR_LINEAR_RANGE(1700000, 0,    0x1e, 50000),
+       REGULATOR_LINEAR_RANGE(3300000, 0x1f, 0x1f, 0),
+};
+
 static const struct regulator_desc arizona_micsupp = {
        .name = "MICVDD",
        .supply_name = "CPVDD",
        .type = REGULATOR_VOLTAGE,
-       .n_voltages = ARIZONA_MICSUPP_MAX_SELECTOR + 1,
+       .n_voltages = 32,
+       .ops = &arizona_micsupp_ops,
+
+       .vsel_reg = ARIZONA_LDO2_CONTROL_1,
+       .vsel_mask = ARIZONA_LDO2_VSEL_MASK,
+       .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1,
+       .enable_mask = ARIZONA_CPMIC_ENA,
+       .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
+       .bypass_mask = ARIZONA_CPMIC_BYPASS,
+
+       .linear_ranges = arizona_micsupp_ranges,
+       .n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ranges),
+
+       .enable_time = 3000,
+
+       .owner = THIS_MODULE,
+};
+
+static const struct regulator_linear_range arizona_micsupp_ext_ranges[] = {
+       REGULATOR_LINEAR_RANGE(900000,  0,    0x14, 25000),
+       REGULATOR_LINEAR_RANGE(1500000, 0x15, 0x27, 100000),
+};
+
+static const struct regulator_desc arizona_micsupp_ext = {
+       .name = "MICVDD",
+       .supply_name = "CPVDD",
+       .type = REGULATOR_VOLTAGE,
+       .n_voltages = 40,
        .ops = &arizona_micsupp_ops,
 
        .vsel_reg = ARIZONA_LDO2_CONTROL_1,
@@ -169,6 +163,9 @@ static const struct regulator_desc arizona_micsupp = {
        .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
        .bypass_mask = ARIZONA_CPMIC_BYPASS,
 
+       .linear_ranges = arizona_micsupp_ext_ranges,
+       .n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ext_ranges),
+
        .enable_time = 3000,
 
        .owner = THIS_MODULE,
@@ -186,9 +183,22 @@ static const struct regulator_init_data arizona_micsupp_default = {
        .num_consumer_supplies = 1,
 };
 
+static const struct regulator_init_data arizona_micsupp_ext_default = {
+       .constraints = {
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+                               REGULATOR_CHANGE_VOLTAGE |
+                               REGULATOR_CHANGE_BYPASS,
+               .min_uV = 900000,
+               .max_uV = 3300000,
+       },
+
+       .num_consumer_supplies = 1,
+};
+
 static int arizona_micsupp_probe(struct platform_device *pdev)
 {
        struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
+       const struct regulator_desc *desc;
        struct regulator_config config = { };
        struct arizona_micsupp *micsupp;
        int ret;
@@ -207,7 +217,17 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
         * default init_data for it.  This will be overridden with
         * platform data if provided.
         */
-       micsupp->init_data = arizona_micsupp_default;
+       switch (arizona->type) {
+       case WM5110:
+               desc = &arizona_micsupp_ext;
+               micsupp->init_data = arizona_micsupp_ext_default;
+               break;
+       default:
+               desc = &arizona_micsupp;
+               micsupp->init_data = arizona_micsupp_default;
+               break;
+       }
+
        micsupp->init_data.consumer_supplies = &micsupp->supply;
        micsupp->supply.supply = "MICVDD";
        micsupp->supply.dev_name = dev_name(arizona->dev);
@@ -226,7 +246,7 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
                           ARIZONA_CPMIC_BYPASS, 0);
 
        micsupp->regulator = devm_regulator_register(&pdev->dev,
-                                                    &arizona_micsupp,
+                                                    desc,
                                                     &config);
        if (IS_ERR(micsupp->regulator)) {
                ret = PTR_ERR(micsupp->regulator);
index 5917fe3dc983dc5335d62e393fe079459817d439..b9f1d24c6812eb91d0cf55031c617888b914c560 100644 (file)
@@ -590,8 +590,8 @@ static int as3722_sd016_set_current_limit(struct regulator_dev *rdev,
        default:
                return -EINVAL;
        }
+       ret <<= ffs(mask) - 1;
        val = ret & mask;
-       val <<= ffs(mask) - 1;
        return as3722_update_bits(as3722, reg, mask, val);
 }
 
index 6382f0af353bc257e3ee6c3b545f75c0c1f2904e..d85f31385b24fe9b68ae45dfe0ece4be0ecc2ceb 100644 (file)
@@ -119,6 +119,11 @@ static const char *rdev_get_name(struct regulator_dev *rdev)
                return "";
 }
 
+static bool have_full_constraints(void)
+{
+       return has_full_constraints || of_have_populated_dt();
+}
+
 /**
  * of_get_regulator - get a regulator device node based on supply name
  * @dev: Device pointer for the consumer (of regulator) device
@@ -1340,7 +1345,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
         * Assume that a regulator is physically present and enabled
         * even if it isn't hooked up and just provide a dummy.
         */
-       if (has_full_constraints && allow_dummy) {
+       if (have_full_constraints() && allow_dummy) {
                pr_warn("%s supply %s not found, using dummy regulator\n",
                        devname, id);
 
@@ -2184,6 +2189,9 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
        struct regulator_ops    *ops = rdev->desc->ops;
        int                     ret;
 
+       if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector)
+               return rdev->desc->fixed_uV;
+
        if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
                return -EINVAL;
 
@@ -3624,7 +3632,7 @@ int regulator_suspend_finish(void)
                        if (error)
                                ret = error;
                } else {
-                       if (!has_full_constraints)
+                       if (!have_full_constraints())
                                goto unlock;
                        if (!ops->disable)
                                goto unlock;
@@ -3822,7 +3830,7 @@ static int __init regulator_init_complete(void)
                if (!enabled)
                        goto unlock;
 
-               if (has_full_constraints) {
+               if (have_full_constraints()) {
                        /* We log since this may kill the system if it
                         * goes wrong. */
                        rdev_info(rdev, "disabling\n");
index 04406a918c041b5773adcf9adf331eadf289caf4..234960dc96077389460632cdc832f0c6ea5e69e1 100644 (file)
@@ -139,6 +139,7 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
        struct property *prop;
        const char *regtype;
        int proplen, gpio, i;
+       int ret;
 
        config = devm_kzalloc(dev,
                        sizeof(struct gpio_regulator_config),
@@ -202,7 +203,11 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
        }
        config->nr_states = i;
 
-       of_property_read_string(np, "regulator-type", &regtype);
+       ret = of_property_read_string(np, "regulator-type", &regtype);
+       if (ret < 0) {
+               dev_err(dev, "Missing 'regulator-type' property\n");
+               return ERR_PTR(-EINVAL);
+       }
 
        if (!strncmp("voltage", regtype, 7))
                config->type = REGULATOR_VOLTAGE;
index 947c05ffe0ab9887899a871a1576936b01b8ba3a..3b1102b75071f9d9f73fa0b34db63e43f9784614 100644 (file)
@@ -25,8 +25,6 @@ struct lp3971 {
        struct device *dev;
        struct mutex io_lock;
        struct i2c_client *i2c;
-       int num_regulators;
-       struct regulator_dev **rdev;
 };
 
 static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg);
@@ -383,42 +381,27 @@ static int setup_regulators(struct lp3971 *lp3971,
 {
        int i, err;
 
-       lp3971->num_regulators = pdata->num_regulators;
-       lp3971->rdev = kcalloc(pdata->num_regulators,
-                               sizeof(struct regulator_dev *), GFP_KERNEL);
-       if (!lp3971->rdev) {
-               err = -ENOMEM;
-               goto err_nomem;
-       }
-
        /* Instantiate the regulators */
        for (i = 0; i < pdata->num_regulators; i++) {
                struct regulator_config config = { };
                struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
+               struct regulator_dev *rdev;
 
                config.dev = lp3971->dev;
                config.init_data = reg->initdata;
                config.driver_data = lp3971;
 
-               lp3971->rdev[i] = regulator_register(&regulators[reg->id],
-                                                    &config);
-               if (IS_ERR(lp3971->rdev[i])) {
-                       err = PTR_ERR(lp3971->rdev[i]);
+               rdev = devm_regulator_register(lp3971->dev,
+                                              &regulators[reg->id], &config);
+               if (IS_ERR(rdev)) {
+                       err = PTR_ERR(rdev);
                        dev_err(lp3971->dev, "regulator init failed: %d\n",
                                err);
-                       goto error;
+                       return err;
                }
        }
 
        return 0;
-
-error:
-       while (--i >= 0)
-               regulator_unregister(lp3971->rdev[i]);
-       kfree(lp3971->rdev);
-       lp3971->rdev = NULL;
-err_nomem:
-       return err;
 }
 
 static int lp3971_i2c_probe(struct i2c_client *i2c,
@@ -460,19 +443,6 @@ static int lp3971_i2c_probe(struct i2c_client *i2c,
        return 0;
 }
 
-static int lp3971_i2c_remove(struct i2c_client *i2c)
-{
-       struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
-       int i;
-
-       for (i = 0; i < lp3971->num_regulators; i++)
-               regulator_unregister(lp3971->rdev[i]);
-
-       kfree(lp3971->rdev);
-
-       return 0;
-}
-
 static const struct i2c_device_id lp3971_i2c_id[] = {
        { "lp3971", 0 },
        { }
@@ -485,7 +455,6 @@ static struct i2c_driver lp3971_i2c_driver = {
                .owner = THIS_MODULE,
        },
        .probe    = lp3971_i2c_probe,
-       .remove   = lp3971_i2c_remove,
        .id_table = lp3971_i2c_id,
 };
 
index 093e6f44ff8a3e0d9f17eb6cd0001c36d5911b37..aea485afcc1a8a9983781320182ed9078ff9517c 100644 (file)
@@ -22,8 +22,6 @@ struct lp3972 {
        struct device *dev;
        struct mutex io_lock;
        struct i2c_client *i2c;
-       int num_regulators;
-       struct regulator_dev **rdev;
 };
 
 /* LP3972 Control Registers */
@@ -478,41 +476,27 @@ static int setup_regulators(struct lp3972 *lp3972,
 {
        int i, err;
 
-       lp3972->num_regulators = pdata->num_regulators;
-       lp3972->rdev = kcalloc(pdata->num_regulators,
-                               sizeof(struct regulator_dev *), GFP_KERNEL);
-       if (!lp3972->rdev) {
-               err = -ENOMEM;
-               goto err_nomem;
-       }
-
        /* Instantiate the regulators */
        for (i = 0; i < pdata->num_regulators; i++) {
                struct lp3972_regulator_subdev *reg = &pdata->regulators[i];
                struct regulator_config config = { };
+               struct regulator_dev *rdev;
 
                config.dev = lp3972->dev;
                config.init_data = reg->initdata;
                config.driver_data = lp3972;
 
-               lp3972->rdev[i] = regulator_register(&regulators[reg->id],
-                                                    &config);
-               if (IS_ERR(lp3972->rdev[i])) {
-                       err = PTR_ERR(lp3972->rdev[i]);
+               rdev = devm_regulator_register(lp3972->dev,
+                                              &regulators[reg->id], &config);
+               if (IS_ERR(rdev)) {
+                       err = PTR_ERR(rdev);
                        dev_err(lp3972->dev, "regulator init failed: %d\n",
                                err);
-                       goto error;
+                       return err;
                }
        }
 
        return 0;
-error:
-       while (--i >= 0)
-               regulator_unregister(lp3972->rdev[i]);
-       kfree(lp3972->rdev);
-       lp3972->rdev = NULL;
-err_nomem:
-       return err;
 }
 
 static int lp3972_i2c_probe(struct i2c_client *i2c,
@@ -557,18 +541,6 @@ static int lp3972_i2c_probe(struct i2c_client *i2c,
        return 0;
 }
 
-static int lp3972_i2c_remove(struct i2c_client *i2c)
-{
-       struct lp3972 *lp3972 = i2c_get_clientdata(i2c);
-       int i;
-
-       for (i = 0; i < lp3972->num_regulators; i++)
-               regulator_unregister(lp3972->rdev[i]);
-       kfree(lp3972->rdev);
-
-       return 0;
-}
-
 static const struct i2c_device_id lp3972_i2c_id[] = {
        { "lp3972", 0 },
        { }
@@ -581,7 +553,6 @@ static struct i2c_driver lp3972_i2c_driver = {
                .owner = THIS_MODULE,
        },
        .probe    = lp3972_i2c_probe,
-       .remove   = lp3972_i2c_remove,
        .id_table = lp3972_i2c_id,
 };
 
index ba67b2c4e2e7fe4da91fdd6afd269ab1233a284e..032df3799efb7a144f6c1eef5cd0a3dfe17b6e50 100644 (file)
@@ -308,9 +308,15 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
        if (ret)
                return ret;
 
-       if (value & 0x0f) {
-               dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
-               return -ENODEV;
+       switch (value & 0x0f) {
+               /* Freescale misprogrammed 1-3% of parts prior to week 8 of 2013 as ID=8 */
+               case 0x8:
+                       dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8");
+               case 0x0:
+                       break;
+               default:
+                       dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
+                       return -ENODEV;
        }
 
        ret = regmap_read(pfuze_chip->regmap, PFUZE100_REVID, &value);
index b0a3f0917a27ea841f3fffefdda7b67b163e8168..3486be935bec367b3721476218028aec364b46f8 100644 (file)
@@ -305,7 +305,7 @@ static int tps51632_probe(struct i2c_client *client,
        }
 
        tps->dev = &client->dev;
-       tps->desc.name = id->name;
+       tps->desc.name = client->name;
        tps->desc.id = 0;
        tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY;
        tps->desc.min_uV = TPS51632_MIN_VOLATGE;
index 92bd22ce676012697be18504d96741b4a3910466..9cbc567698cefd0d3933f7c77198d4ccf34ceeeb 100644 (file)
@@ -504,7 +504,7 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev,
        struct dasd_diag_req *dreq;
        struct dasd_diag_bio *dbio;
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *dst;
        unsigned int count, datasize;
        sector_t recid, first_rec, last_rec;
@@ -525,10 +525,10 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev,
        /* Check struct bio and count the number of blocks for the request. */
        count = 0;
        rq_for_each_segment(bv, req, iter) {
-               if (bv->bv_len & (blksize - 1))
+               if (bv.bv_len & (blksize - 1))
                        /* Fba can only do full blocks. */
                        return ERR_PTR(-EINVAL);
-               count += bv->bv_len >> (block->s2b_shift + 9);
+               count += bv.bv_len >> (block->s2b_shift + 9);
        }
        /* Paranoia. */
        if (count != last_rec - first_rec + 1)
@@ -545,8 +545,8 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev,
        dbio = dreq->bio;
        recid = first_rec;
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv->bv_page) + bv->bv_offset;
-               for (off = 0; off < bv->bv_len; off += blksize) {
+               dst = page_address(bv.bv_page) + bv.bv_offset;
+               for (off = 0; off < bv.bv_len; off += blksize) {
                        memset(dbio, 0, sizeof (struct dasd_diag_bio));
                        dbio->type = rw_cmd;
                        dbio->block_number = recid + 1;
index cee7e2708a1fe35359eb81cc458d939e50ad1906..2e8e0755070b609b13e9e49f5db5f17ac232ef69 100644 (file)
@@ -2551,7 +2551,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
        struct dasd_ccw_req *cqr;
        struct ccw1 *ccw;
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *dst;
        unsigned int off;
        int count, cidaw, cplength, datasize;
@@ -2573,13 +2573,13 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
        count = 0;
        cidaw = 0;
        rq_for_each_segment(bv, req, iter) {
-               if (bv->bv_len & (blksize - 1))
+               if (bv.bv_len & (blksize - 1))
                        /* Eckd can only do full blocks. */
                        return ERR_PTR(-EINVAL);
-               count += bv->bv_len >> (block->s2b_shift + 9);
+               count += bv.bv_len >> (block->s2b_shift + 9);
 #if defined(CONFIG_64BIT)
-               if (idal_is_needed (page_address(bv->bv_page), bv->bv_len))
-                       cidaw += bv->bv_len >> (block->s2b_shift + 9);
+               if (idal_is_needed (page_address(bv.bv_page), bv.bv_len))
+                       cidaw += bv.bv_len >> (block->s2b_shift + 9);
 #endif
        }
        /* Paranoia. */
@@ -2650,16 +2650,16 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
                              last_rec - recid + 1, cmd, basedev, blksize);
        }
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv->bv_page) + bv->bv_offset;
+               dst = page_address(bv.bv_page) + bv.bv_offset;
                if (dasd_page_cache) {
                        char *copy = kmem_cache_alloc(dasd_page_cache,
                                                      GFP_DMA | __GFP_NOWARN);
                        if (copy && rq_data_dir(req) == WRITE)
-                               memcpy(copy + bv->bv_offset, dst, bv->bv_len);
+                               memcpy(copy + bv.bv_offset, dst, bv.bv_len);
                        if (copy)
-                               dst = copy + bv->bv_offset;
+                               dst = copy + bv.bv_offset;
                }
-               for (off = 0; off < bv->bv_len; off += blksize) {
+               for (off = 0; off < bv.bv_len; off += blksize) {
                        sector_t trkid = recid;
                        unsigned int recoffs = sector_div(trkid, blk_per_trk);
                        rcmd = cmd;
@@ -2735,7 +2735,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
        struct dasd_ccw_req *cqr;
        struct ccw1 *ccw;
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *dst, *idaw_dst;
        unsigned int cidaw, cplength, datasize;
        unsigned int tlf;
@@ -2813,8 +2813,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
        idaw_dst = NULL;
        idaw_len = 0;
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv->bv_page) + bv->bv_offset;
-               seg_len = bv->bv_len;
+               dst = page_address(bv.bv_page) + bv.bv_offset;
+               seg_len = bv.bv_len;
                while (seg_len) {
                        if (new_track) {
                                trkid = recid;
@@ -3039,7 +3039,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
 {
        struct dasd_ccw_req *cqr;
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *dst;
        unsigned int trkcount, ctidaw;
        unsigned char cmd;
@@ -3125,8 +3125,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                new_track = 1;
                recid = first_rec;
                rq_for_each_segment(bv, req, iter) {
-                       dst = page_address(bv->bv_page) + bv->bv_offset;
-                       seg_len = bv->bv_len;
+                       dst = page_address(bv.bv_page) + bv.bv_offset;
+                       seg_len = bv.bv_len;
                        while (seg_len) {
                                if (new_track) {
                                        trkid = recid;
@@ -3158,9 +3158,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                }
        } else {
                rq_for_each_segment(bv, req, iter) {
-                       dst = page_address(bv->bv_page) + bv->bv_offset;
+                       dst = page_address(bv.bv_page) + bv.bv_offset;
                        last_tidaw = itcw_add_tidaw(itcw, 0x00,
-                                                   dst, bv->bv_len);
+                                                   dst, bv.bv_len);
                        if (IS_ERR(last_tidaw)) {
                                ret = -EINVAL;
                                goto out_error;
@@ -3224,6 +3224,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
 
        fcx_multitrack = private->features.feature[40] & 0x20;
        data_size = blk_rq_bytes(req);
+       if (data_size % blksize)
+               return ERR_PTR(-EINVAL);
        /* tpm write request add CBC data on each track boundary */
        if (rq_data_dir(req) == WRITE)
                data_size += (last_trk - first_trk) * 4;
@@ -3276,7 +3278,7 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
        struct dasd_ccw_req *cqr;
        struct ccw1 *ccw;
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *dst;
        unsigned char cmd;
        unsigned int trkcount;
@@ -3376,8 +3378,8 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
                        idaws = idal_create_words(idaws, rawpadpage, PAGE_SIZE);
        }
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv->bv_page) + bv->bv_offset;
-               seg_len = bv->bv_len;
+               dst = page_address(bv.bv_page) + bv.bv_offset;
+               seg_len = bv.bv_len;
                if (cmd == DASD_ECKD_CCW_READ_TRACK)
                        memset(dst, 0, seg_len);
                if (!len_to_track_end) {
@@ -3422,7 +3424,7 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
        struct dasd_eckd_private *private;
        struct ccw1 *ccw;
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *dst, *cda;
        unsigned int blksize, blk_per_trk, off;
        sector_t recid;
@@ -3440,8 +3442,8 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
        if (private->uses_cdl == 0 || recid > 2*blk_per_trk)
                ccw++;
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv->bv_page) + bv->bv_offset;
-               for (off = 0; off < bv->bv_len; off += blksize) {
+               dst = page_address(bv.bv_page) + bv.bv_offset;
+               for (off = 0; off < bv.bv_len; off += blksize) {
                        /* Skip locate record. */
                        if (private->uses_cdl && recid <= 2*blk_per_trk)
                                ccw++;
@@ -3452,7 +3454,7 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
                                        cda = (char *)((addr_t) ccw->cda);
                                if (dst != cda) {
                                        if (rq_data_dir(req) == READ)
-                                               memcpy(dst, cda, bv->bv_len);
+                                               memcpy(dst, cda, bv.bv_len);
                                        kmem_cache_free(dasd_page_cache,
                                            (void *)((addr_t)cda & PAGE_MASK));
                                }
index 9cbc8c32ba595739cdff63da752a8f080b51e0de..2c8e68bf9a1cd658be919151387fe3ae24bffad3 100644 (file)
@@ -260,7 +260,7 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
        struct dasd_ccw_req *cqr;
        struct ccw1 *ccw;
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *dst;
        int count, cidaw, cplength, datasize;
        sector_t recid, first_rec, last_rec;
@@ -283,13 +283,13 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
        count = 0;
        cidaw = 0;
        rq_for_each_segment(bv, req, iter) {
-               if (bv->bv_len & (blksize - 1))
+               if (bv.bv_len & (blksize - 1))
                        /* Fba can only do full blocks. */
                        return ERR_PTR(-EINVAL);
-               count += bv->bv_len >> (block->s2b_shift + 9);
+               count += bv.bv_len >> (block->s2b_shift + 9);
 #if defined(CONFIG_64BIT)
-               if (idal_is_needed (page_address(bv->bv_page), bv->bv_len))
-                       cidaw += bv->bv_len / blksize;
+               if (idal_is_needed (page_address(bv.bv_page), bv.bv_len))
+                       cidaw += bv.bv_len / blksize;
 #endif
        }
        /* Paranoia. */
@@ -326,16 +326,16 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
        }
        recid = first_rec;
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv->bv_page) + bv->bv_offset;
+               dst = page_address(bv.bv_page) + bv.bv_offset;
                if (dasd_page_cache) {
                        char *copy = kmem_cache_alloc(dasd_page_cache,
                                                      GFP_DMA | __GFP_NOWARN);
                        if (copy && rq_data_dir(req) == WRITE)
-                               memcpy(copy + bv->bv_offset, dst, bv->bv_len);
+                               memcpy(copy + bv.bv_offset, dst, bv.bv_len);
                        if (copy)
-                               dst = copy + bv->bv_offset;
+                               dst = copy + bv.bv_offset;
                }
-               for (off = 0; off < bv->bv_len; off += blksize) {
+               for (off = 0; off < bv.bv_len; off += blksize) {
                        /* Locate record for stupid devices. */
                        if (private->rdc_data.mode.bits.data_chain == 0) {
                                ccw[-1].flags |= CCW_FLAG_CC;
@@ -384,7 +384,7 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req)
        struct dasd_fba_private *private;
        struct ccw1 *ccw;
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        char *dst, *cda;
        unsigned int blksize, off;
        int status;
@@ -399,8 +399,8 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req)
        if (private->rdc_data.mode.bits.data_chain != 0)
                ccw++;
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv->bv_page) + bv->bv_offset;
-               for (off = 0; off < bv->bv_len; off += blksize) {
+               dst = page_address(bv.bv_page) + bv.bv_offset;
+               for (off = 0; off < bv.bv_len; off += blksize) {
                        /* Skip locate record. */
                        if (private->rdc_data.mode.bits.data_chain == 0)
                                ccw++;
@@ -411,7 +411,7 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req)
                                        cda = (char *)((addr_t) ccw->cda);
                                if (dst != cda) {
                                        if (rq_data_dir(req) == READ)
-                                               memcpy(dst, cda, bv->bv_len);
+                                               memcpy(dst, cda, bv.bv_len);
                                        kmem_cache_free(dasd_page_cache,
                                            (void *)((addr_t)cda & PAGE_MASK));
                                }
index 6eca019bcf30a50edfab1a80daf1b351d2320474..ebf41e228e55836e6ec764b105c357e1856c9d1b 100644 (file)
@@ -808,18 +808,19 @@ static void
 dcssblk_make_request(struct request_queue *q, struct bio *bio)
 {
        struct dcssblk_dev_info *dev_info;
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
        unsigned long index;
        unsigned long page_addr;
        unsigned long source_addr;
        unsigned long bytes_done;
-       int i;
 
        bytes_done = 0;
        dev_info = bio->bi_bdev->bd_disk->private_data;
        if (dev_info == NULL)
                goto fail;
-       if ((bio->bi_sector & 7) != 0 || (bio->bi_size & 4095) != 0)
+       if ((bio->bi_iter.bi_sector & 7) != 0 ||
+           (bio->bi_iter.bi_size & 4095) != 0)
                /* Request is not page-aligned. */
                goto fail;
        if (bio_end_sector(bio) > get_capacity(bio->bi_bdev->bd_disk)) {
@@ -842,22 +843,22 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
                }
        }
 
-       index = (bio->bi_sector >> 3);
-       bio_for_each_segment(bvec, bio, i) {
+       index = (bio->bi_iter.bi_sector >> 3);
+       bio_for_each_segment(bvec, bio, iter) {
                page_addr = (unsigned long)
-                       page_address(bvec->bv_page) + bvec->bv_offset;
+                       page_address(bvec.bv_page) + bvec.bv_offset;
                source_addr = dev_info->start + (index<<12) + bytes_done;
-               if (unlikely((page_addr & 4095) != 0) || (bvec->bv_len & 4095) != 0)
+               if (unlikely((page_addr & 4095) != 0) || (bvec.bv_len & 4095) != 0)
                        // More paranoia.
                        goto fail;
                if (bio_data_dir(bio) == READ) {
                        memcpy((void*)page_addr, (void*)source_addr,
-                               bvec->bv_len);
+                               bvec.bv_len);
                } else {
                        memcpy((void*)source_addr, (void*)page_addr,
-                               bvec->bv_len);
+                               bvec.bv_len);
                }
-               bytes_done += bvec->bv_len;
+               bytes_done += bvec.bv_len;
        }
        bio_endio(bio, 0);
        return;
index d0ab5019d885cea6113f677a4f58990fa4a3ca55..76bed1743db1c7ef23576282b13d9ef8f551aed8 100644 (file)
@@ -130,7 +130,7 @@ static void scm_request_prepare(struct scm_request *scmrq)
        struct aidaw *aidaw = scmrq->aidaw;
        struct msb *msb = &scmrq->aob->msb[0];
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
 
        msb->bs = MSB_BS_4K;
        scmrq->aob->request.msb_count = 1;
@@ -142,9 +142,9 @@ static void scm_request_prepare(struct scm_request *scmrq)
        msb->data_addr = (u64) aidaw;
 
        rq_for_each_segment(bv, scmrq->request, iter) {
-               WARN_ON(bv->bv_offset);
-               msb->blk_count += bv->bv_len >> 12;
-               aidaw->data_addr = (u64) page_address(bv->bv_page);
+               WARN_ON(bv.bv_offset);
+               msb->blk_count += bv.bv_len >> 12;
+               aidaw->data_addr = (u64) page_address(bv.bv_page);
                aidaw++;
        }
 }
index 27f930cd657fcdd3a223412cb68c393ebd565556..9aae909d47a53c88d6345101db2f344b8bc1f7a9 100644 (file)
@@ -122,7 +122,7 @@ static void scm_prepare_cluster_request(struct scm_request *scmrq)
        struct aidaw *aidaw = scmrq->aidaw;
        struct msb *msb = &scmrq->aob->msb[0];
        struct req_iterator iter;
-       struct bio_vec *bv;
+       struct bio_vec bv;
        int i = 0;
        u64 addr;
 
@@ -163,7 +163,7 @@ static void scm_prepare_cluster_request(struct scm_request *scmrq)
                        i++;
                }
                rq_for_each_segment(bv, req, iter) {
-                       aidaw->data_addr = (u64) page_address(bv->bv_page);
+                       aidaw->data_addr = (u64) page_address(bv.bv_page);
                        aidaw++;
                        i++;
                }
index 464dd29d06c07dcbeb1e6ee96a439dbb037a25a9..3e530f9da8c48a42a2c11b1e4c58b04b284d161c 100644 (file)
@@ -184,25 +184,26 @@ static unsigned long xpram_highest_page_index(void)
 static void xpram_make_request(struct request_queue *q, struct bio *bio)
 {
        xpram_device_t *xdev = bio->bi_bdev->bd_disk->private_data;
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
        unsigned int index;
        unsigned long page_addr;
        unsigned long bytes;
-       int i;
 
-       if ((bio->bi_sector & 7) != 0 || (bio->bi_size & 4095) != 0)
+       if ((bio->bi_iter.bi_sector & 7) != 0 ||
+           (bio->bi_iter.bi_size & 4095) != 0)
                /* Request is not page-aligned. */
                goto fail;
-       if ((bio->bi_size >> 12) > xdev->size)
+       if ((bio->bi_iter.bi_size >> 12) > xdev->size)
                /* Request size is no page-aligned. */
                goto fail;
-       if ((bio->bi_sector >> 3) > 0xffffffffU - xdev->offset)
+       if ((bio->bi_iter.bi_sector >> 3) > 0xffffffffU - xdev->offset)
                goto fail;
-       index = (bio->bi_sector >> 3) + xdev->offset;
-       bio_for_each_segment(bvec, bio, i) {
+       index = (bio->bi_iter.bi_sector >> 3) + xdev->offset;
+       bio_for_each_segment(bvec, bio, iter) {
                page_addr = (unsigned long)
-                       kmap(bvec->bv_page) + bvec->bv_offset;
-               bytes = bvec->bv_len;
+                       kmap(bvec.bv_page) + bvec.bv_offset;
+               bytes = bvec.bv_len;
                if ((page_addr & 4095) != 0 || (bytes & 4095) != 0)
                        /* More paranoia. */
                        goto fail;
index a9fe3de2dec17fcce1717d99389468dfc46f4f98..b3f791b2c1f8994de2287052275fc8853b3b946a 100644 (file)
@@ -260,16 +260,16 @@ static int blacklist_parse_proc_parameters(char *buf)
 
        parm = strsep(&buf, " ");
 
-       if (strcmp("free", parm) == 0)
+       if (strcmp("free", parm) == 0) {
                rc = blacklist_parse_parameters(buf, free, 0);
-       else if (strcmp("add", parm) == 0)
+               css_schedule_eval_all_unreg(0);
+       } else if (strcmp("add", parm) == 0)
                rc = blacklist_parse_parameters(buf, add, 0);
        else if (strcmp("purge", parm) == 0)
                return ccw_purge_blacklisted();
        else
                return -EINVAL;
 
-       css_schedule_reprobe();
 
        return rc;
 }
index 13299f902676e647d43dce13d95f864c81300f53..eee70cb8730bf381fe4da4373a7fc65b98361fba 100644 (file)
@@ -237,26 +237,6 @@ void chsc_chp_offline(struct chp_id chpid)
        for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link);
 }
 
-static int s390_process_res_acc_new_sch(struct subchannel_id schid, void *data)
-{
-       struct schib schib;
-       /*
-        * We don't know the device yet, but since a path
-        * may be available now to the device we'll have
-        * to do recognition again.
-        * Since we don't have any idea about which chpid
-        * that beast may be on we'll have to do a stsch
-        * on all devices, grr...
-        */
-       if (stsch_err(schid, &schib))
-               /* We're through */
-               return -ENXIO;
-
-       /* Put it on the slow path. */
-       css_schedule_eval(schid);
-       return 0;
-}
-
 static int __s390_process_res_acc(struct subchannel *sch, void *data)
 {
        spin_lock_irq(sch->lock);
@@ -287,8 +267,8 @@ static void s390_process_res_acc(struct chp_link *link)
         * The more information we have (info), the less scanning
         * will we have to do.
         */
-       for_each_subchannel_staged(__s390_process_res_acc,
-                                  s390_process_res_acc_new_sch, link);
+       for_each_subchannel_staged(__s390_process_res_acc, NULL, link);
+       css_schedule_reprobe();
 }
 
 static int
@@ -663,19 +643,6 @@ static int s390_subchannel_vary_chpid_on(struct subchannel *sch, void *data)
        return 0;
 }
 
-static int
-__s390_vary_chpid_on(struct subchannel_id schid, void *data)
-{
-       struct schib schib;
-
-       if (stsch_err(schid, &schib))
-               /* We're through */
-               return -ENXIO;
-       /* Put it on the slow path. */
-       css_schedule_eval(schid);
-       return 0;
-}
-
 /**
  * chsc_chp_vary - propagate channel-path vary operation to subchannels
  * @chpid: channl-path ID
@@ -694,7 +661,8 @@ int chsc_chp_vary(struct chp_id chpid, int on)
                /* Try to update the channel path description. */
                chp_update_desc(chp);
                for_each_subchannel_staged(s390_subchannel_vary_chpid_on,
-                                          __s390_vary_chpid_on, &chpid);
+                                          NULL, &chpid);
+               css_schedule_reprobe();
        } else
                for_each_subchannel_staged(s390_subchannel_vary_chpid_off,
                                           NULL, &chpid);
index 8c2cb87bccc5d8b1a195ff1dc43181309aa75d82..0268e5fd59b5522fe1d61dbf90ddf17ed4e2df1f 100644 (file)
@@ -69,7 +69,8 @@ static int call_fn_known_sch(struct device *dev, void *data)
        struct cb_data *cb = data;
        int rc = 0;
 
-       idset_sch_del(cb->set, sch->schid);
+       if (cb->set)
+               idset_sch_del(cb->set, sch->schid);
        if (cb->fn_known_sch)
                rc = cb->fn_known_sch(sch, cb->data);
        return rc;
@@ -115,6 +116,13 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
        cb.fn_known_sch = fn_known;
        cb.fn_unknown_sch = fn_unknown;
 
+       if (fn_known && !fn_unknown) {
+               /* Skip idset allocation in case of known-only loop. */
+               cb.set = NULL;
+               return bus_for_each_dev(&css_bus_type, NULL, &cb,
+                                       call_fn_known_sch);
+       }
+
        cb.set = idset_sch_new();
        if (!cb.set)
                /* fall back to brute force scanning in case of oom */
@@ -553,6 +561,9 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data)
                default:
                        rc = 0;
                }
+               /* Allow scheduling here since the containing loop might
+                * take a while.  */
+               cond_resched();
        }
        return rc;
 }
@@ -572,7 +583,7 @@ static void css_slow_path_func(struct work_struct *unused)
        spin_unlock_irqrestore(&slow_subchannel_lock, flags);
 }
 
-static DECLARE_WORK(slow_path_work, css_slow_path_func);
+static DECLARE_DELAYED_WORK(slow_path_work, css_slow_path_func);
 struct workqueue_struct *cio_work_q;
 
 void css_schedule_eval(struct subchannel_id schid)
@@ -582,7 +593,7 @@ void css_schedule_eval(struct subchannel_id schid)
        spin_lock_irqsave(&slow_subchannel_lock, flags);
        idset_sch_add(slow_subchannel_set, schid);
        atomic_set(&css_eval_scheduled, 1);
-       queue_work(cio_work_q, &slow_path_work);
+       queue_delayed_work(cio_work_q, &slow_path_work, 0);
        spin_unlock_irqrestore(&slow_subchannel_lock, flags);
 }
 
@@ -593,7 +604,7 @@ void css_schedule_eval_all(void)
        spin_lock_irqsave(&slow_subchannel_lock, flags);
        idset_fill(slow_subchannel_set);
        atomic_set(&css_eval_scheduled, 1);
-       queue_work(cio_work_q, &slow_path_work);
+       queue_delayed_work(cio_work_q, &slow_path_work, 0);
        spin_unlock_irqrestore(&slow_subchannel_lock, flags);
 }
 
@@ -606,7 +617,7 @@ static int __unset_registered(struct device *dev, void *data)
        return 0;
 }
 
-static void css_schedule_eval_all_unreg(void)
+void css_schedule_eval_all_unreg(unsigned long delay)
 {
        unsigned long flags;
        struct idset *unreg_set;
@@ -624,7 +635,7 @@ static void css_schedule_eval_all_unreg(void)
        spin_lock_irqsave(&slow_subchannel_lock, flags);
        idset_add_set(slow_subchannel_set, unreg_set);
        atomic_set(&css_eval_scheduled, 1);
-       queue_work(cio_work_q, &slow_path_work);
+       queue_delayed_work(cio_work_q, &slow_path_work, delay);
        spin_unlock_irqrestore(&slow_subchannel_lock, flags);
        idset_free(unreg_set);
 }
@@ -637,7 +648,8 @@ void css_wait_for_slow_path(void)
 /* Schedule reprobing of all unregistered subchannels. */
 void css_schedule_reprobe(void)
 {
-       css_schedule_eval_all_unreg();
+       /* Schedule with a delay to allow merging of subsequent calls. */
+       css_schedule_eval_all_unreg(1 * HZ);
 }
 EXPORT_SYMBOL_GPL(css_schedule_reprobe);
 
index 29351321bad6c73b97cdfc490c1d5d71ae12e6ce..2c9107e2025143b34fc5da2be3118b0fe013e7c9 100644 (file)
@@ -133,6 +133,7 @@ extern struct channel_subsystem *channel_subsystems[];
 /* Helper functions to build lists for the slow path. */
 void css_schedule_eval(struct subchannel_id schid);
 void css_schedule_eval_all(void);
+void css_schedule_eval_all_unreg(unsigned long delay);
 int css_complete_work(void);
 
 int sch_is_pseudo_sch(struct subchannel *);
index 02300dcfac91f87397c030f11eab825d1361f393..ab3baa7f95082e0cabf03906354c69ae9ed8880b 100644 (file)
@@ -591,7 +591,13 @@ static int ap_init_queue(ap_qid_t qid)
                if (rc != -ENODEV && rc != -EBUSY)
                        break;
                if (i < AP_MAX_RESET - 1) {
-                       udelay(5);
+                       /* Time we are waiting until we give up (0.7sec * 90).
+                        * Since the actual request (in progress) will not
+                        * interrupted immediately for the reset command,
+                        * we have to be patient. In worst case we have to
+                        * wait 60sec + reset time (some msec).
+                        */
+                       schedule_timeout(AP_RESET_TIMEOUT);
                        status = ap_test_queue(qid, &dummy, &dummy);
                }
        }
@@ -992,6 +998,28 @@ static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
 
 static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
 
+static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
+{
+       if (ap_configuration != NULL) { /* QCI not supported */
+               if (test_facility(76)) { /* format 1 - 256 bit domain field */
+                       return snprintf(buf, PAGE_SIZE,
+                               "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
+                       ap_configuration->adm[0], ap_configuration->adm[1],
+                       ap_configuration->adm[2], ap_configuration->adm[3],
+                       ap_configuration->adm[4], ap_configuration->adm[5],
+                       ap_configuration->adm[6], ap_configuration->adm[7]);
+               } else { /* format 0 - 16 bit domain field */
+                       return snprintf(buf, PAGE_SIZE, "%08x%08x\n",
+                       ap_configuration->adm[0], ap_configuration->adm[1]);
+                 }
+       } else {
+               return snprintf(buf, PAGE_SIZE, "not supported\n");
+         }
+}
+
+static BUS_ATTR(ap_control_domain_mask, 0444,
+               ap_control_domain_mask_show, NULL);
+
 static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
 {
        return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
@@ -1077,6 +1105,7 @@ static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
 
 static struct bus_attribute *const ap_bus_attrs[] = {
        &bus_attr_ap_domain,
+       &bus_attr_ap_control_domain_mask,
        &bus_attr_config_time,
        &bus_attr_poll_thread,
        &bus_attr_ap_interrupts,
index 685f6cc022f92e929e60d865d817caca13269afb..6405ae24a7a69674ddc602d5bbef2a9ccd29d7bf 100644 (file)
@@ -33,7 +33,7 @@
 #define AP_DEVICES 64          /* Number of AP devices. */
 #define AP_DOMAINS 16          /* Number of AP domains. */
 #define AP_MAX_RESET 90                /* Maximum number of resets. */
-#define AP_RESET_TIMEOUT (HZ/2)        /* Time in ticks for reset timeouts. */
+#define AP_RESET_TIMEOUT (HZ*0.7)      /* Time in ticks for reset timeouts. */
 #define AP_CONFIG_TIME 30      /* Time in seconds between AP bus rescans. */
 #define AP_POLL_TIME 1         /* Time in ticks between receive polls. */
 
@@ -125,6 +125,8 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr)
 #define AP_FUNC_CRT4K 2
 #define AP_FUNC_COPRO 3
 #define AP_FUNC_ACCEL 4
+#define AP_FUNC_EP11  5
+#define AP_FUNC_APXA  6
 
 /*
  * AP reset flag states
index 31cfaa556072c0154373d0d3a7fbccb0b54a30e9..3d4bc904d149706cfb8c5c65f9f0b933614e31b6 100644 (file)
@@ -44,6 +44,8 @@
 #include "zcrypt_debug.h"
 #include "zcrypt_api.h"
 
+#include "zcrypt_msgtype6.h"
+
 /*
  * Module description.
  */
@@ -554,9 +556,9 @@ static long zcrypt_send_cprb(struct ica_xcRB *xcRB)
        spin_lock_bh(&zcrypt_device_lock);
        list_for_each_entry(zdev, &zcrypt_device_list, list) {
                if (!zdev->online || !zdev->ops->send_cprb ||
-                   (xcRB->user_defined != AUTOSELECT &&
-                       AP_QID_DEVICE(zdev->ap_dev->qid) != xcRB->user_defined)
-                   )
+                  (zdev->ops->variant == MSGTYPE06_VARIANT_EP11) ||
+                  (xcRB->user_defined != AUTOSELECT &&
+                   AP_QID_DEVICE(zdev->ap_dev->qid) != xcRB->user_defined))
                        continue;
                zcrypt_device_get(zdev);
                get_device(&zdev->ap_dev->device);
@@ -581,6 +583,82 @@ static long zcrypt_send_cprb(struct ica_xcRB *xcRB)
        return -ENODEV;
 }
 
+struct ep11_target_dev_list {
+       short                   targets_num;
+       struct ep11_target_dev  *targets;
+};
+
+static bool is_desired_ep11dev(unsigned int dev_qid,
+                              struct ep11_target_dev_list dev_list)
+{
+       int n;
+
+       for (n = 0; n < dev_list.targets_num; n++, dev_list.targets++) {
+               if ((AP_QID_DEVICE(dev_qid) == dev_list.targets->ap_id) &&
+                   (AP_QID_QUEUE(dev_qid) == dev_list.targets->dom_id)) {
+                       return true;
+               }
+       }
+       return false;
+}
+
+static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
+{
+       struct zcrypt_device *zdev;
+       bool autoselect = false;
+       struct ep11_target_dev_list ep11_dev_list;
+       int rc;
+
+       ep11_dev_list.targets_num = (short) xcrb->targets_num,
+       ep11_dev_list.targets = kmalloc((short)xcrb->targets_num *
+                                        sizeof(struct ep11_target_dev),
+                                        GFP_KERNEL);
+       if (!ep11_dev_list.targets)
+               return -ENOMEM;
+
+       if (copy_from_user(ep11_dev_list.targets, xcrb->targets,
+                          xcrb->targets_num * sizeof(struct ep11_target_dev)))
+               return -EFAULT;
+
+       /* empty list indicates autoselect (all available targets) */
+       if (ep11_dev_list.targets_num == 0)
+               autoselect = true;
+
+       spin_lock_bh(&zcrypt_device_lock);
+       list_for_each_entry(zdev, &zcrypt_device_list, list) {
+               /* check if device is eligible */
+               if (!zdev->online ||
+                   zdev->ops->variant != MSGTYPE06_VARIANT_EP11)
+                       continue;
+
+               /* check if device is selected as valid target */
+               if (!is_desired_ep11dev(zdev->ap_dev->qid, ep11_dev_list) &&
+                   !autoselect)
+                       continue;
+
+               zcrypt_device_get(zdev);
+               get_device(&zdev->ap_dev->device);
+               zdev->request_count++;
+               __zcrypt_decrease_preference(zdev);
+               if (try_module_get(zdev->ap_dev->drv->driver.owner)) {
+                       spin_unlock_bh(&zcrypt_device_lock);
+                       rc = zdev->ops->send_ep11_cprb(zdev, xcrb);
+                       spin_lock_bh(&zcrypt_device_lock);
+                       module_put(zdev->ap_dev->drv->driver.owner);
+               } else {
+                       rc = -EAGAIN;
+                 }
+               zdev->request_count--;
+               __zcrypt_increase_preference(zdev);
+               put_device(&zdev->ap_dev->device);
+               zcrypt_device_put(zdev);
+               spin_unlock_bh(&zcrypt_device_lock);
+               return rc;
+       }
+       spin_unlock_bh(&zcrypt_device_lock);
+       return -ENODEV;
+}
+
 static long zcrypt_rng(char *buffer)
 {
        struct zcrypt_device *zdev;
@@ -784,6 +862,23 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
                        return -EFAULT;
                return rc;
        }
+       case ZSENDEP11CPRB: {
+               struct ep11_urb __user *uxcrb = (void __user *)arg;
+               struct ep11_urb xcrb;
+               if (copy_from_user(&xcrb, uxcrb, sizeof(xcrb)))
+                       return -EFAULT;
+               do {
+                       rc = zcrypt_send_ep11_cprb(&xcrb);
+               } while (rc == -EAGAIN);
+               /* on failure: retry once again after a requested rescan */
+               if ((rc == -ENODEV) && (zcrypt_process_rescan()))
+                       do {
+                               rc = zcrypt_send_ep11_cprb(&xcrb);
+                       } while (rc == -EAGAIN);
+               if (copy_to_user(uxcrb, &xcrb, sizeof(xcrb)))
+                       return -EFAULT;
+               return rc;
+       }
        case Z90STAT_STATUS_MASK: {
                char status[AP_DEVICES];
                zcrypt_status_mask(status);
index 89632919c993ab4ea436c8bf38ade793820de824..b3d496bfaa7eadd08aa27e15a26c0e177a507685 100644 (file)
@@ -74,6 +74,7 @@ struct ica_z90_status {
 #define ZCRYPT_CEX2A           6
 #define ZCRYPT_CEX3C           7
 #define ZCRYPT_CEX3A           8
+#define ZCRYPT_CEX4           10
 
 /**
  * Large random numbers are pulled in 4096 byte chunks from the crypto cards
@@ -89,6 +90,7 @@ struct zcrypt_ops {
        long (*rsa_modexpo_crt)(struct zcrypt_device *,
                                struct ica_rsa_modexpo_crt *);
        long (*send_cprb)(struct zcrypt_device *, struct ica_xcRB *);
+       long (*send_ep11_cprb)(struct zcrypt_device *, struct ep11_urb *);
        long (*rng)(struct zcrypt_device *, char *);
        struct list_head list;          /* zcrypt ops list. */
        struct module *owner;
index ce1226398ac996a13b0546ba11df3ccfee6fa272..569f8b1d86c05305501530b33d2fdfba84e114a9 100644 (file)
 #define CEX4A_MAX_MESSAGE_SIZE MSGTYPE50_CRB3_MAX_MSG_SIZE
 #define CEX4C_MAX_MESSAGE_SIZE MSGTYPE06_MAX_MSG_SIZE
 
-#define CEX4_CLEANUP_TIME      (15*HZ)
+/* Waiting time for requests to be processed.
+ * Currently there are some types of request which are not deterministic.
+ * But the maximum time limit managed by the stomper code is set to 60sec.
+ * Hence we have to wait at least that time period.
+ */
+#define CEX4_CLEANUP_TIME      (61*HZ)
 
 static struct ap_device_id zcrypt_cex4_ids[] = {
        { AP_DEVICE(AP_DEVICE_TYPE_CEX4)  },
@@ -101,6 +106,19 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev)
                        zdev->speed_rating = CEX4C_SPEED_RATING;
                        zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
                                                           MSGTYPE06_VARIANT_DEFAULT);
+               } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_EP11)) {
+                       zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE);
+                       if (!zdev)
+                               return -ENOMEM;
+                       zdev->type_string = "CEX4P";
+                       zdev->user_space_type = ZCRYPT_CEX4;
+                       zdev->min_mod_size = CEX4C_MIN_MOD_SIZE;
+                       zdev->max_mod_size = CEX4C_MAX_MOD_SIZE;
+                       zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
+                       zdev->short_crt = 0;
+                       zdev->speed_rating = CEX4C_SPEED_RATING;
+                       zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
+                                                       MSGTYPE06_VARIANT_EP11);
                }
                break;
        }
index 0079b661721139e4f8ec7f58ef39bb99d08b045f..7b23f43c7b080cc81b4de94ed9016cc0d8a91546 100644 (file)
@@ -106,15 +106,15 @@ static inline int convert_error(struct zcrypt_device *zdev,
        //   REP88_ERROR_MESSAGE_TYPE           // '20' CEX2A
                /*
                 * To sent a message of the wrong type is a bug in the
-                * device driver. Warn about it, disable the device
+                * device driver. Send error msg, disable the device
                 * and then repeat the request.
                 */
-               WARN_ON(1);
                atomic_set(&zcrypt_rescan_req, 1);
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
                ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
-                              zdev->ap_dev->qid,
-                              zdev->online, ehdr->reply_code);
+                       zdev->ap_dev->qid, zdev->online, ehdr->reply_code);
                return -EAGAIN;
        case REP82_ERROR_TRANSPORT_FAIL:
        case REP82_ERROR_MACHINE_FAILURE:
@@ -122,15 +122,17 @@ static inline int convert_error(struct zcrypt_device *zdev,
                /* If a card fails disable it and repeat the request. */
                atomic_set(&zcrypt_rescan_req, 1);
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
                ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
-                              zdev->ap_dev->qid,
-                              zdev->online, ehdr->reply_code);
+                       zdev->ap_dev->qid, zdev->online, ehdr->reply_code);
                return -EAGAIN;
        default:
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
                ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
-                              zdev->ap_dev->qid,
-                              zdev->online, ehdr->reply_code);
+                       zdev->ap_dev->qid, zdev->online, ehdr->reply_code);
                return -EAGAIN; /* repeat the request on a different device. */
        }
 }
index 7c522f338bda16a50f11cf04aa845a8f6f937637..334e282f255b7d9b0a6288bad94d6702a729a556 100644 (file)
@@ -25,6 +25,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define KMSG_COMPONENT "zcrypt"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -332,6 +335,11 @@ static int convert_type80(struct zcrypt_device *zdev,
        if (t80h->len < sizeof(*t80h) + outputdatalength) {
                /* The result is too short, the CEX2A card may not do that.. */
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
+                              zdev->ap_dev->qid, zdev->online, t80h->code);
+
                return -EAGAIN; /* repeat the request on a different device. */
        }
        if (zdev->user_space_type == ZCRYPT_CEX2A)
@@ -359,6 +367,10 @@ static int convert_response(struct zcrypt_device *zdev,
                                      outputdata, outputdatalength);
        default: /* Unknown response type, this should NEVER EVER happen */
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
+                              zdev->ap_dev->qid, zdev->online);
                return -EAGAIN; /* repeat the request on a different device. */
        }
 }
index 7d97fa5a26d0cca4e6f318e5d57d392728f3c5f9..3210e8db42d30578aae8da78715b307fef91dd7a 100644 (file)
@@ -25,6 +25,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define KMSG_COMPONENT "zcrypt"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
@@ -50,6 +53,7 @@ struct response_type {
 };
 #define PCIXCC_RESPONSE_TYPE_ICA  0
 #define PCIXCC_RESPONSE_TYPE_XCRB 1
+#define PCIXCC_RESPONSE_TYPE_EP11 2
 
 MODULE_AUTHOR("IBM Corporation");
 MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \
@@ -358,6 +362,90 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
        return 0;
 }
 
+static int xcrb_msg_to_type6_ep11cprb_msgx(struct zcrypt_device *zdev,
+                                      struct ap_message *ap_msg,
+                                      struct ep11_urb *xcRB)
+{
+       unsigned int lfmt;
+
+       static struct type6_hdr static_type6_ep11_hdr = {
+               .type           =  0x06,
+               .rqid           = {0x00, 0x01},
+               .function_code  = {0x00, 0x00},
+               .agent_id[0]    =  0x58,        /* {'X'} */
+               .agent_id[1]    =  0x43,        /* {'C'} */
+               .offset1        =  0x00000058,
+       };
+
+       struct {
+               struct type6_hdr hdr;
+               struct ep11_cprb cprbx;
+               unsigned char   pld_tag;        /* fixed value 0x30 */
+               unsigned char   pld_lenfmt;     /* payload length format */
+       } __packed * msg = ap_msg->message;
+
+       struct pld_hdr {
+               unsigned char   func_tag;       /* fixed value 0x4 */
+               unsigned char   func_len;       /* fixed value 0x4 */
+               unsigned int    func_val;       /* function ID     */
+               unsigned char   dom_tag;        /* fixed value 0x4 */
+               unsigned char   dom_len;        /* fixed value 0x4 */
+               unsigned int    dom_val;        /* domain id       */
+       } __packed * payload_hdr;
+
+       /* length checks */
+       ap_msg->length = sizeof(struct type6_hdr) + xcRB->req_len;
+       if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE)
+               return -EINVAL;
+
+       if ((sizeof(struct type86_fmt2_msg) + CEIL4(xcRB->resp_len))
+                                        > MSGTYPE06_MAX_MSG_SIZE)
+               return -EINVAL;
+
+       /* prepare type6 header */
+       msg->hdr = static_type6_ep11_hdr;
+       msg->hdr.ToCardLen1   = xcRB->req_len;
+       msg->hdr.FromCardLen1 = xcRB->resp_len;
+
+       /* Import CPRB data from the ioctl input parameter */
+       if (copy_from_user(&(msg->cprbx.cprb_len),
+                          xcRB->req, xcRB->req_len)) {
+               return -EFAULT;
+       }
+
+       /*
+        The target domain field within the cprb body/payload block will be
+        replaced by the usage domain for non-management commands only.
+        Therefore we check the first bit of the 'flags' parameter for
+        management command indication.
+          0 - non managment command
+          1 - management command
+       */
+       if (!((msg->cprbx.flags & 0x80) == 0x80)) {
+               msg->cprbx.target_id = (unsigned int)
+                                       AP_QID_QUEUE(zdev->ap_dev->qid);
+
+               if ((msg->pld_lenfmt & 0x80) == 0x80) { /*ext.len.fmt 2 or 3*/
+                       switch (msg->pld_lenfmt & 0x03) {
+                       case 1:
+                               lfmt = 2;
+                               break;
+                       case 2:
+                               lfmt = 3;
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
+               } else {
+                       lfmt = 1; /* length format #1 */
+                 }
+               payload_hdr = (struct pld_hdr *)((&(msg->pld_lenfmt))+lfmt);
+               payload_hdr->dom_val = (unsigned int)
+                                       AP_QID_QUEUE(zdev->ap_dev->qid);
+       }
+       return 0;
+}
+
 /**
  * Copy results from a type 86 ICA reply message back to user space.
  *
@@ -377,6 +465,12 @@ struct type86x_reply {
        char text[0];
 } __packed;
 
+struct type86_ep11_reply {
+       struct type86_hdr hdr;
+       struct type86_fmt2_ext fmt2;
+       struct ep11_cprb cprbx;
+} __packed;
+
 static int convert_type86_ica(struct zcrypt_device *zdev,
                          struct ap_message *reply,
                          char __user *outputdata,
@@ -440,6 +534,11 @@ static int convert_type86_ica(struct zcrypt_device *zdev,
                if (service_rc == 8 && service_rs == 72)
                        return -EINVAL;
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
+                              zdev->ap_dev->qid, zdev->online,
+                              msg->hdr.reply_code);
                return -EAGAIN; /* repeat the request on a different device. */
        }
        data = msg->text;
@@ -503,6 +602,30 @@ static int convert_type86_xcrb(struct zcrypt_device *zdev,
        return 0;
 }
 
+/**
+ * Copy results from a type 86 EP11 XCRB reply message back to user space.
+ *
+ * @zdev: crypto device pointer
+ * @reply: reply AP message.
+ * @xcRB: pointer to EP11 user request block
+ *
+ * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
+ */
+static int convert_type86_ep11_xcrb(struct zcrypt_device *zdev,
+                                   struct ap_message *reply,
+                                   struct ep11_urb *xcRB)
+{
+       struct type86_fmt2_msg *msg = reply->message;
+       char *data = reply->message;
+
+       /* Copy response CPRB to user */
+       if (copy_to_user(xcRB->resp,
+                        data + msg->fmt2.offset1, msg->fmt2.count1))
+               return -EFAULT;
+       xcRB->resp_len = msg->fmt2.count1;
+       return 0;
+}
+
 static int convert_type86_rng(struct zcrypt_device *zdev,
                          struct ap_message *reply,
                          char *buffer)
@@ -551,6 +674,10 @@ static int convert_response_ica(struct zcrypt_device *zdev,
                 * response */
        default: /* Unknown response type, this should NEVER EVER happen */
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
+                              zdev->ap_dev->qid, zdev->online);
                return -EAGAIN; /* repeat the request on a different device. */
        }
 }
@@ -579,10 +706,40 @@ static int convert_response_xcrb(struct zcrypt_device *zdev,
        default: /* Unknown response type, this should NEVER EVER happen */
                xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
+                              zdev->ap_dev->qid, zdev->online);
                return -EAGAIN; /* repeat the request on a different device. */
        }
 }
 
+static int convert_response_ep11_xcrb(struct zcrypt_device *zdev,
+       struct ap_message *reply, struct ep11_urb *xcRB)
+{
+       struct type86_ep11_reply *msg = reply->message;
+
+       /* Response type byte is the second byte in the response. */
+       switch (((unsigned char *)reply->message)[1]) {
+       case TYPE82_RSP_CODE:
+       case TYPE87_RSP_CODE:
+               return convert_error(zdev, reply);
+       case TYPE86_RSP_CODE:
+               if (msg->hdr.reply_code)
+                       return convert_error(zdev, reply);
+               if (msg->cprbx.cprb_ver_id == 0x04)
+                       return convert_type86_ep11_xcrb(zdev, reply, xcRB);
+       /* Fall through, no break, incorrect cprb version is an unknown resp.*/
+       default: /* Unknown response type, this should NEVER EVER happen */
+               zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
+                              zdev->ap_dev->qid, zdev->online);
+               return -EAGAIN; /* repeat the request on a different device. */
+       }
+}
+
 static int convert_response_rng(struct zcrypt_device *zdev,
                                 struct ap_message *reply,
                                 char *data)
@@ -602,6 +759,10 @@ static int convert_response_rng(struct zcrypt_device *zdev,
                 * response */
        default: /* Unknown response type, this should NEVER EVER happen */
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
+                              zdev->ap_dev->qid, zdev->online);
                return -EAGAIN; /* repeat the request on a different device. */
        }
 }
@@ -657,6 +818,51 @@ out:
        complete(&(resp_type->work));
 }
 
+/**
+ * This function is called from the AP bus code after a crypto request
+ * "msg" has finished with the reply message "reply".
+ * It is called from tasklet context.
+ * @ap_dev: pointer to the AP device
+ * @msg: pointer to the AP message
+ * @reply: pointer to the AP reply message
+ */
+static void zcrypt_msgtype6_receive_ep11(struct ap_device *ap_dev,
+                                        struct ap_message *msg,
+                                        struct ap_message *reply)
+{
+       static struct error_hdr error_reply = {
+               .type = TYPE82_RSP_CODE,
+               .reply_code = REP82_ERROR_MACHINE_FAILURE,
+       };
+       struct response_type *resp_type =
+               (struct response_type *)msg->private;
+       struct type86_ep11_reply *t86r;
+       int length;
+
+       /* Copy the reply message to the request message buffer. */
+       if (IS_ERR(reply)) {
+               memcpy(msg->message, &error_reply, sizeof(error_reply));
+               goto out;
+       }
+       t86r = reply->message;
+       if (t86r->hdr.type == TYPE86_RSP_CODE &&
+           t86r->cprbx.cprb_ver_id == 0x04) {
+               switch (resp_type->type) {
+               case PCIXCC_RESPONSE_TYPE_EP11:
+                       length = t86r->fmt2.offset1 + t86r->fmt2.count1;
+                       length = min(MSGTYPE06_MAX_MSG_SIZE, length);
+                       memcpy(msg->message, reply->message, length);
+                       break;
+               default:
+                       memcpy(msg->message, &error_reply, sizeof(error_reply));
+               }
+       } else {
+               memcpy(msg->message, reply->message, sizeof(error_reply));
+         }
+out:
+       complete(&(resp_type->work));
+}
+
 static atomic_t zcrypt_step = ATOMIC_INIT(0);
 
 /**
@@ -781,6 +987,46 @@ out_free:
        return rc;
 }
 
+/**
+ * The request distributor calls this function if it picked the CEX4P
+ * device to handle a send_ep11_cprb request.
+ * @zdev: pointer to zcrypt_device structure that identifies the
+ *       CEX4P device to the request distributor
+ * @xcRB: pointer to the ep11 user request block
+ */
+static long zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_device *zdev,
+                                               struct ep11_urb *xcrb)
+{
+       struct ap_message ap_msg;
+       struct response_type resp_type = {
+               .type = PCIXCC_RESPONSE_TYPE_EP11,
+       };
+       int rc;
+
+       ap_init_message(&ap_msg);
+       ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
+       if (!ap_msg.message)
+               return -ENOMEM;
+       ap_msg.receive = zcrypt_msgtype6_receive_ep11;
+       ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
+                               atomic_inc_return(&zcrypt_step);
+       ap_msg.private = &resp_type;
+       rc = xcrb_msg_to_type6_ep11cprb_msgx(zdev, &ap_msg, xcrb);
+       if (rc)
+               goto out_free;
+       init_completion(&resp_type.work);
+       ap_queue_message(zdev->ap_dev, &ap_msg);
+       rc = wait_for_completion_interruptible(&resp_type.work);
+       if (rc == 0)
+               rc = convert_response_ep11_xcrb(zdev, &ap_msg, xcrb);
+       else /* Signal pending. */
+               ap_cancel_message(zdev->ap_dev, &ap_msg);
+
+out_free:
+       kzfree(ap_msg.message);
+       return rc;
+}
+
 /**
  * The request distributor calls this function if it picked the PCIXCC/CEX2C
  * device to generate random data.
@@ -839,10 +1085,19 @@ static struct zcrypt_ops zcrypt_msgtype6_ops = {
        .rng = zcrypt_msgtype6_rng,
 };
 
+static struct zcrypt_ops zcrypt_msgtype6_ep11_ops = {
+       .owner = THIS_MODULE,
+       .variant = MSGTYPE06_VARIANT_EP11,
+       .rsa_modexpo = NULL,
+       .rsa_modexpo_crt = NULL,
+       .send_ep11_cprb = zcrypt_msgtype6_send_ep11_cprb,
+};
+
 int __init zcrypt_msgtype6_init(void)
 {
        zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops);
        zcrypt_msgtype_register(&zcrypt_msgtype6_ops);
+       zcrypt_msgtype_register(&zcrypt_msgtype6_ep11_ops);
        return 0;
 }
 
@@ -850,6 +1105,7 @@ void __exit zcrypt_msgtype6_exit(void)
 {
        zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops);
        zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops);
+       zcrypt_msgtype_unregister(&zcrypt_msgtype6_ep11_ops);
 }
 
 module_init(zcrypt_msgtype6_init);
index 1e500d3c073571fe764bd1111cd8a2a7b10e7751..207247570623709c946f3a7708d3e3bfc7a0313e 100644 (file)
@@ -32,6 +32,7 @@
 #define MSGTYPE06_NAME                 "zcrypt_msgtype6"
 #define MSGTYPE06_VARIANT_DEFAULT      0
 #define MSGTYPE06_VARIANT_NORNG                1
+#define MSGTYPE06_VARIANT_EP11         2
 
 #define MSGTYPE06_MAX_MSG_SIZE         (12*1024)
 
@@ -99,6 +100,7 @@ struct type86_hdr {
 } __packed;
 
 #define TYPE86_RSP_CODE 0x86
+#define TYPE87_RSP_CODE 0x87
 #define TYPE86_FMT2    0x02
 
 struct type86_fmt2_ext {
index f2b71d8df01f0c1e42e75bd7b0f9786bbf881cae..7a743f4c646c0e46dadcaed195acc9bccf1bf183 100644 (file)
@@ -24,6 +24,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define KMSG_COMPONENT "zcrypt"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -199,6 +202,10 @@ static int convert_type84(struct zcrypt_device *zdev,
        if (t84h->len < sizeof(*t84h) + outputdatalength) {
                /* The result is too short, the PCICA card may not do that.. */
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
+                              zdev->ap_dev->qid, zdev->online, t84h->code);
                return -EAGAIN; /* repeat the request on a different device. */
        }
        BUG_ON(t84h->len > PCICA_MAX_RESPONSE_SIZE);
@@ -223,6 +230,10 @@ static int convert_response(struct zcrypt_device *zdev,
                                      outputdata, outputdatalength);
        default: /* Unknown response type, this should NEVER EVER happen */
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
+                              zdev->ap_dev->qid, zdev->online);
                return -EAGAIN; /* repeat the request on a different device. */
        }
 }
index 0d90a4334055efcc22ae73a290c53d83fcee8530..4d14c04b746e14ebe656ae08bc14843aee093a45 100644 (file)
@@ -24,6 +24,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define KMSG_COMPONENT "zcrypt"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/gfp.h>
@@ -372,6 +375,11 @@ static int convert_type86(struct zcrypt_device *zdev,
                if (service_rc == 8 && service_rs == 72)
                        return -EINVAL;
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
+                              zdev->ap_dev->qid, zdev->online,
+                              msg->hdr.reply_code);
                return -EAGAIN; /* repeat the request on a different device. */
        }
        data = msg->text;
@@ -425,6 +433,10 @@ static int convert_response(struct zcrypt_device *zdev,
                /* no break, incorrect cprb version is an unknown response */
        default: /* Unknown response type, this should NEVER EVER happen */
                zdev->online = 0;
+               pr_err("Cryptographic device %x failed and was set offline\n",
+                      zdev->ap_dev->qid);
+               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
+                              zdev->ap_dev->qid, zdev->online);
                return -EAGAIN; /* repeat the request on a different device. */
        }
 }
index 5e1e12c0cf4220796112d2d6dd9d9e102fdf537d..0a7325361d2958dceeae99da5959e518f8490985 100644 (file)
@@ -2025,7 +2025,8 @@ static struct scsi_host_template driver_template = {
        .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,
        .use_clustering         = ENABLE_CLUSTERING,
        .shost_attrs            = twa_host_attrs,
-       .emulated               = 1
+       .emulated               = 1,
+       .no_write_same          = 1,
 };
 
 /* This function will probe and initialize a card */
index c845bdbeb6c06f971923300e7f8e11182d18d84c..4de346017e9ff91b43aed80d48231ac60f23a4e3 100644 (file)
@@ -1600,7 +1600,8 @@ static struct scsi_host_template driver_template = {
        .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,
        .use_clustering         = ENABLE_CLUSTERING,
        .shost_attrs            = twl_host_attrs,
-       .emulated               = 1
+       .emulated               = 1,
+       .no_write_same          = 1,
 };
 
 /* This function will probe and initialize a card */
index b9276d10b25c2e277c05e1b6e48e196a11b38fa4..752624e6bc0022807c6265539cad6d8b42d1611f 100644 (file)
@@ -2279,7 +2279,8 @@ static struct scsi_host_template driver_template = {
        .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,  
        .use_clustering         = ENABLE_CLUSTERING,
        .shost_attrs            = tw_host_attrs,
-       .emulated               = 1
+       .emulated               = 1,
+       .no_write_same          = 1,
 };
 
 /* This function will probe and initialize a card */
index 30fa38a0ad39a33102f1cd4656b4d800c498ae07..9176bfbd574586ab04a62786253271b1a1636006 100644 (file)
@@ -201,7 +201,7 @@ static int a2091_probe(struct zorro_dev *z, const struct zorro_device_id *ent)
        instance->irq = IRQ_AMIGA_PORTS;
        instance->unique_id = z->slotaddr;
 
-       regs = (struct a2091_scsiregs *)ZTWO_VADDR(z->resource.start);
+       regs = ZTWO_VADDR(z->resource.start);
        regs->DAWR = DAWR_A2091;
 
        wdregs.SASR = &regs->SASR;
index c0f4f4290dd60dbeb836f547b097ca8b7141eaaf..dd5b64726ddc3c5f9dcee231501630c66424b9ab 100644 (file)
@@ -220,7 +220,7 @@ static int __init amiga_a3000_scsi_probe(struct platform_device *pdev)
 
        instance->irq = IRQ_AMIGA_PORTS;
 
-       regs = (struct a3000_scsiregs *)ZTWO_VADDR(res->start);
+       regs = ZTWO_VADDR(res->start);
        regs->DAWR = DAWR_A3000;
 
        wdregs.SASR = &regs->SASR;
index 70c521f79f7c26fbc92b65645b780e927c7fcac3..f5a2ab41543bd0bd9006a3af5687085343a25220 100644 (file)
@@ -56,7 +56,7 @@ static int __init amiga_a4000t_scsi_probe(struct platform_device *pdev)
        scsi_addr = res->start + A4000T_SCSI_OFFSET;
 
        /* Fill in the required pieces of hostdata */
-       hostdata->base = (void __iomem *)ZTWO_VADDR(scsi_addr);
+       hostdata->base = ZTWO_VADDR(scsi_addr);
        hostdata->clock = 50;
        hostdata->chip710 = 1;
        hostdata->dmode_extra = DMODE_FC2;
index f0d432c139d0cecedf51295562c858d22a9f44f0..4921ed19a027f819b731271c4804be74d2426e5a 100644 (file)
@@ -1081,6 +1081,7 @@ static struct scsi_host_template aac_driver_template = {
 #endif
        .use_clustering                 = ENABLE_CLUSTERING,
        .emulated                       = 1,
+       .no_write_same                  = 1,
 };
 
 static void __aac_shutdown(struct aac_dev * aac)
index 97fd450aff09315194233e7a8ea1f06b566248ef..4f6a30b8e5f99bb3cba345bfec806cdc4972b9f3 100644 (file)
@@ -137,6 +137,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
        .cmd_per_lun            = ARCMSR_MAX_CMD_PERLUN,
        .use_clustering         = ENABLE_CLUSTERING,
        .shost_attrs            = arcmsr_host_attrs,
+       .no_write_same          = 1,
 };
 static struct pci_device_id arcmsr_device_id_table[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)},
index ee4fa40a50b131597a3e1b6960bffc17191f2d03..ce5ef0190bad3f99f7459a859ce0ca0a1e947246 100644 (file)
@@ -4684,6 +4684,7 @@ static struct scsi_host_template gdth_template = {
         .cmd_per_lun            = GDTH_MAXC_P_L,
         .unchecked_isa_dma      = 1,
         .use_clustering         = ENABLE_CLUSTERING,
+       .no_write_same          = 1,
 };
 
 #ifdef CONFIG_ISA
index 2203ac281103b964917f47c1095d6c6a233ec7bf..3b6f83ffddc4e87c59057d0f7eb8a4ded51f11f4 100644 (file)
@@ -310,7 +310,7 @@ static int gvp11_probe(struct zorro_dev *z, const struct zorro_device_id *ent)
        if (!request_mem_region(address, 256, "wd33c93"))
                return -EBUSY;
 
-       regs = (struct gvp11_scsiregs *)(ZTWO_VADDR(address));
+       regs = ZTWO_VADDR(address);
 
        error = check_wd33c93(regs);
        if (error)
index f334859024c0652e3ce9bd197c66ca39b877af65..f2c5005f312af9aabeb25f8831ee17b5f28f6a42 100644 (file)
@@ -395,6 +395,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
        shost->use_clustering = sht->use_clustering;
        shost->ordered_tag = sht->ordered_tag;
        shost->eh_deadline = shost_eh_deadline * HZ;
+       shost->no_write_same = sht->no_write_same;
 
        if (sht->supported_mode == MODE_UNKNOWN)
                /* means we didn't set it ... default to INITIATOR */
index 22f6432eb4755a20af732e8c4d4060e9fbb9e909..8a1569da04bfcfff691474d0e67a1ee3bdb445f8 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/delay.h>
 #include <linux/fs.h>
 #include <linux/timer.h>
-#include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/compat.h>
@@ -223,6 +222,8 @@ static int hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id);
 static int hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr,
                                     int wait_for_ready);
 static inline void finish_cmd(struct CommandList *c);
+static unsigned char hpsa_format_in_progress(struct ctlr_info *h,
+               unsigned char scsi3addr[]);
 #define BOARD_NOT_READY 0
 #define BOARD_READY 1
 
@@ -561,6 +562,7 @@ static struct scsi_host_template hpsa_driver_template = {
        .sdev_attrs = hpsa_sdev_attrs,
        .shost_attrs = hpsa_shost_attrs,
        .max_sectors = 8192,
+       .no_write_same = 1,
 };
 
 
@@ -946,6 +948,112 @@ static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle,
        return DEVICE_NOT_FOUND;
 }
 
+#define OFFLINE_DEVICE_POLL_INTERVAL (120 * HZ)
+static int hpsa_offline_device_thread(void *v)
+{
+       struct ctlr_info *h = v;
+       unsigned long flags;
+       struct offline_device_entry *d;
+       unsigned char need_rescan = 0;
+       struct list_head *this, *tmp;
+
+       while (1) {
+               schedule_timeout_interruptible(OFFLINE_DEVICE_POLL_INTERVAL);
+               if (kthread_should_stop())
+                       break;
+
+               /* Check if any of the offline devices have become ready */
+               spin_lock_irqsave(&h->offline_device_lock, flags);
+               list_for_each_safe(this, tmp, &h->offline_device_list) {
+                       d = list_entry(this, struct offline_device_entry,
+                                       offline_list);
+                       spin_unlock_irqrestore(&h->offline_device_lock, flags);
+                       if (!hpsa_format_in_progress(h, d->scsi3addr)) {
+                               need_rescan = 1;
+                               goto do_rescan;
+                       }
+                       spin_lock_irqsave(&h->offline_device_lock, flags);
+               }
+               spin_unlock_irqrestore(&h->offline_device_lock, flags);
+       }
+
+do_rescan:
+
+       /* Remove all entries from the list and rescan and exit this thread.
+        * If there are still offline devices, the rescan will make a new list
+        * and create a new offline device monitor thread.
+        */
+       spin_lock_irqsave(&h->offline_device_lock, flags);
+       list_for_each_safe(this, tmp, &h->offline_device_list) {
+               d = list_entry(this, struct offline_device_entry, offline_list);
+               list_del_init(this);
+               kfree(d);
+       }
+       h->offline_device_monitor = NULL;
+       h->offline_device_thread_state = OFFLINE_DEVICE_THREAD_STOPPED;
+       spin_unlock_irqrestore(&h->offline_device_lock, flags);
+       if (need_rescan)
+               hpsa_scan_start(h->scsi_host);
+       return 0;
+}
+
+static void hpsa_monitor_offline_device(struct ctlr_info *h,
+                                       unsigned char scsi3addr[])
+{
+       struct offline_device_entry *device;
+       unsigned long flags;
+
+       /* Check to see if device is already on the list */
+       spin_lock_irqsave(&h->offline_device_lock, flags);
+       list_for_each_entry(device, &h->offline_device_list, offline_list) {
+               if (memcmp(device->scsi3addr, scsi3addr,
+                               sizeof(device->scsi3addr)) == 0) {
+                       spin_unlock_irqrestore(&h->offline_device_lock, flags);
+                       return;
+               }
+       }
+       spin_unlock_irqrestore(&h->offline_device_lock, flags);
+
+       /* Device is not on the list, add it. */
+       device = kmalloc(sizeof(*device), GFP_KERNEL);
+       if (!device) {
+               dev_warn(&h->pdev->dev, "out of memory in %s\n", __func__);
+               return;
+       }
+       memcpy(device->scsi3addr, scsi3addr, sizeof(device->scsi3addr));
+       spin_lock_irqsave(&h->offline_device_lock, flags);
+       list_add_tail(&device->offline_list, &h->offline_device_list);
+       if (h->offline_device_thread_state == OFFLINE_DEVICE_THREAD_STOPPED) {
+               h->offline_device_thread_state = OFFLINE_DEVICE_THREAD_RUNNING;
+               spin_unlock_irqrestore(&h->offline_device_lock, flags);
+               h->offline_device_monitor =
+                       kthread_run(hpsa_offline_device_thread, h, HPSA "-odm");
+               spin_lock_irqsave(&h->offline_device_lock, flags);
+       }
+       if (!h->offline_device_monitor) {
+               dev_warn(&h->pdev->dev, "failed to start offline device monitor thread.\n");
+               h->offline_device_thread_state = OFFLINE_DEVICE_THREAD_STOPPED;
+       }
+       spin_unlock_irqrestore(&h->offline_device_lock, flags);
+}
+
+static void stop_offline_device_monitor(struct ctlr_info *h)
+{
+       unsigned long flags;
+       int stop_thread;
+
+       spin_lock_irqsave(&h->offline_device_lock, flags);
+       stop_thread = (h->offline_device_thread_state ==
+                               OFFLINE_DEVICE_THREAD_RUNNING);
+       if (stop_thread)
+               /* STOPPING state prevents new thread from starting. */
+               h->offline_device_thread_state =
+                               OFFLINE_DEVICE_THREAD_STOPPING;
+       spin_unlock_irqrestore(&h->offline_device_lock, flags);
+       if (stop_thread)
+               kthread_stop(h->offline_device_monitor);
+}
+
 static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
        struct hpsa_scsi_dev_t *sd[], int nsds)
 {
@@ -1010,6 +1118,23 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
        for (i = 0; i < nsds; i++) {
                if (!sd[i]) /* if already added above. */
                        continue;
+
+               /* Don't add devices which are NOT READY, FORMAT IN PROGRESS
+                * as the SCSI mid-layer does not handle such devices well.
+                * It relentlessly loops sending TUR at 3Hz, then READ(10)
+                * at 160Hz, and prevents the system from coming up.
+                */
+               if (sd[i]->format_in_progress) {
+                       dev_info(&h->pdev->dev,
+                               "c%db%dt%dl%d: Logical drive parity initialization, erase or format in progress\n",
+                               h->scsi_host->host_no,
+                               sd[i]->bus, sd[i]->target, sd[i]->lun);
+                       dev_info(&h->pdev->dev, "c%db%dt%dl%d: temporarily offline\n",
+                               h->scsi_host->host_no,
+                               sd[i]->bus, sd[i]->target, sd[i]->lun);
+                       continue;
+               }
+
                device_change = hpsa_scsi_find_entry(sd[i], h->dev,
                                        h->ndevices, &entry);
                if (device_change == DEVICE_NOT_FOUND) {
@@ -1028,6 +1153,17 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
        }
        spin_unlock_irqrestore(&h->devlock, flags);
 
+       /* Monitor devices which are NOT READY, FORMAT IN PROGRESS to be
+        * brought online later. This must be done without holding h->devlock,
+        * so don't touch h->dev[]
+        */
+       for (i = 0; i < nsds; i++) {
+               if (!sd[i]) /* if already added above. */
+                       continue;
+               if (sd[i]->format_in_progress)
+                       hpsa_monitor_offline_device(h, sd[i]->scsi3addr);
+       }
+
        /* Don't notify scsi mid layer of any changes the first time through
         * (or if there are no changes) scsi_scan_host will do it later the
         * first time through.
@@ -1288,7 +1424,7 @@ static void complete_scsi_command(struct CommandList *cp)
                                        "has check condition: aborted command: "
                                        "ASC: 0x%x, ASCQ: 0x%x\n",
                                        cp, asc, ascq);
-                               cmd->result = DID_SOFT_ERROR << 16;
+                               cmd->result |= DID_SOFT_ERROR << 16;
                                break;
                        }
                        /* Must be some other type of check condition */
@@ -1715,6 +1851,34 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device,
        device->lun = lun;
 }
 
+static unsigned char hpsa_format_in_progress(struct ctlr_info *h,
+               unsigned char scsi3addr[])
+{
+       struct CommandList *c;
+       unsigned char *sense, sense_key, asc, ascq;
+#define ASC_LUN_NOT_READY 0x04
+#define ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS 0x04
+
+
+       c = cmd_special_alloc(h);
+       if (!c)
+               return 0;
+       fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, scsi3addr, TYPE_CMD);
+       hpsa_scsi_do_simple_cmd_core(h, c);
+       sense = c->err_info->SenseInfo;
+       sense_key = sense[2];
+       asc = sense[12];
+       ascq = sense[13];
+       if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
+               c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION &&
+               sense_key == NOT_READY &&
+               asc == ASC_LUN_NOT_READY &&
+               ascq == ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS)
+               return 1;
+       cmd_special_free(h, c);
+       return 0;
+}
+
 static int hpsa_update_device_info(struct ctlr_info *h,
        unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
        unsigned char *is_OBDR_device)
@@ -1753,10 +1917,14 @@ static int hpsa_update_device_info(struct ctlr_info *h,
                sizeof(this_device->device_id));
 
        if (this_device->devtype == TYPE_DISK &&
-               is_logical_dev_addr_mode(scsi3addr))
+               is_logical_dev_addr_mode(scsi3addr)) {
                hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level);
-       else
+               this_device->format_in_progress =
+                       hpsa_format_in_progress(h, scsi3addr);
+       } else {
                this_device->raid_level = RAID_UNKNOWN;
+               this_device->format_in_progress = 0;
+       }
 
        if (is_OBDR_device) {
                /* See if this is a One-Button-Disaster-Recovery device
@@ -1782,6 +1950,7 @@ static unsigned char *ext_target_model[] = {
        "MSA2312",
        "MSA2324",
        "P2000 G3 SAS",
+       "MSA 2040 SAS",
        NULL,
 };
 
@@ -3170,7 +3339,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
                                hpsa_pci_unmap(h->pdev, c, i,
                                        PCI_DMA_BIDIRECTIONAL);
                                status = -ENOMEM;
-                               goto cleanup1;
+                               goto cleanup0;
                        }
                        c->SG[i].Addr.lower = temp64.val32.lower;
                        c->SG[i].Addr.upper = temp64.val32.upper;
@@ -3186,24 +3355,23 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
        /* Copy the error information out */
        memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info));
        if (copy_to_user(argp, ioc, sizeof(*ioc))) {
-               cmd_special_free(h, c);
                status = -EFAULT;
-               goto cleanup1;
+               goto cleanup0;
        }
        if (ioc->Request.Type.Direction == XFER_READ && ioc->buf_size > 0) {
                /* Copy the data out of the buffer we created */
                BYTE __user *ptr = ioc->buf;
                for (i = 0; i < sg_used; i++) {
                        if (copy_to_user(ptr, buff[i], buff_size[i])) {
-                               cmd_special_free(h, c);
                                status = -EFAULT;
-                               goto cleanup1;
+                               goto cleanup0;
                        }
                        ptr += buff_size[i];
                }
        }
-       cmd_special_free(h, c);
        status = 0;
+cleanup0:
+       cmd_special_free(h, c);
 cleanup1:
        if (buff) {
                for (i = 0; i < sg_used; i++)
@@ -3222,6 +3390,36 @@ static void check_ioctl_unit_attention(struct ctlr_info *h,
                        c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
                (void) check_for_unit_attention(h, c);
 }
+
+static int increment_passthru_count(struct ctlr_info *h)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&h->passthru_count_lock, flags);
+       if (h->passthru_count >= HPSA_MAX_CONCURRENT_PASSTHRUS) {
+               spin_unlock_irqrestore(&h->passthru_count_lock, flags);
+               return -1;
+       }
+       h->passthru_count++;
+       spin_unlock_irqrestore(&h->passthru_count_lock, flags);
+       return 0;
+}
+
+static void decrement_passthru_count(struct ctlr_info *h)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&h->passthru_count_lock, flags);
+       if (h->passthru_count <= 0) {
+               spin_unlock_irqrestore(&h->passthru_count_lock, flags);
+               /* not expecting to get here. */
+               dev_warn(&h->pdev->dev, "Bug detected, passthru_count seems to be incorrect.\n");
+               return;
+       }
+       h->passthru_count--;
+       spin_unlock_irqrestore(&h->passthru_count_lock, flags);
+}
+
 /*
  * ioctl
  */
@@ -3229,6 +3427,7 @@ static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg)
 {
        struct ctlr_info *h;
        void __user *argp = (void __user *)arg;
+       int rc;
 
        h = sdev_to_hba(dev);
 
@@ -3243,9 +3442,17 @@ static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg)
        case CCISS_GETDRIVVER:
                return hpsa_getdrivver_ioctl(h, argp);
        case CCISS_PASSTHRU:
-               return hpsa_passthru_ioctl(h, argp);
+               if (increment_passthru_count(h))
+                       return -EAGAIN;
+               rc = hpsa_passthru_ioctl(h, argp);
+               decrement_passthru_count(h);
+               return rc;
        case CCISS_BIG_PASSTHRU:
-               return hpsa_big_passthru_ioctl(h, argp);
+               if (increment_passthru_count(h))
+                       return -EAGAIN;
+               rc = hpsa_big_passthru_ioctl(h, argp);
+               decrement_passthru_count(h);
+               return rc;
        default:
                return -ENOTTY;
        }
@@ -3444,9 +3651,11 @@ static void start_io(struct ctlr_info *h)
                c = list_entry(h->reqQ.next, struct CommandList, list);
                /* can't do anything if fifo is full */
                if ((h->access.fifo_full(h))) {
+                       h->fifo_recently_full = 1;
                        dev_warn(&h->pdev->dev, "fifo full\n");
                        break;
                }
+               h->fifo_recently_full = 0;
 
                /* Get the first entry from the Request Q */
                removeQ(c);
@@ -3500,15 +3709,41 @@ static inline int bad_tag(struct ctlr_info *h, u32 tag_index,
 static inline void finish_cmd(struct CommandList *c)
 {
        unsigned long flags;
+       int io_may_be_stalled = 0;
+       struct ctlr_info *h = c->h;
 
-       spin_lock_irqsave(&c->h->lock, flags);
+       spin_lock_irqsave(&h->lock, flags);
        removeQ(c);
-       spin_unlock_irqrestore(&c->h->lock, flags);
+
+       /*
+        * Check for possibly stalled i/o.
+        *
+        * If a fifo_full condition is encountered, requests will back up
+        * in h->reqQ.  This queue is only emptied out by start_io which is
+        * only called when a new i/o request comes in.  If no i/o's are
+        * forthcoming, the i/o's in h->reqQ can get stuck.  So we call
+        * start_io from here if we detect such a danger.
+        *
+        * Normally, we shouldn't hit this case, but pounding on the
+        * CCISS_PASSTHRU ioctl can provoke it.  Only call start_io if
+        * commands_outstanding is low.  We want to avoid calling
+        * start_io from in here as much as possible, and esp. don't
+        * want to get in a cycle where we call start_io every time
+        * through here.
+        */
+       if (unlikely(h->fifo_recently_full) &&
+               h->commands_outstanding < 5)
+               io_may_be_stalled = 1;
+
+       spin_unlock_irqrestore(&h->lock, flags);
+
        dial_up_lockup_detection_on_fw_flash_complete(c->h, c);
        if (likely(c->cmd_type == CMD_SCSI))
                complete_scsi_command(c);
        else if (c->cmd_type == CMD_IOCTL_PEND)
                complete(c->waiting);
+       if (unlikely(io_may_be_stalled))
+               start_io(h);
 }
 
 static inline u32 hpsa_tag_contains_index(u32 tag)
@@ -3784,6 +4019,13 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
                 */
                dev_info(&pdev->dev, "using doorbell to reset controller\n");
                writel(use_doorbell, vaddr + SA5_DOORBELL);
+
+               /* PMC hardware guys tell us we need a 5 second delay after
+                * doorbell reset and before any attempt to talk to the board
+                * at all to ensure that this actually works and doesn't fall
+                * over in some weird corner cases.
+                */
+               msleep(5000);
        } else { /* Try to do it the PCI power state way */
 
                /* Quoting from the Open CISS Specification: "The Power
@@ -3980,15 +4222,22 @@ static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
           need a little pause here */
        msleep(HPSA_POST_RESET_PAUSE_MSECS);
 
-       /* Wait for board to become not ready, then ready. */
-       dev_info(&pdev->dev, "Waiting for board to reset.\n");
-       rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY);
-       if (rc) {
-               dev_warn(&pdev->dev,
-                       "failed waiting for board to reset."
-                       " Will try soft reset.\n");
-               rc = -ENOTSUPP; /* Not expected, but try soft reset later */
-               goto unmap_cfgtable;
+       if (!use_doorbell) {
+               /* Wait for board to become not ready, then ready.
+                * (if we used the doorbell, then we already waited 5 secs
+                * so the "not ready" state is already gone by so we
+                * won't catch it.)
+                */
+               dev_info(&pdev->dev, "Waiting for board to reset.\n");
+               rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY);
+               if (rc) {
+                       dev_warn(&pdev->dev,
+                               "failed waiting for board to reset."
+                               " Will try soft reset.\n");
+                       /* Not expected, but try soft reset later */
+                       rc = -ENOTSUPP;
+                       goto unmap_cfgtable;
+               }
        }
        rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_READY);
        if (rc) {
@@ -4819,8 +5068,11 @@ reinit_after_soft_reset:
        h->intr_mode = hpsa_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
        INIT_LIST_HEAD(&h->cmpQ);
        INIT_LIST_HEAD(&h->reqQ);
+       INIT_LIST_HEAD(&h->offline_device_list);
        spin_lock_init(&h->lock);
        spin_lock_init(&h->scan_lock);
+       spin_lock_init(&h->offline_device_lock);
+       spin_lock_init(&h->passthru_count_lock);
        rc = hpsa_pci_init(h);
        if (rc != 0)
                goto clean1;
@@ -4828,6 +5080,7 @@ reinit_after_soft_reset:
        sprintf(h->devname, HPSA "%d", number_of_controllers);
        h->ctlr = number_of_controllers;
        number_of_controllers++;
+       h->offline_device_thread_state = OFFLINE_DEVICE_THREAD_STOPPED;
 
        /* configure PCI DMA stuff */
        rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
@@ -4941,6 +5194,15 @@ static void hpsa_flush_cache(struct ctlr_info *h)
 {
        char *flush_buf;
        struct CommandList *c;
+       unsigned long flags;
+
+       /* Don't bother trying to flush the cache if locked up */
+       spin_lock_irqsave(&h->lock, flags);
+       if (unlikely(h->lockup_detected)) {
+               spin_unlock_irqrestore(&h->lock, flags);
+               return;
+       }
+       spin_unlock_irqrestore(&h->lock, flags);
 
        flush_buf = kzalloc(4, GFP_KERNEL);
        if (!flush_buf)
@@ -4997,6 +5259,7 @@ static void hpsa_remove_one(struct pci_dev *pdev)
        }
        h = pci_get_drvdata(pdev);
        stop_controller_lockup_detector(h);
+       stop_offline_device_monitor(h);
        hpsa_unregister_scsi(h);        /* unhook from SCSI subsystem */
        hpsa_shutdown(pdev);
        iounmap(h->vaddr);
index bc85e7244f4049530ade90c558815b25d9ecce4e..bea2365fa6ee8c160b6006bc617bafcfd9ec9a42 100644 (file)
@@ -46,6 +46,7 @@ struct hpsa_scsi_dev_t {
        unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
        unsigned char model[16];        /* bytes 16-31 of inquiry data */
        unsigned char raid_level;       /* from inquiry page 0xC1 */
+       unsigned char format_in_progress;
 };
 
 struct reply_pool {
@@ -114,6 +115,11 @@ struct ctlr_info {
        struct TransTable_struct *transtable;
        unsigned long transMethod;
 
+       /* cap concurrent passthrus at some reasonable maximum */
+#define HPSA_MAX_CONCURRENT_PASSTHRUS (20)
+       spinlock_t passthru_count_lock; /* protects passthru_count */
+       int passthru_count;
+
        /*
         * Performant mode completion buffers
         */
@@ -131,6 +137,7 @@ struct ctlr_info {
        atomic_t firmware_flash_in_progress;
        u32 lockup_detected;
        struct list_head lockup_list;
+       u32 fifo_recently_full;
        /* Address of h->q[x] is passed to intr handler to know which queue */
        u8 q[MAX_REPLY_QUEUES];
        u32 TMFSupportFlags; /* cache what task mgmt funcs are supported. */
@@ -154,7 +161,20 @@ struct ctlr_info {
 #define HPSATMF_LOG_QRY_TASK    (1 << 23)
 #define HPSATMF_LOG_QRY_TSET    (1 << 24)
 #define HPSATMF_LOG_QRY_ASYNC   (1 << 25)
+       spinlock_t offline_device_lock;
+       struct list_head offline_device_list;
+       struct task_struct *offline_device_monitor;
+       unsigned char offline_device_thread_state;
+#define OFFLINE_DEVICE_THREAD_STOPPED 0
+#define OFFLINE_DEVICE_THREAD_STOPPING 1
+#define OFFLINE_DEVICE_THREAD_RUNNING 2
+};
+
+struct offline_device_entry {
+       unsigned char scsi3addr[8];
+       struct list_head offline_list;
 };
+
 #define HPSA_ABORT_MSG 0
 #define HPSA_DEVICE_RESET_MSG 1
 #define HPSA_RESET_TYPE_CONTROLLER 0x00
index 36ac1c34ce97eb53374f55451b8b42f4752b88f2..573f4128b6b68018f43a3263d166232ef39601fc 100644 (file)
@@ -6305,7 +6305,8 @@ static struct scsi_host_template driver_template = {
        .use_clustering = ENABLE_CLUSTERING,
        .shost_attrs = ipr_ioa_attrs,
        .sdev_attrs = ipr_dev_attrs,
-       .proc_name = IPR_NAME
+       .proc_name = IPR_NAME,
+       .no_write_same = 1,
 };
 
 /**
index 8d5ea8a1e5a6f33ab8235b300417d7ba352f84f7..52a216f21ae579644b97c093e89e12306a265595 100644 (file)
@@ -374,6 +374,7 @@ static struct scsi_host_template ips_driver_template = {
        .sg_tablesize           = IPS_MAX_SG,
        .cmd_per_lun            = 3,
        .use_clustering         = ENABLE_CLUSTERING,
+       .no_write_same          = 1,
 };
 
 
index 161c98efade9b9f290c04588e4638df0f3c421ac..d2895836f9fa4c00fec1a46d993074ecb3edeaea 100644 (file)
@@ -211,7 +211,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
                qc->tf.nsect = 0;
        }
 
-       ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis);
+       ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *)&task->ata_task.fis);
        task->uldd_task = qc;
        if (ata_is_atapi(qc->tf.protocol)) {
                memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
index 446b85110a1fc0a69b07e42bb3ecc7144d76d1ce..0cac7d8fd0f7cac75b0ecc2d63662d18eeda4a56 100644 (file)
@@ -2163,10 +2163,10 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        }
 
        /* do we need to support multiple segments? */
-       if (bio_segments(req->bio) > 1 || bio_segments(rsp->bio) > 1) {
-               printk("%s: multiple segments req %u %u, rsp %u %u\n",
-                      __func__, bio_segments(req->bio), blk_rq_bytes(req),
-                      bio_segments(rsp->bio), blk_rq_bytes(rsp));
+       if (bio_multiple_segments(req->bio) ||
+           bio_multiple_segments(rsp->bio)) {
+               printk("%s: multiple segments req %u, rsp %u\n",
+                      __func__, blk_rq_bytes(req), blk_rq_bytes(rsp));
                return -EINVAL;
        }
 
index 90c95a3385d18bb52f93093da10c8d400514f712..816db12ef5d555159226c5eb618b110ebb790776 100644 (file)
@@ -4244,6 +4244,7 @@ static struct scsi_host_template megaraid_template = {
        .eh_device_reset_handler        = megaraid_reset,
        .eh_bus_reset_handler           = megaraid_reset,
        .eh_host_reset_handler          = megaraid_reset,
+       .no_write_same                  = 1,
 };
 
 static int
index d1a4b82836ea6936f55504e33bcaabb5db9adbee..e2237a97cb9d314b485869cc37da7e3de8062531 100644 (file)
@@ -367,6 +367,7 @@ static struct scsi_host_template megaraid_template_g = {
        .eh_host_reset_handler          = megaraid_reset_handler,
        .change_queue_depth             = megaraid_change_queue_depth,
        .use_clustering                 = ENABLE_CLUSTERING,
+       .no_write_same                  = 1,
        .sdev_attrs                     = megaraid_sdev_attrs,
        .shost_attrs                    = megaraid_shost_attrs,
 };
index 0a743a5d16477a5e168f02a77a99e90f201caac3..c99812bf2a732f7180c291f3dcc23b5eda81a74c 100644 (file)
@@ -2148,6 +2148,7 @@ static struct scsi_host_template megasas_template = {
        .bios_param = megasas_bios_param,
        .use_clustering = ENABLE_CLUSTERING,
        .change_queue_depth = megasas_change_queue_depth,
+       .no_write_same = 1,
 };
 
 /**
index 9d26637308bebe2fc2b2fdec681891cfcbaf9b07..410f4a3e88887a6f0087c06f9da42f22b61f556d 100644 (file)
@@ -1901,7 +1901,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
        Mpi2SmpPassthroughRequest_t *mpi_request;
        Mpi2SmpPassthroughReply_t *mpi_reply;
-       int rc, i;
+       int rc;
        u16 smid;
        u32 ioc_state;
        unsigned long timeleft;
@@ -1916,7 +1916,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        void *pci_addr_out = NULL;
        u16 wait_state_count;
        struct request *rsp = req->next_rq;
-       struct bio_vec *bvec = NULL;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
 
        if (!rsp) {
                printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
@@ -1942,7 +1943,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        ioc->transport_cmds.status = MPT2_CMD_PENDING;
 
        /* Check if the request is split across multiple segments */
-       if (bio_segments(req->bio) > 1) {
+       if (bio_multiple_segments(req->bio)) {
                u32 offset = 0;
 
                /* Allocate memory and copy the request */
@@ -1955,11 +1956,11 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
                        goto out;
                }
 
-               bio_for_each_segment(bvec, req->bio, i) {
+               bio_for_each_segment(bvec, req->bio, iter) {
                        memcpy(pci_addr_out + offset,
-                           page_address(bvec->bv_page) + bvec->bv_offset,
-                           bvec->bv_len);
-                       offset += bvec->bv_len;
+                           page_address(bvec.bv_page) + bvec.bv_offset,
+                           bvec.bv_len);
+                       offset += bvec.bv_len;
                }
        } else {
                dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
@@ -1974,7 +1975,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
 
        /* Check if the response needs to be populated across
         * multiple segments */
-       if (bio_segments(rsp->bio) > 1) {
+       if (bio_multiple_segments(rsp->bio)) {
                pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp),
                    &pci_dma_in);
                if (!pci_addr_in) {
@@ -2041,7 +2042,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
            MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
        sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       if (bio_segments(req->bio) > 1) {
+       if (bio_multiple_segments(req->bio)) {
                ioc->base_add_sg_single(psge, sgl_flags |
                    (blk_rq_bytes(req) - 4), pci_dma_out);
        } else {
@@ -2057,7 +2058,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
            MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
            MPI2_SGE_FLAGS_END_OF_LIST);
        sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-       if (bio_segments(rsp->bio) > 1) {
+       if (bio_multiple_segments(rsp->bio)) {
                ioc->base_add_sg_single(psge, sgl_flags |
                    (blk_rq_bytes(rsp) + 4), pci_dma_in);
        } else {
@@ -2102,23 +2103,23 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
                    le16_to_cpu(mpi_reply->ResponseDataLength);
                /* check if the resp needs to be copied from the allocated
                 * pci mem */
-               if (bio_segments(rsp->bio) > 1) {
+               if (bio_multiple_segments(rsp->bio)) {
                        u32 offset = 0;
                        u32 bytes_to_copy =
                            le16_to_cpu(mpi_reply->ResponseDataLength);
-                       bio_for_each_segment(bvec, rsp->bio, i) {
-                               if (bytes_to_copy <= bvec->bv_len) {
-                                       memcpy(page_address(bvec->bv_page) +
-                                           bvec->bv_offset, pci_addr_in +
+                       bio_for_each_segment(bvec, rsp->bio, iter) {
+                               if (bytes_to_copy <= bvec.bv_len) {
+                                       memcpy(page_address(bvec.bv_page) +
+                                           bvec.bv_offset, pci_addr_in +
                                            offset, bytes_to_copy);
                                        break;
                                } else {
-                                       memcpy(page_address(bvec->bv_page) +
-                                           bvec->bv_offset, pci_addr_in +
-                                           offset, bvec->bv_len);
-                                       bytes_to_copy -= bvec->bv_len;
+                                       memcpy(page_address(bvec.bv_page) +
+                                           bvec.bv_offset, pci_addr_in +
+                                           offset, bvec.bv_len);
+                                       bytes_to_copy -= bvec.bv_len;
                                }
-                               offset += bvec->bv_len;
+                               offset += bvec.bv_len;
                        }
                }
        } else {
index e771a88c6a7441c45c6b49e8ffb85d5258b22e99..65170cb1a00fa5fa0ca3c95a94e3ed686edca9f7 100644 (file)
@@ -1884,7 +1884,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
        Mpi2SmpPassthroughRequest_t *mpi_request;
        Mpi2SmpPassthroughReply_t *mpi_reply;
-       int rc, i;
+       int rc;
        u16 smid;
        u32 ioc_state;
        unsigned long timeleft;
@@ -1898,7 +1898,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        void *pci_addr_out = NULL;
        u16 wait_state_count;
        struct request *rsp = req->next_rq;
-       struct bio_vec *bvec = NULL;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
 
        if (!rsp) {
                pr_err(MPT3SAS_FMT "%s: the smp response space is missing\n",
@@ -1925,7 +1926,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        ioc->transport_cmds.status = MPT3_CMD_PENDING;
 
        /* Check if the request is split across multiple segments */
-       if (req->bio->bi_vcnt > 1) {
+       if (bio_multiple_segments(req->bio)) {
                u32 offset = 0;
 
                /* Allocate memory and copy the request */
@@ -1938,11 +1939,11 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
                        goto out;
                }
 
-               bio_for_each_segment(bvec, req->bio, i) {
+               bio_for_each_segment(bvec, req->bio, iter) {
                        memcpy(pci_addr_out + offset,
-                           page_address(bvec->bv_page) + bvec->bv_offset,
-                           bvec->bv_len);
-                       offset += bvec->bv_len;
+                           page_address(bvec.bv_page) + bvec.bv_offset,
+                           bvec.bv_len);
+                       offset += bvec.bv_len;
                }
        } else {
                dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
@@ -1957,7 +1958,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
 
        /* Check if the response needs to be populated across
         * multiple segments */
-       if (rsp->bio->bi_vcnt > 1) {
+       if (bio_multiple_segments(rsp->bio)) {
                pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp),
                    &pci_dma_in);
                if (!pci_addr_in) {
@@ -2018,7 +2019,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
        mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
        psge = &mpi_request->SGL;
 
-       if (req->bio->bi_vcnt > 1)
+       if (bio_multiple_segments(req->bio))
                ioc->build_sg(ioc, psge, pci_dma_out, (blk_rq_bytes(req) - 4),
                    pci_dma_in, (blk_rq_bytes(rsp) + 4));
        else
@@ -2063,23 +2064,23 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
 
                /* check if the resp needs to be copied from the allocated
                 * pci mem */
-               if (rsp->bio->bi_vcnt > 1) {
+               if (bio_multiple_segments(rsp->bio)) {
                        u32 offset = 0;
                        u32 bytes_to_copy =
                            le16_to_cpu(mpi_reply->ResponseDataLength);
-                       bio_for_each_segment(bvec, rsp->bio, i) {
-                               if (bytes_to_copy <= bvec->bv_len) {
-                                       memcpy(page_address(bvec->bv_page) +
-                                           bvec->bv_offset, pci_addr_in +
+                       bio_for_each_segment(bvec, rsp->bio, iter) {
+                               if (bytes_to_copy <= bvec.bv_len) {
+                                       memcpy(page_address(bvec.bv_page) +
+                                           bvec.bv_offset, pci_addr_in +
                                            offset, bytes_to_copy);
                                        break;
                                } else {
-                                       memcpy(page_address(bvec->bv_page) +
-                                           bvec->bv_offset, pci_addr_in +
-                                           offset, bvec->bv_len);
-                                       bytes_to_copy -= bvec->bv_len;
+                                       memcpy(page_address(bvec.bv_page) +
+                                           bvec.bv_offset, pci_addr_in +
+                                           offset, bvec.bv_len);
+                                       bytes_to_copy -= bvec.bv_len;
                                }
-                               offset += bvec->bv_len;
+                               offset += bvec.bv_len;
                        }
                }
        } else {
index aa66361ed44b71772da913c74c69640b43909f23..bac04c2335aaf997c73e7b3b8b8a08129bfca455 100644 (file)
@@ -731,7 +731,7 @@ static int _osd_req_list_objects(struct osd_request *or,
 
        bio->bi_rw &= ~REQ_WRITE;
        or->in.bio = bio;
-       or->in.total_bytes = bio->bi_size;
+       or->in.total_bytes = bio->bi_iter.bi_size;
        return 0;
 }
 
index bd6f743d87a78af19c698d38d70291723fd28dfb..be8ce54f99b247bcba427a16c2f4873b987329c8 100644 (file)
@@ -1404,11 +1404,22 @@ enum {
 };
 #define PMCRAID_AEN_CMD_MAX (__PMCRAID_AEN_CMD_MAX - 1)
 
+static struct genl_multicast_group pmcraid_mcgrps[] = {
+       { .name = "events", /* not really used - see ID discussion below */ },
+};
+
 static struct genl_family pmcraid_event_family = {
-       .id = GENL_ID_GENERATE,
+       /*
+        * Due to prior multicast group abuse (the code having assumed that
+        * the family ID can be used as a multicast group ID) we need to
+        * statically allocate a family (and thus group) ID.
+        */
+       .id = GENL_ID_PMCRAID,
        .name = "pmcraid",
        .version = 1,
-       .maxattr = PMCRAID_AEN_ATTR_MAX
+       .maxattr = PMCRAID_AEN_ATTR_MAX,
+       .mcgrps = pmcraid_mcgrps,
+       .n_mcgrps = ARRAY_SIZE(pmcraid_mcgrps),
 };
 
 /**
@@ -1511,9 +1522,8 @@ static int pmcraid_notify_aen(
                return result;
        }
 
-       result =
-               genlmsg_multicast(&pmcraid_event_family, skb, 0,
-                                 pmcraid_event_family.id, GFP_ATOMIC);
+       result = genlmsg_multicast(&pmcraid_event_family, skb,
+                                  0, 0, GFP_ATOMIC);
 
        /* If there are no listeners, genlmsg_multicast may return non-zero
         * value.
@@ -4315,6 +4325,7 @@ static struct scsi_host_template pmcraid_host_template = {
        .this_id = -1,
        .sg_tablesize = PMCRAID_MAX_IOADLS,
        .max_sectors = PMCRAID_IOA_MAX_SECTORS,
+       .no_write_same = 1,
        .cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN,
        .use_clustering = ENABLE_CLUSTERING,
        .shost_attrs = pmcraid_host_attrs,
index 5f174b83f56fb3dab862d01aa56a3e72935a941a..570c7fcc0c4df5dff1c805754757c598e5cb311d 100644 (file)
@@ -862,7 +862,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
 }
 
 void
-qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
+qla2x00_free_sysfs_attr(scsi_qla_host_t *vha, bool stop_beacon)
 {
        struct Scsi_Host *host = vha->host;
        struct sysfs_entry *iter;
@@ -880,7 +880,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
                    iter->attr);
        }
 
-       if (ha->beacon_blink_led == 1)
+       if (stop_beacon && ha->beacon_blink_led == 1)
                ha->isp_ops->beacon_off(vha);
 }
 
@@ -890,7 +890,7 @@ static ssize_t
 qla2x00_drvr_version_show(struct device *dev,
                          struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);
+       return scnprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);
 }
 
 static ssize_t
@@ -901,7 +901,7 @@ qla2x00_fw_version_show(struct device *dev,
        struct qla_hw_data *ha = vha->hw;
        char fw_str[128];
 
-       return snprintf(buf, PAGE_SIZE, "%s\n",
+       return scnprintf(buf, PAGE_SIZE, "%s\n",
            ha->isp_ops->fw_version_str(vha, fw_str));
 }
 
@@ -914,15 +914,15 @@ qla2x00_serial_num_show(struct device *dev, struct device_attribute *attr,
        uint32_t sn;
 
        if (IS_QLAFX00(vha->hw)) {
-               return snprintf(buf, PAGE_SIZE, "%s\n",
+               return scnprintf(buf, PAGE_SIZE, "%s\n",
                    vha->hw->mr.serial_num);
        } else if (IS_FWI2_CAPABLE(ha)) {
-               qla2xxx_get_vpd_field(vha, "SN", buf, PAGE_SIZE);
-               return snprintf(buf, PAGE_SIZE, "%s\n", buf);
+               qla2xxx_get_vpd_field(vha, "SN", buf, PAGE_SIZE - 1);
+               return strlen(strcat(buf, "\n"));
        }
 
        sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
-       return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000,
+       return scnprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000,
            sn % 100000);
 }
 
@@ -931,7 +931,7 @@ qla2x00_isp_name_show(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
-       return snprintf(buf, PAGE_SIZE, "ISP%04X\n", vha->hw->pdev->device);
+       return scnprintf(buf, PAGE_SIZE, "ISP%04X\n", vha->hw->pdev->device);
 }
 
 static ssize_t
@@ -942,10 +942,10 @@ qla2x00_isp_id_show(struct device *dev, struct device_attribute *attr,
        struct qla_hw_data *ha = vha->hw;
 
        if (IS_QLAFX00(vha->hw))
-               return snprintf(buf, PAGE_SIZE, "%s\n",
+               return scnprintf(buf, PAGE_SIZE, "%s\n",
                    vha->hw->mr.hw_version);
 
-       return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
+       return scnprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
            ha->product_id[0], ha->product_id[1], ha->product_id[2],
            ha->product_id[3]);
 }
@@ -956,11 +956,7 @@ qla2x00_model_name_show(struct device *dev, struct device_attribute *attr,
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 
-       if (IS_QLAFX00(vha->hw))
-               return snprintf(buf, PAGE_SIZE, "%s\n",
-                   vha->hw->mr.product_name);
-
-       return snprintf(buf, PAGE_SIZE, "%s\n", vha->hw->model_number);
+       return scnprintf(buf, PAGE_SIZE, "%s\n", vha->hw->model_number);
 }
 
 static ssize_t
@@ -968,7 +964,7 @@ qla2x00_model_desc_show(struct device *dev, struct device_attribute *attr,
                        char *buf)
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
-       return snprintf(buf, PAGE_SIZE, "%s\n",
+       return scnprintf(buf, PAGE_SIZE, "%s\n",
            vha->hw->model_desc ? vha->hw->model_desc : "");
 }
 
@@ -979,7 +975,7 @@ qla2x00_pci_info_show(struct device *dev, struct device_attribute *attr,
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
        char pci_info[30];
 
-       return snprintf(buf, PAGE_SIZE, "%s\n",
+       return scnprintf(buf, PAGE_SIZE, "%s\n",
            vha->hw->isp_ops->pci_info_str(vha, pci_info));
 }
 
@@ -994,29 +990,29 @@ qla2x00_link_state_show(struct device *dev, struct device_attribute *attr,
        if (atomic_read(&vha->loop_state) == LOOP_DOWN ||
            atomic_read(&vha->loop_state) == LOOP_DEAD ||
            vha->device_flags & DFLG_NO_CABLE)
-               len = snprintf(buf, PAGE_SIZE, "Link Down\n");
+               len = scnprintf(buf, PAGE_SIZE, "Link Down\n");
        else if (atomic_read(&vha->loop_state) != LOOP_READY ||
            qla2x00_reset_active(vha))
-               len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
+               len = scnprintf(buf, PAGE_SIZE, "Unknown Link State\n");
        else {
-               len = snprintf(buf, PAGE_SIZE, "Link Up - ");
+               len = scnprintf(buf, PAGE_SIZE, "Link Up - ");
 
                switch (ha->current_topology) {
                case ISP_CFG_NL:
-                       len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
+                       len += scnprintf(buf + len, PAGE_SIZE-len, "Loop\n");
                        break;
                case ISP_CFG_FL:
-                       len += snprintf(buf + len, PAGE_SIZE-len, "FL_Port\n");
+                       len += scnprintf(buf + len, PAGE_SIZE-len, "FL_Port\n");
                        break;
                case ISP_CFG_N:
-                       len += snprintf(buf + len, PAGE_SIZE-len,
+                       len += scnprintf(buf + len, PAGE_SIZE-len,
                            "N_Port to N_Port\n");
                        break;
                case ISP_CFG_F:
-                       len += snprintf(buf + len, PAGE_SIZE-len, "F_Port\n");
+                       len += scnprintf(buf + len, PAGE_SIZE-len, "F_Port\n");
                        break;
                default:
-                       len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
+                       len += scnprintf(buf + len, PAGE_SIZE-len, "Loop\n");
                        break;
                }
        }
@@ -1032,10 +1028,10 @@ qla2x00_zio_show(struct device *dev, struct device_attribute *attr,
 
        switch (vha->hw->zio_mode) {
        case QLA_ZIO_MODE_6:
-               len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n");
+               len += scnprintf(buf + len, PAGE_SIZE-len, "Mode 6\n");
                break;
        case QLA_ZIO_DISABLED:
-               len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
+               len += scnprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
                break;
        }
        return len;
@@ -1075,7 +1071,7 @@ qla2x00_zio_timer_show(struct device *dev, struct device_attribute *attr,
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 
-       return snprintf(buf, PAGE_SIZE, "%d us\n", vha->hw->zio_timer * 100);
+       return scnprintf(buf, PAGE_SIZE, "%d us\n", vha->hw->zio_timer * 100);
 }
 
 static ssize_t
@@ -1105,9 +1101,9 @@ qla2x00_beacon_show(struct device *dev, struct device_attribute *attr,
        int len = 0;
 
        if (vha->hw->beacon_blink_led)
-               len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n");
+               len += scnprintf(buf + len, PAGE_SIZE-len, "Enabled\n");
        else
-               len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
+               len += scnprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
        return len;
 }
 
@@ -1149,7 +1145,7 @@ qla2x00_optrom_bios_version_show(struct device *dev,
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
        struct qla_hw_data *ha = vha->hw;
-       return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1],
+       return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1],
            ha->bios_revision[0]);
 }
 
@@ -1159,7 +1155,7 @@ qla2x00_optrom_efi_version_show(struct device *dev,
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
        struct qla_hw_data *ha = vha->hw;
-       return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1],
+       return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1],
            ha->efi_revision[0]);
 }
 
@@ -1169,7 +1165,7 @@ qla2x00_optrom_fcode_version_show(struct device *dev,
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
        struct qla_hw_data *ha = vha->hw;
-       return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1],
+       return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1],
            ha->fcode_revision[0]);
 }
 
@@ -1179,7 +1175,7 @@ qla2x00_optrom_fw_version_show(struct device *dev,
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
        struct qla_hw_data *ha = vha->hw;
-       return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n",
+       return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n",
            ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2],
            ha->fw_revision[3]);
 }
@@ -1192,9 +1188,9 @@ qla2x00_optrom_gold_fw_version_show(struct device *dev,
        struct qla_hw_data *ha = vha->hw;
 
        if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
-               return snprintf(buf, PAGE_SIZE, "\n");
+               return scnprintf(buf, PAGE_SIZE, "\n");
 
-       return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n",
+       return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n",
            ha->gold_fw_version[0], ha->gold_fw_version[1],
            ha->gold_fw_version[2], ha->gold_fw_version[3]);
 }
@@ -1204,7 +1200,7 @@ qla2x00_total_isp_aborts_show(struct device *dev,
                              struct device_attribute *attr, char *buf)
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
-       return snprintf(buf, PAGE_SIZE, "%d\n",
+       return scnprintf(buf, PAGE_SIZE, "%d\n",
            vha->qla_stats.total_isp_aborts);
 }
 
@@ -1218,16 +1214,16 @@ qla24xx_84xx_fw_version_show(struct device *dev,
        struct qla_hw_data *ha = vha->hw;
 
        if (!IS_QLA84XX(ha))
-               return snprintf(buf, PAGE_SIZE, "\n");
+               return scnprintf(buf, PAGE_SIZE, "\n");
 
        if (ha->cs84xx->op_fw_version == 0)
                rval = qla84xx_verify_chip(vha, status);
 
        if ((rval == QLA_SUCCESS) && (status[0] == 0))
-               return snprintf(buf, PAGE_SIZE, "%u\n",
+               return scnprintf(buf, PAGE_SIZE, "%u\n",
                        (uint32_t)ha->cs84xx->op_fw_version);
 
-       return snprintf(buf, PAGE_SIZE, "\n");
+       return scnprintf(buf, PAGE_SIZE, "\n");
 }
 
 static ssize_t
@@ -1238,9 +1234,9 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
        struct qla_hw_data *ha = vha->hw;
 
        if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
-               return snprintf(buf, PAGE_SIZE, "\n");
+               return scnprintf(buf, PAGE_SIZE, "\n");
 
-       return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
+       return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
            ha->mpi_version[0], ha->mpi_version[1], ha->mpi_version[2],
            ha->mpi_capabilities);
 }
@@ -1253,9 +1249,9 @@ qla2x00_phy_version_show(struct device *dev, struct device_attribute *attr,
        struct qla_hw_data *ha = vha->hw;
 
        if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
-               return snprintf(buf, PAGE_SIZE, "\n");
+               return scnprintf(buf, PAGE_SIZE, "\n");
 
-       return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
+       return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
            ha->phy_version[0], ha->phy_version[1], ha->phy_version[2]);
 }
 
@@ -1266,7 +1262,7 @@ qla2x00_flash_block_size_show(struct device *dev,
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
        struct qla_hw_data *ha = vha->hw;
 
-       return snprintf(buf, PAGE_SIZE, "0x%x\n", ha->fdt_block_size);
+       return scnprintf(buf, PAGE_SIZE, "0x%x\n", ha->fdt_block_size);
 }
 
 static ssize_t
@@ -1276,9 +1272,9 @@ qla2x00_vlan_id_show(struct device *dev, struct device_attribute *attr,
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 
        if (!IS_CNA_CAPABLE(vha->hw))
-               return snprintf(buf, PAGE_SIZE, "\n");
+               return scnprintf(buf, PAGE_SIZE, "\n");
 
-       return snprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id);
+       return scnprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id);
 }
 
 static ssize_t
@@ -1288,9 +1284,9 @@ qla2x00_vn_port_mac_address_show(struct device *dev,
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 
        if (!IS_CNA_CAPABLE(vha->hw))
-               return snprintf(buf, PAGE_SIZE, "\n");
+               return scnprintf(buf, PAGE_SIZE, "\n");
 
-       return snprintf(buf, PAGE_SIZE, "%pMR\n", vha->fcoe_vn_port_mac);
+       return scnprintf(buf, PAGE_SIZE, "%pMR\n", vha->fcoe_vn_port_mac);
 }
 
 static ssize_t
@@ -1299,7 +1295,7 @@ qla2x00_fabric_param_show(struct device *dev, struct device_attribute *attr,
 {
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 
-       return snprintf(buf, PAGE_SIZE, "%d\n", vha->hw->switch_cap);
+       return scnprintf(buf, PAGE_SIZE, "%d\n", vha->hw->switch_cap);
 }
 
 static ssize_t
@@ -1320,10 +1316,10 @@ qla2x00_thermal_temp_show(struct device *dev,
        }
 
        if (qla2x00_get_thermal_temp(vha, &temp) == QLA_SUCCESS)
-               return snprintf(buf, PAGE_SIZE, "%d\n", temp);
+               return scnprintf(buf, PAGE_SIZE, "%d\n", temp);
 
 done:
-       return snprintf(buf, PAGE_SIZE, "\n");
+       return scnprintf(buf, PAGE_SIZE, "\n");
 }
 
 static ssize_t
@@ -1337,7 +1333,7 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
 
        if (IS_QLAFX00(vha->hw)) {
                pstate = qlafx00_fw_state_show(dev, attr, buf);
-               return snprintf(buf, PAGE_SIZE, "0x%x\n", pstate);
+               return scnprintf(buf, PAGE_SIZE, "0x%x\n", pstate);
        }
 
        if (qla2x00_reset_active(vha))
@@ -1348,7 +1344,7 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
        if (rval != QLA_SUCCESS)
                memset(state, -1, sizeof(state));
 
-       return snprintf(buf, PAGE_SIZE, "0x%x 0x%x 0x%x 0x%x 0x%x\n", state[0],
+       return scnprintf(buf, PAGE_SIZE, "0x%x 0x%x 0x%x 0x%x 0x%x\n", state[0],
            state[1], state[2], state[3], state[4]);
 }
 
@@ -1359,9 +1355,9 @@ qla2x00_diag_requests_show(struct device *dev,
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 
        if (!IS_BIDI_CAPABLE(vha->hw))
-               return snprintf(buf, PAGE_SIZE, "\n");
+               return scnprintf(buf, PAGE_SIZE, "\n");
 
-       return snprintf(buf, PAGE_SIZE, "%llu\n", vha->bidi_stats.io_count);
+       return scnprintf(buf, PAGE_SIZE, "%llu\n", vha->bidi_stats.io_count);
 }
 
 static ssize_t
@@ -1371,9 +1367,9 @@ qla2x00_diag_megabytes_show(struct device *dev,
        scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 
        if (!IS_BIDI_CAPABLE(vha->hw))
-               return snprintf(buf, PAGE_SIZE, "\n");
+               return scnprintf(buf, PAGE_SIZE, "\n");
 
-       return snprintf(buf, PAGE_SIZE, "%llu\n",
+       return scnprintf(buf, PAGE_SIZE, "%llu\n",
            vha->bidi_stats.transfer_bytes >> 20);
 }
 
@@ -1392,7 +1388,7 @@ qla2x00_fw_dump_size_show(struct device *dev, struct device_attribute *attr,
        else
                size = ha->fw_dump_len;
 
-       return snprintf(buf, PAGE_SIZE, "%d\n", size);
+       return scnprintf(buf, PAGE_SIZE, "%d\n", size);
 }
 
 static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
index aa57bf0af574e872ab6e00dae36f7fe4df1a2199..f15d03e6b7eeb1fb98612eaa7b1eafedfc8b7ec5 100644 (file)
@@ -2021,6 +2021,46 @@ done:
        return rval;
 }
 
+static int
+qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
+{
+       struct Scsi_Host *host = bsg_job->shost;
+       scsi_qla_host_t *vha = shost_priv(host);
+       int rval = 0;
+       struct qla_serdes_reg sr;
+
+       memset(&sr, 0, sizeof(sr));
+
+       sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+           bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
+
+       switch (sr.cmd) {
+       case INT_SC_SERDES_WRITE_REG:
+               rval = qla2x00_write_serdes_word(vha, sr.addr, sr.val);
+               bsg_job->reply->reply_payload_rcv_len = 0;
+               break;
+       case INT_SC_SERDES_READ_REG:
+               rval = qla2x00_read_serdes_word(vha, sr.addr, &sr.val);
+               sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
+                   bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
+               bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
+               break;
+       default:
+               ql_log(ql_log_warn, vha, 0x708c,
+                   "Unknown serdes cmd %x.\n", sr.cmd);
+               rval = -EDOM;
+               break;
+       }
+
+       bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+           rval ? EXT_STATUS_MAILBOX : 0;
+
+       bsg_job->reply_len = sizeof(struct fc_bsg_reply);
+       bsg_job->reply->result = DID_OK << 16;
+       bsg_job->job_done(bsg_job);
+       return 0;
+}
+
 static int
 qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
 {
@@ -2069,6 +2109,10 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
 
        case QL_VND_FX00_MGMT_CMD:
                return qlafx00_mgmt_cmd(bsg_job);
+
+       case QL_VND_SERDES_OP:
+               return qla26xx_serdes_op(bsg_job);
+
        default:
                return -ENOSYS;
        }
index 04f770332c2b805022fa09110aea2732b7f8a058..e5c2126221e9359b406d5488df6d1d31a1739195 100644 (file)
@@ -23,6 +23,7 @@
 #define QL_VND_WRITE_I2C       0x10
 #define QL_VND_READ_I2C                0x11
 #define QL_VND_FX00_MGMT_CMD   0x12
+#define QL_VND_SERDES_OP       0x13
 
 /* BSG Vendor specific subcode returns */
 #define EXT_STATUS_OK                  0
@@ -212,4 +213,16 @@ struct qla_i2c_access {
        uint8_t  buffer[0x40];
 } __packed;
 
+/* 26xx serdes register interface */
+
+/* serdes reg commands */
+#define INT_SC_SERDES_READ_REG         1
+#define INT_SC_SERDES_WRITE_REG                2
+
+struct qla_serdes_reg {
+       uint16_t cmd;
+       uint16_t addr;
+       uint16_t val;
+} __packed;
+
 #endif
index ee5c1833eb731cb1e0e731448c287ca1b8f5b2ad..f6103f553bb1b648fac1755add363c661d454295 100644 (file)
@@ -11,8 +11,9 @@
  * ----------------------------------------------------------------------
  * |             Level            |   Last Value Used  |     Holes     |
  * ----------------------------------------------------------------------
- * | Module Init and Probe        |       0x0159       | 0x4b,0xba,0xfa |
- * | Mailbox commands             |       0x1181       | 0x111a-0x111b  |
+ * | Module Init and Probe        |       0x015b       | 0x4b,0xba,0xfa |
+ * |                              |                    | 0x0x015a      |
+ * | Mailbox commands             |       0x1187       | 0x111a-0x111b  |
  * |                              |                    | 0x1155-0x1158  |
  * |                              |                    | 0x1018-0x1019  |
  * |                              |                    | 0x1115-0x1116  |
@@ -26,7 +27,7 @@
  * |                              |                    | 0x302d,0x3033  |
  * |                              |                    | 0x3036,0x3038  |
  * |                              |                    | 0x303a                |
- * | DPC Thread                   |       0x4022       | 0x4002,0x4013  |
+ * | DPC Thread                   |       0x4023       | 0x4002,0x4013  |
  * | Async Events                 |       0x5087       | 0x502b-0x502f  |
  * |                              |                    | 0x5047,0x5052  |
  * |                              |                    | 0x5084,0x5075 |
index 93db74ef346117a1fc419b3f836948cfa8056150..41d6491d7bd9ec9e376ef93c710774b793df6889 100644 (file)
@@ -862,7 +862,6 @@ struct mbx_cmd_32 {
  */
 #define MBC_LOAD_RAM                   1       /* Load RAM. */
 #define MBC_EXECUTE_FIRMWARE           2       /* Execute firmware. */
-#define MBC_WRITE_RAM_WORD             4       /* Write RAM word. */
 #define MBC_READ_RAM_WORD              5       /* Read RAM word. */
 #define MBC_MAILBOX_REGISTER_TEST      6       /* Wrap incoming mailboxes */
 #define MBC_VERIFY_CHECKSUM            7       /* Verify checksum. */
@@ -937,6 +936,8 @@ struct mbx_cmd_32 {
 /*
  * ISP24xx mailbox commands
  */
+#define MBC_WRITE_SERDES               0x3     /* Write serdes word. */
+#define MBC_READ_SERDES                        0x4     /* Read serdes word. */
 #define MBC_SERDES_PARAMS              0x10    /* Serdes Tx Parameters. */
 #define MBC_GET_IOCB_STATUS            0x12    /* Get IOCB status command. */
 #define MBC_PORT_PARAMS                        0x1A    /* Port iDMA Parameters. */
@@ -2734,7 +2735,6 @@ struct req_que {
        srb_t **outstanding_cmds;
        uint32_t current_outstanding_cmd;
        uint16_t num_outstanding_cmds;
-#define        MAX_Q_DEPTH             32
        int max_q_depth;
 
        dma_addr_t  dma_fx00;
@@ -3302,12 +3302,7 @@ struct qla_hw_data {
        struct work_struct nic_core_reset;
        struct work_struct idc_state_handler;
        struct work_struct nic_core_unrecoverable;
-
-#define HOST_QUEUE_RAMPDOWN_INTERVAL           (60 * HZ)
-#define HOST_QUEUE_RAMPUP_INTERVAL             (30 * HZ)
-       unsigned long   host_last_rampdown_time;
-       unsigned long   host_last_rampup_time;
-       int             cfg_lun_q_depth;
+       struct work_struct board_disable;
 
        struct mr_data_fx00 mr;
 
@@ -3372,12 +3367,11 @@ typedef struct scsi_qla_host {
 #define MPI_RESET_NEEDED       19      /* Initiate MPI FW reset */
 #define ISP_QUIESCE_NEEDED     20      /* Driver need some quiescence */
 #define SCR_PENDING            21      /* SCR in target mode */
-#define HOST_RAMP_DOWN_QUEUE_DEPTH     22
-#define HOST_RAMP_UP_QUEUE_DEPTH       23
-#define PORT_UPDATE_NEEDED     24
-#define FX00_RESET_RECOVERY    25
-#define FX00_TARGET_SCAN       26
-#define FX00_CRITEMP_RECOVERY  27
+#define PORT_UPDATE_NEEDED     22
+#define FX00_RESET_RECOVERY    23
+#define FX00_TARGET_SCAN       24
+#define FX00_CRITEMP_RECOVERY  25
+#define FX00_HOST_INFO_RESEND  26
 
        uint32_t        device_flags;
 #define SWITCH_FOUND           BIT_0
index 4446bf5fe2921dafe7ccafa23fb73589446020c8..00427e0ff5b2ae3370809f3a9433ba24d116aef3 100644 (file)
@@ -98,7 +98,6 @@ extern int qlport_down_retry;
 extern int ql2xplogiabsentdevice;
 extern int ql2xloginretrycount;
 extern int ql2xfdmienable;
-extern int ql2xmaxqdepth;
 extern int ql2xallocfwdump;
 extern int ql2xextended_error_logging;
 extern int ql2xiidmaenable;
@@ -160,6 +159,9 @@ extern int qla83xx_clear_drv_presence(scsi_qla_host_t *vha);
 extern int __qla83xx_clear_drv_presence(scsi_qla_host_t *vha);
 extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
 
+extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
+extern void qla2x00_disable_board_on_pci_error(struct work_struct *);
+
 /*
  * Global Functions in qla_mid.c source file.
  */
@@ -338,6 +340,11 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *, unsigned int,
 extern int
 qla2x00_system_error(scsi_qla_host_t *);
 
+extern int
+qla2x00_write_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t);
+extern int
+qla2x00_read_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t *);
+
 extern int
 qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
 
@@ -455,6 +462,7 @@ extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
 extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
                                    uint32_t);
 extern int qla2x00_is_a_vp_did(scsi_qla_host_t *, uint32_t);
+bool qla2x00_check_reg_for_disconnect(scsi_qla_host_t *, uint32_t);
 
 extern int qla2x00_beacon_on(struct scsi_qla_host *);
 extern int qla2x00_beacon_off(struct scsi_qla_host *);
@@ -541,10 +549,9 @@ struct fc_function_template;
 extern struct fc_function_template qla2xxx_transport_functions;
 extern struct fc_function_template qla2xxx_transport_vport_functions;
 extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
-extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
+extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *, bool);
 extern void qla2x00_init_host_attr(scsi_qla_host_t *);
 extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
-extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
 extern int qla2x00_loopback_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *);
 extern int qla2x00_echo_test(scsi_qla_host_t *,
        struct msg_echo_lb *, uint16_t *);
index 03f715e7591e75409a04c2a31d3bb015105d0bd1..e7e5f4facf7f3c9850764b34aa5f0ac067d63351 100644 (file)
@@ -1694,6 +1694,8 @@ enable_82xx_npiv:
                                if (!fw_major_version && ql2xallocfwdump
                                    && !(IS_P3P_TYPE(ha)))
                                        qla2x00_alloc_fw_dump(vha);
+                       } else {
+                               goto failed;
                        }
                } else {
                        ql_log(ql_log_fatal, vha, 0x00cd,
index 957088b0461141c27d8260ed58d9cbd1e998fcc5..ce8b5fb0f347c46127d4b0a6077255db202c561f 100644 (file)
@@ -260,25 +260,6 @@ qla2x00_gid_list_size(struct qla_hw_data *ha)
                return sizeof(struct gid_list_info) * ha->max_fibre_devices;
 }
 
-static inline void
-qla2x00_do_host_ramp_up(scsi_qla_host_t *vha)
-{
-       if (vha->hw->cfg_lun_q_depth >= ql2xmaxqdepth)
-               return;
-
-       /* Wait at least HOST_QUEUE_RAMPDOWN_INTERVAL before ramping up */
-       if (time_before(jiffies, (vha->hw->host_last_rampdown_time +
-           HOST_QUEUE_RAMPDOWN_INTERVAL)))
-               return;
-
-       /* Wait at least HOST_QUEUE_RAMPUP_INTERVAL between each ramp up */
-       if (time_before(jiffies, (vha->hw->host_last_rampup_time +
-           HOST_QUEUE_RAMPUP_INTERVAL)))
-               return;
-
-       set_bit(HOST_RAMP_UP_QUEUE_DEPTH, &vha->dpc_flags);
-}
-
 static inline void
 qla2x00_handle_mbx_completion(struct qla_hw_data *ha, int status)
 {
index ff9c86b1a0d896a870dd62b22515ee5dfc629284..9bc86b9e86b172145443d161e0715658df6acdc7 100644 (file)
@@ -56,6 +56,16 @@ qla2100_intr_handler(int irq, void *dev_id)
        vha = pci_get_drvdata(ha->pdev);
        for (iter = 50; iter--; ) {
                hccr = RD_REG_WORD(&reg->hccr);
+               /* Check for PCI disconnection */
+               if (hccr == 0xffff) {
+                       /*
+                        * Schedule this on the default system workqueue so that
+                        * all the adapter workqueues and the DPC thread can be
+                        * shutdown cleanly.
+                        */
+                       schedule_work(&ha->board_disable);
+                       break;
+               }
                if (hccr & HCCR_RISC_PAUSE) {
                        if (pci_channel_offline(ha->pdev))
                                break;
@@ -110,6 +120,22 @@ qla2100_intr_handler(int irq, void *dev_id)
        return (IRQ_HANDLED);
 }
 
+bool
+qla2x00_check_reg_for_disconnect(scsi_qla_host_t *vha, uint32_t reg)
+{
+       /* Check for PCI disconnection */
+       if (reg == 0xffffffff) {
+               /*
+                * Schedule this on the default system workqueue so that all the
+                * adapter workqueues and the DPC thread can be shutdown
+                * cleanly.
+                */
+               schedule_work(&vha->hw->board_disable);
+               return true;
+       } else
+               return false;
+}
+
 /**
  * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
  * @irq:
@@ -148,11 +174,14 @@ qla2300_intr_handler(int irq, void *dev_id)
        vha = pci_get_drvdata(ha->pdev);
        for (iter = 50; iter--; ) {
                stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
+               if (qla2x00_check_reg_for_disconnect(vha, stat))
+                       break;
                if (stat & HSR_RISC_PAUSED) {
                        if (unlikely(pci_channel_offline(ha->pdev)))
                                break;
 
                        hccr = RD_REG_WORD(&reg->hccr);
+
                        if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8))
                                ql_log(ql_log_warn, vha, 0x5026,
                                    "Parity error -- HCCR=%x, Dumping "
@@ -269,11 +298,18 @@ qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr)
                { "Complete", "Request Notification", "Time Extension" };
        int rval;
        struct device_reg_24xx __iomem *reg24 = &vha->hw->iobase->isp24;
+       struct device_reg_82xx __iomem *reg82 = &vha->hw->iobase->isp82;
        uint16_t __iomem *wptr;
        uint16_t cnt, timeout, mb[QLA_IDC_ACK_REGS];
 
        /* Seed data -- mailbox1 -> mailbox7. */
-       wptr = (uint16_t __iomem *)&reg24->mailbox1;
+       if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw))
+               wptr = (uint16_t __iomem *)&reg24->mailbox1;
+       else if (IS_QLA8044(vha->hw))
+               wptr = (uint16_t __iomem *)&reg82->mailbox_out[1];
+       else
+               return;
+
        for (cnt = 0; cnt < QLA_IDC_ACK_REGS; cnt++, wptr++)
                mb[cnt] = RD_REG_WORD(wptr);
 
@@ -287,7 +323,7 @@ qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr)
        case MBA_IDC_COMPLETE:
                if (mb[1] >> 15) {
                        vha->hw->flags.idc_compl_status = 1;
-                       if (vha->hw->notify_dcbx_comp)
+                       if (vha->hw->notify_dcbx_comp && !vha->vp_idx)
                                complete(&vha->hw->dcbx_comp);
                }
                break;
@@ -758,7 +794,7 @@ skip_rio:
                        ql_dbg(ql_dbg_async, vha, 0x500d,
                            "DCBX Completed -- %04x %04x %04x.\n",
                            mb[1], mb[2], mb[3]);
-                       if (ha->notify_dcbx_comp)
+                       if (ha->notify_dcbx_comp && !vha->vp_idx)
                                complete(&ha->dcbx_comp);
 
                } else
@@ -1032,7 +1068,7 @@ skip_rio:
                        }
                }
        case MBA_IDC_COMPLETE:
-               if (ha->notify_lb_portup_comp)
+               if (ha->notify_lb_portup_comp && !vha->vp_idx)
                        complete(&ha->lb_portup_comp);
                /* Fallthru */
        case MBA_IDC_TIME_EXT:
@@ -1991,7 +2027,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 
        /* Fast path completion. */
        if (comp_status == CS_COMPLETE && scsi_status == 0) {
-               qla2x00_do_host_ramp_up(vha);
                qla2x00_process_completed_request(vha, req, handle);
 
                return;
@@ -2250,9 +2285,6 @@ out:
                    cp->cmnd, scsi_bufflen(cp), rsp_info_len,
                    resid_len, fw_resid_len);
 
-       if (!res)
-               qla2x00_do_host_ramp_up(vha);
-
        if (rsp->status_srb == NULL)
                sp->done(ha, sp, res);
 }
@@ -2575,6 +2607,8 @@ qla24xx_intr_handler(int irq, void *dev_id)
        vha = pci_get_drvdata(ha->pdev);
        for (iter = 50; iter--; ) {
                stat = RD_REG_DWORD(&reg->host_status);
+               if (qla2x00_check_reg_for_disconnect(vha, stat))
+                       break;
                if (stat & HSRX_RISC_PAUSED) {
                        if (unlikely(pci_channel_offline(ha->pdev)))
                                break;
@@ -2644,6 +2678,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
        struct device_reg_24xx __iomem *reg;
        struct scsi_qla_host *vha;
        unsigned long flags;
+       uint32_t stat = 0;
 
        rsp = (struct rsp_que *) dev_id;
        if (!rsp) {
@@ -2657,11 +2692,19 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
        vha = pci_get_drvdata(ha->pdev);
+       /*
+        * Use host_status register to check to PCI disconnection before we
+        * we process the response queue.
+        */
+       stat = RD_REG_DWORD(&reg->host_status);
+       if (qla2x00_check_reg_for_disconnect(vha, stat))
+               goto out;
        qla24xx_process_response_queue(vha, rsp);
        if (!ha->flags.disable_msix_handshake) {
                WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
                RD_REG_DWORD_RELAXED(&reg->hccr);
        }
+out:
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        return IRQ_HANDLED;
@@ -2671,9 +2714,11 @@ static irqreturn_t
 qla25xx_msix_rsp_q(int irq, void *dev_id)
 {
        struct qla_hw_data *ha;
+       scsi_qla_host_t *vha;
        struct rsp_que *rsp;
        struct device_reg_24xx __iomem *reg;
        unsigned long flags;
+       uint32_t hccr = 0;
 
        rsp = (struct rsp_que *) dev_id;
        if (!rsp) {
@@ -2682,17 +2727,21 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
                return IRQ_NONE;
        }
        ha = rsp->hw;
+       vha = pci_get_drvdata(ha->pdev);
 
        /* Clear the interrupt, if enabled, for this response queue */
        if (!ha->flags.disable_msix_handshake) {
                reg = &ha->iobase->isp24;
                spin_lock_irqsave(&ha->hardware_lock, flags);
                WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
-               RD_REG_DWORD_RELAXED(&reg->hccr);
+               hccr = RD_REG_DWORD_RELAXED(&reg->hccr);
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
        }
+       if (qla2x00_check_reg_for_disconnect(vha, hccr))
+               goto out;
        queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work);
 
+out:
        return IRQ_HANDLED;
 }
 
@@ -2723,6 +2772,8 @@ qla24xx_msix_default(int irq, void *dev_id)
        vha = pci_get_drvdata(ha->pdev);
        do {
                stat = RD_REG_DWORD(&reg->host_status);
+               if (qla2x00_check_reg_for_disconnect(vha, stat))
+                       break;
                if (stat & HSRX_RISC_PAUSED) {
                        if (unlikely(pci_channel_offline(ha->pdev)))
                                break;
@@ -2937,7 +2988,7 @@ msix_out:
 int
 qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
 {
-       int ret;
+       int ret = QLA_FUNCTION_FAILED;
        device_reg_t __iomem *reg = ha->iobase;
        scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 
@@ -2971,10 +3022,12 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
                    ha->chip_revision, ha->fw_attributes);
                goto clear_risc_ints;
        }
-       ql_log(ql_log_info, vha, 0x0037,
-           "MSI-X Falling back-to MSI mode -%d.\n", ret);
+
 skip_msix:
 
+       ql_log(ql_log_info, vha, 0x0037,
+           "Falling back-to MSI mode -%d.\n", ret);
+
        if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
            !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha))
                goto skip_msi;
@@ -2986,14 +3039,13 @@ skip_msix:
                ha->flags.msi_enabled = 1;
        } else
                ql_log(ql_log_warn, vha, 0x0039,
-                   "MSI-X; Falling back-to INTa mode -- %d.\n", ret);
+                   "Falling back-to INTa mode -- %d.\n", ret);
+skip_msi:
 
        /* Skip INTx on ISP82xx. */
        if (!ha->flags.msi_enabled && IS_QLA82XX(ha))
                return QLA_FUNCTION_FAILED;
 
-skip_msi:
-
        ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
            ha->flags.msi_enabled ? 0 : IRQF_SHARED,
            QLA2XXX_DRIVER_NAME, rsp);
index a9aae500e791b2ade17ad472a462aaa89e88d351..b94511ae00514a37ac35c73e7014f93627ca720e 100644 (file)
@@ -468,7 +468,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
                mcp->mb[1] = MSW(risc_addr);
                mcp->mb[2] = LSW(risc_addr);
                mcp->mb[3] = 0;
-               if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) {
+               if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha)) {
                        struct nvram_81xx *nv = ha->nvram;
                        mcp->mb[4] = (nv->enhanced_features &
                            EXTENDED_BB_CREDITS);
@@ -1214,7 +1214,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
        mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
        mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
        mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-       if ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && ha->ex_init_cb->ex_version) {
+       if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
                mcp->mb[1] = BIT_0;
                mcp->mb[10] = MSW(ha->ex_init_cb_dma);
                mcp->mb[11] = LSW(ha->ex_init_cb_dma);
@@ -2800,6 +2800,75 @@ qla2x00_system_error(scsi_qla_host_t *vha)
        return rval;
 }
 
+int
+qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
+{
+       int rval;
+       mbx_cmd_t mc;
+       mbx_cmd_t *mcp = &mc;
+
+       if (!IS_QLA2031(vha->hw))
+               return QLA_FUNCTION_FAILED;
+
+       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
+           "Entered %s.\n", __func__);
+
+       mcp->mb[0] = MBC_WRITE_SERDES;
+       mcp->mb[1] = addr;
+       mcp->mb[2] = data & 0xff;
+       mcp->mb[3] = 0;
+       mcp->out_mb = 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, 0x1183,
+                   "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+       } else {
+               ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
+                   "Done %s.\n", __func__);
+       }
+
+       return rval;
+}
+
+int
+qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
+{
+       int rval;
+       mbx_cmd_t mc;
+       mbx_cmd_t *mcp = &mc;
+
+       if (!IS_QLA2031(vha->hw))
+               return QLA_FUNCTION_FAILED;
+
+       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
+           "Entered %s.\n", __func__);
+
+       mcp->mb[0] = MBC_READ_SERDES;
+       mcp->mb[1] = addr;
+       mcp->mb[3] = 0;
+       mcp->out_mb = MBX_3|MBX_1|MBX_0;
+       mcp->in_mb = MBX_1|MBX_0;
+       mcp->tov = MBX_TOV_SECONDS;
+       mcp->flags = 0;
+       rval = qla2x00_mailbox_command(vha, mcp);
+
+       *data = mcp->mb[1] & 0xff;
+
+       if (rval != QLA_SUCCESS) {
+               ql_dbg(ql_dbg_mbx, vha, 0x1186,
+                   "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+       } else {
+               ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
+                   "Done %s.\n", __func__);
+       }
+
+       return rval;
+}
+
 /**
  * qla2x00_set_serdes_params() -
  * @ha: HA context
index 30d20e74e48a393b3560a44bb354fb1fd058e60e..ba6f8b139c984b88a5a5396ab70e1e1109af72b6 100644 (file)
@@ -1610,6 +1610,22 @@ qlafx00_timer_routine(scsi_qla_host_t *vha)
                        ha->mr.fw_critemp_timer_tick--;
                }
        }
+       if (ha->mr.host_info_resend) {
+               /*
+                * Incomplete host info might be sent to firmware
+                * durinng system boot - info should be resend
+                */
+               if (ha->mr.hinfo_resend_timer_tick == 0) {
+                       ha->mr.host_info_resend = false;
+                       set_bit(FX00_HOST_INFO_RESEND, &vha->dpc_flags);
+                       ha->mr.hinfo_resend_timer_tick =
+                           QLAFX00_HINFO_RESEND_INTERVAL;
+                       qla2xxx_wake_dpc(vha);
+               } else {
+                       ha->mr.hinfo_resend_timer_tick--;
+               }
+       }
+
 }
 
 /*
@@ -1867,6 +1883,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
                        goto done_free_sp;
                }
                break;
+       case FXDISC_ABORT_IOCTL:
        default:
                break;
        }
@@ -1888,6 +1905,8 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
                            p_sysid->sysname, SYSNAME_LENGTH);
                        strncpy(phost_info->nodename,
                            p_sysid->nodename, NODENAME_LENGTH);
+                       if (!strcmp(phost_info->nodename, "(none)"))
+                               ha->mr.host_info_resend = true;
                        strncpy(phost_info->release,
                            p_sysid->release, RELEASE_LENGTH);
                        strncpy(phost_info->version,
@@ -1948,8 +1967,8 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
        if (fx_type == FXDISC_GET_CONFIG_INFO) {
                struct config_info_data *pinfo =
                    (struct config_info_data *) fdisc->u.fxiocb.rsp_addr;
-               memcpy(&vha->hw->mr.product_name, pinfo->product_name,
-                   sizeof(vha->hw->mr.product_name));
+               strcpy(vha->hw->model_number, pinfo->model_num);
+               strcpy(vha->hw->model_desc, pinfo->model_description);
                memcpy(&vha->hw->mr.symbolic_name, pinfo->symbolic_name,
                    sizeof(vha->hw->mr.symbolic_name));
                memcpy(&vha->hw->mr.serial_num, pinfo->serial_num,
@@ -1993,7 +2012,11 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
                ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0146,
                    (uint8_t *)pinfo, 16);
                memcpy(vha->hw->gid_list, pinfo, QLAFX00_TGT_NODE_LIST_SIZE);
-       }
+       } else if (fx_type == FXDISC_ABORT_IOCTL)
+               fdisc->u.fxiocb.result =
+                   (fdisc->u.fxiocb.result == cpu_to_le32(0x68)) ?
+                   cpu_to_le32(QLA_SUCCESS) : cpu_to_le32(QLA_FUNCTION_FAILED);
+
        rval = le32_to_cpu(fdisc->u.fxiocb.result);
 
 done_unmap_dma:
@@ -2092,6 +2115,10 @@ qlafx00_abort_command(srb_t *sp)
                /* Command not found. */
                return QLA_FUNCTION_FAILED;
        }
+       if (sp->type == SRB_FXIOCB_DCMD)
+               return qlafx00_fx_disc(vha, &vha->hw->mr.fcport,
+                   FXDISC_ABORT_IOCTL);
+
        return qlafx00_async_abt_cmd(sp);
 }
 
@@ -2419,7 +2446,6 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 
        /* Fast path completion. */
        if (comp_status == CS_COMPLETE && scsi_status == 0) {
-               qla2x00_do_host_ramp_up(vha);
                qla2x00_process_completed_request(vha, req, handle);
                return;
        }
@@ -2630,9 +2656,6 @@ check_scsi_status:
                    rsp_info_len, resid_len, fw_resid_len, sense_len,
                    par_sense_len, rsp_info_len);
 
-       if (!res)
-               qla2x00_do_host_ramp_up(vha);
-
        if (rsp->status_srb == NULL)
                sp->done(ha, sp, res);
 }
@@ -3021,6 +3044,8 @@ qlafx00_intr_handler(int irq, void *dev_id)
        vha = pci_get_drvdata(ha->pdev);
        for (iter = 50; iter--; clr_intr = 0) {
                stat = QLAFX00_RD_INTR_REG(ha);
+               if (qla2x00_check_reg_for_disconnect(vha, stat))
+                       break;
                if ((stat & QLAFX00_HST_INT_STS_BITS) == 0)
                        break;
 
index 79a93c52baec54b828f65cdeb7f602269a0a7724..6cd7072cc0fff57b8c43369a81d70f968515b0ae 100644 (file)
@@ -304,7 +304,9 @@ struct register_host_info {
 #define QLAFX00_TGT_NODE_LIST_SIZE (sizeof(uint32_t) * 32)
 
 struct config_info_data {
-       uint8_t         product_name[256];
+       uint8_t         model_num[16];
+       uint8_t         model_description[80];
+       uint8_t         reserved0[160];
        uint8_t         symbolic_name[64];
        uint8_t         serial_num[32];
        uint8_t         hw_version[16];
@@ -343,6 +345,7 @@ struct config_info_data {
 #define FXDISC_GET_TGT_NODE_INFO       0x80
 #define FXDISC_GET_TGT_NODE_LIST       0x81
 #define FXDISC_REG_HOST_INFO           0x99
+#define FXDISC_ABORT_IOCTL             0xff
 
 #define QLAFX00_HBA_ICNTRL_REG         0x20B08
 #define QLAFX00_ICR_ENB_MASK            0x80000000
@@ -490,7 +493,6 @@ struct qla_mt_iocb_rsp_fx00 {
 #define FX00_DEF_RATOV 10
 
 struct mr_data_fx00 {
-       uint8_t product_name[256];
        uint8_t symbolic_name[64];
        uint8_t serial_num[32];
        uint8_t hw_version[16];
@@ -511,6 +513,8 @@ struct mr_data_fx00 {
        uint32_t old_aenmbx0_state;
        uint32_t critical_temperature;
        bool extended_io_enabled;
+       bool host_info_resend;
+       uint8_t hinfo_resend_timer_tick;
 };
 
 #define QLAFX00_EXTENDED_IO_EN_MASK    0x20
@@ -537,7 +541,11 @@ struct mr_data_fx00 {
 #define QLAFX00_RESET_INTERVAL         120     /* number of seconds */
 #define QLAFX00_MAX_RESET_INTERVAL     600     /* number of seconds */
 #define QLAFX00_CRITEMP_INTERVAL       60      /* number of seconds */
+#define QLAFX00_HINFO_RESEND_INTERVAL  60      /* number of seconds */
 
 #define QLAFX00_CRITEMP_THRSHLD                80      /* Celsius degrees */
 
+/* Max conncurrent IOs that can be queued */
+#define QLAFX00_MAX_CANQUEUE           1024
+
 #endif
index 11ce53dcbe7e120c96cb28c1257c4a6af57f0db0..1468c59d8960f3d93af4985d27428348e2565d8a 100644 (file)
@@ -2096,6 +2096,7 @@ qla82xx_msix_default(int irq, void *dev_id)
        int status = 0;
        unsigned long flags;
        uint32_t stat = 0;
+       uint32_t host_int = 0;
        uint16_t mb[4];
 
        rsp = (struct rsp_que *) dev_id;
@@ -2111,7 +2112,10 @@ qla82xx_msix_default(int irq, void *dev_id)
        spin_lock_irqsave(&ha->hardware_lock, flags);
        vha = pci_get_drvdata(ha->pdev);
        do {
-               if (RD_REG_DWORD(&reg->host_int)) {
+               host_int = RD_REG_DWORD(&reg->host_int);
+               if (qla2x00_check_reg_for_disconnect(vha, host_int))
+                       break;
+               if (host_int) {
                        stat = RD_REG_DWORD(&reg->host_status);
 
                        switch (stat & 0xff) {
@@ -2156,6 +2160,7 @@ qla82xx_msix_rsp_q(int irq, void *dev_id)
        struct rsp_que *rsp;
        struct device_reg_82xx __iomem *reg;
        unsigned long flags;
+       uint32_t host_int = 0;
 
        rsp = (struct rsp_que *) dev_id;
        if (!rsp) {
@@ -2168,8 +2173,12 @@ qla82xx_msix_rsp_q(int irq, void *dev_id)
        reg = &ha->iobase->isp82;
        spin_lock_irqsave(&ha->hardware_lock, flags);
        vha = pci_get_drvdata(ha->pdev);
+       host_int = RD_REG_DWORD(&reg->host_int);
+       if (qla2x00_check_reg_for_disconnect(vha, host_int))
+               goto out;
        qla24xx_process_response_queue(vha, rsp);
        WRT_REG_DWORD(&reg->host_int, 0);
+out:
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
        return IRQ_HANDLED;
 }
@@ -2183,6 +2192,7 @@ qla82xx_poll(int irq, void *dev_id)
        struct device_reg_82xx __iomem *reg;
        int status = 0;
        uint32_t stat;
+       uint32_t host_int = 0;
        uint16_t mb[4];
        unsigned long flags;
 
@@ -2198,7 +2208,10 @@ qla82xx_poll(int irq, void *dev_id)
        spin_lock_irqsave(&ha->hardware_lock, flags);
        vha = pci_get_drvdata(ha->pdev);
 
-       if (RD_REG_DWORD(&reg->host_int)) {
+       host_int = RD_REG_DWORD(&reg->host_int);
+       if (qla2x00_check_reg_for_disconnect(vha, host_int))
+               goto out;
+       if (host_int) {
                stat = RD_REG_DWORD(&reg->host_status);
                switch (stat & 0xff) {
                case 0x1:
@@ -2224,8 +2237,9 @@ qla82xx_poll(int irq, void *dev_id)
                            stat * 0xff);
                        break;
                }
+               WRT_REG_DWORD(&reg->host_int, 0);
        }
-       WRT_REG_DWORD(&reg->host_int, 0);
+out:
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
index 8164cc9e7286a49a51ed31bf72201f61827213bb..cc3522fbcaa2f25adeafc673862f06d8223101af 100644 (file)
@@ -1555,6 +1555,15 @@ qla8044_need_reset_handler(struct scsi_qla_host *vha)
                qla8044_idc_lock(ha);
        }
 
+       drv_state = qla8044_rd_direct(vha,
+           QLA8044_CRB_DRV_STATE_INDEX);
+       drv_active = qla8044_rd_direct(vha,
+           QLA8044_CRB_DRV_ACTIVE_INDEX);
+
+       ql_log(ql_log_info, vha, 0xb0c5,
+           "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
+           __func__, vha->host_no, drv_state, drv_active);
+
        if (!ha->flags.nic_core_reset_owner) {
                ql_dbg(ql_dbg_p3p, vha, 0xb0c3,
                    "%s(%ld): reset acknowledged\n",
@@ -1580,23 +1589,15 @@ qla8044_need_reset_handler(struct scsi_qla_host *vha)
 
                        dev_state = qla8044_rd_direct(vha,
                                        QLA8044_CRB_DEV_STATE_INDEX);
-               } while (dev_state == QLA8XXX_DEV_NEED_RESET);
+               } while (((drv_state & drv_active) != drv_active) &&
+                   (dev_state == QLA8XXX_DEV_NEED_RESET));
        } else {
                qla8044_set_rst_ready(vha);
 
                /* wait for 10 seconds for reset ack from all functions */
                reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
 
-               drv_state = qla8044_rd_direct(vha,
-                   QLA8044_CRB_DRV_STATE_INDEX);
-               drv_active = qla8044_rd_direct(vha,
-                   QLA8044_CRB_DRV_ACTIVE_INDEX);
-
-               ql_log(ql_log_info, vha, 0xb0c5,
-                   "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
-                   __func__, vha->host_no, drv_state, drv_active);
-
-               while (drv_state != drv_active) {
+               while ((drv_state & drv_active) != drv_active) {
                        if (time_after_eq(jiffies, reset_timeout)) {
                                ql_log(ql_log_info, vha, 0xb0c6,
                                    "%s: RESET TIMEOUT!"
@@ -1859,7 +1860,7 @@ qla8044_device_state_handler(struct scsi_qla_host *vha)
                        goto exit;
                case QLA8XXX_DEV_COLD:
                        rval = qla8044_device_bootstrap(vha);
-                       goto exit;
+                       break;
                case QLA8XXX_DEV_INITIALIZING:
                        qla8044_idc_unlock(ha);
                        msleep(1000);
index 52be35e0300c901ac18faff6ded2aaf65e43b675..20d58be7b8d570c0b2b32614ef8acbb176673caa 100644 (file)
@@ -110,7 +110,8 @@ MODULE_PARM_DESC(ql2xfdmienable,
                "Enables FDMI registrations. "
                "0 - no FDMI. Default is 1 - perform FDMI.");
 
-int ql2xmaxqdepth = MAX_Q_DEPTH;
+#define MAX_Q_DEPTH    32
+static int ql2xmaxqdepth = MAX_Q_DEPTH;
 module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(ql2xmaxqdepth,
                "Maximum queue depth to set for each LUN. "
@@ -728,10 +729,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
        }
 
        sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
-       if (!sp) {
-               set_bit(HOST_RAMP_DOWN_QUEUE_DEPTH, &vha->dpc_flags);
+       if (!sp)
                goto qc24_host_busy;
-       }
 
        sp->u.scmd.cmd = cmd;
        sp->type = SRB_SCSI_CMD;
@@ -744,7 +743,6 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
        if (rval != QLA_SUCCESS) {
                ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3013,
                    "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd);
-               set_bit(HOST_RAMP_DOWN_QUEUE_DEPTH, &vha->dpc_flags);
                goto qc24_host_busy_free_sp;
        }
 
@@ -1474,81 +1472,6 @@ qla2x00_change_queue_type(struct scsi_device *sdev, int tag_type)
        return tag_type;
 }
 
-static void
-qla2x00_host_ramp_down_queuedepth(scsi_qla_host_t *vha)
-{
-       scsi_qla_host_t *vp;
-       struct Scsi_Host *shost;
-       struct scsi_device *sdev;
-       struct qla_hw_data *ha = vha->hw;
-       unsigned long flags;
-
-       ha->host_last_rampdown_time = jiffies;
-
-       if (ha->cfg_lun_q_depth <= vha->host->cmd_per_lun)
-               return;
-
-       if ((ha->cfg_lun_q_depth / 2) < vha->host->cmd_per_lun)
-               ha->cfg_lun_q_depth = vha->host->cmd_per_lun;
-       else
-               ha->cfg_lun_q_depth = ha->cfg_lun_q_depth / 2;
-
-       /*
-        * Geometrically ramp down the queue depth for all devices on this
-        * adapter
-        */
-       spin_lock_irqsave(&ha->vport_slock, flags);
-       list_for_each_entry(vp, &ha->vp_list, list) {
-               shost = vp->host;
-               shost_for_each_device(sdev, shost) {
-                       if (sdev->queue_depth > shost->cmd_per_lun) {
-                               if (sdev->queue_depth < ha->cfg_lun_q_depth)
-                                       continue;
-                               ql_dbg(ql_dbg_io, vp, 0x3031,
-                                   "%ld:%d:%d: Ramping down queue depth to %d",
-                                   vp->host_no, sdev->id, sdev->lun,
-                                   ha->cfg_lun_q_depth);
-                               qla2x00_change_queue_depth(sdev,
-                                   ha->cfg_lun_q_depth, SCSI_QDEPTH_DEFAULT);
-                       }
-               }
-       }
-       spin_unlock_irqrestore(&ha->vport_slock, flags);
-
-       return;
-}
-
-static void
-qla2x00_host_ramp_up_queuedepth(scsi_qla_host_t *vha)
-{
-       scsi_qla_host_t *vp;
-       struct Scsi_Host *shost;
-       struct scsi_device *sdev;
-       struct qla_hw_data *ha = vha->hw;
-       unsigned long flags;
-
-       ha->host_last_rampup_time = jiffies;
-       ha->cfg_lun_q_depth++;
-
-       /*
-        * Linearly ramp up the queue depth for all devices on this
-        * adapter
-        */
-       spin_lock_irqsave(&ha->vport_slock, flags);
-       list_for_each_entry(vp, &ha->vp_list, list) {
-               shost = vp->host;
-               shost_for_each_device(sdev, shost) {
-                       if (sdev->queue_depth > ha->cfg_lun_q_depth)
-                               continue;
-                       qla2x00_change_queue_depth(sdev, ha->cfg_lun_q_depth,
-                           SCSI_QDEPTH_RAMP_UP);
-               }
-       }
-       spin_unlock_irqrestore(&ha->vport_slock, flags);
-
-       return;
-}
-
 /**
  * qla2x00_config_dma_addressing() - Configure OS DMA addressing method.
  * @ha: HA context
@@ -2424,7 +2347,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ha->init_cb_size = sizeof(init_cb_t);
        ha->link_data_rate = PORT_SPEED_UNKNOWN;
        ha->optrom_size = OPTROM_SIZE_2300;
-       ha->cfg_lun_q_depth = ql2xmaxqdepth;
 
        /* Assign ISP specific operations. */
        if (IS_QLA2100(ha)) {
@@ -2573,6 +2495,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->mr.fw_reset_timer_tick = QLAFX00_RESET_INTERVAL;
                ha->mr.fw_critemp_timer_tick = QLAFX00_CRITEMP_INTERVAL;
                ha->mr.fw_hbt_en = 1;
+               ha->mr.host_info_resend = false;
+               ha->mr.hinfo_resend_timer_tick = QLAFX00_HINFO_RESEND_INTERVAL;
        }
 
        ql_dbg_pci(ql_dbg_init, pdev, 0x001e,
@@ -2638,7 +2562,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        host = base_vha->host;
        base_vha->req = req;
        if (IS_QLAFX00(ha))
-               host->can_queue = 1024;
+               host->can_queue = QLAFX00_MAX_CANQUEUE;
        else
                host->can_queue = req->length + 128;
        if (IS_QLA2XXX_MIDTYPE(ha))
@@ -2816,6 +2740,8 @@ que_init:
         */
        qla2xxx_wake_dpc(base_vha);
 
+       INIT_WORK(&ha->board_disable, qla2x00_disable_board_on_pci_error);
+
        if (IS_QLA8031(ha) || IS_MCTP_CAPABLE(ha)) {
                sprintf(wq_name, "qla2xxx_%lu_dpc_lp_wq", base_vha->host_no);
                ha->dpc_lp_wq = create_singlethread_workqueue(wq_name);
@@ -2979,22 +2905,6 @@ probe_out:
        return ret;
 }
 
-static void
-qla2x00_stop_dpc_thread(scsi_qla_host_t *vha)
-{
-       struct qla_hw_data *ha = vha->hw;
-       struct task_struct *t = ha->dpc_thread;
-
-       if (ha->dpc_thread == NULL)
-               return;
-       /*
-        * qla2xxx_wake_dpc checks for ->dpc_thread
-        * so we need to zero it out.
-        */
-       ha->dpc_thread = NULL;
-       kthread_stop(t);
-}
-
 static void
 qla2x00_shutdown(struct pci_dev *pdev)
 {
@@ -3038,29 +2948,14 @@ qla2x00_shutdown(struct pci_dev *pdev)
        qla2x00_free_fw_dump(ha);
 }
 
+/* Deletes all the virtual ports for a given ha */
 static void
-qla2x00_remove_one(struct pci_dev *pdev)
+qla2x00_delete_all_vps(struct qla_hw_data *ha, scsi_qla_host_t *base_vha)
 {
-       scsi_qla_host_t *base_vha, *vha;
-       struct qla_hw_data  *ha;
+       struct Scsi_Host *scsi_host;
+       scsi_qla_host_t *vha;
        unsigned long flags;
 
-       /*
-        * If the PCI device is disabled that means that probe failed and any
-        * resources should be have cleaned up on probe exit.
-        */
-       if (!atomic_read(&pdev->enable_cnt))
-               return;
-
-       base_vha = pci_get_drvdata(pdev);
-       ha = base_vha->hw;
-
-       ha->flags.host_shutting_down = 1;
-
-       set_bit(UNLOADING, &base_vha->dpc_flags);
-       if (IS_QLAFX00(ha))
-               qlafx00_driver_shutdown(base_vha, 20);
-
        mutex_lock(&ha->vport_lock);
        while (ha->cur_vport_count) {
                spin_lock_irqsave(&ha->vport_slock, flags);
@@ -3068,7 +2963,7 @@ qla2x00_remove_one(struct pci_dev *pdev)
                BUG_ON(base_vha->list.next == &ha->vp_list);
                /* This assumes first entry in ha->vp_list is always base vha */
                vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list);
-               scsi_host_get(vha->host);
+               scsi_host = scsi_host_get(vha->host);
 
                spin_unlock_irqrestore(&ha->vport_slock, flags);
                mutex_unlock(&ha->vport_lock);
@@ -3079,27 +2974,12 @@ qla2x00_remove_one(struct pci_dev *pdev)
                mutex_lock(&ha->vport_lock);
        }
        mutex_unlock(&ha->vport_lock);
+}
 
-       if (IS_QLA8031(ha)) {
-               ql_dbg(ql_dbg_p3p, base_vha, 0xb07e,
-                   "Clearing fcoe driver presence.\n");
-               if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS)
-                       ql_dbg(ql_dbg_p3p, base_vha, 0xb079,
-                           "Error while clearing DRV-Presence.\n");
-       }
-
-       qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
-
-       qla2x00_dfs_remove(base_vha);
-
-       qla84xx_put_chip(base_vha);
-
-       /* Disable timer */
-       if (base_vha->timer_active)
-               qla2x00_stop_timer(base_vha);
-
-       base_vha->flags.online = 0;
-
+/* Stops all deferred work threads */
+static void
+qla2x00_destroy_deferred_work(struct qla_hw_data *ha)
+{
        /* Flush the work queue and remove it */
        if (ha->wq) {
                flush_workqueue(ha->wq);
@@ -3133,27 +3013,12 @@ qla2x00_remove_one(struct pci_dev *pdev)
                ha->dpc_thread = NULL;
                kthread_stop(t);
        }
-       qlt_remove_target(ha, base_vha);
-
-       qla2x00_free_sysfs_attr(base_vha);
-
-       fc_remove_host(base_vha->host);
-
-       scsi_remove_host(base_vha->host);
-
-       qla2x00_free_device(base_vha);
-
-       scsi_host_put(base_vha->host);
+}
 
-       if (IS_QLA8044(ha)) {
-               qla8044_idc_lock(ha);
-               qla8044_clear_drv_active(base_vha);
-               qla8044_idc_unlock(ha);
-       }
+static void
+qla2x00_unmap_iobases(struct qla_hw_data *ha)
+{
        if (IS_QLA82XX(ha)) {
-               qla82xx_idc_lock(ha);
-               qla82xx_clear_drv_active(ha);
-               qla82xx_idc_unlock(ha);
 
                iounmap((device_reg_t __iomem *)ha->nx_pcibase);
                if (!ql2xdbwr)
@@ -3171,6 +3036,84 @@ qla2x00_remove_one(struct pci_dev *pdev)
                if (IS_QLA83XX(ha) && ha->msixbase)
                        iounmap(ha->msixbase);
        }
+}
+
+static void
+qla2x00_clear_drv_active(scsi_qla_host_t *vha)
+{
+       struct qla_hw_data *ha = vha->hw;
+
+       if (IS_QLA8044(ha)) {
+               qla8044_idc_lock(ha);
+               qla8044_clear_drv_active(vha);
+               qla8044_idc_unlock(ha);
+       } else if (IS_QLA82XX(ha)) {
+               qla82xx_idc_lock(ha);
+               qla82xx_clear_drv_active(ha);
+               qla82xx_idc_unlock(ha);
+       }
+}
+
+static void
+qla2x00_remove_one(struct pci_dev *pdev)
+{
+       scsi_qla_host_t *base_vha;
+       struct qla_hw_data  *ha;
+
+       /*
+        * If the PCI device is disabled that means that probe failed and any
+        * resources should be have cleaned up on probe exit.
+        */
+       if (!atomic_read(&pdev->enable_cnt))
+               return;
+
+       base_vha = pci_get_drvdata(pdev);
+       ha = base_vha->hw;
+
+       set_bit(UNLOADING, &base_vha->dpc_flags);
+
+       if (IS_QLAFX00(ha))
+               qlafx00_driver_shutdown(base_vha, 20);
+
+       qla2x00_delete_all_vps(ha, base_vha);
+
+       if (IS_QLA8031(ha)) {
+               ql_dbg(ql_dbg_p3p, base_vha, 0xb07e,
+                   "Clearing fcoe driver presence.\n");
+               if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS)
+                       ql_dbg(ql_dbg_p3p, base_vha, 0xb079,
+                           "Error while clearing DRV-Presence.\n");
+       }
+
+       qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
+
+       qla2x00_dfs_remove(base_vha);
+
+       qla84xx_put_chip(base_vha);
+
+       /* Disable timer */
+       if (base_vha->timer_active)
+               qla2x00_stop_timer(base_vha);
+
+       base_vha->flags.online = 0;
+
+       qla2x00_destroy_deferred_work(ha);
+
+       qlt_remove_target(ha, base_vha);
+
+       qla2x00_free_sysfs_attr(base_vha, true);
+
+       fc_remove_host(base_vha->host);
+
+       scsi_remove_host(base_vha->host);
+
+       qla2x00_free_device(base_vha);
+
+       scsi_host_put(base_vha->host);
+
+       qla2x00_clear_drv_active(base_vha);
+
+       qla2x00_unmap_iobases(ha);
 
        pci_release_selected_regions(ha->pdev, ha->bars);
        kfree(ha);
@@ -3192,9 +3135,8 @@ qla2x00_free_device(scsi_qla_host_t *vha)
        if (vha->timer_active)
                qla2x00_stop_timer(vha);
 
-       qla2x00_stop_dpc_thread(vha);
-
        qla25xx_delete_queues(vha);
+
        if (ha->flags.fce_enabled)
                qla2x00_disable_fce_trace(vha, NULL, NULL);
 
@@ -4731,6 +4673,66 @@ exit:
        return rval;
 }
 
+void
+qla2x00_disable_board_on_pci_error(struct work_struct *work)
+{
+       struct qla_hw_data *ha = container_of(work, struct qla_hw_data,
+           board_disable);
+       struct pci_dev *pdev = ha->pdev;
+       scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+
+       ql_log(ql_log_warn, base_vha, 0x015b,
+           "Disabling adapter.\n");
+
+       set_bit(UNLOADING, &base_vha->dpc_flags);
+
+       qla2x00_delete_all_vps(ha, base_vha);
+
+       qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
+
+       qla2x00_dfs_remove(base_vha);
+
+       qla84xx_put_chip(base_vha);
+
+       if (base_vha->timer_active)
+               qla2x00_stop_timer(base_vha);
+
+       base_vha->flags.online = 0;
+
+       qla2x00_destroy_deferred_work(ha);
+
+       /*
+        * Do not try to stop beacon blink as it will issue a mailbox
+        * command.
+        */
+       qla2x00_free_sysfs_attr(base_vha, false);
+
+       fc_remove_host(base_vha->host);
+
+       scsi_remove_host(base_vha->host);
+
+       base_vha->flags.init_done = 0;
+       qla25xx_delete_queues(base_vha);
+       qla2x00_free_irqs(base_vha);
+       qla2x00_free_fcports(base_vha);
+       qla2x00_mem_free(ha);
+       qla82xx_md_free(base_vha);
+       qla2x00_free_queues(ha);
+
+       scsi_host_put(base_vha->host);
+
+       qla2x00_unmap_iobases(ha);
+
+       pci_release_selected_regions(ha->pdev, ha->bars);
+       kfree(ha);
+       ha = NULL;
+
+       pci_disable_pcie_error_reporting(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+
+}
+
 /**************************************************************************
 * qla2x00_do_dpc
 *   This kernel thread is a task that is schedule by the interrupt handler
@@ -4863,6 +4865,14 @@ qla2x00_do_dpc(void *data)
                                ql_dbg(ql_dbg_dpc, base_vha, 0x401f,
                                    "ISPFx00 Target Scan End\n");
                        }
+                       if (test_and_clear_bit(FX00_HOST_INFO_RESEND,
+                               &base_vha->dpc_flags)) {
+                               ql_dbg(ql_dbg_dpc, base_vha, 0x4023,
+                                   "ISPFx00 Host Info resend scheduled\n");
+                               qlafx00_fx_disc(base_vha,
+                                   &base_vha->hw->mr.fcport,
+                                   FXDISC_REG_HOST_INFO);
+                       }
                }
 
                if (test_and_clear_bit(ISP_ABORT_NEEDED,
@@ -4990,17 +5000,6 @@ loop_resync_check:
                        qla2xxx_flash_npiv_conf(base_vha);
                }
 
-               if (test_and_clear_bit(HOST_RAMP_DOWN_QUEUE_DEPTH,
-                   &base_vha->dpc_flags)) {
-                       /* Prevents simultaneous ramp up and down */
-                       clear_bit(HOST_RAMP_UP_QUEUE_DEPTH,
-                           &base_vha->dpc_flags);
-                       qla2x00_host_ramp_down_queuedepth(base_vha);
-               }
-
-               if (test_and_clear_bit(HOST_RAMP_UP_QUEUE_DEPTH,
-                   &base_vha->dpc_flags))
-                       qla2x00_host_ramp_up_queuedepth(base_vha);
 intr_on_check:
                if (!ha->interrupts_on)
                        ha->isp_ops->enable_intrs(ha);
@@ -5095,9 +5094,20 @@ qla2x00_timer(scsi_qla_host_t *vha)
                return;
        }
 
-       /* Hardware read to raise pending EEH errors during mailbox waits. */
-       if (!pci_channel_offline(ha->pdev))
+       /*
+        * Hardware read to raise pending EEH errors during mailbox waits. If
+        * the read returns -1 then disable the board.
+        */
+       if (!pci_channel_offline(ha->pdev)) {
                pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
+               if (w == 0xffff)
+                       /*
+                        * Schedule this on the default system workqueue so that
+                        * all the adapter workqueues and the DPC thread can be
+                        * shutdown cleanly.
+                        */
+                       schedule_work(&ha->board_disable);
+       }
 
        /* Make sure qla82xx_watchdog is run only for physical port */
        if (!vha->vp_idx && IS_P3P_TYPE(ha)) {
@@ -5182,7 +5192,6 @@ qla2x00_timer(scsi_qla_host_t *vha)
                    "Loop down - seconds remaining %d.\n",
                    atomic_read(&vha->loop_down_timer));
        }
-
        /* Check if beacon LED needs to be blinked for physical host only */
        if (!vha->vp_idx && (ha->beacon_blink_led == 1)) {
                /* There is no beacon_blink function for ISP82xx */
@@ -5206,9 +5215,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
            test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) ||
            test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) ||
            test_bit(VP_DPC_NEEDED, &vha->dpc_flags) ||
-           test_bit(RELOGIN_NEEDED, &vha->dpc_flags) ||
-           test_bit(HOST_RAMP_DOWN_QUEUE_DEPTH, &vha->dpc_flags) ||
-           test_bit(HOST_RAMP_UP_QUEUE_DEPTH, &vha->dpc_flags))) {
+           test_bit(RELOGIN_NEEDED, &vha->dpc_flags))) {
                ql_dbg(ql_dbg_timer, vha, 0x600b,
                    "isp_abort_needed=%d loop_resync_needed=%d "
                    "fcport_update_needed=%d start_dpc=%d "
@@ -5221,15 +5228,12 @@ qla2x00_timer(scsi_qla_host_t *vha)
                ql_dbg(ql_dbg_timer, vha, 0x600c,
                    "beacon_blink_needed=%d isp_unrecoverable=%d "
                    "fcoe_ctx_reset_needed=%d vp_dpc_needed=%d "
-                   "relogin_needed=%d, host_ramp_down_needed=%d "
-                   "host_ramp_up_needed=%d.\n",
+                   "relogin_needed=%d.\n",
                    test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags),
                    test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags),
                    test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags),
                    test_bit(VP_DPC_NEEDED, &vha->dpc_flags),
-                   test_bit(RELOGIN_NEEDED, &vha->dpc_flags),
-                   test_bit(HOST_RAMP_UP_QUEUE_DEPTH, &vha->dpc_flags),
-                   test_bit(HOST_RAMP_DOWN_QUEUE_DEPTH, &vha->dpc_flags));
+                   test_bit(RELOGIN_NEEDED, &vha->dpc_flags));
                qla2xxx_wake_dpc(vha);
        }
 
index a808e293dae03a14166c71841716ba495c7ecaa6..31d19535b015ece4f10649e38dcaf0ee402a7d97 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.06.00.08-k"
+#define QLA2XXX_VERSION      "8.06.00.12-k"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   6
index 084d1fd59c9e137e337c663ff076c488957d731a..e2be308c0d9ea0b9c8c13288472350112d731ef1 100644 (file)
                n &= ~v;        \
 }
 
+#define OP_STATE(o, f, p) {                    \
+       p = (o & f) ? "enable" : "disable";     \
+}
+
 /*
  * Retry & Timeout Values
  */
@@ -476,6 +480,34 @@ struct ipaddress_config {
        uint16_t eth_mtu_size;
        uint16_t ipv4_port;
        uint16_t ipv6_port;
+       uint8_t control;
+       uint16_t ipv6_tcp_options;
+       uint8_t tcp_wsf;
+       uint8_t ipv6_tcp_wsf;
+       uint8_t ipv4_tos;
+       uint8_t ipv4_cache_id;
+       uint8_t ipv6_cache_id;
+       uint8_t ipv4_alt_cid_len;
+       uint8_t ipv4_alt_cid[11];
+       uint8_t ipv4_vid_len;
+       uint8_t ipv4_vid[11];
+       uint8_t ipv4_ttl;
+       uint16_t ipv6_flow_lbl;
+       uint8_t ipv6_traffic_class;
+       uint8_t ipv6_hop_limit;
+       uint32_t ipv6_nd_reach_time;
+       uint32_t ipv6_nd_rexmit_timer;
+       uint32_t ipv6_nd_stale_timeout;
+       uint8_t ipv6_dup_addr_detect_count;
+       uint32_t ipv6_gw_advrt_mtu;
+       uint16_t def_timeout;
+       uint8_t abort_timer;
+       uint16_t iscsi_options;
+       uint16_t iscsi_max_pdu_size;
+       uint16_t iscsi_first_burst_len;
+       uint16_t iscsi_max_outstnd_r2t;
+       uint16_t iscsi_max_burst_len;
+       uint8_t iscsi_name[224];
 };
 
 #define QL4_CHAP_MAX_NAME_LEN 256
index 1243e5942b76dfe3883e38303937f0688f22c199..3060652757076aabc3f5361f03c2bfa1448c1ba0 100644 (file)
@@ -551,6 +551,7 @@ struct addr_ctrl_blk {
 #define  IFCB_VER_MIN                  0x01
 #define  IFCB_VER_MAX                  0x02
        uint8_t control;        /* 01 */
+#define         CTRLOPT_NEW_CONN_DISABLE       0x0002
 
        uint16_t fw_options;    /* 02-03 */
 #define         FWOPT_HEARTBEAT_ENABLE           0x1000
@@ -582,11 +583,40 @@ struct addr_ctrl_blk {
        uint32_t shdwreg_addr_hi;       /* 2C-2F */
 
        uint16_t iscsi_opts;    /* 30-31 */
+#define ISCSIOPTS_HEADER_DIGEST_EN             0x2000
+#define ISCSIOPTS_DATA_DIGEST_EN               0x1000
+#define ISCSIOPTS_IMMEDIATE_DATA_EN            0x0800
+#define ISCSIOPTS_INITIAL_R2T_EN               0x0400
+#define ISCSIOPTS_DATA_SEQ_INORDER_EN          0x0200
+#define ISCSIOPTS_DATA_PDU_INORDER_EN          0x0100
+#define ISCSIOPTS_CHAP_AUTH_EN                 0x0080
+#define ISCSIOPTS_SNACK_EN                     0x0040
+#define ISCSIOPTS_DISCOVERY_LOGOUT_EN          0x0020
+#define ISCSIOPTS_BIDI_CHAP_EN                 0x0010
+#define ISCSIOPTS_DISCOVERY_AUTH_EN            0x0008
+#define ISCSIOPTS_STRICT_LOGIN_COMP_EN         0x0004
+#define ISCSIOPTS_ERL                          0x0003
        uint16_t ipv4_tcp_opts; /* 32-33 */
+#define TCPOPT_DELAYED_ACK_DISABLE     0x8000
 #define TCPOPT_DHCP_ENABLE             0x0200
+#define TCPOPT_DNS_SERVER_IP_EN                0x0100
+#define TCPOPT_SLP_DA_INFO_EN          0x0080
+#define TCPOPT_NAGLE_ALGO_DISABLE      0x0020
+#define TCPOPT_WINDOW_SCALE_DISABLE    0x0010
+#define TCPOPT_TIMER_SCALE             0x000E
+#define TCPOPT_TIMESTAMP_ENABLE                0x0001
        uint16_t ipv4_ip_opts;  /* 34-35 */
 #define IPOPT_IPV4_PROTOCOL_ENABLE     0x8000
+#define IPOPT_IPV4_TOS_EN              0x4000
 #define IPOPT_VLAN_TAGGING_ENABLE      0x2000
+#define IPOPT_GRAT_ARP_EN              0x1000
+#define IPOPT_ALT_CID_EN               0x0800
+#define IPOPT_REQ_VID_EN               0x0400
+#define IPOPT_USE_VID_EN               0x0200
+#define IPOPT_LEARN_IQN_EN             0x0100
+#define IPOPT_FRAGMENTATION_DISABLE    0x0010
+#define IPOPT_IN_FORWARD_EN            0x0008
+#define IPOPT_ARP_REDIRECT_EN          0x0004
 
        uint16_t iscsi_max_pdu_size;    /* 36-37 */
        uint8_t ipv4_tos;       /* 38 */
@@ -637,15 +667,24 @@ struct addr_ctrl_blk {
        uint32_t cookie;        /* 200-203 */
        uint16_t ipv6_port;     /* 204-205 */
        uint16_t ipv6_opts;     /* 206-207 */
-#define IPV6_OPT_IPV6_PROTOCOL_ENABLE  0x8000
-#define IPV6_OPT_VLAN_TAGGING_ENABLE   0x2000
+#define IPV6_OPT_IPV6_PROTOCOL_ENABLE          0x8000
+#define IPV6_OPT_VLAN_TAGGING_ENABLE           0x2000
+#define IPV6_OPT_GRAT_NEIGHBOR_ADV_EN          0x1000
+#define IPV6_OPT_REDIRECT_EN                   0x0004
 
        uint16_t ipv6_addtl_opts;       /* 208-209 */
+#define IPV6_ADDOPT_IGNORE_ICMP_ECHO_REQ               0x0040
+#define IPV6_ADDOPT_MLD_EN                             0x0004
 #define IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE     0x0002 /* Pri ACB
                                                                  Only */
 #define IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR         0x0001
 
        uint16_t ipv6_tcp_opts; /* 20A-20B */
+#define IPV6_TCPOPT_DELAYED_ACK_DISABLE                0x8000
+#define IPV6_TCPOPT_NAGLE_ALGO_DISABLE         0x0020
+#define IPV6_TCPOPT_WINDOW_SCALE_DISABLE       0x0010
+#define IPV6_TCPOPT_TIMER_SCALE                        0x000E
+#define IPV6_TCPOPT_TIMESTAMP_EN               0x0001
        uint8_t ipv6_tcp_wsf;   /* 20C */
        uint16_t ipv6_flow_lbl; /* 20D-20F */
        uint8_t ipv6_dflt_rtr_addr[16]; /* 210-21F */
index 5cef2527180aaf1541962a5c1caec1ab850d1a48..b8e87b33b48ec16cfe1f96e3737bceea96f616b4 100644 (file)
@@ -276,6 +276,7 @@ int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,
 int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config);
 int qla4_83xx_ms_mem_write_128b(struct scsi_qla_host *ha,
                                uint64_t addr, uint32_t *data, uint32_t count);
+uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state);
 
 extern int ql4xextended_error_logging;
 extern int ql4xdontresethba;
index 7dff09f09b7130d41411969229898281a1bd7723..66cc9c1ba53c62ee4c26af484daee971606e8f53 100644 (file)
@@ -606,6 +606,36 @@ static int qla4_83xx_loopback_in_progress(struct scsi_qla_host *ha)
        return rval;
 }
 
+static void qla4xxx_update_ipaddr_state(struct scsi_qla_host *ha,
+                                       uint32_t ipaddr_idx,
+                                       uint32_t ipaddr_fw_state)
+{
+       uint8_t ipaddr_state;
+       uint8_t ip_idx;
+
+       ip_idx = ipaddr_idx & 0xF;
+       ipaddr_state = qla4xxx_set_ipaddr_state((uint8_t)ipaddr_fw_state);
+
+       switch (ip_idx) {
+       case 0:
+               ha->ip_config.ipv4_addr_state = ipaddr_state;
+               break;
+       case 1:
+               ha->ip_config.ipv6_link_local_state = ipaddr_state;
+               break;
+       case 2:
+               ha->ip_config.ipv6_addr0_state = ipaddr_state;
+               break;
+       case 3:
+               ha->ip_config.ipv6_addr1_state = ipaddr_state;
+               break;
+       default:
+               ql4_printk(KERN_INFO, ha, "%s: Invalid IPADDR index %d\n",
+                          __func__, ip_idx);
+       }
+}
+
+
 /**
  * qla4xxx_isr_decode_mailbox - decodes mailbox status
  * @ha: Pointer to host adapter structure.
@@ -741,6 +771,8 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
                            "mbox_sts[3]=%04x\n", ha->host_no, mbox_sts[0],
                            mbox_sts[2], mbox_sts[3]);
 
+                       qla4xxx_update_ipaddr_state(ha, mbox_sts[5],
+                                                   mbox_sts[3]);
                        /* mbox_sts[2] = Old ACB state
                         * mbox_sts[3] = new ACB state */
                        if ((mbox_sts[3] == ACB_STATE_VALID) &&
index 22cbd005bdf497c7ca5b011e8e21a607041c1c84..351793c0e18f3a6ac51dcaf925e7074a7f39a210 100644 (file)
@@ -418,6 +418,38 @@ qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
        return QLA_SUCCESS;
 }
 
+uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state)
+{
+       uint8_t ipaddr_state;
+
+       switch (fw_ipaddr_state) {
+       case IP_ADDRSTATE_UNCONFIGURED:
+               ipaddr_state = ISCSI_IPDDRESS_STATE_UNCONFIGURED;
+               break;
+       case IP_ADDRSTATE_INVALID:
+               ipaddr_state = ISCSI_IPDDRESS_STATE_INVALID;
+               break;
+       case IP_ADDRSTATE_ACQUIRING:
+               ipaddr_state = ISCSI_IPDDRESS_STATE_ACQUIRING;
+               break;
+       case IP_ADDRSTATE_TENTATIVE:
+               ipaddr_state = ISCSI_IPDDRESS_STATE_TENTATIVE;
+               break;
+       case IP_ADDRSTATE_DEPRICATED:
+               ipaddr_state = ISCSI_IPDDRESS_STATE_DEPRECATED;
+               break;
+       case IP_ADDRSTATE_PREFERRED:
+               ipaddr_state = ISCSI_IPDDRESS_STATE_VALID;
+               break;
+       case IP_ADDRSTATE_DISABLING:
+               ipaddr_state = ISCSI_IPDDRESS_STATE_DISABLING;
+               break;
+       default:
+               ipaddr_state = ISCSI_IPDDRESS_STATE_UNCONFIGURED;
+       }
+       return ipaddr_state;
+}
+
 static void
 qla4xxx_update_local_ip(struct scsi_qla_host *ha,
                        struct addr_ctrl_blk *init_fw_cb)
@@ -425,7 +457,7 @@ qla4xxx_update_local_ip(struct scsi_qla_host *ha,
        ha->ip_config.tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts);
        ha->ip_config.ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts);
        ha->ip_config.ipv4_addr_state =
-                               le16_to_cpu(init_fw_cb->ipv4_addr_state);
+                       qla4xxx_set_ipaddr_state(init_fw_cb->ipv4_addr_state);
        ha->ip_config.eth_mtu_size =
                                le16_to_cpu(init_fw_cb->eth_mtu_size);
        ha->ip_config.ipv4_port = le16_to_cpu(init_fw_cb->ipv4_port);
@@ -434,6 +466,8 @@ qla4xxx_update_local_ip(struct scsi_qla_host *ha,
                ha->ip_config.ipv6_options = le16_to_cpu(init_fw_cb->ipv6_opts);
                ha->ip_config.ipv6_addl_options =
                                le16_to_cpu(init_fw_cb->ipv6_addtl_opts);
+               ha->ip_config.ipv6_tcp_options =
+                               le16_to_cpu(init_fw_cb->ipv6_tcp_opts);
        }
 
        /* Save IPv4 Address Info */
@@ -448,17 +482,65 @@ qla4xxx_update_local_ip(struct scsi_qla_host *ha,
                   sizeof(init_fw_cb->ipv4_gw_addr)));
 
        ha->ip_config.ipv4_vlan_tag = be16_to_cpu(init_fw_cb->ipv4_vlan_tag);
+       ha->ip_config.control = init_fw_cb->control;
+       ha->ip_config.tcp_wsf = init_fw_cb->ipv4_tcp_wsf;
+       ha->ip_config.ipv4_tos = init_fw_cb->ipv4_tos;
+       ha->ip_config.ipv4_cache_id = init_fw_cb->ipv4_cacheid;
+       ha->ip_config.ipv4_alt_cid_len = init_fw_cb->ipv4_dhcp_alt_cid_len;
+       memcpy(ha->ip_config.ipv4_alt_cid, init_fw_cb->ipv4_dhcp_alt_cid,
+              min(sizeof(ha->ip_config.ipv4_alt_cid),
+                  sizeof(init_fw_cb->ipv4_dhcp_alt_cid)));
+       ha->ip_config.ipv4_vid_len = init_fw_cb->ipv4_dhcp_vid_len;
+       memcpy(ha->ip_config.ipv4_vid, init_fw_cb->ipv4_dhcp_vid,
+              min(sizeof(ha->ip_config.ipv4_vid),
+                  sizeof(init_fw_cb->ipv4_dhcp_vid)));
+       ha->ip_config.ipv4_ttl = init_fw_cb->ipv4_ttl;
+       ha->ip_config.def_timeout = le16_to_cpu(init_fw_cb->def_timeout);
+       ha->ip_config.abort_timer = init_fw_cb->abort_timer;
+       ha->ip_config.iscsi_options = le16_to_cpu(init_fw_cb->iscsi_opts);
+       ha->ip_config.iscsi_max_pdu_size =
+                               le16_to_cpu(init_fw_cb->iscsi_max_pdu_size);
+       ha->ip_config.iscsi_first_burst_len =
+                               le16_to_cpu(init_fw_cb->iscsi_fburst_len);
+       ha->ip_config.iscsi_max_outstnd_r2t =
+                               le16_to_cpu(init_fw_cb->iscsi_max_outstnd_r2t);
+       ha->ip_config.iscsi_max_burst_len =
+                               le16_to_cpu(init_fw_cb->iscsi_max_burst_len);
+       memcpy(ha->ip_config.iscsi_name, init_fw_cb->iscsi_name,
+              min(sizeof(ha->ip_config.iscsi_name),
+                  sizeof(init_fw_cb->iscsi_name)));
 
        if (is_ipv6_enabled(ha)) {
                /* Save IPv6 Address */
                ha->ip_config.ipv6_link_local_state =
-                       le16_to_cpu(init_fw_cb->ipv6_lnk_lcl_addr_state);
+                 qla4xxx_set_ipaddr_state(init_fw_cb->ipv6_lnk_lcl_addr_state);
                ha->ip_config.ipv6_addr0_state =
-                               le16_to_cpu(init_fw_cb->ipv6_addr0_state);
+                       qla4xxx_set_ipaddr_state(init_fw_cb->ipv6_addr0_state);
                ha->ip_config.ipv6_addr1_state =
-                               le16_to_cpu(init_fw_cb->ipv6_addr1_state);
-               ha->ip_config.ipv6_default_router_state =
-                               le16_to_cpu(init_fw_cb->ipv6_dflt_rtr_state);
+                       qla4xxx_set_ipaddr_state(init_fw_cb->ipv6_addr1_state);
+
+               switch (le16_to_cpu(init_fw_cb->ipv6_dflt_rtr_state)) {
+               case IPV6_RTRSTATE_UNKNOWN:
+                       ha->ip_config.ipv6_default_router_state =
+                                               ISCSI_ROUTER_STATE_UNKNOWN;
+                       break;
+               case IPV6_RTRSTATE_MANUAL:
+                       ha->ip_config.ipv6_default_router_state =
+                                               ISCSI_ROUTER_STATE_MANUAL;
+                       break;
+               case IPV6_RTRSTATE_ADVERTISED:
+                       ha->ip_config.ipv6_default_router_state =
+                                               ISCSI_ROUTER_STATE_ADVERTISED;
+                       break;
+               case IPV6_RTRSTATE_STALE:
+                       ha->ip_config.ipv6_default_router_state =
+                                               ISCSI_ROUTER_STATE_STALE;
+                       break;
+               default:
+                       ha->ip_config.ipv6_default_router_state =
+                                               ISCSI_ROUTER_STATE_UNKNOWN;
+               }
+
                ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE;
                ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80;
 
@@ -479,6 +561,23 @@ qla4xxx_update_local_ip(struct scsi_qla_host *ha,
                ha->ip_config.ipv6_vlan_tag =
                                be16_to_cpu(init_fw_cb->ipv6_vlan_tag);
                ha->ip_config.ipv6_port = le16_to_cpu(init_fw_cb->ipv6_port);
+               ha->ip_config.ipv6_cache_id = init_fw_cb->ipv6_cache_id;
+               ha->ip_config.ipv6_flow_lbl =
+                               le16_to_cpu(init_fw_cb->ipv6_flow_lbl);
+               ha->ip_config.ipv6_traffic_class =
+                               init_fw_cb->ipv6_traffic_class;
+               ha->ip_config.ipv6_hop_limit = init_fw_cb->ipv6_hop_limit;
+               ha->ip_config.ipv6_nd_reach_time =
+                               le32_to_cpu(init_fw_cb->ipv6_nd_reach_time);
+               ha->ip_config.ipv6_nd_rexmit_timer =
+                               le32_to_cpu(init_fw_cb->ipv6_nd_rexmit_timer);
+               ha->ip_config.ipv6_nd_stale_timeout =
+                               le32_to_cpu(init_fw_cb->ipv6_nd_stale_timeout);
+               ha->ip_config.ipv6_dup_addr_detect_count =
+                                       init_fw_cb->ipv6_dup_addr_detect_count;
+               ha->ip_config.ipv6_gw_advrt_mtu =
+                               le32_to_cpu(init_fw_cb->ipv6_gw_advrt_mtu);
+               ha->ip_config.ipv6_tcp_wsf = init_fw_cb->ipv6_tcp_wsf;
        }
 }
 
index a28d5e624aabcdd729e4c64c4c904549e21d6e17..4706b8c0ec6431dfb7395b70b5a3d5e16b54de80 100644 (file)
@@ -440,6 +440,65 @@ static umode_t qla4_attr_is_visible(int param_type, int param)
                case ISCSI_NET_PARAM_VLAN_ENABLED:
                case ISCSI_NET_PARAM_MTU:
                case ISCSI_NET_PARAM_PORT:
+               case ISCSI_NET_PARAM_IPADDR_STATE:
+               case ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE:
+               case ISCSI_NET_PARAM_IPV6_ROUTER_STATE:
+               case ISCSI_NET_PARAM_DELAYED_ACK_EN:
+               case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE:
+               case ISCSI_NET_PARAM_TCP_WSF_DISABLE:
+               case ISCSI_NET_PARAM_TCP_WSF:
+               case ISCSI_NET_PARAM_TCP_TIMER_SCALE:
+               case ISCSI_NET_PARAM_TCP_TIMESTAMP_EN:
+               case ISCSI_NET_PARAM_CACHE_ID:
+               case ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN:
+               case ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN:
+               case ISCSI_NET_PARAM_IPV4_TOS_EN:
+               case ISCSI_NET_PARAM_IPV4_TOS:
+               case ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN:
+               case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN:
+               case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID:
+               case ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN:
+               case ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN:
+               case ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID:
+               case ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN:
+               case ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE:
+               case ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN:
+               case ISCSI_NET_PARAM_REDIRECT_EN:
+               case ISCSI_NET_PARAM_IPV4_TTL:
+               case ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN:
+               case ISCSI_NET_PARAM_IPV6_MLD_EN:
+               case ISCSI_NET_PARAM_IPV6_FLOW_LABEL:
+               case ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS:
+               case ISCSI_NET_PARAM_IPV6_HOP_LIMIT:
+               case ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO:
+               case ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME:
+               case ISCSI_NET_PARAM_IPV6_ND_STALE_TMO:
+               case ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT:
+               case ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU:
+                       return S_IRUGO;
+               default:
+                       return 0;
+               }
+       case ISCSI_IFACE_PARAM:
+               switch (param) {
+               case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO:
+               case ISCSI_IFACE_PARAM_HDRDGST_EN:
+               case ISCSI_IFACE_PARAM_DATADGST_EN:
+               case ISCSI_IFACE_PARAM_IMM_DATA_EN:
+               case ISCSI_IFACE_PARAM_INITIAL_R2T_EN:
+               case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN:
+               case ISCSI_IFACE_PARAM_PDU_INORDER_EN:
+               case ISCSI_IFACE_PARAM_ERL:
+               case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH:
+               case ISCSI_IFACE_PARAM_FIRST_BURST:
+               case ISCSI_IFACE_PARAM_MAX_R2T:
+               case ISCSI_IFACE_PARAM_MAX_BURST:
+               case ISCSI_IFACE_PARAM_CHAP_AUTH_EN:
+               case ISCSI_IFACE_PARAM_BIDI_CHAP_EN:
+               case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL:
+               case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN:
+               case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN:
+               case ISCSI_IFACE_PARAM_INITIATOR_NAME:
                        return S_IRUGO;
                default:
                        return 0;
@@ -802,6 +861,7 @@ static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void *data, int len)
        int type;
        int rem = len;
        int rc = 0;
+       int size;
 
        memset(&chap_rec, 0, sizeof(chap_rec));
 
@@ -816,12 +876,14 @@ static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void *data, int len)
                        chap_rec.chap_type = param_info->value[0];
                        break;
                case ISCSI_CHAP_PARAM_USERNAME:
-                       memcpy(chap_rec.username, param_info->value,
-                              param_info->len);
+                       size = min_t(size_t, sizeof(chap_rec.username),
+                                    param_info->len);
+                       memcpy(chap_rec.username, param_info->value, size);
                        break;
                case ISCSI_CHAP_PARAM_PASSWORD:
-                       memcpy(chap_rec.password, param_info->value,
-                              param_info->len);
+                       size = min_t(size_t, sizeof(chap_rec.password),
+                                    param_info->len);
+                       memcpy(chap_rec.password, param_info->value, size);
                        break;
                case ISCSI_CHAP_PARAM_PASSWORD_LEN:
                        chap_rec.password_length = param_info->value[0];
@@ -894,107 +956,437 @@ static int qla4xxx_get_iface_param(struct iscsi_iface *iface,
 {
        struct Scsi_Host *shost = iscsi_iface_to_shost(iface);
        struct scsi_qla_host *ha = to_qla_host(shost);
+       int ival;
+       char *pval = NULL;
        int len = -ENOSYS;
 
-       if (param_type != ISCSI_NET_PARAM)
-               return -ENOSYS;
+       if (param_type == ISCSI_NET_PARAM) {
+               switch (param) {
+               case ISCSI_NET_PARAM_IPV4_ADDR:
+                       len = sprintf(buf, "%pI4\n", &ha->ip_config.ip_address);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_SUBNET:
+                       len = sprintf(buf, "%pI4\n",
+                                     &ha->ip_config.subnet_mask);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_GW:
+                       len = sprintf(buf, "%pI4\n", &ha->ip_config.gateway);
+                       break;
+               case ISCSI_NET_PARAM_IFACE_ENABLE:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
+                               OP_STATE(ha->ip_config.ipv4_options,
+                                        IPOPT_IPV4_PROTOCOL_ENABLE, pval);
+                       } else {
+                               OP_STATE(ha->ip_config.ipv6_options,
+                                        IPV6_OPT_IPV6_PROTOCOL_ENABLE, pval);
+                       }
 
-       switch (param) {
-       case ISCSI_NET_PARAM_IPV4_ADDR:
-               len = sprintf(buf, "%pI4\n", &ha->ip_config.ip_address);
-               break;
-       case ISCSI_NET_PARAM_IPV4_SUBNET:
-               len = sprintf(buf, "%pI4\n", &ha->ip_config.subnet_mask);
-               break;
-       case ISCSI_NET_PARAM_IPV4_GW:
-               len = sprintf(buf, "%pI4\n", &ha->ip_config.gateway);
-               break;
-       case ISCSI_NET_PARAM_IFACE_ENABLE:
-               if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
-                       len = sprintf(buf, "%s\n",
-                                     (ha->ip_config.ipv4_options &
-                                      IPOPT_IPV4_PROTOCOL_ENABLE) ?
-                                     "enabled" : "disabled");
-               else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
                        len = sprintf(buf, "%s\n",
-                                     (ha->ip_config.ipv6_options &
-                                      IPV6_OPT_IPV6_PROTOCOL_ENABLE) ?
-                                      "enabled" : "disabled");
-               break;
-       case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
-               len = sprintf(buf, "%s\n",
-                             (ha->ip_config.tcp_options & TCPOPT_DHCP_ENABLE) ?
-                             "dhcp" : "static");
-               break;
-       case ISCSI_NET_PARAM_IPV6_ADDR:
-               if (iface->iface_num == 0)
-                       len = sprintf(buf, "%pI6\n", &ha->ip_config.ipv6_addr0);
-               if (iface->iface_num == 1)
-                       len = sprintf(buf, "%pI6\n", &ha->ip_config.ipv6_addr1);
-               break;
-       case ISCSI_NET_PARAM_IPV6_LINKLOCAL:
-               len = sprintf(buf, "%pI6\n",
-                             &ha->ip_config.ipv6_link_local_addr);
-               break;
-       case ISCSI_NET_PARAM_IPV6_ROUTER:
-               len = sprintf(buf, "%pI6\n",
-                             &ha->ip_config.ipv6_default_router_addr);
-               break;
-       case ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG:
-               len = sprintf(buf, "%s\n",
-                             (ha->ip_config.ipv6_addl_options &
-                              IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE) ?
-                              "nd" : "static");
-               break;
-       case ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG:
-               len = sprintf(buf, "%s\n",
-                             (ha->ip_config.ipv6_addl_options &
-                              IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR) ?
-                              "auto" : "static");
-               break;
-       case ISCSI_NET_PARAM_VLAN_ID:
-               if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
+                                     (ha->ip_config.tcp_options &
+                                      TCPOPT_DHCP_ENABLE) ?
+                                     "dhcp" : "static");
+                       break;
+               case ISCSI_NET_PARAM_IPV6_ADDR:
+                       if (iface->iface_num == 0)
+                               len = sprintf(buf, "%pI6\n",
+                                             &ha->ip_config.ipv6_addr0);
+                       if (iface->iface_num == 1)
+                               len = sprintf(buf, "%pI6\n",
+                                             &ha->ip_config.ipv6_addr1);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_LINKLOCAL:
+                       len = sprintf(buf, "%pI6\n",
+                                     &ha->ip_config.ipv6_link_local_addr);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_ROUTER:
+                       len = sprintf(buf, "%pI6\n",
+                                     &ha->ip_config.ipv6_default_router_addr);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG:
+                       pval = (ha->ip_config.ipv6_addl_options &
+                               IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE) ?
+                               "nd" : "static";
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG:
+                       pval = (ha->ip_config.ipv6_addl_options &
+                               IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR) ?
+                               "auto" : "static";
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_VLAN_ID:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
+                               ival = ha->ip_config.ipv4_vlan_tag &
+                                      ISCSI_MAX_VLAN_ID;
+                       else
+                               ival = ha->ip_config.ipv6_vlan_tag &
+                                      ISCSI_MAX_VLAN_ID;
+
+                       len = sprintf(buf, "%d\n", ival);
+                       break;
+               case ISCSI_NET_PARAM_VLAN_PRIORITY:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
+                               ival = (ha->ip_config.ipv4_vlan_tag >> 13) &
+                                      ISCSI_MAX_VLAN_PRIORITY;
+                       else
+                               ival = (ha->ip_config.ipv6_vlan_tag >> 13) &
+                                      ISCSI_MAX_VLAN_PRIORITY;
+
+                       len = sprintf(buf, "%d\n", ival);
+                       break;
+               case ISCSI_NET_PARAM_VLAN_ENABLED:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
+                               OP_STATE(ha->ip_config.ipv4_options,
+                                        IPOPT_VLAN_TAGGING_ENABLE, pval);
+                       } else {
+                               OP_STATE(ha->ip_config.ipv6_options,
+                                        IPV6_OPT_VLAN_TAGGING_ENABLE, pval);
+                       }
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_MTU:
+                       len = sprintf(buf, "%d\n", ha->ip_config.eth_mtu_size);
+                       break;
+               case ISCSI_NET_PARAM_PORT:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
+                               len = sprintf(buf, "%d\n",
+                                             ha->ip_config.ipv4_port);
+                       else
+                               len = sprintf(buf, "%d\n",
+                                             ha->ip_config.ipv6_port);
+                       break;
+               case ISCSI_NET_PARAM_IPADDR_STATE:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
+                               pval = iscsi_get_ipaddress_state_name(
+                                               ha->ip_config.ipv4_addr_state);
+                       } else {
+                               if (iface->iface_num == 0)
+                                       pval = iscsi_get_ipaddress_state_name(
+                                               ha->ip_config.ipv6_addr0_state);
+                               else if (iface->iface_num == 1)
+                                       pval = iscsi_get_ipaddress_state_name(
+                                               ha->ip_config.ipv6_addr1_state);
+                       }
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE:
+                       pval = iscsi_get_ipaddress_state_name(
+                                       ha->ip_config.ipv6_link_local_state);
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_ROUTER_STATE:
+                       pval = iscsi_get_router_state_name(
+                                     ha->ip_config.ipv6_default_router_state);
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_DELAYED_ACK_EN:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
+                               OP_STATE(~ha->ip_config.tcp_options,
+                                        TCPOPT_DELAYED_ACK_DISABLE, pval);
+                       } else {
+                               OP_STATE(~ha->ip_config.ipv6_tcp_options,
+                                        IPV6_TCPOPT_DELAYED_ACK_DISABLE, pval);
+                       }
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
+                               OP_STATE(~ha->ip_config.tcp_options,
+                                        TCPOPT_NAGLE_ALGO_DISABLE, pval);
+                       } else {
+                               OP_STATE(~ha->ip_config.ipv6_tcp_options,
+                                        IPV6_TCPOPT_NAGLE_ALGO_DISABLE, pval);
+                       }
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_TCP_WSF_DISABLE:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
+                               OP_STATE(~ha->ip_config.tcp_options,
+                                        TCPOPT_WINDOW_SCALE_DISABLE, pval);
+                       } else {
+                               OP_STATE(~ha->ip_config.ipv6_tcp_options,
+                                        IPV6_TCPOPT_WINDOW_SCALE_DISABLE,
+                                        pval);
+                       }
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_TCP_WSF:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
+                               len = sprintf(buf, "%d\n",
+                                             ha->ip_config.tcp_wsf);
+                       else
+                               len = sprintf(buf, "%d\n",
+                                             ha->ip_config.ipv6_tcp_wsf);
+                       break;
+               case ISCSI_NET_PARAM_TCP_TIMER_SCALE:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
+                               ival = (ha->ip_config.tcp_options &
+                                       TCPOPT_TIMER_SCALE) >> 1;
+                       else
+                               ival = (ha->ip_config.ipv6_tcp_options &
+                                       IPV6_TCPOPT_TIMER_SCALE) >> 1;
+
+                       len = sprintf(buf, "%d\n", ival);
+                       break;
+               case ISCSI_NET_PARAM_TCP_TIMESTAMP_EN:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
+                               OP_STATE(ha->ip_config.tcp_options,
+                                        TCPOPT_TIMESTAMP_ENABLE, pval);
+                       } else {
+                               OP_STATE(ha->ip_config.ipv6_tcp_options,
+                                        IPV6_TCPOPT_TIMESTAMP_EN, pval);
+                       }
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_CACHE_ID:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
+                               len = sprintf(buf, "%d\n",
+                                             ha->ip_config.ipv4_cache_id);
+                       else
+                               len = sprintf(buf, "%d\n",
+                                             ha->ip_config.ipv6_cache_id);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN:
+                       OP_STATE(ha->ip_config.tcp_options,
+                                TCPOPT_DNS_SERVER_IP_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN:
+                       OP_STATE(ha->ip_config.tcp_options,
+                                TCPOPT_SLP_DA_INFO_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_TOS_EN:
+                       OP_STATE(ha->ip_config.ipv4_options,
+                                IPOPT_IPV4_TOS_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_TOS:
+                       len = sprintf(buf, "%d\n", ha->ip_config.ipv4_tos);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN:
+                       OP_STATE(ha->ip_config.ipv4_options,
+                                IPOPT_GRAT_ARP_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN:
+                       OP_STATE(ha->ip_config.ipv4_options, IPOPT_ALT_CID_EN,
+                                pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID:
+                       pval = (ha->ip_config.ipv4_alt_cid_len) ?
+                              (char *)ha->ip_config.ipv4_alt_cid : "";
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN:
+                       OP_STATE(ha->ip_config.ipv4_options,
+                                IPOPT_REQ_VID_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN:
+                       OP_STATE(ha->ip_config.ipv4_options,
+                                IPOPT_USE_VID_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID:
+                       pval = (ha->ip_config.ipv4_vid_len) ?
+                              (char *)ha->ip_config.ipv4_vid : "";
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN:
+                       OP_STATE(ha->ip_config.ipv4_options,
+                                IPOPT_LEARN_IQN_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE:
+                       OP_STATE(~ha->ip_config.ipv4_options,
+                                IPOPT_FRAGMENTATION_DISABLE, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN:
+                       OP_STATE(ha->ip_config.ipv4_options,
+                                IPOPT_IN_FORWARD_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_REDIRECT_EN:
+                       if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
+                               OP_STATE(ha->ip_config.ipv4_options,
+                                        IPOPT_ARP_REDIRECT_EN, pval);
+                       } else {
+                               OP_STATE(ha->ip_config.ipv6_options,
+                                        IPV6_OPT_REDIRECT_EN, pval);
+                       }
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV4_TTL:
+                       len = sprintf(buf, "%d\n", ha->ip_config.ipv4_ttl);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN:
+                       OP_STATE(ha->ip_config.ipv6_options,
+                                IPV6_OPT_GRAT_NEIGHBOR_ADV_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_MLD_EN:
+                       OP_STATE(ha->ip_config.ipv6_addl_options,
+                                IPV6_ADDOPT_MLD_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_FLOW_LABEL:
+                       len = sprintf(buf, "%u\n", ha->ip_config.ipv6_flow_lbl);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS:
                        len = sprintf(buf, "%d\n",
-                                     (ha->ip_config.ipv4_vlan_tag &
-                                      ISCSI_MAX_VLAN_ID));
-               else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
+                                     ha->ip_config.ipv6_traffic_class);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_HOP_LIMIT:
                        len = sprintf(buf, "%d\n",
-                                     (ha->ip_config.ipv6_vlan_tag &
-                                      ISCSI_MAX_VLAN_ID));
-               break;
-       case ISCSI_NET_PARAM_VLAN_PRIORITY:
-               if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
+                                     ha->ip_config.ipv6_hop_limit);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO:
                        len = sprintf(buf, "%d\n",
-                                     ((ha->ip_config.ipv4_vlan_tag >> 13) &
-                                       ISCSI_MAX_VLAN_PRIORITY));
-               else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
+                                     ha->ip_config.ipv6_nd_reach_time);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME:
                        len = sprintf(buf, "%d\n",
-                                     ((ha->ip_config.ipv6_vlan_tag >> 13) &
-                                       ISCSI_MAX_VLAN_PRIORITY));
-               break;
-       case ISCSI_NET_PARAM_VLAN_ENABLED:
-               if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
-                       len = sprintf(buf, "%s\n",
-                                     (ha->ip_config.ipv4_options &
-                                      IPOPT_VLAN_TAGGING_ENABLE) ?
-                                      "enabled" : "disabled");
-               else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
-                       len = sprintf(buf, "%s\n",
-                                     (ha->ip_config.ipv6_options &
-                                      IPV6_OPT_VLAN_TAGGING_ENABLE) ?
-                                      "enabled" : "disabled");
-               break;
-       case ISCSI_NET_PARAM_MTU:
-               len = sprintf(buf, "%d\n", ha->ip_config.eth_mtu_size);
-               break;
-       case ISCSI_NET_PARAM_PORT:
-               if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
-                       len = sprintf(buf, "%d\n", ha->ip_config.ipv4_port);
-               else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
-                       len = sprintf(buf, "%d\n", ha->ip_config.ipv6_port);
-               break;
-       default:
-               len = -ENOSYS;
+                                     ha->ip_config.ipv6_nd_rexmit_timer);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_ND_STALE_TMO:
+                       len = sprintf(buf, "%d\n",
+                                     ha->ip_config.ipv6_nd_stale_timeout);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT:
+                       len = sprintf(buf, "%d\n",
+                                     ha->ip_config.ipv6_dup_addr_detect_count);
+                       break;
+               case ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU:
+                       len = sprintf(buf, "%d\n",
+                                     ha->ip_config.ipv6_gw_advrt_mtu);
+                       break;
+               default:
+                       len = -ENOSYS;
+               }
+       } else if (param_type == ISCSI_IFACE_PARAM) {
+               switch (param) {
+               case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO:
+                       len = sprintf(buf, "%d\n", ha->ip_config.def_timeout);
+                       break;
+               case ISCSI_IFACE_PARAM_HDRDGST_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_HEADER_DIGEST_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_DATADGST_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_DATA_DIGEST_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_IMM_DATA_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_IMMEDIATE_DATA_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_INITIAL_R2T_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_INITIAL_R2T_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_DATA_SEQ_INORDER_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_PDU_INORDER_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_DATA_PDU_INORDER_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_ERL:
+                       len = sprintf(buf, "%d\n",
+                                     (ha->ip_config.iscsi_options &
+                                      ISCSIOPTS_ERL));
+                       break;
+               case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH:
+                       len = sprintf(buf, "%u\n",
+                                     ha->ip_config.iscsi_max_pdu_size *
+                                     BYTE_UNITS);
+                       break;
+               case ISCSI_IFACE_PARAM_FIRST_BURST:
+                       len = sprintf(buf, "%u\n",
+                                     ha->ip_config.iscsi_first_burst_len *
+                                     BYTE_UNITS);
+                       break;
+               case ISCSI_IFACE_PARAM_MAX_R2T:
+                       len = sprintf(buf, "%d\n",
+                                     ha->ip_config.iscsi_max_outstnd_r2t);
+                       break;
+               case ISCSI_IFACE_PARAM_MAX_BURST:
+                       len = sprintf(buf, "%u\n",
+                                     ha->ip_config.iscsi_max_burst_len *
+                                     BYTE_UNITS);
+                       break;
+               case ISCSI_IFACE_PARAM_CHAP_AUTH_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_CHAP_AUTH_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_BIDI_CHAP_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_BIDI_CHAP_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_DISCOVERY_AUTH_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_DISCOVERY_LOGOUT_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN:
+                       OP_STATE(ha->ip_config.iscsi_options,
+                                ISCSIOPTS_STRICT_LOGIN_COMP_EN, pval);
+
+                       len = sprintf(buf, "%s\n", pval);
+                       break;
+               case ISCSI_IFACE_PARAM_INITIATOR_NAME:
+                       len = sprintf(buf, "%s\n", ha->ip_config.iscsi_name);
+                       break;
+               default:
+                       len = -ENOSYS;
+               }
        }
 
        return len;
@@ -1366,8 +1758,8 @@ static void qla4xxx_set_ipv6(struct scsi_qla_host *ha,
                                cpu_to_le16(
                                  IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE);
                else
-                       ql4_printk(KERN_ERR, ha, "Invalid autocfg setting for "
-                                  "IPv6 addr\n");
+                       ql4_printk(KERN_ERR, ha,
+                                  "Invalid autocfg setting for IPv6 addr\n");
                break;
        case ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG:
                /* Autocfg applies to even interface */
@@ -1383,8 +1775,8 @@ static void qla4xxx_set_ipv6(struct scsi_qla_host *ha,
                        init_fw_cb->ipv6_addtl_opts &= cpu_to_le16(
                                       ~IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR);
                else
-                       ql4_printk(KERN_ERR, ha, "Invalid autocfg setting for "
-                                  "IPv6 linklocal addr\n");
+                       ql4_printk(KERN_ERR, ha,
+                                  "Invalid autocfg setting for IPv6 linklocal addr\n");
                break;
        case ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG:
                /* Autocfg applies to even interface */
@@ -1433,6 +1825,135 @@ static void qla4xxx_set_ipv6(struct scsi_qla_host *ha,
                init_fw_cb->ipv6_port =
                                cpu_to_le16(*(uint16_t *)iface_param->value);
                break;
+       case ISCSI_NET_PARAM_DELAYED_ACK_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
+                       init_fw_cb->ipv6_tcp_opts |=
+                               cpu_to_le16(IPV6_TCPOPT_DELAYED_ACK_DISABLE);
+               else
+                       init_fw_cb->ipv6_tcp_opts &=
+                               cpu_to_le16(~IPV6_TCPOPT_DELAYED_ACK_DISABLE);
+               break;
+       case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
+                       init_fw_cb->ipv6_tcp_opts |=
+                               cpu_to_le16(IPV6_TCPOPT_NAGLE_ALGO_DISABLE);
+               else
+                       init_fw_cb->ipv6_tcp_opts &=
+                               cpu_to_le16(~IPV6_TCPOPT_NAGLE_ALGO_DISABLE);
+               break;
+       case ISCSI_NET_PARAM_TCP_WSF_DISABLE:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
+                       init_fw_cb->ipv6_tcp_opts |=
+                               cpu_to_le16(IPV6_TCPOPT_WINDOW_SCALE_DISABLE);
+               else
+                       init_fw_cb->ipv6_tcp_opts &=
+                               cpu_to_le16(~IPV6_TCPOPT_WINDOW_SCALE_DISABLE);
+               break;
+       case ISCSI_NET_PARAM_TCP_WSF:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_tcp_wsf = iface_param->value[0];
+               break;
+       case ISCSI_NET_PARAM_TCP_TIMER_SCALE:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_tcp_opts &=
+                                       cpu_to_le16(~IPV6_TCPOPT_TIMER_SCALE);
+               init_fw_cb->ipv6_tcp_opts |=
+                               cpu_to_le16((iface_param->value[0] << 1) &
+                                           IPV6_TCPOPT_TIMER_SCALE);
+               break;
+       case ISCSI_NET_PARAM_TCP_TIMESTAMP_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv6_tcp_opts |=
+                               cpu_to_le16(IPV6_TCPOPT_TIMESTAMP_EN);
+               else
+                       init_fw_cb->ipv6_tcp_opts &=
+                               cpu_to_le16(~IPV6_TCPOPT_TIMESTAMP_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv6_opts |=
+                               cpu_to_le16(IPV6_OPT_GRAT_NEIGHBOR_ADV_EN);
+               else
+                       init_fw_cb->ipv6_opts &=
+                               cpu_to_le16(~IPV6_OPT_GRAT_NEIGHBOR_ADV_EN);
+               break;
+       case ISCSI_NET_PARAM_REDIRECT_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv6_opts |=
+                               cpu_to_le16(IPV6_OPT_REDIRECT_EN);
+               else
+                       init_fw_cb->ipv6_opts &=
+                               cpu_to_le16(~IPV6_OPT_REDIRECT_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV6_MLD_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv6_addtl_opts |=
+                               cpu_to_le16(IPV6_ADDOPT_MLD_EN);
+               else
+                       init_fw_cb->ipv6_addtl_opts &=
+                               cpu_to_le16(~IPV6_ADDOPT_MLD_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV6_FLOW_LABEL:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_flow_lbl =
+                               cpu_to_le16(*(uint16_t *)iface_param->value);
+               break;
+       case ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_traffic_class = iface_param->value[0];
+               break;
+       case ISCSI_NET_PARAM_IPV6_HOP_LIMIT:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_hop_limit = iface_param->value[0];
+               break;
+       case ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_nd_reach_time =
+                               cpu_to_le32(*(uint32_t *)iface_param->value);
+               break;
+       case ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_nd_rexmit_timer =
+                               cpu_to_le32(*(uint32_t *)iface_param->value);
+               break;
+       case ISCSI_NET_PARAM_IPV6_ND_STALE_TMO:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_nd_stale_timeout =
+                               cpu_to_le32(*(uint32_t *)iface_param->value);
+               break;
+       case ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_dup_addr_detect_count = iface_param->value[0];
+               break;
+       case ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv6_gw_advrt_mtu =
+                               cpu_to_le32(*(uint32_t *)iface_param->value);
+               break;
        default:
                ql4_printk(KERN_ERR, ha, "Unknown IPv6 param = %d\n",
                           iface_param->param);
@@ -1501,6 +2022,195 @@ static void qla4xxx_set_ipv4(struct scsi_qla_host *ha,
                init_fw_cb->ipv4_port =
                                cpu_to_le16(*(uint16_t *)iface_param->value);
                break;
+       case ISCSI_NET_PARAM_DELAYED_ACK_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
+                       init_fw_cb->ipv4_tcp_opts |=
+                               cpu_to_le16(TCPOPT_DELAYED_ACK_DISABLE);
+               else
+                       init_fw_cb->ipv4_tcp_opts &=
+                               cpu_to_le16(~TCPOPT_DELAYED_ACK_DISABLE);
+               break;
+       case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
+                       init_fw_cb->ipv4_tcp_opts |=
+                               cpu_to_le16(TCPOPT_NAGLE_ALGO_DISABLE);
+               else
+                       init_fw_cb->ipv4_tcp_opts &=
+                               cpu_to_le16(~TCPOPT_NAGLE_ALGO_DISABLE);
+               break;
+       case ISCSI_NET_PARAM_TCP_WSF_DISABLE:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
+                       init_fw_cb->ipv4_tcp_opts |=
+                               cpu_to_le16(TCPOPT_WINDOW_SCALE_DISABLE);
+               else
+                       init_fw_cb->ipv4_tcp_opts &=
+                               cpu_to_le16(~TCPOPT_WINDOW_SCALE_DISABLE);
+               break;
+       case ISCSI_NET_PARAM_TCP_WSF:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv4_tcp_wsf = iface_param->value[0];
+               break;
+       case ISCSI_NET_PARAM_TCP_TIMER_SCALE:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv4_tcp_opts &= cpu_to_le16(~TCPOPT_TIMER_SCALE);
+               init_fw_cb->ipv4_tcp_opts |=
+                               cpu_to_le16((iface_param->value[0] << 1) &
+                                           TCPOPT_TIMER_SCALE);
+               break;
+       case ISCSI_NET_PARAM_TCP_TIMESTAMP_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_tcp_opts |=
+                               cpu_to_le16(TCPOPT_TIMESTAMP_ENABLE);
+               else
+                       init_fw_cb->ipv4_tcp_opts &=
+                               cpu_to_le16(~TCPOPT_TIMESTAMP_ENABLE);
+               break;
+       case ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_tcp_opts |=
+                               cpu_to_le16(TCPOPT_DNS_SERVER_IP_EN);
+               else
+                       init_fw_cb->ipv4_tcp_opts &=
+                               cpu_to_le16(~TCPOPT_DNS_SERVER_IP_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_tcp_opts |=
+                               cpu_to_le16(TCPOPT_SLP_DA_INFO_EN);
+               else
+                       init_fw_cb->ipv4_tcp_opts &=
+                               cpu_to_le16(~TCPOPT_SLP_DA_INFO_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV4_TOS_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_ip_opts |=
+                               cpu_to_le16(IPOPT_IPV4_TOS_EN);
+               else
+                       init_fw_cb->ipv4_ip_opts &=
+                               cpu_to_le16(~IPOPT_IPV4_TOS_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV4_TOS:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv4_tos = iface_param->value[0];
+               break;
+       case ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_ip_opts |=
+                                       cpu_to_le16(IPOPT_GRAT_ARP_EN);
+               else
+                       init_fw_cb->ipv4_ip_opts &=
+                                       cpu_to_le16(~IPOPT_GRAT_ARP_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_ip_opts |=
+                               cpu_to_le16(IPOPT_ALT_CID_EN);
+               else
+                       init_fw_cb->ipv4_ip_opts &=
+                               cpu_to_le16(~IPOPT_ALT_CID_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               memcpy(init_fw_cb->ipv4_dhcp_alt_cid, iface_param->value,
+                      (sizeof(init_fw_cb->ipv4_dhcp_alt_cid) - 1));
+               init_fw_cb->ipv4_dhcp_alt_cid_len =
+                                       strlen(init_fw_cb->ipv4_dhcp_alt_cid);
+               break;
+       case ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_ip_opts |=
+                                       cpu_to_le16(IPOPT_REQ_VID_EN);
+               else
+                       init_fw_cb->ipv4_ip_opts &=
+                                       cpu_to_le16(~IPOPT_REQ_VID_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_ip_opts |=
+                                       cpu_to_le16(IPOPT_USE_VID_EN);
+               else
+                       init_fw_cb->ipv4_ip_opts &=
+                                       cpu_to_le16(~IPOPT_USE_VID_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               memcpy(init_fw_cb->ipv4_dhcp_vid, iface_param->value,
+                      (sizeof(init_fw_cb->ipv4_dhcp_vid) - 1));
+               init_fw_cb->ipv4_dhcp_vid_len =
+                                       strlen(init_fw_cb->ipv4_dhcp_vid);
+               break;
+       case ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_ip_opts |=
+                                       cpu_to_le16(IPOPT_LEARN_IQN_EN);
+               else
+                       init_fw_cb->ipv4_ip_opts &=
+                                       cpu_to_le16(~IPOPT_LEARN_IQN_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
+                       init_fw_cb->ipv4_ip_opts |=
+                               cpu_to_le16(IPOPT_FRAGMENTATION_DISABLE);
+               else
+                       init_fw_cb->ipv4_ip_opts &=
+                               cpu_to_le16(~IPOPT_FRAGMENTATION_DISABLE);
+               break;
+       case ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_ip_opts |=
+                               cpu_to_le16(IPOPT_IN_FORWARD_EN);
+               else
+                       init_fw_cb->ipv4_ip_opts &=
+                               cpu_to_le16(~IPOPT_IN_FORWARD_EN);
+               break;
+       case ISCSI_NET_PARAM_REDIRECT_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->ipv4_ip_opts |=
+                               cpu_to_le16(IPOPT_ARP_REDIRECT_EN);
+               else
+                       init_fw_cb->ipv4_ip_opts &=
+                               cpu_to_le16(~IPOPT_ARP_REDIRECT_EN);
+               break;
+       case ISCSI_NET_PARAM_IPV4_TTL:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->ipv4_ttl = iface_param->value[0];
+               break;
        default:
                ql4_printk(KERN_ERR, ha, "Unknown IPv4 param = %d\n",
                           iface_param->param);
@@ -1508,6 +2218,168 @@ static void qla4xxx_set_ipv4(struct scsi_qla_host *ha,
        }
 }
 
+static void qla4xxx_set_iscsi_param(struct scsi_qla_host *ha,
+                                   struct iscsi_iface_param_info *iface_param,
+                                   struct addr_ctrl_blk *init_fw_cb)
+{
+       switch (iface_param->param) {
+       case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->def_timeout =
+                               cpu_to_le16(*(uint16_t *)iface_param->value);
+               break;
+       case ISCSI_IFACE_PARAM_HDRDGST_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_HEADER_DIGEST_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_HEADER_DIGEST_EN);
+               break;
+       case ISCSI_IFACE_PARAM_DATADGST_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_DATA_DIGEST_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_DATA_DIGEST_EN);
+               break;
+       case ISCSI_IFACE_PARAM_IMM_DATA_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_IMMEDIATE_DATA_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_IMMEDIATE_DATA_EN);
+               break;
+       case ISCSI_IFACE_PARAM_INITIAL_R2T_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_INITIAL_R2T_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_INITIAL_R2T_EN);
+               break;
+       case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_DATA_SEQ_INORDER_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_DATA_SEQ_INORDER_EN);
+               break;
+       case ISCSI_IFACE_PARAM_PDU_INORDER_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_DATA_PDU_INORDER_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_DATA_PDU_INORDER_EN);
+               break;
+       case ISCSI_IFACE_PARAM_ERL:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->iscsi_opts &= cpu_to_le16(~ISCSIOPTS_ERL);
+               init_fw_cb->iscsi_opts |= cpu_to_le16(iface_param->value[0] &
+                                                     ISCSIOPTS_ERL);
+               break;
+       case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->iscsi_max_pdu_size =
+                               cpu_to_le32(*(uint32_t *)iface_param->value) /
+                               BYTE_UNITS;
+               break;
+       case ISCSI_IFACE_PARAM_FIRST_BURST:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->iscsi_fburst_len =
+                               cpu_to_le32(*(uint32_t *)iface_param->value) /
+                               BYTE_UNITS;
+               break;
+       case ISCSI_IFACE_PARAM_MAX_R2T:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->iscsi_max_outstnd_r2t =
+                               cpu_to_le16(*(uint16_t *)iface_param->value);
+               break;
+       case ISCSI_IFACE_PARAM_MAX_BURST:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               init_fw_cb->iscsi_max_burst_len =
+                               cpu_to_le32(*(uint32_t *)iface_param->value) /
+                               BYTE_UNITS;
+               break;
+       case ISCSI_IFACE_PARAM_CHAP_AUTH_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_CHAP_AUTH_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_CHAP_AUTH_EN);
+               break;
+       case ISCSI_IFACE_PARAM_BIDI_CHAP_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_BIDI_CHAP_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_BIDI_CHAP_EN);
+               break;
+       case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_DISCOVERY_AUTH_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_DISCOVERY_AUTH_EN);
+               break;
+       case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_DISCOVERY_LOGOUT_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_DISCOVERY_LOGOUT_EN);
+               break;
+       case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN:
+               if (iface_param->iface_num & 0x1)
+                       break;
+               if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
+                       init_fw_cb->iscsi_opts |=
+                               cpu_to_le16(ISCSIOPTS_STRICT_LOGIN_COMP_EN);
+               else
+                       init_fw_cb->iscsi_opts &=
+                               cpu_to_le16(~ISCSIOPTS_STRICT_LOGIN_COMP_EN);
+               break;
+       default:
+               ql4_printk(KERN_ERR, ha, "Unknown iscsi param = %d\n",
+                          iface_param->param);
+               break;
+       }
+}
+
 static void
 qla4xxx_initcb_to_acb(struct addr_ctrl_blk *init_fw_cb)
 {
@@ -1565,40 +2437,47 @@ qla4xxx_iface_set_param(struct Scsi_Host *shost, void *data, uint32_t len)
        nla_for_each_attr(attr, data, len, rem) {
                iface_param = nla_data(attr);
 
-               if (iface_param->param_type != ISCSI_NET_PARAM)
-                       continue;
-
-               switch (iface_param->iface_type) {
-               case ISCSI_IFACE_TYPE_IPV4:
-                       switch (iface_param->iface_num) {
-                       case 0:
-                               qla4xxx_set_ipv4(ha, iface_param, init_fw_cb);
-                               break;
-                       default:
+               if (iface_param->param_type == ISCSI_NET_PARAM) {
+                       switch (iface_param->iface_type) {
+                       case ISCSI_IFACE_TYPE_IPV4:
+                               switch (iface_param->iface_num) {
+                               case 0:
+                                       qla4xxx_set_ipv4(ha, iface_param,
+                                                        init_fw_cb);
+                                       break;
+                               default:
                                /* Cannot have more than one IPv4 interface */
-                               ql4_printk(KERN_ERR, ha, "Invalid IPv4 iface "
-                                          "number = %d\n",
-                                          iface_param->iface_num);
+                                       ql4_printk(KERN_ERR, ha,
+                                                  "Invalid IPv4 iface number = %d\n",
+                                                  iface_param->iface_num);
+                                       break;
+                               }
                                break;
-                       }
-                       break;
-               case ISCSI_IFACE_TYPE_IPV6:
-                       switch (iface_param->iface_num) {
-                       case 0:
-                       case 1:
-                               qla4xxx_set_ipv6(ha, iface_param, init_fw_cb);
+                       case ISCSI_IFACE_TYPE_IPV6:
+                               switch (iface_param->iface_num) {
+                               case 0:
+                               case 1:
+                                       qla4xxx_set_ipv6(ha, iface_param,
+                                                        init_fw_cb);
+                                       break;
+                               default:
+                               /* Cannot have more than two IPv6 interface */
+                                       ql4_printk(KERN_ERR, ha,
+                                                  "Invalid IPv6 iface number = %d\n",
+                                                  iface_param->iface_num);
+                                       break;
+                               }
                                break;
                        default:
-                               /* Cannot have more than two IPv6 interface */
-                               ql4_printk(KERN_ERR, ha, "Invalid IPv6 iface "
-                                          "number = %d\n",
-                                          iface_param->iface_num);
+                               ql4_printk(KERN_ERR, ha,
+                                          "Invalid iface type\n");
                                break;
                        }
-                       break;
-               default:
-                       ql4_printk(KERN_ERR, ha, "Invalid iface type\n");
-                       break;
+               } else if (iface_param->param_type == ISCSI_IFACE_PARAM) {
+                               qla4xxx_set_iscsi_param(ha, iface_param,
+                                                       init_fw_cb);
+               } else {
+                       continue;
                }
        }
 
index f4fef72c9bcd64fcd8c0905ae045fd7b4a4fb3b3..7427d94a311f6aebf41c4c790bb4a9c8d23ce253 100644 (file)
@@ -5,4 +5,4 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 
-#define QLA4XXX_DRIVER_VERSION "5.04.00-k1"
+#define QLA4XXX_DRIVER_VERSION "5.04.00-k2"
index 80b8b10edf4186bbbca2224c041b78fd5b0c8568..2decc6417518ffb1b730ad2a0c842df6f3f62411 100644 (file)
@@ -2873,13 +2873,13 @@ static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host)
        return 0;
 }
 
-static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf)
+static ssize_t delay_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_delay);
 }
 
-static ssize_t sdebug_delay_store(struct device_driver * ddp,
-                                 const char * buf, size_t count)
+static ssize_t delay_store(struct device_driver *ddp, const char *buf,
+                          size_t count)
 {
         int delay;
        char work[20];
@@ -2892,16 +2892,15 @@ static ssize_t sdebug_delay_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show,
-           sdebug_delay_store);
+static DRIVER_ATTR_RW(delay);
 
-static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf)
+static ssize_t opts_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "0x%x\n", scsi_debug_opts);
 }
 
-static ssize_t sdebug_opts_store(struct device_driver * ddp,
-                                const char * buf, size_t count)
+static ssize_t opts_store(struct device_driver *ddp, const char *buf,
+                         size_t count)
 {
         int opts;
        char work[20];
@@ -2921,15 +2920,14 @@ opts_done:
        scsi_debug_cmnd_count = 0;
        return count;
 }
-DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show,
-           sdebug_opts_store);
+static DRIVER_ATTR_RW(opts);
 
-static ssize_t sdebug_ptype_show(struct device_driver * ddp, char * buf)
+static ssize_t ptype_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_ptype);
 }
-static ssize_t sdebug_ptype_store(struct device_driver * ddp,
-                                 const char * buf, size_t count)
+static ssize_t ptype_store(struct device_driver *ddp, const char *buf,
+                          size_t count)
 {
         int n;
 
@@ -2939,14 +2937,14 @@ static ssize_t sdebug_ptype_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(ptype, S_IRUGO | S_IWUSR, sdebug_ptype_show, sdebug_ptype_store);
+static DRIVER_ATTR_RW(ptype);
 
-static ssize_t sdebug_dsense_show(struct device_driver * ddp, char * buf)
+static ssize_t dsense_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dsense);
 }
-static ssize_t sdebug_dsense_store(struct device_driver * ddp,
-                                 const char * buf, size_t count)
+static ssize_t dsense_store(struct device_driver *ddp, const char *buf,
+                           size_t count)
 {
         int n;
 
@@ -2956,15 +2954,14 @@ static ssize_t sdebug_dsense_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show,
-           sdebug_dsense_store);
+static DRIVER_ATTR_RW(dsense);
 
-static ssize_t sdebug_fake_rw_show(struct device_driver * ddp, char * buf)
+static ssize_t fake_rw_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_fake_rw);
 }
-static ssize_t sdebug_fake_rw_store(struct device_driver * ddp,
-                                   const char * buf, size_t count)
+static ssize_t fake_rw_store(struct device_driver *ddp, const char *buf,
+                            size_t count)
 {
         int n;
 
@@ -2974,15 +2971,14 @@ static ssize_t sdebug_fake_rw_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(fake_rw, S_IRUGO | S_IWUSR, sdebug_fake_rw_show,
-           sdebug_fake_rw_store);
+static DRIVER_ATTR_RW(fake_rw);
 
-static ssize_t sdebug_no_lun_0_show(struct device_driver * ddp, char * buf)
+static ssize_t no_lun_0_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_no_lun_0);
 }
-static ssize_t sdebug_no_lun_0_store(struct device_driver * ddp,
-                                    const char * buf, size_t count)
+static ssize_t no_lun_0_store(struct device_driver *ddp, const char *buf,
+                             size_t count)
 {
         int n;
 
@@ -2992,15 +2988,14 @@ static ssize_t sdebug_no_lun_0_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(no_lun_0, S_IRUGO | S_IWUSR, sdebug_no_lun_0_show,
-           sdebug_no_lun_0_store);
+static DRIVER_ATTR_RW(no_lun_0);
 
-static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf)
+static ssize_t num_tgts_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts);
 }
-static ssize_t sdebug_num_tgts_store(struct device_driver * ddp,
-                                    const char * buf, size_t count)
+static ssize_t num_tgts_store(struct device_driver *ddp, const char *buf,
+                             size_t count)
 {
         int n;
 
@@ -3011,27 +3006,26 @@ static ssize_t sdebug_num_tgts_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show,
-           sdebug_num_tgts_store);
+static DRIVER_ATTR_RW(num_tgts);
 
-static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf)
+static ssize_t dev_size_mb_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dev_size_mb);
 }
-DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL);
+static DRIVER_ATTR_RO(dev_size_mb);
 
-static ssize_t sdebug_num_parts_show(struct device_driver * ddp, char * buf)
+static ssize_t num_parts_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_parts);
 }
-DRIVER_ATTR(num_parts, S_IRUGO, sdebug_num_parts_show, NULL);
+static DRIVER_ATTR_RO(num_parts);
 
-static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf)
+static ssize_t every_nth_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_every_nth);
 }
-static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
-                                     const char * buf, size_t count)
+static ssize_t every_nth_store(struct device_driver *ddp, const char *buf,
+                              size_t count)
 {
         int nth;
 
@@ -3042,15 +3036,14 @@ static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(every_nth, S_IRUGO | S_IWUSR, sdebug_every_nth_show,
-           sdebug_every_nth_store);
+static DRIVER_ATTR_RW(every_nth);
 
-static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf)
+static ssize_t max_luns_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_luns);
 }
-static ssize_t sdebug_max_luns_store(struct device_driver * ddp,
-                                    const char * buf, size_t count)
+static ssize_t max_luns_store(struct device_driver *ddp, const char *buf,
+                             size_t count)
 {
         int n;
 
@@ -3061,15 +3054,14 @@ static ssize_t sdebug_max_luns_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show,
-           sdebug_max_luns_store);
+static DRIVER_ATTR_RW(max_luns);
 
-static ssize_t sdebug_max_queue_show(struct device_driver * ddp, char * buf)
+static ssize_t max_queue_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_queue);
 }
-static ssize_t sdebug_max_queue_store(struct device_driver * ddp,
-                                     const char * buf, size_t count)
+static ssize_t max_queue_store(struct device_driver *ddp, const char *buf,
+                              size_t count)
 {
         int n;
 
@@ -3080,27 +3072,26 @@ static ssize_t sdebug_max_queue_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(max_queue, S_IRUGO | S_IWUSR, sdebug_max_queue_show,
-           sdebug_max_queue_store);
+static DRIVER_ATTR_RW(max_queue);
 
-static ssize_t sdebug_no_uld_show(struct device_driver * ddp, char * buf)
+static ssize_t no_uld_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_no_uld);
 }
-DRIVER_ATTR(no_uld, S_IRUGO, sdebug_no_uld_show, NULL);
+static DRIVER_ATTR_RO(no_uld);
 
-static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf)
+static ssize_t scsi_level_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level);
 }
-DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL);
+static DRIVER_ATTR_RO(scsi_level);
 
-static ssize_t sdebug_virtual_gb_show(struct device_driver * ddp, char * buf)
+static ssize_t virtual_gb_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_virtual_gb);
 }
-static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp,
-                                      const char * buf, size_t count)
+static ssize_t virtual_gb_store(struct device_driver *ddp, const char *buf,
+                               size_t count)
 {
         int n;
 
@@ -3113,16 +3104,15 @@ static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(virtual_gb, S_IRUGO | S_IWUSR, sdebug_virtual_gb_show,
-           sdebug_virtual_gb_store);
+static DRIVER_ATTR_RW(virtual_gb);
 
-static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf)
+static ssize_t add_host_show(struct device_driver *ddp, char *buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host);
 }
 
-static ssize_t sdebug_add_host_store(struct device_driver * ddp,
-                                    const char * buf, size_t count)
+static ssize_t add_host_store(struct device_driver *ddp, const char *buf,
+                             size_t count)
 {
        int delta_hosts;
 
@@ -3139,16 +3129,14 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
        }
        return count;
 }
-DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show,
-           sdebug_add_host_store);
+static DRIVER_ATTR_RW(add_host);
 
-static ssize_t sdebug_vpd_use_hostno_show(struct device_driver * ddp,
-                                         char * buf)
+static ssize_t vpd_use_hostno_show(struct device_driver *ddp, char *buf)
 {
        return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_vpd_use_hostno);
 }
-static ssize_t sdebug_vpd_use_hostno_store(struct device_driver * ddp,
-                                          const char * buf, size_t count)
+static ssize_t vpd_use_hostno_store(struct device_driver *ddp, const char *buf,
+                                   size_t count)
 {
        int n;
 
@@ -3158,40 +3146,39 @@ static ssize_t sdebug_vpd_use_hostno_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(vpd_use_hostno, S_IRUGO | S_IWUSR, sdebug_vpd_use_hostno_show,
-           sdebug_vpd_use_hostno_store);
+static DRIVER_ATTR_RW(vpd_use_hostno);
 
-static ssize_t sdebug_sector_size_show(struct device_driver * ddp, char * buf)
+static ssize_t sector_size_show(struct device_driver *ddp, char *buf)
 {
        return scnprintf(buf, PAGE_SIZE, "%u\n", scsi_debug_sector_size);
 }
-DRIVER_ATTR(sector_size, S_IRUGO, sdebug_sector_size_show, NULL);
+static DRIVER_ATTR_RO(sector_size);
 
-static ssize_t sdebug_dix_show(struct device_driver *ddp, char *buf)
+static ssize_t dix_show(struct device_driver *ddp, char *buf)
 {
        return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dix);
 }
-DRIVER_ATTR(dix, S_IRUGO, sdebug_dix_show, NULL);
+static DRIVER_ATTR_RO(dix);
 
-static ssize_t sdebug_dif_show(struct device_driver *ddp, char *buf)
+static ssize_t dif_show(struct device_driver *ddp, char *buf)
 {
        return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dif);
 }
-DRIVER_ATTR(dif, S_IRUGO, sdebug_dif_show, NULL);
+static DRIVER_ATTR_RO(dif);
 
-static ssize_t sdebug_guard_show(struct device_driver *ddp, char *buf)
+static ssize_t guard_show(struct device_driver *ddp, char *buf)
 {
        return scnprintf(buf, PAGE_SIZE, "%u\n", scsi_debug_guard);
 }
-DRIVER_ATTR(guard, S_IRUGO, sdebug_guard_show, NULL);
+static DRIVER_ATTR_RO(guard);
 
-static ssize_t sdebug_ato_show(struct device_driver *ddp, char *buf)
+static ssize_t ato_show(struct device_driver *ddp, char *buf)
 {
        return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_ato);
 }
-DRIVER_ATTR(ato, S_IRUGO, sdebug_ato_show, NULL);
+static DRIVER_ATTR_RO(ato);
 
-static ssize_t sdebug_map_show(struct device_driver *ddp, char *buf)
+static ssize_t map_show(struct device_driver *ddp, char *buf)
 {
        ssize_t count;
 
@@ -3206,15 +3193,14 @@ static ssize_t sdebug_map_show(struct device_driver *ddp, char *buf)
 
        return count;
 }
-DRIVER_ATTR(map, S_IRUGO, sdebug_map_show, NULL);
+static DRIVER_ATTR_RO(map);
 
-static ssize_t sdebug_removable_show(struct device_driver *ddp,
-                                    char *buf)
+static ssize_t removable_show(struct device_driver *ddp, char *buf)
 {
        return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_removable ? 1 : 0);
 }
-static ssize_t sdebug_removable_store(struct device_driver *ddp,
-                                     const char *buf, size_t count)
+static ssize_t removable_store(struct device_driver *ddp, const char *buf,
+                              size_t count)
 {
        int n;
 
@@ -3224,74 +3210,43 @@ static ssize_t sdebug_removable_store(struct device_driver *ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(removable, S_IRUGO | S_IWUSR, sdebug_removable_show,
-           sdebug_removable_store);
+static DRIVER_ATTR_RW(removable);
 
-
-/* Note: The following function creates attribute files in the
+/* Note: The following array creates attribute files in the
    /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these
    files (over those found in the /sys/module/scsi_debug/parameters
    directory) is that auxiliary actions can be triggered when an attribute
    is changed. For example see: sdebug_add_host_store() above.
  */
-static int do_create_driverfs_files(void)
-{
-       int ret;
 
-       ret = driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_fake_rw);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_queue);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_no_uld);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_removable);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_sector_size);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dix);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dif);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_guard);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ato);
-       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_map);
-       return ret;
-}
-
-static void do_remove_driverfs_files(void)
-{
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_map);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ato);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_guard);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dif);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dix);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_sector_size);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_removable);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_no_uld);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_queue);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_fake_rw);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dsense);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_delay);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host);
-}
+static struct attribute *sdebug_drv_attrs[] = {
+       &driver_attr_delay.attr,
+       &driver_attr_opts.attr,
+       &driver_attr_ptype.attr,
+       &driver_attr_dsense.attr,
+       &driver_attr_fake_rw.attr,
+       &driver_attr_no_lun_0.attr,
+       &driver_attr_num_tgts.attr,
+       &driver_attr_dev_size_mb.attr,
+       &driver_attr_num_parts.attr,
+       &driver_attr_every_nth.attr,
+       &driver_attr_max_luns.attr,
+       &driver_attr_max_queue.attr,
+       &driver_attr_no_uld.attr,
+       &driver_attr_scsi_level.attr,
+       &driver_attr_virtual_gb.attr,
+       &driver_attr_add_host.attr,
+       &driver_attr_vpd_use_hostno.attr,
+       &driver_attr_sector_size.attr,
+       &driver_attr_dix.attr,
+       &driver_attr_dif.attr,
+       &driver_attr_guard.attr,
+       &driver_attr_ato.attr,
+       &driver_attr_map.attr,
+       &driver_attr_removable.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(sdebug_drv);
 
 struct device *pseudo_primary;
 
@@ -3456,12 +3411,6 @@ static int __init scsi_debug_init(void)
                        ret);
                goto bus_unreg;
        }
-       ret = do_create_driverfs_files();
-       if (ret < 0) {
-               printk(KERN_WARNING "scsi_debug: driver_create_file error: %d\n",
-                       ret);
-               goto del_files;
-       }
 
        init_all_queued();
 
@@ -3482,9 +3431,6 @@ static int __init scsi_debug_init(void)
        }
        return 0;
 
-del_files:
-       do_remove_driverfs_files();
-       driver_unregister(&sdebug_driverfs_driver);
 bus_unreg:
        bus_unregister(&pseudo_lld_bus);
 dev_unreg:
@@ -3506,7 +3452,6 @@ static void __exit scsi_debug_exit(void)
        stop_all_queued();
        for (; k; k--)
                sdebug_remove_adapter();
-       do_remove_driverfs_files();
        driver_unregister(&sdebug_driverfs_driver);
        bus_unregister(&pseudo_lld_bus);
        root_device_unregister(pseudo_primary);
@@ -4096,4 +4041,5 @@ static struct bus_type pseudo_lld_bus = {
        .match = pseudo_lld_bus_match,
        .probe = sdebug_driver_probe,
        .remove = sdebug_driver_remove,
+       .drv_groups = sdebug_drv_groups,
 };
index af4c050ce6e4e96179f586aae4c54690229b9705..001e9ceda4c3b51bed2ba47248d9333e18d39487 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "scsi_priv.h"
 
+#ifdef CONFIG_PM_SLEEP
+
 static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *))
 {
        int err;
@@ -43,8 +45,6 @@ static int scsi_dev_type_resume(struct device *dev, int (*cb)(struct device *))
        return err;
 }
 
-#ifdef CONFIG_PM_SLEEP
-
 static int
 scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *))
 {
@@ -145,38 +145,22 @@ static int scsi_bus_restore(struct device *dev)
 
 #ifdef CONFIG_PM_RUNTIME
 
-static int sdev_blk_runtime_suspend(struct scsi_device *sdev,
-                                       int (*cb)(struct device *))
+static int sdev_runtime_suspend(struct device *dev)
 {
+       const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+       struct scsi_device *sdev = to_scsi_device(dev);
        int err;
 
        err = blk_pre_runtime_suspend(sdev->request_queue);
        if (err)
                return err;
-       if (cb)
-               err = cb(&sdev->sdev_gendev);
+       if (pm && pm->runtime_suspend)
+               err = pm->runtime_suspend(dev);
        blk_post_runtime_suspend(sdev->request_queue, err);
 
        return err;
 }
 
-static int sdev_runtime_suspend(struct device *dev)
-{
-       const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-       int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL;
-       struct scsi_device *sdev = to_scsi_device(dev);
-       int err;
-
-       if (sdev->request_queue->dev)
-               return sdev_blk_runtime_suspend(sdev, cb);
-
-       err = scsi_dev_type_suspend(dev, cb);
-       if (err == -EAGAIN)
-               pm_schedule_suspend(dev, jiffies_to_msecs(
-                                       round_jiffies_up_relative(HZ/10)));
-       return err;
-}
-
 static int scsi_runtime_suspend(struct device *dev)
 {
        int err = 0;
@@ -190,31 +174,20 @@ static int scsi_runtime_suspend(struct device *dev)
        return err;
 }
 
-static int sdev_blk_runtime_resume(struct scsi_device *sdev,
-                                       int (*cb)(struct device *))
+static int sdev_runtime_resume(struct device *dev)
 {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
        int err = 0;
 
        blk_pre_runtime_resume(sdev->request_queue);
-       if (cb)
-               err = cb(&sdev->sdev_gendev);
+       if (pm && pm->runtime_resume)
+               err = pm->runtime_resume(dev);
        blk_post_runtime_resume(sdev->request_queue, err);
 
        return err;
 }
 
-static int sdev_runtime_resume(struct device *dev)
-{
-       struct scsi_device *sdev = to_scsi_device(dev);
-       const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-       int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL;
-
-       if (sdev->request_queue->dev)
-               return sdev_blk_runtime_resume(sdev, cb);
-       else
-               return scsi_dev_type_resume(dev, cb);
-}
-
 static int scsi_runtime_resume(struct device *dev)
 {
        int err = 0;
@@ -235,14 +208,11 @@ static int scsi_runtime_idle(struct device *dev)
        /* Insert hooks here for targets, hosts, and transport classes */
 
        if (scsi_is_sdev_device(dev)) {
-               struct scsi_device *sdev = to_scsi_device(dev);
-
-               if (sdev->request_queue->dev) {
-                       pm_runtime_mark_last_busy(dev);
-                       pm_runtime_autosuspend(dev);
-                       return -EBUSY;
-               }
+               pm_runtime_mark_last_busy(dev);
+               pm_runtime_autosuspend(dev);
+               return -EBUSY;
        }
+
        return 0;
 }
 
index 63a6ca49d4e5e8d1b0f53c592943c279bcffcb60..9477f84c83a6c16163dd8d04ac3a2738b966ddad 100644 (file)
@@ -305,20 +305,71 @@ show_##type##_##name(struct device *dev, struct device_attribute *attr,   \
        iscsi_iface_attr_show(type, name, ISCSI_NET_PARAM, param)       \
 static ISCSI_IFACE_ATTR(type, name, S_IRUGO, show_##type##_##name, NULL);
 
-/* generic read only ipvi4 attribute */
+#define iscsi_iface_attr(type, name, param)                            \
+       iscsi_iface_attr_show(type, name, ISCSI_IFACE_PARAM, param)     \
+static ISCSI_IFACE_ATTR(type, name, S_IRUGO, show_##type##_##name, NULL);
+
+/* generic read only ipv4 attribute */
 iscsi_iface_net_attr(ipv4_iface, ipaddress, ISCSI_NET_PARAM_IPV4_ADDR);
 iscsi_iface_net_attr(ipv4_iface, gateway, ISCSI_NET_PARAM_IPV4_GW);
 iscsi_iface_net_attr(ipv4_iface, subnet, ISCSI_NET_PARAM_IPV4_SUBNET);
 iscsi_iface_net_attr(ipv4_iface, bootproto, ISCSI_NET_PARAM_IPV4_BOOTPROTO);
+iscsi_iface_net_attr(ipv4_iface, dhcp_dns_address_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_slp_da_info_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN);
+iscsi_iface_net_attr(ipv4_iface, tos_en, ISCSI_NET_PARAM_IPV4_TOS_EN);
+iscsi_iface_net_attr(ipv4_iface, tos, ISCSI_NET_PARAM_IPV4_TOS);
+iscsi_iface_net_attr(ipv4_iface, grat_arp_en,
+                    ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_alt_client_id_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_alt_client_id,
+                    ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID);
+iscsi_iface_net_attr(ipv4_iface, dhcp_req_vendor_id_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_use_vendor_id_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN);
+iscsi_iface_net_attr(ipv4_iface, dhcp_vendor_id,
+                    ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID);
+iscsi_iface_net_attr(ipv4_iface, dhcp_learn_iqn_en,
+                    ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN);
+iscsi_iface_net_attr(ipv4_iface, fragment_disable,
+                    ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE);
+iscsi_iface_net_attr(ipv4_iface, incoming_forwarding_en,
+                    ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN);
+iscsi_iface_net_attr(ipv4_iface, ttl, ISCSI_NET_PARAM_IPV4_TTL);
 
 /* generic read only ipv6 attribute */
 iscsi_iface_net_attr(ipv6_iface, ipaddress, ISCSI_NET_PARAM_IPV6_ADDR);
-iscsi_iface_net_attr(ipv6_iface, link_local_addr, ISCSI_NET_PARAM_IPV6_LINKLOCAL);
+iscsi_iface_net_attr(ipv6_iface, link_local_addr,
+                    ISCSI_NET_PARAM_IPV6_LINKLOCAL);
 iscsi_iface_net_attr(ipv6_iface, router_addr, ISCSI_NET_PARAM_IPV6_ROUTER);
 iscsi_iface_net_attr(ipv6_iface, ipaddr_autocfg,
                     ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG);
 iscsi_iface_net_attr(ipv6_iface, link_local_autocfg,
                     ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG);
+iscsi_iface_net_attr(ipv6_iface, link_local_state,
+                    ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE);
+iscsi_iface_net_attr(ipv6_iface, router_state,
+                    ISCSI_NET_PARAM_IPV6_ROUTER_STATE);
+iscsi_iface_net_attr(ipv6_iface, grat_neighbor_adv_en,
+                    ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN);
+iscsi_iface_net_attr(ipv6_iface, mld_en, ISCSI_NET_PARAM_IPV6_MLD_EN);
+iscsi_iface_net_attr(ipv6_iface, flow_label, ISCSI_NET_PARAM_IPV6_FLOW_LABEL);
+iscsi_iface_net_attr(ipv6_iface, traffic_class,
+                    ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS);
+iscsi_iface_net_attr(ipv6_iface, hop_limit, ISCSI_NET_PARAM_IPV6_HOP_LIMIT);
+iscsi_iface_net_attr(ipv6_iface, nd_reachable_tmo,
+                    ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO);
+iscsi_iface_net_attr(ipv6_iface, nd_rexmit_time,
+                    ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME);
+iscsi_iface_net_attr(ipv6_iface, nd_stale_tmo,
+                    ISCSI_NET_PARAM_IPV6_ND_STALE_TMO);
+iscsi_iface_net_attr(ipv6_iface, dup_addr_detect_cnt,
+                    ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT);
+iscsi_iface_net_attr(ipv6_iface, router_adv_link_mtu,
+                    ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU);
 
 /* common read only iface attribute */
 iscsi_iface_net_attr(iface, enabled, ISCSI_NET_PARAM_IFACE_ENABLE);
@@ -327,6 +378,40 @@ iscsi_iface_net_attr(iface, vlan_priority, ISCSI_NET_PARAM_VLAN_PRIORITY);
 iscsi_iface_net_attr(iface, vlan_enabled, ISCSI_NET_PARAM_VLAN_ENABLED);
 iscsi_iface_net_attr(iface, mtu, ISCSI_NET_PARAM_MTU);
 iscsi_iface_net_attr(iface, port, ISCSI_NET_PARAM_PORT);
+iscsi_iface_net_attr(iface, ipaddress_state, ISCSI_NET_PARAM_IPADDR_STATE);
+iscsi_iface_net_attr(iface, delayed_ack_en, ISCSI_NET_PARAM_DELAYED_ACK_EN);
+iscsi_iface_net_attr(iface, tcp_nagle_disable,
+                    ISCSI_NET_PARAM_TCP_NAGLE_DISABLE);
+iscsi_iface_net_attr(iface, tcp_wsf_disable, ISCSI_NET_PARAM_TCP_WSF_DISABLE);
+iscsi_iface_net_attr(iface, tcp_wsf, ISCSI_NET_PARAM_TCP_WSF);
+iscsi_iface_net_attr(iface, tcp_timer_scale, ISCSI_NET_PARAM_TCP_TIMER_SCALE);
+iscsi_iface_net_attr(iface, tcp_timestamp_en, ISCSI_NET_PARAM_TCP_TIMESTAMP_EN);
+iscsi_iface_net_attr(iface, cache_id, ISCSI_NET_PARAM_CACHE_ID);
+iscsi_iface_net_attr(iface, redirect_en, ISCSI_NET_PARAM_REDIRECT_EN);
+
+/* common iscsi specific settings attributes */
+iscsi_iface_attr(iface, def_taskmgmt_tmo, ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO);
+iscsi_iface_attr(iface, header_digest, ISCSI_IFACE_PARAM_HDRDGST_EN);
+iscsi_iface_attr(iface, data_digest, ISCSI_IFACE_PARAM_DATADGST_EN);
+iscsi_iface_attr(iface, immediate_data, ISCSI_IFACE_PARAM_IMM_DATA_EN);
+iscsi_iface_attr(iface, initial_r2t, ISCSI_IFACE_PARAM_INITIAL_R2T_EN);
+iscsi_iface_attr(iface, data_seq_in_order,
+                ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN);
+iscsi_iface_attr(iface, data_pdu_in_order, ISCSI_IFACE_PARAM_PDU_INORDER_EN);
+iscsi_iface_attr(iface, erl, ISCSI_IFACE_PARAM_ERL);
+iscsi_iface_attr(iface, max_recv_dlength, ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH);
+iscsi_iface_attr(iface, first_burst_len, ISCSI_IFACE_PARAM_FIRST_BURST);
+iscsi_iface_attr(iface, max_outstanding_r2t, ISCSI_IFACE_PARAM_MAX_R2T);
+iscsi_iface_attr(iface, max_burst_len, ISCSI_IFACE_PARAM_MAX_BURST);
+iscsi_iface_attr(iface, chap_auth, ISCSI_IFACE_PARAM_CHAP_AUTH_EN);
+iscsi_iface_attr(iface, bidi_chap, ISCSI_IFACE_PARAM_BIDI_CHAP_EN);
+iscsi_iface_attr(iface, discovery_auth_optional,
+                ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL);
+iscsi_iface_attr(iface, discovery_logout,
+                ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN);
+iscsi_iface_attr(iface, strict_login_comp_en,
+                ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN);
+iscsi_iface_attr(iface, initiator_name, ISCSI_IFACE_PARAM_INITIATOR_NAME);
 
 static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                                          struct attribute *attr, int i)
@@ -335,6 +420,7 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
        struct iscsi_iface *iface = iscsi_dev_to_iface(dev);
        struct iscsi_transport *t = iface->transport;
        int param;
+       int param_type;
 
        if (attr == &dev_attr_iface_enabled.attr)
                param = ISCSI_NET_PARAM_IFACE_ENABLE;
@@ -348,6 +434,60 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                param = ISCSI_NET_PARAM_MTU;
        else if (attr == &dev_attr_iface_port.attr)
                param = ISCSI_NET_PARAM_PORT;
+       else if (attr == &dev_attr_iface_ipaddress_state.attr)
+               param = ISCSI_NET_PARAM_IPADDR_STATE;
+       else if (attr == &dev_attr_iface_delayed_ack_en.attr)
+               param = ISCSI_NET_PARAM_DELAYED_ACK_EN;
+       else if (attr == &dev_attr_iface_tcp_nagle_disable.attr)
+               param = ISCSI_NET_PARAM_TCP_NAGLE_DISABLE;
+       else if (attr == &dev_attr_iface_tcp_wsf_disable.attr)
+               param = ISCSI_NET_PARAM_TCP_WSF_DISABLE;
+       else if (attr == &dev_attr_iface_tcp_wsf.attr)
+               param = ISCSI_NET_PARAM_TCP_WSF;
+       else if (attr == &dev_attr_iface_tcp_timer_scale.attr)
+               param = ISCSI_NET_PARAM_TCP_TIMER_SCALE;
+       else if (attr == &dev_attr_iface_tcp_timestamp_en.attr)
+               param = ISCSI_NET_PARAM_TCP_TIMESTAMP_EN;
+       else if (attr == &dev_attr_iface_cache_id.attr)
+               param = ISCSI_NET_PARAM_CACHE_ID;
+       else if (attr == &dev_attr_iface_redirect_en.attr)
+               param = ISCSI_NET_PARAM_REDIRECT_EN;
+       else if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr)
+               param = ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO;
+       else if (attr == &dev_attr_iface_header_digest.attr)
+               param = ISCSI_IFACE_PARAM_HDRDGST_EN;
+       else if (attr == &dev_attr_iface_data_digest.attr)
+               param = ISCSI_IFACE_PARAM_DATADGST_EN;
+       else if (attr == &dev_attr_iface_immediate_data.attr)
+               param = ISCSI_IFACE_PARAM_IMM_DATA_EN;
+       else if (attr == &dev_attr_iface_initial_r2t.attr)
+               param = ISCSI_IFACE_PARAM_INITIAL_R2T_EN;
+       else if (attr == &dev_attr_iface_data_seq_in_order.attr)
+               param = ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN;
+       else if (attr == &dev_attr_iface_data_pdu_in_order.attr)
+               param = ISCSI_IFACE_PARAM_PDU_INORDER_EN;
+       else if (attr == &dev_attr_iface_erl.attr)
+               param = ISCSI_IFACE_PARAM_ERL;
+       else if (attr == &dev_attr_iface_max_recv_dlength.attr)
+               param = ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH;
+       else if (attr == &dev_attr_iface_first_burst_len.attr)
+               param = ISCSI_IFACE_PARAM_FIRST_BURST;
+       else if (attr == &dev_attr_iface_max_outstanding_r2t.attr)
+               param = ISCSI_IFACE_PARAM_MAX_R2T;
+       else if (attr == &dev_attr_iface_max_burst_len.attr)
+               param = ISCSI_IFACE_PARAM_MAX_BURST;
+       else if (attr == &dev_attr_iface_chap_auth.attr)
+               param = ISCSI_IFACE_PARAM_CHAP_AUTH_EN;
+       else if (attr == &dev_attr_iface_bidi_chap.attr)
+               param = ISCSI_IFACE_PARAM_BIDI_CHAP_EN;
+       else if (attr == &dev_attr_iface_discovery_auth_optional.attr)
+               param = ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL;
+       else if (attr == &dev_attr_iface_discovery_logout.attr)
+               param = ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN;
+       else if (attr == &dev_attr_iface_strict_login_comp_en.attr)
+               param = ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN;
+       else if (attr == &dev_attr_iface_initiator_name.attr)
+               param = ISCSI_IFACE_PARAM_INITIATOR_NAME;
        else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
                if (attr == &dev_attr_ipv4_iface_ipaddress.attr)
                        param = ISCSI_NET_PARAM_IPV4_ADDR;
@@ -357,6 +497,42 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                        param = ISCSI_NET_PARAM_IPV4_SUBNET;
                else if (attr == &dev_attr_ipv4_iface_bootproto.attr)
                        param = ISCSI_NET_PARAM_IPV4_BOOTPROTO;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_dns_address_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_slp_da_info_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN;
+               else if (attr == &dev_attr_ipv4_iface_tos_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_TOS_EN;
+               else if (attr == &dev_attr_ipv4_iface_tos.attr)
+                       param = ISCSI_NET_PARAM_IPV4_TOS;
+               else if (attr == &dev_attr_ipv4_iface_grat_arp_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_alt_client_id_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN;
+               else if (attr == &dev_attr_ipv4_iface_dhcp_alt_client_id.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_req_vendor_id_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_use_vendor_id_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN;
+               else if (attr == &dev_attr_ipv4_iface_dhcp_vendor_id.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_dhcp_learn_iqn_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_fragment_disable.attr)
+                       param = ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE;
+               else if (attr ==
+                        &dev_attr_ipv4_iface_incoming_forwarding_en.attr)
+                       param = ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN;
+               else if (attr == &dev_attr_ipv4_iface_ttl.attr)
+                       param = ISCSI_NET_PARAM_IPV4_TTL;
                else
                        return 0;
        } else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) {
@@ -370,6 +546,31 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                        param = ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG;
                else if (attr == &dev_attr_ipv6_iface_link_local_autocfg.attr)
                        param = ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG;
+               else if (attr == &dev_attr_ipv6_iface_link_local_state.attr)
+                       param = ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE;
+               else if (attr == &dev_attr_ipv6_iface_router_state.attr)
+                       param = ISCSI_NET_PARAM_IPV6_ROUTER_STATE;
+               else if (attr ==
+                        &dev_attr_ipv6_iface_grat_neighbor_adv_en.attr)
+                       param = ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN;
+               else if (attr == &dev_attr_ipv6_iface_mld_en.attr)
+                       param = ISCSI_NET_PARAM_IPV6_MLD_EN;
+               else if (attr == &dev_attr_ipv6_iface_flow_label.attr)
+                       param = ISCSI_NET_PARAM_IPV6_FLOW_LABEL;
+               else if (attr == &dev_attr_ipv6_iface_traffic_class.attr)
+                       param = ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS;
+               else if (attr == &dev_attr_ipv6_iface_hop_limit.attr)
+                       param = ISCSI_NET_PARAM_IPV6_HOP_LIMIT;
+               else if (attr == &dev_attr_ipv6_iface_nd_reachable_tmo.attr)
+                       param = ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO;
+               else if (attr == &dev_attr_ipv6_iface_nd_rexmit_time.attr)
+                       param = ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME;
+               else if (attr == &dev_attr_ipv6_iface_nd_stale_tmo.attr)
+                       param = ISCSI_NET_PARAM_IPV6_ND_STALE_TMO;
+               else if (attr == &dev_attr_ipv6_iface_dup_addr_detect_cnt.attr)
+                       param = ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT;
+               else if (attr == &dev_attr_ipv6_iface_router_adv_link_mtu.attr)
+                       param = ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU;
                else
                        return 0;
        } else {
@@ -377,7 +578,32 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
                return 0;
        }
 
-       return t->attr_is_visible(ISCSI_NET_PARAM, param);
+       switch (param) {
+       case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO:
+       case ISCSI_IFACE_PARAM_HDRDGST_EN:
+       case ISCSI_IFACE_PARAM_DATADGST_EN:
+       case ISCSI_IFACE_PARAM_IMM_DATA_EN:
+       case ISCSI_IFACE_PARAM_INITIAL_R2T_EN:
+       case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN:
+       case ISCSI_IFACE_PARAM_PDU_INORDER_EN:
+       case ISCSI_IFACE_PARAM_ERL:
+       case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH:
+       case ISCSI_IFACE_PARAM_FIRST_BURST:
+       case ISCSI_IFACE_PARAM_MAX_R2T:
+       case ISCSI_IFACE_PARAM_MAX_BURST:
+       case ISCSI_IFACE_PARAM_CHAP_AUTH_EN:
+       case ISCSI_IFACE_PARAM_BIDI_CHAP_EN:
+       case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL:
+       case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN:
+       case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN:
+       case ISCSI_IFACE_PARAM_INITIATOR_NAME:
+               param_type = ISCSI_IFACE_PARAM;
+               break;
+       default:
+               param_type = ISCSI_NET_PARAM;
+       }
+
+       return t->attr_is_visible(param_type, param);
 }
 
 static struct attribute *iscsi_iface_attrs[] = {
@@ -396,6 +622,59 @@ static struct attribute *iscsi_iface_attrs[] = {
        &dev_attr_ipv6_iface_link_local_autocfg.attr,
        &dev_attr_iface_mtu.attr,
        &dev_attr_iface_port.attr,
+       &dev_attr_iface_ipaddress_state.attr,
+       &dev_attr_iface_delayed_ack_en.attr,
+       &dev_attr_iface_tcp_nagle_disable.attr,
+       &dev_attr_iface_tcp_wsf_disable.attr,
+       &dev_attr_iface_tcp_wsf.attr,
+       &dev_attr_iface_tcp_timer_scale.attr,
+       &dev_attr_iface_tcp_timestamp_en.attr,
+       &dev_attr_iface_cache_id.attr,
+       &dev_attr_iface_redirect_en.attr,
+       &dev_attr_iface_def_taskmgmt_tmo.attr,
+       &dev_attr_iface_header_digest.attr,
+       &dev_attr_iface_data_digest.attr,
+       &dev_attr_iface_immediate_data.attr,
+       &dev_attr_iface_initial_r2t.attr,
+       &dev_attr_iface_data_seq_in_order.attr,
+       &dev_attr_iface_data_pdu_in_order.attr,
+       &dev_attr_iface_erl.attr,
+       &dev_attr_iface_max_recv_dlength.attr,
+       &dev_attr_iface_first_burst_len.attr,
+       &dev_attr_iface_max_outstanding_r2t.attr,
+       &dev_attr_iface_max_burst_len.attr,
+       &dev_attr_iface_chap_auth.attr,
+       &dev_attr_iface_bidi_chap.attr,
+       &dev_attr_iface_discovery_auth_optional.attr,
+       &dev_attr_iface_discovery_logout.attr,
+       &dev_attr_iface_strict_login_comp_en.attr,
+       &dev_attr_iface_initiator_name.attr,
+       &dev_attr_ipv4_iface_dhcp_dns_address_en.attr,
+       &dev_attr_ipv4_iface_dhcp_slp_da_info_en.attr,
+       &dev_attr_ipv4_iface_tos_en.attr,
+       &dev_attr_ipv4_iface_tos.attr,
+       &dev_attr_ipv4_iface_grat_arp_en.attr,
+       &dev_attr_ipv4_iface_dhcp_alt_client_id_en.attr,
+       &dev_attr_ipv4_iface_dhcp_alt_client_id.attr,
+       &dev_attr_ipv4_iface_dhcp_req_vendor_id_en.attr,
+       &dev_attr_ipv4_iface_dhcp_use_vendor_id_en.attr,
+       &dev_attr_ipv4_iface_dhcp_vendor_id.attr,
+       &dev_attr_ipv4_iface_dhcp_learn_iqn_en.attr,
+       &dev_attr_ipv4_iface_fragment_disable.attr,
+       &dev_attr_ipv4_iface_incoming_forwarding_en.attr,
+       &dev_attr_ipv4_iface_ttl.attr,
+       &dev_attr_ipv6_iface_link_local_state.attr,
+       &dev_attr_ipv6_iface_router_state.attr,
+       &dev_attr_ipv6_iface_grat_neighbor_adv_en.attr,
+       &dev_attr_ipv6_iface_mld_en.attr,
+       &dev_attr_ipv6_iface_flow_label.attr,
+       &dev_attr_ipv6_iface_traffic_class.attr,
+       &dev_attr_ipv6_iface_hop_limit.attr,
+       &dev_attr_ipv6_iface_nd_reachable_tmo.attr,
+       &dev_attr_ipv6_iface_nd_rexmit_time.attr,
+       &dev_attr_ipv6_iface_nd_stale_tmo.attr,
+       &dev_attr_ipv6_iface_dup_addr_detect_cnt.attr,
+       &dev_attr_ipv6_iface_router_adv_link_mtu.attr,
        NULL,
 };
 
@@ -404,6 +683,61 @@ static struct attribute_group iscsi_iface_group = {
        .is_visible = iscsi_iface_attr_is_visible,
 };
 
+/* convert iscsi_ipaddress_state values to ascii string name */
+static const struct {
+       enum iscsi_ipaddress_state      value;
+       char                            *name;
+} iscsi_ipaddress_state_names[] = {
+       {ISCSI_IPDDRESS_STATE_UNCONFIGURED,     "Unconfigured" },
+       {ISCSI_IPDDRESS_STATE_ACQUIRING,        "Acquiring" },
+       {ISCSI_IPDDRESS_STATE_TENTATIVE,        "Tentative" },
+       {ISCSI_IPDDRESS_STATE_VALID,            "Valid" },
+       {ISCSI_IPDDRESS_STATE_DISABLING,        "Disabling" },
+       {ISCSI_IPDDRESS_STATE_INVALID,          "Invalid" },
+       {ISCSI_IPDDRESS_STATE_DEPRECATED,       "Deprecated" },
+};
+
+char *iscsi_get_ipaddress_state_name(enum iscsi_ipaddress_state port_state)
+{
+       int i;
+       char *state = NULL;
+
+       for (i = 0; i < ARRAY_SIZE(iscsi_ipaddress_state_names); i++) {
+               if (iscsi_ipaddress_state_names[i].value == port_state) {
+                       state = iscsi_ipaddress_state_names[i].name;
+                       break;
+               }
+       }
+       return state;
+}
+EXPORT_SYMBOL_GPL(iscsi_get_ipaddress_state_name);
+
+/* convert iscsi_router_state values to ascii string name */
+static const struct {
+       enum iscsi_router_state value;
+       char                    *name;
+} iscsi_router_state_names[] = {
+       {ISCSI_ROUTER_STATE_UNKNOWN,            "Unknown" },
+       {ISCSI_ROUTER_STATE_ADVERTISED,         "Advertised" },
+       {ISCSI_ROUTER_STATE_MANUAL,             "Manual" },
+       {ISCSI_ROUTER_STATE_STALE,              "Stale" },
+};
+
+char *iscsi_get_router_state_name(enum iscsi_router_state router_state)
+{
+       int i;
+       char *state = NULL;
+
+       for (i = 0; i < ARRAY_SIZE(iscsi_router_state_names); i++) {
+               if (iscsi_router_state_names[i].value == router_state) {
+                       state = iscsi_router_state_names[i].name;
+                       break;
+               }
+       }
+       return state;
+}
+EXPORT_SYMBOL_GPL(iscsi_get_router_state_name);
+
 struct iscsi_iface *
 iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
                   uint32_t iface_type, uint32_t iface_num, int dd_size)
index e6c4bff04339cb1975637a92bb3842601e1e158f..5c8a3b696a1dbf3ab18f914225e36f7c4d0a3a31 100644 (file)
@@ -801,7 +801,7 @@ static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq)
        if (sdkp->device->no_write_same)
                return BLKPREP_KILL;
 
-       BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size);
+       BUG_ON(bio_offset(bio) || bio_iovec(bio).bv_len != sdp->sector_size);
 
        sector >>= ilog2(sdp->sector_size) - 9;
        nr_sectors >>= ilog2(sdp->sector_size) - 9;
@@ -2659,6 +2659,12 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
 {
        struct scsi_device *sdev = sdkp->device;
 
+       if (sdev->host->no_write_same) {
+               sdev->no_write_same = 1;
+
+               return;
+       }
+
        if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) {
                /* too large values might cause issues with arcmsr */
                int vpd_buf_len = 64;
index 6174ca4ea27594487d7dc0828d9e21841742b8ed..a7a691d0af7d105a431ba3b560a5496acb71d58b 100644 (file)
@@ -365,7 +365,6 @@ void sd_dif_prepare(struct request *rq, sector_t hw_sector,
        struct bio *bio;
        struct scsi_disk *sdkp;
        struct sd_dif_tuple *sdt;
-       unsigned int i, j;
        u32 phys, virt;
 
        sdkp = rq->bio->bi_bdev->bd_disk->private_data;
@@ -376,19 +375,21 @@ void sd_dif_prepare(struct request *rq, sector_t hw_sector,
        phys = hw_sector & 0xffffffff;
 
        __rq_for_each_bio(bio, rq) {
-               struct bio_vec *iv;
+               struct bio_vec iv;
+               struct bvec_iter iter;
+               unsigned int j;
 
                /* Already remapped? */
                if (bio_flagged(bio, BIO_MAPPED_INTEGRITY))
                        break;
 
-               virt = bio->bi_integrity->bip_sector & 0xffffffff;
+               virt = bio->bi_integrity->bip_iter.bi_sector & 0xffffffff;
 
-               bip_for_each_vec(iv, bio->bi_integrity, i) {
-                       sdt = kmap_atomic(iv->bv_page)
-                               + iv->bv_offset;
+               bip_for_each_vec(iv, bio->bi_integrity, iter) {
+                       sdt = kmap_atomic(iv.bv_page)
+                               + iv.bv_offset;
 
-                       for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) {
+                       for (j = 0; j < iv.bv_len; j += tuple_sz, sdt++) {
 
                                if (be32_to_cpu(sdt->ref_tag) == virt)
                                        sdt->ref_tag = cpu_to_be32(phys);
@@ -414,7 +415,7 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
        struct scsi_disk *sdkp;
        struct bio *bio;
        struct sd_dif_tuple *sdt;
-       unsigned int i, j, sectors, sector_sz;
+       unsigned int j, sectors, sector_sz;
        u32 phys, virt;
 
        sdkp = scsi_disk(scmd->request->rq_disk);
@@ -430,15 +431,16 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
                phys >>= 3;
 
        __rq_for_each_bio(bio, scmd->request) {
-               struct bio_vec *iv;
+               struct bio_vec iv;
+               struct bvec_iter iter;
 
-               virt = bio->bi_integrity->bip_sector & 0xffffffff;
+               virt = bio->bi_integrity->bip_iter.bi_sector & 0xffffffff;
 
-               bip_for_each_vec(iv, bio->bi_integrity, i) {
-                       sdt = kmap_atomic(iv->bv_page)
-                               + iv->bv_offset;
+               bip_for_each_vec(iv, bio->bi_integrity, iter) {
+                       sdt = kmap_atomic(iv.bv_page)
+                               + iv.bv_offset;
 
-                       for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) {
+                       for (j = 0; j < iv.bv_len; j += tuple_sz, sdt++) {
 
                                if (sectors == 0) {
                                        kunmap_atomic(sdt);
index 119d67f9c47edef7517e120f510169df4b105316..40d85929aefeac1e694a1462f8f5b553f5540d1f 100644 (file)
@@ -161,14 +161,10 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
                goto out;
        cd = scsi_cd(disk);
        kref_get(&cd->kref);
-       if (scsi_device_get(cd->device))
-               goto out_put;
-       if (!scsi_autopm_get_device(cd->device))
-               goto out;
-
- out_put:
-       kref_put(&cd->kref, sr_kref_release);
-       cd = NULL;
+       if (scsi_device_get(cd->device)) {
+               kref_put(&cd->kref, sr_kref_release);
+               cd = NULL;
+       }
  out:
        mutex_unlock(&sr_ref_mutex);
        return cd;
@@ -180,7 +176,6 @@ static void scsi_cd_put(struct scsi_cd *cd)
 
        mutex_lock(&sr_ref_mutex);
        kref_put(&cd->kref, sr_kref_release);
-       scsi_autopm_put_device(sdev);
        scsi_device_put(sdev);
        mutex_unlock(&sr_ref_mutex);
 }
@@ -558,8 +553,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
        void __user *argp = (void __user *)arg;
        int ret;
 
-       scsi_autopm_get_device(cd->device);
-
        mutex_lock(&sr_mutex);
 
        /*
@@ -591,7 +584,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 
 out:
        mutex_unlock(&sr_mutex);
-       scsi_autopm_put_device(cd->device);
        return ret;
 }
 
@@ -599,17 +591,11 @@ static unsigned int sr_block_check_events(struct gendisk *disk,
                                          unsigned int clearing)
 {
        struct scsi_cd *cd = scsi_cd(disk);
-       unsigned int ret;
 
-       if (atomic_read(&cd->device->disk_events_disable_depth) == 0) {
-               scsi_autopm_get_device(cd->device);
-               ret = cdrom_check_events(&cd->cdi, clearing);
-               scsi_autopm_put_device(cd->device);
-       } else {
-               ret = 0;
-       }
+       if (atomic_read(&cd->device->disk_events_disable_depth))
+               return 0;
 
-       return ret;
+       return cdrom_check_events(&cd->cdi, clearing);
 }
 
 static int sr_block_revalidate_disk(struct gendisk *disk)
@@ -617,8 +603,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
        struct scsi_cd *cd = scsi_cd(disk);
        struct scsi_sense_hdr sshdr;
 
-       scsi_autopm_get_device(cd->device);
-
        /* if the unit is not ready, nothing more to do */
        if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
                goto out;
@@ -626,7 +610,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
        sr_cd_check(&cd->cdi);
        get_sectorsize(cd);
 out:
-       scsi_autopm_put_device(cd->device);
        return 0;
 }
 
@@ -747,6 +730,12 @@ static int sr_probe(struct device *dev)
        if (register_cdrom(&cd->cdi))
                goto fail_put;
 
+       /*
+        * Initialize block layer runtime PM stuffs before the
+        * periodic event checking request gets started in add_disk.
+        */
+       blk_pm_runtime_init(sdev->request_queue, dev);
+
        dev_set_drvdata(dev, cd);
        disk->flags |= GENHD_FL_REMOVABLE;
        add_disk(disk);
index 1a28f5632797ed2da2f27c0752013e3c7e4dde5d..17d7404272400dd1a76989a3965e0c4b85343036 100644 (file)
@@ -1697,6 +1697,7 @@ static struct scsi_host_template scsi_driver = {
        .use_clustering =       DISABLE_CLUSTERING,
        /* Make sure we dont get a sg segment crosses a page boundary */
        .dma_boundary =         PAGE_SIZE-1,
+       .no_write_same =        1,
 };
 
 enum {
index cbf3476c68cd3511e13592296198da53ddcc441d..aff31991aea9808f5f98180cb126be87be12db26 100644 (file)
@@ -104,7 +104,7 @@ static int zorro7xx_init_one(struct zorro_dev *z,
        if (ioaddr > 0x01000000)
                hostdata->base = ioremap(ioaddr, zorro_resource_len(z));
        else
-               hostdata->base = (void __iomem *)ZTWO_VADDR(ioaddr);
+               hostdata->base = ZTWO_VADDR(ioaddr);
 
        hostdata->clock = 50;
        hostdata->chip710 = 1;
index f5b4ca581541539f8336aaec73c286de1f0773fb..1c3d127f3dba65a5a682a2ee7768c1c668700b03 100644 (file)
@@ -60,8 +60,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/kernel.h>
-#include <acpi/acpi.h>
-
+#include <linux/acpi.h>
 #include <linux/sfi.h>
 #include "sfi_core.h"
 
index eb1f1ef5fa2eb69db729b6061b2d96c85aaf968b..893ec5d777ff4ab678f389c99350e3e6b2351591 100644 (file)
@@ -301,6 +301,7 @@ config SPI_OMAP_UWIRE
 
 config SPI_OMAP24XX
        tristate "McSPI driver for OMAP"
+       depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SH
        depends on ARCH_OMAP2PLUS || COMPILE_TEST
        help
          SPI master controller for OMAP24XX and later Multichannel SPI
@@ -407,7 +408,8 @@ config SPI_SC18IS602
 
 config SPI_SH_MSIOF
        tristate "SuperH MSIOF SPI controller"
-       depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
+       depends on HAVE_CLK
+       depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
        select SPI_BITBANG
        help
          SPI driver for SuperH and SH Mobile MSIOF blocks.
index 3ed666fe840a0cdbaf1a2a2c6cd75670dd25fb48..9025edd7dc45fde131c7c9c6004ce5434829c785 100644 (file)
@@ -377,7 +377,7 @@ out_master_put:
 
 static int bcm2835_spi_remove(struct platform_device *pdev)
 {
-       struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+       struct spi_master *master = platform_get_drvdata(pdev);
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
 
        free_irq(bs->irq, master);
index 80d56b214eb51af96ceb9e9d55ffea6bbb2d7302..469ecd8763581c3628c033e00adc47699e033f12 100644 (file)
@@ -435,7 +435,7 @@ out:
 
 static int bcm63xx_spi_remove(struct platform_device *pdev)
 {
-       struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+       struct spi_master *master = platform_get_drvdata(pdev);
        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 
        /* reset spi block */
index 50b2d88c81901c2b0b0ec1720f7e802ccf4924fb..d3f638613b4093f8413d2848771c0392b4ae9927 100644 (file)
@@ -963,8 +963,8 @@ static int davinci_spi_probe(struct platform_device *pdev)
                        goto free_clk;
 
                dev_info(&pdev->dev, "DMA: supported\n");
-               dev_info(&pdev->dev, "DMA: RX channel: %d, TX channel: %d, "
-                               "event queue: %d\n", dma_rx_chan, dma_tx_chan,
+               dev_info(&pdev->dev, "DMA: RX channel: %pa, TX channel: %pa, "
+                               "event queue: %d\n", &dma_rx_chan, &dma_tx_chan,
                                pdata->dma_event_q);
        }
 
index 3fb09f981980aedb23a760dd0b14d604c843661b..7beeb29472ac73f59fcf0e92e04c9c31ef88a75a 100644 (file)
@@ -115,17 +115,17 @@ spi_to_pdata(const struct spi_device *spi)
 
 static inline void setsck(const struct spi_device *spi, int is_on)
 {
-       gpio_set_value(SPI_SCK_GPIO, is_on);
+       gpio_set_value_cansleep(SPI_SCK_GPIO, is_on);
 }
 
 static inline void setmosi(const struct spi_device *spi, int is_on)
 {
-       gpio_set_value(SPI_MOSI_GPIO, is_on);
+       gpio_set_value_cansleep(SPI_MOSI_GPIO, is_on);
 }
 
 static inline int getmiso(const struct spi_device *spi)
 {
-       return !!gpio_get_value(SPI_MISO_GPIO);
+       return !!gpio_get_value_cansleep(SPI_MISO_GPIO);
 }
 
 #undef pdata
@@ -229,7 +229,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
 
        if (cs != SPI_GPIO_NO_CHIPSELECT) {
                /* SPI is normally active-low */
-               gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
+               gpio_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
        }
 }
 
index 9602bbd8d7eac061fffb5543704fc9d68a48f135..87676587d783551e120f5478f9b522c7add7df31 100644 (file)
@@ -557,7 +557,7 @@ free_master:
 
 static int mpc512x_psc_spi_do_remove(struct device *dev)
 {
-       struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
+       struct spi_master *master = dev_get_drvdata(dev);
        struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
 
        clk_disable_unprepare(mps->clk_mclk);
index 73afb56c08cc26826d468ad4aaacdce3a7e7043f..3adebfa22e3d785b6bf7ffb2149e77652039c3c3 100644 (file)
@@ -565,7 +565,7 @@ static int mxs_spi_remove(struct platform_device *pdev)
        struct mxs_spi *spi;
        struct mxs_ssp *ssp;
 
-       master = spi_master_get(platform_get_drvdata(pdev));
+       master = platform_get_drvdata(pdev);
        spi = spi_master_get_devdata(master);
        ssp = &spi->ssp;
 
index 443df39840bc899fb3525dcb141ed82da87d72f4..a72127f08e39faa04d1433094590094ea1ac357d 100644 (file)
@@ -157,14 +157,14 @@ static inline void mcspi_write_reg(struct spi_master *master,
 {
        struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
 
-       __raw_writel(val, mcspi->base + idx);
+       writel_relaxed(val, mcspi->base + idx);
 }
 
 static inline u32 mcspi_read_reg(struct spi_master *master, int idx)
 {
        struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
 
-       return __raw_readl(mcspi->base + idx);
+       return readl_relaxed(mcspi->base + idx);
 }
 
 static inline void mcspi_write_cs_reg(const struct spi_device *spi,
@@ -172,14 +172,14 @@ static inline void mcspi_write_cs_reg(const struct spi_device *spi,
 {
        struct omap2_mcspi_cs   *cs = spi->controller_state;
 
-       __raw_writel(val, cs->base +  idx);
+       writel_relaxed(val, cs->base +  idx);
 }
 
 static inline u32 mcspi_read_cs_reg(const struct spi_device *spi, int idx)
 {
        struct omap2_mcspi_cs   *cs = spi->controller_state;
 
-       return __raw_readl(cs->base + idx);
+       return readl_relaxed(cs->base + idx);
 }
 
 static inline u32 mcspi_cached_chconf0(const struct spi_device *spi)
@@ -338,7 +338,7 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
        mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, ctx->wakeupenable);
 
        list_for_each_entry(cs, &ctx->cs, node)
-               __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+               writel_relaxed(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
 }
 
 static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
@@ -346,9 +346,9 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
        unsigned long timeout;
 
        timeout = jiffies + msecs_to_jiffies(1000);
-       while (!(__raw_readl(reg) & bit)) {
+       while (!(readl_relaxed(reg) & bit)) {
                if (time_after(jiffies, timeout)) {
-                       if (!(__raw_readl(reg) & bit))
+                       if (!(readl_relaxed(reg) & bit))
                                return -ETIMEDOUT;
                        else
                                return 0;
@@ -675,7 +675,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                }
                                dev_vdbg(&spi->dev, "write-%d %02x\n",
                                                word_len, *tx);
-                               __raw_writel(*tx++, tx_reg);
+                               writel_relaxed(*tx++, tx_reg);
                        }
                        if (rx != NULL) {
                                if (mcspi_wait_for_reg_bit(chstat_reg,
@@ -687,7 +687,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                if (c == 1 && tx == NULL &&
                                    (l & OMAP2_MCSPI_CHCONF_TURBO)) {
                                        omap2_mcspi_set_enable(spi, 0);
-                                       *rx++ = __raw_readl(rx_reg);
+                                       *rx++ = readl_relaxed(rx_reg);
                                        dev_vdbg(&spi->dev, "read-%d %02x\n",
                                                    word_len, *(rx - 1));
                                        if (mcspi_wait_for_reg_bit(chstat_reg,
@@ -701,7 +701,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                        omap2_mcspi_set_enable(spi, 0);
                                }
 
-                               *rx++ = __raw_readl(rx_reg);
+                               *rx++ = readl_relaxed(rx_reg);
                                dev_vdbg(&spi->dev, "read-%d %02x\n",
                                                word_len, *(rx - 1));
                        }
@@ -722,7 +722,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                }
                                dev_vdbg(&spi->dev, "write-%d %04x\n",
                                                word_len, *tx);
-                               __raw_writel(*tx++, tx_reg);
+                               writel_relaxed(*tx++, tx_reg);
                        }
                        if (rx != NULL) {
                                if (mcspi_wait_for_reg_bit(chstat_reg,
@@ -734,7 +734,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                if (c == 2 && tx == NULL &&
                                    (l & OMAP2_MCSPI_CHCONF_TURBO)) {
                                        omap2_mcspi_set_enable(spi, 0);
-                                       *rx++ = __raw_readl(rx_reg);
+                                       *rx++ = readl_relaxed(rx_reg);
                                        dev_vdbg(&spi->dev, "read-%d %04x\n",
                                                    word_len, *(rx - 1));
                                        if (mcspi_wait_for_reg_bit(chstat_reg,
@@ -748,7 +748,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                        omap2_mcspi_set_enable(spi, 0);
                                }
 
-                               *rx++ = __raw_readl(rx_reg);
+                               *rx++ = readl_relaxed(rx_reg);
                                dev_vdbg(&spi->dev, "read-%d %04x\n",
                                                word_len, *(rx - 1));
                        }
@@ -769,7 +769,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                }
                                dev_vdbg(&spi->dev, "write-%d %08x\n",
                                                word_len, *tx);
-                               __raw_writel(*tx++, tx_reg);
+                               writel_relaxed(*tx++, tx_reg);
                        }
                        if (rx != NULL) {
                                if (mcspi_wait_for_reg_bit(chstat_reg,
@@ -781,7 +781,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                if (c == 4 && tx == NULL &&
                                    (l & OMAP2_MCSPI_CHCONF_TURBO)) {
                                        omap2_mcspi_set_enable(spi, 0);
-                                       *rx++ = __raw_readl(rx_reg);
+                                       *rx++ = readl_relaxed(rx_reg);
                                        dev_vdbg(&spi->dev, "read-%d %08x\n",
                                                    word_len, *(rx - 1));
                                        if (mcspi_wait_for_reg_bit(chstat_reg,
@@ -795,7 +795,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                        omap2_mcspi_set_enable(spi, 0);
                                }
 
-                               *rx++ = __raw_readl(rx_reg);
+                               *rx++ = readl_relaxed(rx_reg);
                                dev_vdbg(&spi->dev, "read-%d %08x\n",
                                                word_len, *(rx - 1));
                        }
@@ -1107,7 +1107,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
 
                        /* RX_ONLY mode needs dummy data in TX reg */
                        if (t->tx_buf == NULL)
-                               __raw_writel(0, cs->base
+                               writel_relaxed(0, cs->base
                                                + OMAP2_MCSPI_TX0);
 
                        if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) &&
@@ -1470,9 +1470,9 @@ static int omap2_mcspi_resume(struct device *dev)
                         * change in account.
                         */
                        cs->chconf0 |= OMAP2_MCSPI_CHCONF_FORCE;
-                       __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+                       writel_relaxed(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
                        cs->chconf0 &= ~OMAP2_MCSPI_CHCONF_FORCE;
-                       __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+                       writel_relaxed(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
                }
        }
        pm_runtime_mark_last_busy(mcspi->dev);
index cb0e1f1137adb65384188ce31651171cb3f5f311..7765b1999537a08e5c6d95eed39bdea4c8c9c9dd 100644 (file)
@@ -1073,6 +1073,8 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)
 static struct acpi_device_id pxa2xx_spi_acpi_match[] = {
        { "INT33C0", 0 },
        { "INT33C1", 0 },
+       { "INT3430", 0 },
+       { "INT3431", 0 },
        { "80860F0E", 0 },
        { },
 };
@@ -1291,6 +1293,9 @@ static int pxa2xx_spi_resume(struct device *dev)
        /* Enable the SSP clock */
        clk_prepare_enable(ssp->clk);
 
+       /* Restore LPSS private register bits */
+       lpss_ssp_setup(drv_data);
+
        /* Start the queue running */
        status = spi_master_resume(drv_data->master);
        if (status != 0) {
index 58449ad4ad0d3a83eb273b49f292909078519ca1..19c65c43cbc52b7d2db0fb45568acd9869901f6e 100644 (file)
@@ -268,7 +268,7 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
                spcmd = SPCMD_SPB_8BIT;
        else if (access_size == 16)
                spcmd = SPCMD_SPB_16BIT;
-       else if (access_size == 32)
+       else
                spcmd = SPCMD_SPB_32BIT;
 
        spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SSLKP | SPCMD_SPNDEN;
@@ -885,14 +885,10 @@ static void rspi_release_dma(struct rspi_data *rspi)
 
 static int rspi_remove(struct platform_device *pdev)
 {
-       struct rspi_data *rspi = spi_master_get(platform_get_drvdata(pdev));
+       struct rspi_data *rspi = platform_get_drvdata(pdev);
 
        spi_unregister_master(rspi->master);
        rspi_release_dma(rspi);
-       free_irq(platform_get_irq(pdev, 0), rspi);
-       clk_put(rspi->clk);
-       iounmap(rspi->addr);
-       spi_master_put(rspi->master);
 
        return 0;
 }
@@ -914,12 +910,6 @@ static int rspi_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "there is no set_config_register\n");
                return -ENODEV;
        }
-       /* get base addr */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (unlikely(res == NULL)) {
-               dev_err(&pdev->dev, "invalid resource\n");
-               return -EINVAL;
-       }
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
@@ -937,19 +927,20 @@ static int rspi_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, rspi);
        rspi->ops = ops;
        rspi->master = master;
-       rspi->addr = ioremap(res->start, resource_size(res));
-       if (rspi->addr == NULL) {
-               dev_err(&pdev->dev, "ioremap error.\n");
-               ret = -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rspi->addr = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(rspi->addr)) {
+               ret = PTR_ERR(rspi->addr);
                goto error1;
        }
 
        snprintf(clk_name, sizeof(clk_name), "%s%d", id_entry->name, pdev->id);
-       rspi->clk = clk_get(&pdev->dev, clk_name);
+       rspi->clk = devm_clk_get(&pdev->dev, clk_name);
        if (IS_ERR(rspi->clk)) {
                dev_err(&pdev->dev, "cannot get clock\n");
                ret = PTR_ERR(rspi->clk);
-               goto error2;
+               goto error1;
        }
        clk_enable(rspi->clk);
 
@@ -967,36 +958,32 @@ static int rspi_probe(struct platform_device *pdev)
        master->transfer = rspi_transfer;
        master->cleanup = rspi_cleanup;
 
-       ret = request_irq(irq, rspi_irq, 0, dev_name(&pdev->dev), rspi);
+       ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,
+                              dev_name(&pdev->dev), rspi);
        if (ret < 0) {
                dev_err(&pdev->dev, "request_irq error\n");
-               goto error3;
+               goto error1;
        }
 
        rspi->irq = irq;
        ret = rspi_request_dma(rspi, pdev);
        if (ret < 0) {
                dev_err(&pdev->dev, "rspi_request_dma failed.\n");
-               goto error4;
+               goto error2;
        }
 
        ret = spi_register_master(master);
        if (ret < 0) {
                dev_err(&pdev->dev, "spi_register_master error.\n");
-               goto error4;
+               goto error2;
        }
 
        dev_info(&pdev->dev, "probed\n");
 
        return 0;
 
-error4:
-       rspi_release_dma(rspi);
-       free_irq(irq, rspi);
-error3:
-       clk_put(rspi->clk);
 error2:
-       iounmap(rspi->addr);
+       rspi_release_dma(rspi);
 error1:
        spi_master_put(master);
 
index c74298cf70e2406d8972f4fe75cc2fcd59a15864..d96b047afcd213e37b3dbfcf43ed69dc20250ae2 100644 (file)
@@ -421,7 +421,7 @@ static void sh_msiof_spi_chipselect(struct spi_device *spi, int is_on)
        }
 
        /* use spi->controller data for CS (same strategy as spi_gpio) */
-       gpio_set_value((unsigned)spi->controller_data, value);
+       gpio_set_value((uintptr_t)spi->controller_data, value);
 
        if (is_on == BITBANG_CS_INACTIVE) {
                if (test_and_clear_bit(0, &p->flags)) {
@@ -635,8 +635,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
        master = spi_alloc_master(&pdev->dev, sizeof(struct sh_msiof_spi_priv));
        if (master == NULL) {
                dev_err(&pdev->dev, "failed to allocate spi master\n");
-               ret = -ENOMEM;
-               goto err0;
+               return -ENOMEM;
        }
 
        p = spi_master_get_devdata(master);
@@ -655,32 +654,38 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
 
        init_completion(&p->done);
 
-       p->clk = clk_get(&pdev->dev, NULL);
+       p->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(p->clk)) {
                dev_err(&pdev->dev, "cannot get clock\n");
                ret = PTR_ERR(p->clk);
                goto err1;
        }
 
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        i = platform_get_irq(pdev, 0);
-       if (!r || i < 0) {
-               dev_err(&pdev->dev, "cannot get platform resources\n");
+       if (i < 0) {
+               dev_err(&pdev->dev, "cannot get platform IRQ\n");
                ret = -ENOENT;
-               goto err2;
+               goto err1;
        }
-       p->mapbase = ioremap_nocache(r->start, resource_size(r));
-       if (!p->mapbase) {
-               dev_err(&pdev->dev, "unable to ioremap\n");
-               ret = -ENXIO;
-               goto err2;
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       p->mapbase = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(p->mapbase)) {
+               ret = PTR_ERR(p->mapbase);
+               goto err1;
        }
 
-       ret = request_irq(i, sh_msiof_spi_irq, 0,
-                         dev_name(&pdev->dev), p);
+       ret = devm_request_irq(&pdev->dev, i, sh_msiof_spi_irq, 0,
+                              dev_name(&pdev->dev), p);
        if (ret) {
                dev_err(&pdev->dev, "unable to request irq\n");
-               goto err3;
+               goto err1;
+       }
+
+       ret = clk_prepare(p->clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "unable to prepare clock\n");
+               goto err1;
        }
 
        p->pdev = pdev;
@@ -719,13 +724,9 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
                return 0;
 
        pm_runtime_disable(&pdev->dev);
- err3:
-       iounmap(p->mapbase);
- err2:
-       clk_put(p->clk);
+       clk_unprepare(p->clk);
  err1:
        spi_master_put(master);
- err0:
        return ret;
 }
 
@@ -737,9 +738,7 @@ static int sh_msiof_spi_remove(struct platform_device *pdev)
        ret = spi_bitbang_stop(&p->bitbang);
        if (!ret) {
                pm_runtime_disable(&pdev->dev);
-               free_irq(platform_get_irq(pdev, 0), p);
-               iounmap(p->mapbase);
-               clk_put(p->clk);
+               clk_unprepare(p->clk);
                spi_master_put(p->bitbang.master);
        }
        return ret;
index 0b71270fbf67ba671dd43f116db48de30076514c..4396bd44854063d9488cfd5dadc863c40c9e1dbf 100644 (file)
@@ -161,7 +161,7 @@ static int ti_qspi_setup(struct spi_device *spi)
                        qspi->spi_max_frequency, clk_div);
 
        ret = pm_runtime_get_sync(qspi->dev);
-       if (ret) {
+       if (ret < 0) {
                dev_err(qspi->dev, "pm_runtime_get_sync() failed\n");
                return ret;
        }
@@ -459,11 +459,10 @@ static int ti_qspi_probe(struct platform_device *pdev)
        if (!of_property_read_u32(np, "num-cs", &num_cs))
                master->num_chipselect = num_cs;
 
-       platform_set_drvdata(pdev, master);
-
        qspi = spi_master_get_devdata(master);
        qspi->master = master;
        qspi->dev = &pdev->dev;
+       platform_set_drvdata(pdev, qspi);
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
@@ -517,10 +516,26 @@ free_master:
 
 static int ti_qspi_remove(struct platform_device *pdev)
 {
-       struct  ti_qspi *qspi = platform_get_drvdata(pdev);
+       struct spi_master *master;
+       struct ti_qspi *qspi;
+       int ret;
+
+       master = platform_get_drvdata(pdev);
+       qspi = spi_master_get_devdata(master);
+
+       ret = pm_runtime_get_sync(qspi->dev);
+       if (ret < 0) {
+               dev_err(qspi->dev, "pm_runtime_get_sync() failed\n");
+               return ret;
+       }
 
        ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG);
 
+       pm_runtime_put(qspi->dev);
+       pm_runtime_disable(&pdev->dev);
+
+       spi_unregister_master(master);
+
        return 0;
 }
 
index 637cce2b8bdde8d3f37c8134a5f3aee7c4adead8..18c9bb2b5f39108793a32a2b71624f0e59434712 100644 (file)
@@ -425,7 +425,7 @@ exit:
 
 static int txx9spi_remove(struct platform_device *dev)
 {
-       struct spi_master *master = spi_master_get(platform_get_drvdata(dev));
+       struct spi_master *master = platform_get_drvdata(dev);
        struct txx9spi *c = spi_master_get_devdata(master);
 
        destroy_workqueue(c->workqueue);
index 18cc625d887f796aed4b082eb2366262aec8aaa8..98f4b77380df1d1d5739a6b7de743b6cc0442575 100644 (file)
@@ -1415,7 +1415,7 @@ int devm_spi_register_master(struct device *dev, struct spi_master *master)
                return -ENOMEM;
 
        ret = spi_register_master(master);
-       if (ret != 0) {
+       if (!ret) {
                *ptr = master;
                devres_add(dev, ptr);
        } else {
@@ -1596,15 +1596,11 @@ int spi_setup(struct spi_device *spi)
 }
 EXPORT_SYMBOL_GPL(spi_setup);
 
-static int __spi_async(struct spi_device *spi, struct spi_message *message)
+static int __spi_validate(struct spi_device *spi, struct spi_message *message)
 {
        struct spi_master *master = spi->master;
        struct spi_transfer *xfer;
 
-       message->spi = spi;
-
-       trace_spi_message_submit(message);
-
        if (list_empty(&message->transfers))
                return -EINVAL;
        if (!message->complete)
@@ -1705,6 +1701,18 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
        }
 
        message->status = -EINPROGRESS;
+
+       return 0;
+}
+
+static int __spi_async(struct spi_device *spi, struct spi_message *message)
+{
+       struct spi_master *master = spi->master;
+
+       message->spi = spi;
+
+       trace_spi_message_submit(message);
+
        return master->transfer(spi, message);
 }
 
@@ -1743,6 +1751,10 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
        int ret;
        unsigned long flags;
 
+       ret = __spi_validate(spi, message);
+       if (ret != 0)
+               return ret;
+
        spin_lock_irqsave(&master->bus_lock_spinlock, flags);
 
        if (master->bus_lock_flag)
@@ -1791,6 +1803,10 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message)
        int ret;
        unsigned long flags;
 
+       ret = __spi_validate(spi, message);
+       if (ret != 0)
+               return ret;
+
        spin_lock_irqsave(&master->bus_lock_spinlock, flags);
 
        ret = __spi_async(spi, message);
index 3bfdaa8d80a9ccb9b299d6bd4fde693ed4d03652..facc025a5106fbdd4701e9afd08b87cba3f4fe57 100644 (file)
@@ -54,6 +54,8 @@ source "drivers/staging/rtl8188eu/Kconfig"
 
 source "drivers/staging/rts5139/Kconfig"
 
+source "drivers/staging/rts5208/Kconfig"
+
 source "drivers/staging/frontier/Kconfig"
 
 source "drivers/staging/phison/Kconfig"
index b0d3303b46808f224578c3757006aef96099e4cd..094aba9419edd6ad49536bbd50042ec1f41b58d5 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_RTL8192E)                += rtl8192e/
 obj-$(CONFIG_R8712U)           += rtl8712/
 obj-$(CONFIG_R8188EU)          += rtl8188eu/
 obj-$(CONFIG_RTS5139)          += rts5139/
+obj-$(CONFIG_RTS5208)          += rts5208/
 obj-$(CONFIG_TRANZPORT)                += frontier/
 obj-$(CONFIG_IDE_PHISON)       += phison/
 obj-$(CONFIG_LINE6_USB)                += line6/
index 647694f43dcf12fe9c30c300674f128569f79780..2fc7cdd4c4e3b5f117f20cafe796b61c43396ba9 100644 (file)
@@ -68,11 +68,10 @@ static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT];
  */
 static int is_wakeup(enum android_alarm_type type)
 {
-       return (type == ANDROID_ALARM_RTC_WAKEUP ||
-               type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP);
+       return type == ANDROID_ALARM_RTC_WAKEUP ||
+               type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP;
 }
 
-
 static void devalarm_start(struct devalarm *alrm, ktime_t exp)
 {
        if (is_wakeup(alrm->type))
@@ -111,7 +110,6 @@ static void alarm_clear(enum android_alarm_type alarm_type)
        }
        alarm_enabled &= ~alarm_type_mask;
        spin_unlock_irqrestore(&alarm_slock, flags);
-
 }
 
 static void alarm_set(enum android_alarm_type alarm_type,
@@ -280,6 +278,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
        return 0;
 }
+
 #ifdef CONFIG_COMPAT
 static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
                                                        unsigned long arg)
@@ -371,7 +370,6 @@ static void devalarm_triggered(struct devalarm *alarm)
        spin_unlock_irqrestore(&alarm_slock, flags);
 }
 
-
 static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt)
 {
        struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt);
index 38ea986dc70f84dc72c38918f3a3b07d26e75ff4..62e2255b1c1e2c1a4bc52da6e90f50fa09c35cc7 100644 (file)
@@ -28,7 +28,7 @@ struct sync_fence;
 
 /**
  * struct sync_timeline_ops - sync object implementation ops
- * @driver_name:       name of the implentation
+ * @driver_name:       name of the implementation
  * @dup:               duplicate a sync_pt
  * @has_signaled:      returns:
  *                       1 if pt has signaled
@@ -37,12 +37,12 @@ struct sync_fence;
  * @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
+ *                      -1 if a will signal before b
  * @free_pt:           called before sync_pt is freed
  * @release_obj:       called before sync_timeline is freed
  * @print_obj:         deprecated
  * @print_pt:          deprecated
- * @fill_driver_data:  write implmentation specific driver data to data.
+ * @fill_driver_data:  write implementation specific driver data to data.
  *                       should return an error if there is not enough room
  *                       as specified by size.  This information is returned
  *                       to userspace by SYNC_IOC_FENCE_INFO.
@@ -88,9 +88,9 @@ struct sync_timeline_ops {
 /**
  * struct sync_timeline - sync object
  * @kref:              reference count on fence.
- * @ops:               ops that define the implementaiton of the sync_timeline
+ * @ops:               ops that define the implementation of the sync_timeline
  * @name:              name of the sync_timeline. Useful for debugging
- * @destoryed:         set when sync_timeline is destroyed
+ * @destroyed:         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
@@ -119,12 +119,12 @@ struct sync_timeline {
  * @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
- * @signaled_list:     membership in temorary signaled_list on stack
+ * @signaled_list:     membership in temporary signaled_list on stack
  * @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
  * @timestamp:         time which sync_pt status transitioned from active to
- *                       singaled or error.
+ *                       signaled or error.
  */
 struct sync_pt {
        struct sync_timeline            *parent;
@@ -145,9 +145,9 @@ struct sync_pt {
 /**
  * struct sync_fence - sync fence
  * @file:              file representing this fence
- * @kref:              referenace count on fence.
+ * @kref:              reference count on fence.
  * @name:              name of sync_fence.  Useful for debugging
- * @pt_list_head:      list of sync_pts in ths fence.  immutable once fence
+ * @pt_list_head:      list of sync_pts in the 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
@@ -201,23 +201,23 @@ static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter,
 
 /**
  * sync_timeline_create() - creates a sync object
- * @ops:       specifies the implemention ops for the object
+ * @ops:       specifies the implementation 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.
+ * Creates a new sync_timeline which will use the implementation specified by
+ * @ops.  @size bytes will be allocated allowing for implementation specific
+ * data to be kept after the generic sync_timeline struct.
  */
 struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
                                           int size, const char *name);
 
 /**
- * sync_timeline_destory() - destorys a sync object
+ * sync_timeline_destroy() - destroys 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
+ * A sync implementation should call this when the @obj is going away
+ * (i.e. module unload.)  @obj won't actually be freed until all its children
  * sync_pts are freed.
  */
 void sync_timeline_destroy(struct sync_timeline *obj);
@@ -226,7 +226,7 @@ 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
+ * A sync implementation 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);
@@ -236,8 +236,8 @@ void sync_timeline_signal(struct sync_timeline *obj);
  * @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
+ * Creates a new sync_pt as a child of @parent.  @size bytes will be
+ * allocated allowing for implementation specific data to be kept after
  * the generic sync_timeline struct.
  */
 struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size);
@@ -287,7 +287,7 @@ struct sync_fence *sync_fence_merge(const char *name,
 struct sync_fence *sync_fence_fdget(int fd);
 
 /**
- * sync_fence_put() - puts a refernnce of a sync fence
+ * sync_fence_put() - puts a reference of a sync fence
  * @fence:     fence to put
  *
  * Puts a reference on @fence.  If this is the last reference, the fence and
@@ -297,7 +297,7 @@ void sync_fence_put(struct sync_fence *fence);
 
 /**
  * sync_fence_install() - installs a fence into a file descriptor
- * @fence:     fence to instal
+ * @fence:     fence to install
  * @fd:                file descriptor in which to install the fence
  *
  * Installs @fence into @fd.  @fd's should be acquired through get_unused_fd().
@@ -359,10 +359,10 @@ struct sync_merge_data {
  * struct sync_pt_info - detailed sync_pt information
  * @len:               length of sync_pt_info including any driver_data
  * @obj_name:          name of parent sync_timeline
- * @driver_name:       name of driver implmenting the parent
+ * @driver_name:       name of driver implementing the parent
  * @status:            status of the sync_pt 0:active 1:signaled <0:error
  * @timestamp_ns:      timestamp of status change in nanoseconds
- * @driver_data:       any driver dependant data
+ * @driver_data:       any driver dependent data
  */
 struct sync_pt_info {
        __u32   len;
@@ -377,7 +377,7 @@ struct sync_pt_info {
 /**
  * struct sync_fence_info_data - data returned from fence info ioctl
  * @len:       ioctl caller writes the size of the buffer its passing in.
- *             ioctl returns length of sync_fence_data reutnred to userspace
+ *             ioctl returns length of sync_fence_data returned to userspace
  *             including pt_info.
  * @name:      name of fence
  * @status:    status of fence. 1: signaled 0:active <0:error
@@ -418,7 +418,7 @@ struct sync_fence_info_data {
  * pt_info.
  *
  * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
- * To itterate over the sync_pt_infos, use the sync_pt_info.len field.
+ * To iterate over the sync_pt_infos, use the sync_pt_info.len field.
  */
 #define SYNC_IOC_FENCE_INFO    _IOWR(SYNC_IOC_MAGIC, 2,\
        struct sync_fence_info_data)
index 87b74ca84c42154eac8c8715deea37f5b20aa5ce..62415342ee288dcd5420ec19b74c440efdcb1db9 100644 (file)
@@ -160,7 +160,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
        struct bcm_ioctl_buffer IoBuffer;
        int bytes;
 
-       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg);
+       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+                       "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX",
+                       cmd, arg);
 
        if (_IOC_TYPE(cmd) != BCM_IOCTL)
                return -EFAULT;
@@ -266,7 +268,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                                (uiTempVar == EEPROM_REJECT_REG_3) ||
                                (uiTempVar == EEPROM_REJECT_REG_4))) {
 
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                       "EEPROM Access Denied, not in VSG Mode\n");
                        return -EFAULT;
                }
 
@@ -274,9 +277,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                                (PUINT)sWrmBuffer.Data, sizeof(ULONG));
 
                if (Status == STATUS_SUCCESS) {
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+                                       DBG_LVL_ALL, "WRM Done\n");
                } else {
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+                                       DBG_LVL_ALL, "WRM Failed\n");
                        Status = -EFAULT;
                }
                break;
@@ -291,7 +296,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                        (Adapter->bShutStatus == TRUE) ||
                        (Adapter->bPreparingForLowPowerMode == TRUE)) {
 
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                       "Device in Idle Mode, Blocking Rdms\n");
                        return -EACCES;
                }
 
@@ -317,7 +323,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
                        ((ULONG)sRdmBuffer.Register & 0x3)) {
 
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n",
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                       "RDM Done On invalid Address : %x Access Denied.\n",
                                        (int)sRdmBuffer.Register);
 
                        kfree(temp_buff);
@@ -325,7 +332,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                }
 
                uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
-               bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength);
+               bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register,
+                                      (PUINT)temp_buff, IoBuffer.OutputLength);
 
                if (bytes > 0) {
                        Status = STATUS_SUCCESS;
@@ -349,7 +357,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                        (Adapter->bShutStatus == TRUE) ||
                        (Adapter->bPreparingForLowPowerMode == TRUE)) {
 
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                       "Device in Idle Mode, Blocking Wrms\n");
                        return -EACCES;
                }
 
@@ -367,7 +376,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
                        ((ULONG)sWrmBuffer.Register & 0x3)) {
 
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)sWrmBuffer.Register);
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                       "WRM Done On invalid Address : %x Access Denied.\n",
+                                       (int)sWrmBuffer.Register);
                        return -EINVAL;
                }
 
@@ -379,17 +390,21 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                                (uiTempVar == EEPROM_REJECT_REG_4)) &&
                                (cmd == IOCTL_BCM_REGISTER_WRITE)) {
 
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                               "EEPROM Access Denied, not in VSG Mode\n");
                                return -EFAULT;
                }
 
                Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
-                                       (PUINT)sWrmBuffer.Data, sWrmBuffer.Length);
+                                       (PUINT)sWrmBuffer.Data,
+                                       sWrmBuffer.Length);
 
                if (Status == STATUS_SUCCESS) {
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG,
+                                       DBG_LVL_ALL, "WRM Done\n");
                } else {
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+                                       DBG_LVL_ALL, "WRM Failed\n");
                        Status = -EFAULT;
                }
                break;
@@ -405,7 +420,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                        (Adapter->bShutStatus == TRUE) ||
                        (Adapter->bPreparingForLowPowerMode == TRUE)) {
 
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+                                       DBG_LVL_ALL,
+                                       "GPIO Can't be set/clear in Low power Mode");
                        return -EACCES;
                }
 
@@ -423,7 +440,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                value = (1<<uiBit);
 
                if (IsReqGpioIsLedInNVM(Adapter, value) == false) {
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!", value);
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+                                       DBG_LVL_ALL,
+                                       "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",
+                                       value);
                        Status = -EINVAL;
                        break;
                }
@@ -431,27 +451,42 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                /* Set - setting 1 */
                if (uiOperation) {
                        /* Set the gpio output register */
-                       Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, (PUINT)(&value), sizeof(UINT));
+                       Status = wrmaltWithLock(Adapter,
+                                               BCM_GPIO_OUTPUT_SET_REG,
+                                               (PUINT)(&value), sizeof(UINT));
 
                        if (Status == STATUS_SUCCESS) {
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n");
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+                                               OSAL_DBG, DBG_LVL_ALL,
+                                               "Set the GPIO bit\n");
                        } else {
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to set the %dth GPIO\n", uiBit);
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+                                               OSAL_DBG, DBG_LVL_ALL,
+                                               "Failed to set the %dth GPIO\n",
+                                               uiBit);
                                break;
                        }
                } else {
                        /* Set the gpio output register */
-                       Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)(&value), sizeof(UINT));
+                       Status = wrmaltWithLock(Adapter,
+                                               BCM_GPIO_OUTPUT_CLR_REG,
+                                               (PUINT)(&value), sizeof(UINT));
 
                        if (Status == STATUS_SUCCESS) {
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n");
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+                                               OSAL_DBG, DBG_LVL_ALL,
+                                               "Set the GPIO bit\n");
                        } else {
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to clear the %dth GPIO\n", uiBit);
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+                                               OSAL_DBG, DBG_LVL_ALL,
+                                               "Failed to clear the %dth GPIO\n",
+                                               uiBit);
                                break;
                        }
                }
 
-               bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
+               bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
+                                      (PUINT)ucResetValue, sizeof(UINT));
                if (bytes < 0) {
                        Status = bytes;
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
@@ -467,9 +502,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                                        (PUINT)ucResetValue, sizeof(UINT));
 
                if (Status == STATUS_SUCCESS) {
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO to output Mode\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+                                       DBG_LVL_ALL,
+                                       "Set the GPIO to output Mode\n");
                } else {
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+                                       DBG_LVL_ALL,
+                                       "Failed to put GPIO in Output Mode\n");
                        break;
                }
        }
@@ -477,13 +516,16 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
 
        case BCM_LED_THREAD_STATE_CHANGE_REQ: {
                struct bcm_user_thread_req threadReq = {0};
-               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "User made LED thread InActive");
+               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+                               "User made LED thread InActive");
 
                if ((Adapter->IdleMode == TRUE) ||
                        (Adapter->bShutStatus == TRUE) ||
                        (Adapter->bPreparingForLowPowerMode == TRUE)) {
 
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+                                       DBG_LVL_ALL,
+                                       "GPIO Can't be set/clear in Low power Mode");
                        Status = -EACCES;
                        break;
                }
@@ -500,10 +542,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                /* if LED thread is running(Actively or Inactively) set it state to make inactive */
                if (Adapter->LEDInfo.led_thread_running) {
                        if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) {
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Activating thread req");
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+                                               OSAL_DBG, DBG_LVL_ALL,
+                                               "Activating thread req");
                                Adapter->DriverState = LED_THREAD_ACTIVE;
                        } else {
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DeActivating Thread req.....");
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+                                               OSAL_DBG, DBG_LVL_ALL,
+                                               "DeActivating Thread req.....");
                                Adapter->DriverState = LED_THREAD_INACTIVE;
                        }
 
@@ -540,7 +586,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
 
                if (bytes < 0) {
                        Status = bytes;
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n");
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                       "RDM Failed\n");
                        return Status;
                } else {
                        Status = STATUS_SUCCESS;
@@ -570,9 +617,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                        return -EFAULT;
 
                if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == false) {
-                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+                       BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+                                       DBG_LVL_ALL,
                                        "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
-                                       pgpio_multi_info[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap);
+                                       pgpio_multi_info[WIMAX_IDX].uiGPIOMask,
+                                       Adapter->gpioBitMap);
                        Status = -EINVAL;
                        break;
                }
@@ -590,7 +639,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                                                        (PUINT)ucResetValue, sizeof(ULONG));
 
                        if (Status != STATUS_SUCCESS) {
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                               "WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
                                return Status;
                        }
 
@@ -603,7 +653,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                                Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue, sizeof(ULONG));
 
                        if (Status != STATUS_SUCCESS) {
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed.");
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                               "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed.");
                                return Status;
                        }
                }
@@ -613,7 +664,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
 
                        if (bytes < 0) {
                                Status = bytes;
-                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM to GPIO_PIN_STATE_REGISTER Failed.");
+                               BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+                                               "RDM to GPIO_PIN_STATE_REGISTER Failed.");
                                return Status;
                        } else {
                                Status = STATUS_SUCCESS;
@@ -1190,7 +1242,7 @@ cntrlEnd:
                break;
 
        case IOCTL_BCM_CAL_INIT: {
-               UINT uiSectorSize = 0 ;
+               UINT uiSectorSize = 0;
                if (Adapter->eNVMType == NVM_FLASH) {
                        if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
                                return -EFAULT;
@@ -1403,7 +1455,7 @@ cntrlEnd:
 
        case IOCTL_BCM_FLASH2X_SECTION_READ: {
                struct bcm_flash2x_readwrite sFlash2xRead = {0};
-               PUCHAR pReadBuff = NULL ;
+               PUCHAR pReadBuff = NULL;
                UINT NOB = 0;
                UINT BuffSize = 0;
                UINT ReadBytes = 0;
@@ -1438,7 +1490,7 @@ cntrlEnd:
                else
                        BuffSize = NOB;
 
-               ReadOffset = sFlash2xRead.offset ;
+               ReadOffset = sFlash2xRead.offset;
                OutPutBuff = IoBuffer.OutputBuffer;
                pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
 
@@ -1483,7 +1535,7 @@ cntrlEnd:
                        NOB = NOB - ReadBytes;
                        if (NOB) {
                                ReadOffset = ReadOffset + ReadBytes;
-                               OutPutBuff = OutPutBuff + ReadBytes ;
+                               OutPutBuff = OutPutBuff + ReadBytes;
                        }
                }
 
@@ -1538,7 +1590,7 @@ cntrlEnd:
                if (NOB > Adapter->uiSectorSize)
                        BuffSize = Adapter->uiSectorSize;
                else
-                       BuffSize = NOB ;
+                       BuffSize = NOB;
 
                pWriteBuff = kmalloc(BuffSize, GFP_KERNEL);
 
@@ -1841,10 +1893,10 @@ cntrlEnd:
 
        case IOCTL_BCM_NVM_RAW_READ: {
                struct bcm_nvm_readwrite stNVMRead;
-               INT NOB ;
-               INT BuffSize ;
+               INT NOB;
+               INT BuffSize;
                INT ReadOffset = 0;
-               UINT ReadBytes = 0 ;
+               UINT ReadBytes = 0;
                PUCHAR pReadBuff;
                void __user *OutPutBuff;
 
index 9f7e30f637eaff41d0f0128fd315cd5f5ce3960f..6bddf723e06a0ff55075ce0f3b0e79d7d3fc1df3 100644 (file)
 
     //DDR INIT-133Mhz
 #define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12  //index for 0x0F007000
-static struct bcm_ddr_setting asT3_DDRSetting133MHz[]= {//      # DPLL Clock Setting
-                                        {0x0F000800,0x00007212},
-                                        {0x0f000820,0x07F13FFF},
-                                        {0x0f000810,0x00000F95},
-                                        {0x0f000860,0x00000000},
-                                        {0x0f000880,0x000003DD},
+static struct bcm_ddr_setting asT3_DDRSetting133MHz[] = {//      # DPLL Clock Setting
+                                        {0x0F000800, 0x00007212},
+                                        {0x0f000820, 0x07F13FFF},
+                                        {0x0f000810, 0x00000F95},
+                                        {0x0f000860, 0x00000000},
+                                        {0x0f000880, 0x000003DD},
                                         // Changed source for X-bar and MIPS clock to APLL
-                                        {0x0f000840,0x0FFF1B00},
-                                        {0x0f000870,0x00000002},
-                                        {0x0F00a044,0x1fffffff},
-                                        {0x0F00a040,0x1f000000},
-                                        {0x0F00a084,0x1Cffffff},
-                                        {0x0F00a080,0x1C000000},
-                                        {0x0F00a04C,0x0000000C},
+                                        {0x0f000840, 0x0FFF1B00},
+                                        {0x0f000870, 0x00000002},
+                                        {0x0F00a044, 0x1fffffff},
+                                        {0x0F00a040, 0x1f000000},
+                                        {0x0F00a084, 0x1Cffffff},
+                                        {0x0F00a080, 0x1C000000},
+                                        {0x0F00a04C, 0x0000000C},
                                         //Memcontroller Default values
-                                        {0x0F007000,0x00010001},
-                                        {0x0F007004,0x01010100},
-                                        {0x0F007008,0x01000001},
-                                        {0x0F00700c,0x00000000},
-                                        {0x0F007010,0x01000000},
-                                        {0x0F007014,0x01000100},
-                                        {0x0F007018,0x01000000},
-                                        {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001
-                                        {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107
-                                        {0x0F007024,0x02000007},
-                                        {0x0F007028,0x02020202},
-                                        {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a
-                                        {0x0F007030,0x05000000},
-                                        {0x0F007034,0x00000003},
-                                        {0x0F007038,0x110a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
-                                        {0x0F00703C,0x02101010},//ROB - 0x02101010,//0x02101018},
-                                        {0x0F007040,0x45751200},//ROB - 0x45751200,//0x450f1200},
-                                        {0x0F007044,0x110a0d00},//ROB - 0x110a0d00//0x111f0d00
-                                        {0x0F007048,0x081b0306},
-                                        {0x0F00704c,0x00000000},
-                                        {0x0F007050,0x0000001c},
-                                        {0x0F007054,0x00000000},
-                                        {0x0F007058,0x00000000},
-                                        {0x0F00705c,0x00000000},
-                                        {0x0F007060,0x0010246c},
-                                        {0x0F007064,0x00000010},
-                                        {0x0F007068,0x00000000},
-                                        {0x0F00706c,0x00000001},
-                                        {0x0F007070,0x00007000},
-                                        {0x0F007074,0x00000000},
-                                        {0x0F007078,0x00000000},
-                                        {0x0F00707C,0x00000000},
-                                        {0x0F007080,0x00000000},
-                                        {0x0F007084,0x00000000},
+                                        {0x0F007000, 0x00010001},
+                                        {0x0F007004, 0x01010100},
+                                        {0x0F007008, 0x01000001},
+                                        {0x0F00700c, 0x00000000},
+                                        {0x0F007010, 0x01000000},
+                                        {0x0F007014, 0x01000100},
+                                        {0x0F007018, 0x01000000},
+                                        {0x0F00701c, 0x01020001},// POP - 0x00020001 Normal 0x01020001
+                                        {0x0F007020, 0x04030107}, //Normal - 0x04030107 POP - 0x05030107
+                                        {0x0F007024, 0x02000007},
+                                        {0x0F007028, 0x02020202},
+                                        {0x0F00702c, 0x0206060a},//ROB- 0x0205050a,//0x0206060a
+                                        {0x0F007030, 0x05000000},
+                                        {0x0F007034, 0x00000003},
+                                        {0x0F007038, 0x110a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+                                        {0x0F00703C, 0x02101010},//ROB - 0x02101010,//0x02101018},
+                                        {0x0F007040, 0x45751200},//ROB - 0x45751200,//0x450f1200},
+                                        {0x0F007044, 0x110a0d00},//ROB - 0x110a0d00//0x111f0d00
+                                        {0x0F007048, 0x081b0306},
+                                        {0x0F00704c, 0x00000000},
+                                        {0x0F007050, 0x0000001c},
+                                        {0x0F007054, 0x00000000},
+                                        {0x0F007058, 0x00000000},
+                                        {0x0F00705c, 0x00000000},
+                                        {0x0F007060, 0x0010246c},
+                                        {0x0F007064, 0x00000010},
+                                        {0x0F007068, 0x00000000},
+                                        {0x0F00706c, 0x00000001},
+                                        {0x0F007070, 0x00007000},
+                                        {0x0F007074, 0x00000000},
+                                        {0x0F007078, 0x00000000},
+                                        {0x0F00707C, 0x00000000},
+                                        {0x0F007080, 0x00000000},
+                                        {0x0F007084, 0x00000000},
                                         //# Enable BW improvement within memory controller
-                                        {0x0F007094,0x00000104},
+                                        {0x0F007094, 0x00000104},
                                         //# Enable 2 ports within X-bar
-                                        {0x0F00A000,0x00000016},
+                                        {0x0F00A000, 0x00000016},
                                         //# Enable start bit within memory controller
-                                        {0x0F007018,0x01010000}
+                                        {0x0F007018, 0x01010000}
                                         };
 //80Mhz
 #define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10  //index for 0x0F007000
-static struct bcm_ddr_setting asT3_DDRSetting80MHz[]= {//   # DPLL Clock Setting
-                                        {0x0f000810,0x00000F95},
-                                        {0x0f000820,0x07f1ffff},
-                                        {0x0f000860,0x00000000},
-                                        {0x0f000880,0x000003DD},
-                                        {0x0F00a044,0x1fffffff},
-                                        {0x0F00a040,0x1f000000},
-                                        {0x0F00a084,0x1Cffffff},
-                                        {0x0F00a080,0x1C000000},
-                                        {0x0F00a000,0x00000016},
-                                        {0x0F00a04C,0x0000000C},
+static struct bcm_ddr_setting asT3_DDRSetting80MHz[] = {//   # DPLL Clock Setting
+                                        {0x0f000810, 0x00000F95},
+                                        {0x0f000820, 0x07f1ffff},
+                                        {0x0f000860, 0x00000000},
+                                        {0x0f000880, 0x000003DD},
+                                        {0x0F00a044, 0x1fffffff},
+                                        {0x0F00a040, 0x1f000000},
+                                        {0x0F00a084, 0x1Cffffff},
+                                        {0x0F00a080, 0x1C000000},
+                                        {0x0F00a000, 0x00000016},
+                                        {0x0F00a04C, 0x0000000C},
                                 //Memcontroller Default values
-                                        {0x0F007000,0x00010001},
-                                        {0x0F007004,0x01000000},
-                                        {0x0F007008,0x01000001},
-                                        {0x0F00700c,0x00000000},
-                                        {0x0F007010,0x01000000},
-                                        {0x0F007014,0x01000100},
-                                        {0x0F007018,0x01000000},
-                                        {0x0F00701c,0x01020000},
-                                        {0x0F007020,0x04020107},
-                                        {0x0F007024,0x00000007},
-                                        {0x0F007028,0x02020201},
-                                        {0x0F00702c,0x0204040a},
-                                        {0x0F007030,0x04000000},
-                                        {0x0F007034,0x00000002},
-                                        {0x0F007038,0x1F060200},
-                                        {0x0F00703C,0x1C22221F},
-                                        {0x0F007040,0x8A006600},
-                                        {0x0F007044,0x221a0800},
-                                        {0x0F007048,0x02690204},
-                                        {0x0F00704c,0x00000000},
-                                        {0x0F007050,0x0000001c},
-                                        {0x0F007054,0x00000000},
-                                        {0x0F007058,0x00000000},
-                                        {0x0F00705c,0x00000000},
-                                        {0x0F007060,0x000A15D6},
-                                        {0x0F007064,0x0000000A},
-                                        {0x0F007068,0x00000000},
-                                        {0x0F00706c,0x00000001},
-                                        {0x0F007070,0x00004000},
-                                        {0x0F007074,0x00000000},
-                                        {0x0F007078,0x00000000},
-                                        {0x0F00707C,0x00000000},
-                                        {0x0F007080,0x00000000},
-                                        {0x0F007084,0x00000000},
-                                        {0x0F007094,0x00000104},
+                                        {0x0F007000, 0x00010001},
+                                        {0x0F007004, 0x01000000},
+                                        {0x0F007008, 0x01000001},
+                                        {0x0F00700c, 0x00000000},
+                                        {0x0F007010, 0x01000000},
+                                        {0x0F007014, 0x01000100},
+                                        {0x0F007018, 0x01000000},
+                                        {0x0F00701c, 0x01020000},
+                                        {0x0F007020, 0x04020107},
+                                        {0x0F007024, 0x00000007},
+                                        {0x0F007028, 0x02020201},
+                                        {0x0F00702c, 0x0204040a},
+                                        {0x0F007030, 0x04000000},
+                                        {0x0F007034, 0x00000002},
+                                        {0x0F007038, 0x1F060200},
+                                        {0x0F00703C, 0x1C22221F},
+                                        {0x0F007040, 0x8A006600},
+                                        {0x0F007044, 0x221a0800},
+                                        {0x0F007048, 0x02690204},
+                                        {0x0F00704c, 0x00000000},
+                                        {0x0F007050, 0x0000001c},
+                                        {0x0F007054, 0x00000000},
+                                        {0x0F007058, 0x00000000},
+                                        {0x0F00705c, 0x00000000},
+                                        {0x0F007060, 0x000A15D6},
+                                        {0x0F007064, 0x0000000A},
+                                        {0x0F007068, 0x00000000},
+                                        {0x0F00706c, 0x00000001},
+                                        {0x0F007070, 0x00004000},
+                                        {0x0F007074, 0x00000000},
+                                        {0x0F007078, 0x00000000},
+                                        {0x0F00707C, 0x00000000},
+                                        {0x0F007080, 0x00000000},
+                                        {0x0F007084, 0x00000000},
+                                        {0x0F007094, 0x00000104},
                                         //# Enable start bit within memory controller
-                                                                               {0x0F007018,0x01010000}
+                                       {0x0F007018, 0x01010000}
                                 };
 //100Mhz
 #define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13  //index for 0x0F007000
-static struct bcm_ddr_setting asT3_DDRSetting100MHz[]= {//  # DPLL Clock Setting
-                                        {0x0F000800,0x00007008},
-                                        {0x0f000810,0x00000F95},
-                                        {0x0f000820,0x07F13E3F},
-                                        {0x0f000860,0x00000000},
-                                        {0x0f000880,0x000003DD},
+static struct bcm_ddr_setting asT3_DDRSetting100MHz[] = {//  # DPLL Clock Setting
+                                        {0x0F000800, 0x00007008},
+                                        {0x0f000810, 0x00000F95},
+                                        {0x0f000820, 0x07F13E3F},
+                                        {0x0f000860, 0x00000000},
+                                        {0x0f000880, 0x000003DD},
                                 // Changed source for X-bar and MIPS clock to APLL
                                 //0x0f000840,0x0FFF1800,
-                                        {0x0f000840,0x0FFF1B00},
-                                        {0x0f000870,0x00000002},
-                                        {0x0F00a044,0x1fffffff},
-                                        {0x0F00a040,0x1f000000},
-                                        {0x0F00a084,0x1Cffffff},
-                                        {0x0F00a080,0x1C000000},
-                                        {0x0F00a04C,0x0000000C},
+                                        {0x0f000840, 0x0FFF1B00},
+                                        {0x0f000870, 0x00000002},
+                                        {0x0F00a044, 0x1fffffff},
+                                        {0x0F00a040, 0x1f000000},
+                                        {0x0F00a084, 0x1Cffffff},
+                                        {0x0F00a080, 0x1C000000},
+                                        {0x0F00a04C, 0x0000000C},
                                 //# Enable 2 ports within X-bar
-                                        {0x0F00A000,0x00000016},
+                                        {0x0F00A000, 0x00000016},
                                 //Memcontroller Default values
-                                        {0x0F007000,0x00010001},
-                                        {0x0F007004,0x01010100},
-                                        {0x0F007008,0x01000001},
-                                        {0x0F00700c,0x00000000},
-                                        {0x0F007010,0x01000000},
-                                        {0x0F007014,0x01000100},
-                                        {0x0F007018,0x01000000},
-                                        {0x0F00701c,0x01020001}, // POP - 0x00020000 Normal 0x01020000
-                                        {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107
-                                        {0x0F007024,0x00000007},
-                                        {0x0F007028,0x01020201},
-                                        {0x0F00702c,0x0204040A},
-                                        {0x0F007030,0x06000000},
-                                        {0x0F007034,0x00000004},
-                                        {0x0F007038,0x20080200},
-                                        {0x0F00703C,0x02030320},
-                                        {0x0F007040,0x6E7F1200},
-                                        {0x0F007044,0x01190A00},
-                                        {0x0F007048,0x06120305},//0x02690204 // 0x06120305
-                                        {0x0F00704c,0x00000000},
-                                        {0x0F007050,0x0000001C},
-                                        {0x0F007054,0x00000000},
-                                        {0x0F007058,0x00000000},
-                                        {0x0F00705c,0x00000000},
-                                        {0x0F007060,0x00082ED6},
-                                        {0x0F007064,0x0000000A},
-                                        {0x0F007068,0x00000000},
-                                        {0x0F00706c,0x00000001},
-                                        {0x0F007070,0x00005000},
-                                        {0x0F007074,0x00000000},
-                                        {0x0F007078,0x00000000},
-                                        {0x0F00707C,0x00000000},
-                                        {0x0F007080,0x00000000},
-                                        {0x0F007084,0x00000000},
+                                        {0x0F007000, 0x00010001},
+                                        {0x0F007004, 0x01010100},
+                                        {0x0F007008, 0x01000001},
+                                        {0x0F00700c, 0x00000000},
+                                        {0x0F007010, 0x01000000},
+                                        {0x0F007014, 0x01000100},
+                                        {0x0F007018, 0x01000000},
+                                        {0x0F00701c, 0x01020001}, // POP - 0x00020000 Normal 0x01020000
+                                        {0x0F007020, 0x04020107},//Normal - 0x04030107 POP - 0x05030107
+                                        {0x0F007024, 0x00000007},
+                                        {0x0F007028, 0x01020201},
+                                        {0x0F00702c, 0x0204040A},
+                                        {0x0F007030, 0x06000000},
+                                        {0x0F007034, 0x00000004},
+                                        {0x0F007038, 0x20080200},
+                                        {0x0F00703C, 0x02030320},
+                                        {0x0F007040, 0x6E7F1200},
+                                        {0x0F007044, 0x01190A00},
+                                        {0x0F007048, 0x06120305},//0x02690204 // 0x06120305
+                                        {0x0F00704c, 0x00000000},
+                                        {0x0F007050, 0x0000001C},
+                                        {0x0F007054, 0x00000000},
+                                        {0x0F007058, 0x00000000},
+                                        {0x0F00705c, 0x00000000},
+                                        {0x0F007060, 0x00082ED6},
+                                        {0x0F007064, 0x0000000A},
+                                        {0x0F007068, 0x00000000},
+                                        {0x0F00706c, 0x00000001},
+                                        {0x0F007070, 0x00005000},
+                                        {0x0F007074, 0x00000000},
+                                        {0x0F007078, 0x00000000},
+                                        {0x0F00707C, 0x00000000},
+                                        {0x0F007080, 0x00000000},
+                                        {0x0F007084, 0x00000000},
                                 //# Enable BW improvement within memory controller
-                                        {0x0F007094,0x00000104},
+                                        {0x0F007094, 0x00000104},
                                 //# Enable start bit within memory controller
-                                        {0x0F007018,0x01010000}
+                                        {0x0F007018, 0x01010000}
                                 };
 
 //Net T3B DDR Settings
 //DDR INIT-133Mhz
 static struct bcm_ddr_setting asDPLL_266MHZ[] = {
-                                        {0x0F000800,0x00007212},
-                                        {0x0f000820,0x07F13FFF},
-                                        {0x0f000810,0x00000F95},
-                                        {0x0f000860,0x00000000},
-                                        {0x0f000880,0x000003DD},
+                                        {0x0F000800, 0x00007212},
+                                        {0x0f000820, 0x07F13FFF},
+                                        {0x0f000810, 0x00000F95},
+                                        {0x0f000860, 0x00000000},
+                                        {0x0f000880, 0x000003DD},
                                         // Changed source for X-bar and MIPS clock to APLL
-                                        {0x0f000840,0x0FFF1B00},
-                                        {0x0f000870,0x00000002}
+                                        {0x0f000840, 0x0FFF1B00},
+                                        {0x0f000870, 0x00000002}
                                                                          };
 
 #define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11  //index for 0x0F007000
 static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = {//      # DPLL Clock Setting
-                                        {0x0f000810,0x00000F95},
-                                        {0x0f000810,0x00000F95},
-                                        {0x0f000810,0x00000F95},
-                                        {0x0f000820,0x07F13652},
-                                        {0x0f000840,0x0FFF0800},
+                                        {0x0f000810, 0x00000F95},
+                                        {0x0f000810, 0x00000F95},
+                                        {0x0f000810, 0x00000F95},
+                                        {0x0f000820, 0x07F13652},
+                                        {0x0f000840, 0x0FFF0800},
                                         // Changed source for X-bar and MIPS clock to APLL
-                                        {0x0f000880,0x000003DD},
-                                        {0x0f000860,0x00000000},
+                                        {0x0f000880, 0x000003DD},
+                                        {0x0f000860, 0x00000000},
                                         // Changed source for X-bar and MIPS clock to APLL
-                                        {0x0F00a044,0x1fffffff},
-                                        {0x0F00a040,0x1f000000},
-                                        {0x0F00a084,0x1Cffffff},
-                                        {0x0F00a080,0x1C000000},
+                                        {0x0F00a044, 0x1fffffff},
+                                        {0x0F00a040, 0x1f000000},
+                                        {0x0F00a084, 0x1Cffffff},
+                                        {0x0F00a080, 0x1C000000},
                                         //# Enable 2 ports within X-bar
-                                        {0x0F00A000,0x00000016},
+                                        {0x0F00A000, 0x00000016},
                                         //Memcontroller Default values
-                                        {0x0F007000,0x00010001},
-                                        {0x0F007004,0x01010100},
-                                        {0x0F007008,0x01000001},
-                                        {0x0F00700c,0x00000000},
-                                        {0x0F007010,0x01000000},
-                                        {0x0F007014,0x01000100},
-                                        {0x0F007018,0x01000000},
-                                        {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001
-                                        {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107
-                                        {0x0F007024,0x02000007},
-                                        {0x0F007028,0x02020202},
-                                        {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a
-                                        {0x0F007030,0x05000000},
-                                        {0x0F007034,0x00000003},
-                                        {0x0F007038,0x130a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
-                                        {0x0F00703C,0x02101012},//ROB - 0x02101010,//0x02101018},
-                                        {0x0F007040,0x457D1200},//ROB - 0x45751200,//0x450f1200},
-                                        {0x0F007044,0x11130d00},//ROB - 0x110a0d00//0x111f0d00
-                                        {0x0F007048,0x040D0306},
-                                        {0x0F00704c,0x00000000},
-                                        {0x0F007050,0x0000001c},
-                                        {0x0F007054,0x00000000},
-                                        {0x0F007058,0x00000000},
-                                        {0x0F00705c,0x00000000},
-                                        {0x0F007060,0x0010246c},
-                                        {0x0F007064,0x00000012},
-                                        {0x0F007068,0x00000000},
-                                        {0x0F00706c,0x00000001},
-                                        {0x0F007070,0x00007000},
-                                        {0x0F007074,0x00000000},
-                                        {0x0F007078,0x00000000},
-                                        {0x0F00707C,0x00000000},
-                                        {0x0F007080,0x00000000},
-                                        {0x0F007084,0x00000000},
+                                        {0x0F007000, 0x00010001},
+                                        {0x0F007004, 0x01010100},
+                                        {0x0F007008, 0x01000001},
+                                        {0x0F00700c, 0x00000000},
+                                        {0x0F007010, 0x01000000},
+                                        {0x0F007014, 0x01000100},
+                                        {0x0F007018, 0x01000000},
+                                        {0x0F00701c, 0x01020001},// POP - 0x00020001 Normal 0x01020001
+                                        {0x0F007020, 0x04030107}, //Normal - 0x04030107 POP - 0x05030107
+                                        {0x0F007024, 0x02000007},
+                                        {0x0F007028, 0x02020202},
+                                        {0x0F00702c, 0x0206060a},//ROB- 0x0205050a,//0x0206060a
+                                        {0x0F007030, 0x05000000},
+                                        {0x0F007034, 0x00000003},
+                                        {0x0F007038, 0x130a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+                                        {0x0F00703C, 0x02101012},//ROB - 0x02101010,//0x02101018},
+                                        {0x0F007040, 0x457D1200},//ROB - 0x45751200,//0x450f1200},
+                                        {0x0F007044, 0x11130d00},//ROB - 0x110a0d00//0x111f0d00
+                                        {0x0F007048, 0x040D0306},
+                                        {0x0F00704c, 0x00000000},
+                                        {0x0F007050, 0x0000001c},
+                                        {0x0F007054, 0x00000000},
+                                        {0x0F007058, 0x00000000},
+                                        {0x0F00705c, 0x00000000},
+                                        {0x0F007060, 0x0010246c},
+                                        {0x0F007064, 0x00000012},
+                                        {0x0F007068, 0x00000000},
+                                        {0x0F00706c, 0x00000001},
+                                        {0x0F007070, 0x00007000},
+                                        {0x0F007074, 0x00000000},
+                                        {0x0F007078, 0x00000000},
+                                        {0x0F00707C, 0x00000000},
+                                        {0x0F007080, 0x00000000},
+                                        {0x0F007084, 0x00000000},
                                         //# Enable BW improvement within memory controller
-                                        {0x0F007094,0x00000104},
+                                        {0x0F007094, 0x00000104},
                                         //# Enable start bit within memory controller
-                                        {0x0F007018,0x01010000},
+                                        {0x0F007018, 0x01010000},
                                         };
 
 #define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9  //index for 0x0F007000
 static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = {//       # DPLL Clock Setting
-                                                                               {0x0f000810,0x00000F95},
-                                                                               {0x0f000820,0x07F13FFF},
-                                                                               {0x0f000840,0x0FFF1F00},
-                                                                               {0x0f000880,0x000003DD},
-                                                                               {0x0f000860,0x00000000},
+                                                                               {0x0f000810, 0x00000F95},
+                                                                               {0x0f000820, 0x07F13FFF},
+                                                                               {0x0f000840, 0x0FFF1F00},
+                                                                               {0x0f000880, 0x000003DD},
+                                                                               {0x0f000860, 0x00000000},
 
-                                                                               {0x0F00a044,0x1fffffff},
-                                                                               {0x0F00a040,0x1f000000},
-                                                                               {0x0F00a084,0x1Cffffff},
-                                                                               {0x0F00a080,0x1C000000},
-                                                                               {0x0F00a000,0x00000016},
+                                                                               {0x0F00a044, 0x1fffffff},
+                                                                               {0x0F00a040, 0x1f000000},
+                                                                               {0x0F00a084, 0x1Cffffff},
+                                                                               {0x0F00a080, 0x1C000000},
+                                                                               {0x0F00a000, 0x00000016},
                                                                                //Memcontroller Default values
-                                                                               {0x0F007000,0x00010001},
-                                                                               {0x0F007004,0x01000000},
-                                                                               {0x0F007008,0x01000001},
-                                                                               {0x0F00700c,0x00000000},
-                                                                               {0x0F007010,0x01000000},
-                                                                               {0x0F007014,0x01000100},
-                                                                               {0x0F007018,0x01000000},
-                                                                               {0x0F00701c,0x01020000},
-                                                                               {0x0F007020,0x04020107},
-                                                                               {0x0F007024,0x00000007},
-                                                                               {0x0F007028,0x02020201},
-                                                                               {0x0F00702c,0x0204040a},
-                                                                               {0x0F007030,0x04000000},
-                                                                               {0x0F007034,0x02000002},
-                                                                               {0x0F007038,0x1F060202},
-                                                                               {0x0F00703C,0x1C22221F},
-                                                                               {0x0F007040,0x8A006600},
-                                                                               {0x0F007044,0x221a0800},
-                                                                               {0x0F007048,0x02690204},
-                                                                               {0x0F00704c,0x00000000},
-                                                                               {0x0F007050,0x0100001c},
-                                                                               {0x0F007054,0x00000000},
-                                                                               {0x0F007058,0x00000000},
-                                                                               {0x0F00705c,0x00000000},
-                                                                               {0x0F007060,0x000A15D6},
-                                                                               {0x0F007064,0x0000000A},
-                                                                               {0x0F007068,0x00000000},
-                                                                               {0x0F00706c,0x00000001},
-                                                                               {0x0F007070,0x00004000},
-                                                                               {0x0F007074,0x00000000},
-                                                                               {0x0F007078,0x00000000},
-                                                                               {0x0F00707C,0x00000000},
-                                                                               {0x0F007080,0x00000000},
-                                                                               {0x0F007084,0x00000000},
-                                                                               {0x0F007094,0x00000104},
+                                                                               {0x0F007000, 0x00010001},
+                                                                               {0x0F007004, 0x01000000},
+                                                                               {0x0F007008, 0x01000001},
+                                                                               {0x0F00700c, 0x00000000},
+                                                                               {0x0F007010, 0x01000000},
+                                                                               {0x0F007014, 0x01000100},
+                                                                               {0x0F007018, 0x01000000},
+                                                                               {0x0F00701c, 0x01020000},
+                                                                               {0x0F007020, 0x04020107},
+                                                                               {0x0F007024, 0x00000007},
+                                                                               {0x0F007028, 0x02020201},
+                                                                               {0x0F00702c, 0x0204040a},
+                                                                               {0x0F007030, 0x04000000},
+                                                                               {0x0F007034, 0x02000002},
+                                                                               {0x0F007038, 0x1F060202},
+                                                                               {0x0F00703C, 0x1C22221F},
+                                                                               {0x0F007040, 0x8A006600},
+                                                                               {0x0F007044, 0x221a0800},
+                                                                               {0x0F007048, 0x02690204},
+                                                                               {0x0F00704c, 0x00000000},
+                                                                               {0x0F007050, 0x0100001c},
+                                                                               {0x0F007054, 0x00000000},
+                                                                               {0x0F007058, 0x00000000},
+                                                                               {0x0F00705c, 0x00000000},
+                                                                               {0x0F007060, 0x000A15D6},
+                                                                               {0x0F007064, 0x0000000A},
+                                                                               {0x0F007068, 0x00000000},
+                                                                               {0x0F00706c, 0x00000001},
+                                                                               {0x0F007070, 0x00004000},
+                                                                               {0x0F007074, 0x00000000},
+                                                                               {0x0F007078, 0x00000000},
+                                                                               {0x0F00707C, 0x00000000},
+                                                                               {0x0F007080, 0x00000000},
+                                                                               {0x0F007084, 0x00000000},
+                                                                               {0x0F007094, 0x00000104},
                                                                                //# Enable start bit within memory controller
-                                                                               {0x0F007018,0x01010000}
+                                                                               {0x0F007018, 0x01010000}
                                                                };
 
 //100Mhz
 #define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9  //index for 0x0F007000
 static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = {//      # DPLL Clock Setting
-                                                                               {0x0f000810,0x00000F95},
-                                                                               {0x0f000820,0x07F1369B},
-                                                                               {0x0f000840,0x0FFF0800},
-                                                                               {0x0f000880,0x000003DD},
-                                                                               {0x0f000860,0x00000000},
-                                                                               {0x0F00a044,0x1fffffff},
-                                                                               {0x0F00a040,0x1f000000},
-                                                                               {0x0F00a084,0x1Cffffff},
-                                                                               {0x0F00a080,0x1C000000},
+                                                                               {0x0f000810, 0x00000F95},
+                                                                               {0x0f000820, 0x07F1369B},
+                                                                               {0x0f000840, 0x0FFF0800},
+                                                                               {0x0f000880, 0x000003DD},
+                                                                               {0x0f000860, 0x00000000},
+                                                                               {0x0F00a044, 0x1fffffff},
+                                                                               {0x0F00a040, 0x1f000000},
+                                                                               {0x0F00a084, 0x1Cffffff},
+                                                                               {0x0F00a080, 0x1C000000},
                                                                                //# Enable 2 ports within X-bar
-                                                                               {0x0F00A000,0x00000016},
+                                                                               {0x0F00A000, 0x00000016},
                                                                //Memcontroller Default values
-                                                                               {0x0F007000,0x00010001},
-                                                                               {0x0F007004,0x01010100},
-                                                                               {0x0F007008,0x01000001},
-                                                                               {0x0F00700c,0x00000000},
-                                                                               {0x0F007010,0x01000000},
-                                                                               {0x0F007014,0x01000100},
-                                                                               {0x0F007018,0x01000000},
-                                                                               {0x0F00701c,0x01020000}, // POP - 0x00020000 Normal 0x01020000
-                                                                               {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107
-                                                                               {0x0F007024,0x00000007},
-                                                                               {0x0F007028,0x01020201},
-                                                                               {0x0F00702c,0x0204040A},
-                                                                               {0x0F007030,0x06000000},
-                                                                               {0x0F007034,0x02000004},
-                                                                               {0x0F007038,0x20080200},
-                                                                               {0x0F00703C,0x02030320},
-                                                                               {0x0F007040,0x6E7F1200},
-                                                                               {0x0F007044,0x01190A00},
-                                                                               {0x0F007048,0x06120305},//0x02690204 // 0x06120305
-                                                                               {0x0F00704c,0x00000000},
-                                                                               {0x0F007050,0x0100001C},
-                                                                               {0x0F007054,0x00000000},
-                                                                               {0x0F007058,0x00000000},
-                                                                               {0x0F00705c,0x00000000},
-                                                                               {0x0F007060,0x00082ED6},
-                                                                               {0x0F007064,0x0000000A},
-                                                                               {0x0F007068,0x00000000},
-                                                                               {0x0F00706c,0x00000001},
-                                                                               {0x0F007070,0x00005000},
-                                                                               {0x0F007074,0x00000000},
-                                                                               {0x0F007078,0x00000000},
-                                                                               {0x0F00707C,0x00000000},
-                                                                               {0x0F007080,0x00000000},
-                                                                               {0x0F007084,0x00000000},
+                                                                               {0x0F007000, 0x00010001},
+                                                                               {0x0F007004, 0x01010100},
+                                                                               {0x0F007008, 0x01000001},
+                                                                               {0x0F00700c, 0x00000000},
+                                                                               {0x0F007010, 0x01000000},
+                                                                               {0x0F007014, 0x01000100},
+                                                                               {0x0F007018, 0x01000000},
+                                                                               {0x0F00701c, 0x01020000}, // POP - 0x00020000 Normal 0x01020000
+                                                                               {0x0F007020, 0x04020107},//Normal - 0x04030107 POP - 0x05030107
+                                                                               {0x0F007024, 0x00000007},
+                                                                               {0x0F007028, 0x01020201},
+                                                                               {0x0F00702c, 0x0204040A},
+                                                                               {0x0F007030, 0x06000000},
+                                                                               {0x0F007034, 0x02000004},
+                                                                               {0x0F007038, 0x20080200},
+                                                                               {0x0F00703C, 0x02030320},
+                                                                               {0x0F007040, 0x6E7F1200},
+                                                                               {0x0F007044, 0x01190A00},
+                                                                               {0x0F007048, 0x06120305},//0x02690204 // 0x06120305
+                                                                               {0x0F00704c, 0x00000000},
+                                                                               {0x0F007050, 0x0100001C},
+                                                                               {0x0F007054, 0x00000000},
+                                                                               {0x0F007058, 0x00000000},
+                                                                               {0x0F00705c, 0x00000000},
+                                                                               {0x0F007060, 0x00082ED6},
+                                                                               {0x0F007064, 0x0000000A},
+                                                                               {0x0F007068, 0x00000000},
+                                                                               {0x0F00706c, 0x00000001},
+                                                                               {0x0F007070, 0x00005000},
+                                                                               {0x0F007074, 0x00000000},
+                                                                               {0x0F007078, 0x00000000},
+                                                                               {0x0F00707C, 0x00000000},
+                                                                               {0x0F007080, 0x00000000},
+                                                                               {0x0F007084, 0x00000000},
                                                                //# Enable BW improvement within memory controller
-                                                                               {0x0F007094,0x00000104},
+                                                                               {0x0F007094, 0x00000104},
                                                                //# Enable start bit within memory controller
-                                                                               {0x0F007018,0x01010000}
+                                                                               {0x0F007018, 0x01010000}
                                                        };
 
 
 #define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9  //index for 0x0F007000
-static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[]= {//   # DPLL Clock Setting
-                                                               {0x0f000820,0x03F1365B},
-                                                               {0x0f000810,0x00002F95},
-                                                               {0x0f000880,0x000003DD},
+static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[] = {//  # DPLL Clock Setting
+                                                               {0x0f000820, 0x03F1365B},
+                                                               {0x0f000810, 0x00002F95},
+                                                               {0x0f000880, 0x000003DD},
                                                                // Changed source for X-bar and MIPS clock to APLL
-                                                               {0x0f000840,0x0FFF0000},
-                                                               {0x0f000860,0x00000000},
-                                                               {0x0F00a044,0x1fffffff},
-                                                               {0x0F00a040,0x1f000000},
-                                                               {0x0F00a084,0x1Cffffff},
-                                                               {0x0F00a080,0x1C000000},
-                                                               {0x0F00A000,0x00000016},
+                                                               {0x0f000840, 0x0FFF0000},
+                                                               {0x0f000860, 0x00000000},
+                                                               {0x0F00a044, 0x1fffffff},
+                                                               {0x0F00a040, 0x1f000000},
+                                                               {0x0F00a084, 0x1Cffffff},
+                                                               {0x0F00a080, 0x1C000000},
+                                                               {0x0F00A000, 0x00000016},
                                                                //Memcontroller Default values
-                                                               {0x0F007000,0x00010001},
-                                                               {0x0F007004,0x01010100},
-                                                               {0x0F007008,0x01000001},
-                                                               {0x0F00700c,0x00000000},
-                                                               {0x0F007010,0x01000000},
-                                                               {0x0F007014,0x01000100},
-                                                               {0x0F007018,0x01000000},
-                                                               {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001
-                                                               {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107
-                                                               {0x0F007024,0x02000007},
-                                                               {0x0F007028,0x02020200},
-                                                               {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a
-                                                               {0x0F007030,0x05000000},
-                                                               {0x0F007034,0x00000003},
-                                                               {0x0F007038,0x200a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
-                                                               {0x0F00703C,0x02101020},//ROB - 0x02101010,//0x02101018,
-                                                               {0x0F007040,0x45711200},//ROB - 0x45751200,//0x450f1200,
-                                                               {0x0F007044,0x110D0D00},//ROB - 0x110a0d00//0x111f0d00
-                                                               {0x0F007048,0x04080306},
-                                                               {0x0F00704c,0x00000000},
-                                                               {0x0F007050,0x0100001c},
-                                                               {0x0F007054,0x00000000},
-                                                               {0x0F007058,0x00000000},
-                                                               {0x0F00705c,0x00000000},
-                                                               {0x0F007060,0x0010245F},
-                                                               {0x0F007064,0x00000010},
-                                                               {0x0F007068,0x00000000},
-                                                               {0x0F00706c,0x00000001},
-                                                               {0x0F007070,0x00007000},
-                                                               {0x0F007074,0x00000000},
-                                                               {0x0F007078,0x00000000},
-                                                               {0x0F00707C,0x00000000},
-                                                               {0x0F007080,0x00000000},
-                                                               {0x0F007084,0x00000000},
-                                                               {0x0F007088,0x01000001},
-                                                               {0x0F00708c,0x00000101},
-                                                               {0x0F007090,0x00000000},
+                                                               {0x0F007000, 0x00010001},
+                                                               {0x0F007004, 0x01010100},
+                                                               {0x0F007008, 0x01000001},
+                                                               {0x0F00700c, 0x00000000},
+                                                               {0x0F007010, 0x01000000},
+                                                               {0x0F007014, 0x01000100},
+                                                               {0x0F007018, 0x01000000},
+                                                               {0x0F00701c, 0x01020001},// POP - 0x00020001 Normal 0x01020001
+                                                               {0x0F007020, 0x04030107}, //Normal - 0x04030107 POP - 0x05030107
+                                                               {0x0F007024, 0x02000007},
+                                                               {0x0F007028, 0x02020200},
+                                                               {0x0F00702c, 0x0206060a},//ROB- 0x0205050a,//0x0206060a
+                                                               {0x0F007030, 0x05000000},
+                                                               {0x0F007034, 0x00000003},
+                                                               {0x0F007038, 0x200a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+                                                               {0x0F00703C, 0x02101020},//ROB - 0x02101010,//0x02101018,
+                                                               {0x0F007040, 0x45711200},//ROB - 0x45751200,//0x450f1200,
+                                                               {0x0F007044, 0x110D0D00},//ROB - 0x110a0d00//0x111f0d00
+                                                               {0x0F007048, 0x04080306},
+                                                               {0x0F00704c, 0x00000000},
+                                                               {0x0F007050, 0x0100001c},
+                                                               {0x0F007054, 0x00000000},
+                                                               {0x0F007058, 0x00000000},
+                                                               {0x0F00705c, 0x00000000},
+                                                               {0x0F007060, 0x0010245F},
+                                                               {0x0F007064, 0x00000010},
+                                                               {0x0F007068, 0x00000000},
+                                                               {0x0F00706c, 0x00000001},
+                                                               {0x0F007070, 0x00007000},
+                                                               {0x0F007074, 0x00000000},
+                                                               {0x0F007078, 0x00000000},
+                                                               {0x0F00707C, 0x00000000},
+                                                               {0x0F007080, 0x00000000},
+                                                               {0x0F007084, 0x00000000},
+                                                               {0x0F007088, 0x01000001},
+                                                               {0x0F00708c, 0x00000101},
+                                                               {0x0F007090, 0x00000000},
                                                                //# Enable BW improvement within memory controller
-                                                               {0x0F007094,0x00040000},
-                                                               {0x0F007098,0x00000000},
-                                                               {0x0F0070c8,0x00000104},
+                                                               {0x0F007094, 0x00040000},
+                                                               {0x0F007098, 0x00000000},
+                                                               {0x0F0070c8, 0x00000104},
                                                                //# Enable 2 ports within X-bar
                                                                //# Enable start bit within memory controller
-                                                               {0x0F007018,0x01010000}
+                                                               {0x0F007018, 0x01010000}
 };
 
 #define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11  //index for 0x0F007000
-static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[]= {//   # DPLL Clock Setting
-                                                               {0x0f000810,0x00002F95},
-                                                               {0x0f000820,0x03F1369B},
-                                                               {0x0f000840,0x0fff0000},
-                                                               {0x0f000860,0x00000000},
-                                                               {0x0f000880,0x000003DD},
+static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[] = {//  # DPLL Clock Setting
+                                                               {0x0f000810, 0x00002F95},
+                                                               {0x0f000820, 0x03F1369B},
+                                                               {0x0f000840, 0x0fff0000},
+                                                               {0x0f000860, 0x00000000},
+                                                               {0x0f000880, 0x000003DD},
                                                                // Changed source for X-bar and MIPS clock to APLL
-                                                               {0x0f000840,0x0FFF0000},
-                                                               {0x0F00a044,0x1fffffff},
-                                                               {0x0F00a040,0x1f000000},
-                                                               {0x0F00a084,0x1Cffffff},
-                                                               {0x0F00a080,0x1C000000},
+                                                               {0x0f000840, 0x0FFF0000},
+                                                               {0x0F00a044, 0x1fffffff},
+                                                               {0x0F00a040, 0x1f000000},
+                                                               {0x0F00a084, 0x1Cffffff},
+                                                               {0x0F00a080, 0x1C000000},
                                                                //Memcontroller Default values
-                                                               {0x0F007000,0x00010001},
-                                                               {0x0F007004,0x01010100},
-                                                               {0x0F007008,0x01000001},
-                                                               {0x0F00700c,0x00000000},
-                                                               {0x0F007010,0x01000000},
-                                                               {0x0F007014,0x01000100},
-                                                               {0x0F007018,0x01000000},
-                                                               {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001
-                                                               {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107
-                                                               {0x0F007024,0x00000007},
-                                                               {0x0F007028,0x01020200},
-                                                               {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a
-                                                               {0x0F007030,0x06000000},
-                                                               {0x0F007034,0x00000004},
-                                                               {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
-                                                               {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018,
-                                                               {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200,
-                                                               {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00
-                                                               {0x0F007048,0x03000305},
-                                                               {0x0F00704c,0x00000000},
-                                                               {0x0F007050,0x0100001c},
-                                                               {0x0F007054,0x00000000},
-                                                               {0x0F007058,0x00000000},
-                                                               {0x0F00705c,0x00000000},
-                                                               {0x0F007060,0x00082ED6},
-                                                               {0x0F007064,0x0000000A},
-                                                               {0x0F007068,0x00000000},
-                                                               {0x0F00706c,0x00000001},
-                                                               {0x0F007070,0x00005000},
-                                                               {0x0F007074,0x00000000},
-                                                               {0x0F007078,0x00000000},
-                                                               {0x0F00707C,0x00000000},
-                                                               {0x0F007080,0x00000000},
-                                                               {0x0F007084,0x00000000},
-                                                               {0x0F007088,0x01000001},
-                                                               {0x0F00708c,0x00000101},
-                                                               {0x0F007090,0x00000000},
-                                                               {0x0F007094,0x00010000},
-                                                               {0x0F007098,0x00000000},
-                                                               {0x0F0070C8,0x00000104},
+                                                               {0x0F007000, 0x00010001},
+                                                               {0x0F007004, 0x01010100},
+                                                               {0x0F007008, 0x01000001},
+                                                               {0x0F00700c, 0x00000000},
+                                                               {0x0F007010, 0x01000000},
+                                                               {0x0F007014, 0x01000100},
+                                                               {0x0F007018, 0x01000000},
+                                                               {0x0F00701c, 0x01020000},// POP - 0x00020001 Normal 0x01020001
+                                                               {0x0F007020, 0x04020107}, //Normal - 0x04030107 POP - 0x05030107
+                                                               {0x0F007024, 0x00000007},
+                                                               {0x0F007028, 0x01020200},
+                                                               {0x0F00702c, 0x0204040a},//ROB- 0x0205050a,//0x0206060a
+                                                               {0x0F007030, 0x06000000},
+                                                               {0x0F007034, 0x00000004},
+                                                               {0x0F007038, 0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+                                                               {0x0F00703C, 0x0203031F},//ROB - 0x02101010,//0x02101018,
+                                                               {0x0F007040, 0x6e001200},//ROB - 0x45751200,//0x450f1200,
+                                                               {0x0F007044, 0x011a0a00},//ROB - 0x110a0d00//0x111f0d00
+                                                               {0x0F007048, 0x03000305},
+                                                               {0x0F00704c, 0x00000000},
+                                                               {0x0F007050, 0x0100001c},
+                                                               {0x0F007054, 0x00000000},
+                                                               {0x0F007058, 0x00000000},
+                                                               {0x0F00705c, 0x00000000},
+                                                               {0x0F007060, 0x00082ED6},
+                                                               {0x0F007064, 0x0000000A},
+                                                               {0x0F007068, 0x00000000},
+                                                               {0x0F00706c, 0x00000001},
+                                                               {0x0F007070, 0x00005000},
+                                                               {0x0F007074, 0x00000000},
+                                                               {0x0F007078, 0x00000000},
+                                                               {0x0F00707C, 0x00000000},
+                                                               {0x0F007080, 0x00000000},
+                                                               {0x0F007084, 0x00000000},
+                                                               {0x0F007088, 0x01000001},
+                                                               {0x0F00708c, 0x00000101},
+                                                               {0x0F007090, 0x00000000},
+                                                               {0x0F007094, 0x00010000},
+                                                               {0x0F007098, 0x00000000},
+                                                               {0x0F0070C8, 0x00000104},
                                                                //# Enable 2 ports within X-bar
-                                                               {0x0F00A000,0x00000016},
+                                                               {0x0F00A000, 0x00000016},
                                                                //# Enable start bit within memory controller
-                                                               {0x0F007018,0x01010000}
+                                                               {0x0F007018, 0x01010000}
 };
 
 #define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9  //index for 0x0F007000
-static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[]= {//    # DPLL Clock Setting
-                                                               {0x0f000820,0x07F13FFF},
-                                                               {0x0f000810,0x00002F95},
-                                                               {0x0f000860,0x00000000},
-                                                               {0x0f000880,0x000003DD},
-                                                               {0x0f000840,0x0FFF1F00},
-                                                               {0x0F00a044,0x1fffffff},
-                                                               {0x0F00a040,0x1f000000},
-                                                               {0x0F00a084,0x1Cffffff},
-                                                               {0x0F00a080,0x1C000000},
-                                                               {0x0F00A000,0x00000016},
-                                                               {0x0f007000,0x00010001},
-                                                               {0x0f007004,0x01000000},
-                                                               {0x0f007008,0x01000001},
-                                                               {0x0f00700c,0x00000000},
-                                                               {0x0f007010,0x01000000},
-                                                               {0x0f007014,0x01000100},
-                                                               {0x0f007018,0x01000000},
-                                                               {0x0f00701c,0x01020000},
-                                                               {0x0f007020,0x04020107},
-                                                               {0x0f007024,0x00000007},
-                                                               {0x0f007028,0x02020200},
-                                                               {0x0f00702c,0x0204040a},
-                                                               {0x0f007030,0x04000000},
-                                                               {0x0f007034,0x00000002},
-                                                               {0x0f007038,0x1d060200},
-                                                               {0x0f00703c,0x1c22221d},
-                                                               {0x0f007040,0x8A116600},
-                                                               {0x0f007044,0x222d0800},
-                                                               {0x0f007048,0x02690204},
-                                                               {0x0f00704c,0x00000000},
-                                                               {0x0f007050,0x0100001c},
-                                                               {0x0f007054,0x00000000},
-                                                               {0x0f007058,0x00000000},
-                                                               {0x0f00705c,0x00000000},
-                                                               {0x0f007060,0x000A15D6},
-                                                               {0x0f007064,0x0000000A},
-                                                               {0x0f007068,0x00000000},
-                                                               {0x0f00706c,0x00000001},
-                                                               {0x0f007070,0x00004000},
-                                                               {0x0f007074,0x00000000},
-                                                               {0x0f007078,0x00000000},
-                                                               {0x0f00707c,0x00000000},
-                                                               {0x0f007080,0x00000000},
-                                                               {0x0f007084,0x00000000},
-                                                               {0x0f007088,0x01000001},
-                                                               {0x0f00708c,0x00000101},
-                                                               {0x0f007090,0x00000000},
-                                                               {0x0f007094,0x00010000},
-                                                               {0x0f007098,0x00000000},
-                                                               {0x0F0070C8,0x00000104},
-                                                               {0x0F007018,0x01010000}
+static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[] = {//   # DPLL Clock Setting
+                                                               {0x0f000820, 0x07F13FFF},
+                                                               {0x0f000810, 0x00002F95},
+                                                               {0x0f000860, 0x00000000},
+                                                               {0x0f000880, 0x000003DD},
+                                                               {0x0f000840, 0x0FFF1F00},
+                                                               {0x0F00a044, 0x1fffffff},
+                                                               {0x0F00a040, 0x1f000000},
+                                                               {0x0F00a084, 0x1Cffffff},
+                                                               {0x0F00a080, 0x1C000000},
+                                                               {0x0F00A000, 0x00000016},
+                                                               {0x0f007000, 0x00010001},
+                                                               {0x0f007004, 0x01000000},
+                                                               {0x0f007008, 0x01000001},
+                                                               {0x0f00700c, 0x00000000},
+                                                               {0x0f007010, 0x01000000},
+                                                               {0x0f007014, 0x01000100},
+                                                               {0x0f007018, 0x01000000},
+                                                               {0x0f00701c, 0x01020000},
+                                                               {0x0f007020, 0x04020107},
+                                                               {0x0f007024, 0x00000007},
+                                                               {0x0f007028, 0x02020200},
+                                                               {0x0f00702c, 0x0204040a},
+                                                               {0x0f007030, 0x04000000},
+                                                               {0x0f007034, 0x00000002},
+                                                               {0x0f007038, 0x1d060200},
+                                                               {0x0f00703c, 0x1c22221d},
+                                                               {0x0f007040, 0x8A116600},
+                                                               {0x0f007044, 0x222d0800},
+                                                               {0x0f007048, 0x02690204},
+                                                               {0x0f00704c, 0x00000000},
+                                                               {0x0f007050, 0x0100001c},
+                                                               {0x0f007054, 0x00000000},
+                                                               {0x0f007058, 0x00000000},
+                                                               {0x0f00705c, 0x00000000},
+                                                               {0x0f007060, 0x000A15D6},
+                                                               {0x0f007064, 0x0000000A},
+                                                               {0x0f007068, 0x00000000},
+                                                               {0x0f00706c, 0x00000001},
+                                                               {0x0f007070, 0x00004000},
+                                                               {0x0f007074, 0x00000000},
+                                                               {0x0f007078, 0x00000000},
+                                                               {0x0f00707c, 0x00000000},
+                                                               {0x0f007080, 0x00000000},
+                                                               {0x0f007084, 0x00000000},
+                                                               {0x0f007088, 0x01000001},
+                                                               {0x0f00708c, 0x00000101},
+                                                               {0x0f007090, 0x00000000},
+                                                               {0x0f007094, 0x00010000},
+                                                               {0x0f007098, 0x00000000},
+                                                               {0x0F0070C8, 0x00000104},
+                                                               {0x0F007018, 0x01010000}
 };
 
 
@@ -536,246 +536,245 @@ static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[]= {//     # DPLL Clock Setting
 ///T3 LP-B (UMA-B)
 
 #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7  //index for 0x0F007000
-static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[]= {//  # DPLL Clock Setting
-
-                                                               {0x0f000820,0x03F137DB},
-                                                               {0x0f000810,0x01842795},
-                                                               {0x0f000860,0x00000000},
-                                                               {0x0f000880,0x000003DD},
-                                                               {0x0f000840,0x0FFF0400},
-                                                               {0x0F00a044,0x1fffffff},
-                                                               {0x0F00a040,0x1f000000},
-                                                               {0x0f003050,0x00000021},//this is flash/eeprom clock divisor which set the flash clock to 20 MHz
-                                                               {0x0F00a084,0x1Cffffff},//Now dump from her in internal memory
-                                                               {0x0F00a080,0x1C000000},
-                                                               {0x0F00A000,0x00000016},
-                                                               {0x0f007000,0x00010001},
-                                                               {0x0f007004,0x01000001},
-                                                               {0x0f007008,0x01000101},
-                                                               {0x0f00700c,0x00000000},
-                                                               {0x0f007010,0x01000100},
-                                                               {0x0f007014,0x01000100},
-                                                               {0x0f007018,0x01000000},
-                                                               {0x0f00701c,0x01020000},
-                                                               {0x0f007020,0x04030107},
-                                                               {0x0f007024,0x02000007},
-                                                               {0x0f007028,0x02020200},
-                                                               {0x0f00702c,0x0206060a},
-                                                               {0x0f007030,0x050d0d00},
-                                                               {0x0f007034,0x00000003},
-                                                               {0x0f007038,0x170a0200},
-                                                               {0x0f00703c,0x02101012},
-                                                               {0x0f007040,0x45161200},
-                                                               {0x0f007044,0x11250c00},
-                                                               {0x0f007048,0x04da0307},
-                                                               {0x0f00704c,0x00000000},
-                                                               {0x0f007050,0x0000001c},
-                                                               {0x0f007054,0x00000000},
-                                                               {0x0f007058,0x00000000},
-                                                               {0x0f00705c,0x00000000},
-                                                               {0x0f007060,0x00142bb6},
-                                                               {0x0f007064,0x20430014},
-                                                               {0x0f007068,0x00000000},
-                                                               {0x0f00706c,0x00000001},
-                                                               {0x0f007070,0x00009000},
-                                                               {0x0f007074,0x00000000},
-                                                               {0x0f007078,0x00000000},
-                                                               {0x0f00707c,0x00000000},
-                                                               {0x0f007080,0x00000000},
-                                                               {0x0f007084,0x00000000},
-                                                               {0x0f007088,0x01000001},
-                                                               {0x0f00708c,0x00000101},
-                                                               {0x0f007090,0x00000000},
-                                                               {0x0f007094,0x00040000},
-                                                               {0x0f007098,0x00000000},
-                                                               {0x0F0070C8,0x00000104},
-                                                               {0x0F007018,0x01010000}
+static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[] = {// # DPLL Clock Setting
+                                                               {0x0f000820, 0x03F137DB},
+                                                               {0x0f000810, 0x01842795},
+                                                               {0x0f000860, 0x00000000},
+                                                               {0x0f000880, 0x000003DD},
+                                                               {0x0f000840, 0x0FFF0400},
+                                                               {0x0F00a044, 0x1fffffff},
+                                                               {0x0F00a040, 0x1f000000},
+                                                               {0x0f003050, 0x00000021},//this is flash/eeprom clock divisor which set the flash clock to 20 MHz
+                                                               {0x0F00a084, 0x1Cffffff},//Now dump from her in internal memory
+                                                               {0x0F00a080, 0x1C000000},
+                                                               {0x0F00A000, 0x00000016},
+                                                               {0x0f007000, 0x00010001},
+                                                               {0x0f007004, 0x01000001},
+                                                               {0x0f007008, 0x01000101},
+                                                               {0x0f00700c, 0x00000000},
+                                                               {0x0f007010, 0x01000100},
+                                                               {0x0f007014, 0x01000100},
+                                                               {0x0f007018, 0x01000000},
+                                                               {0x0f00701c, 0x01020000},
+                                                               {0x0f007020, 0x04030107},
+                                                               {0x0f007024, 0x02000007},
+                                                               {0x0f007028, 0x02020200},
+                                                               {0x0f00702c, 0x0206060a},
+                                                               {0x0f007030, 0x050d0d00},
+                                                               {0x0f007034, 0x00000003},
+                                                               {0x0f007038, 0x170a0200},
+                                                               {0x0f00703c, 0x02101012},
+                                                               {0x0f007040, 0x45161200},
+                                                               {0x0f007044, 0x11250c00},
+                                                               {0x0f007048, 0x04da0307},
+                                                               {0x0f00704c, 0x00000000},
+                                                               {0x0f007050, 0x0000001c},
+                                                               {0x0f007054, 0x00000000},
+                                                               {0x0f007058, 0x00000000},
+                                                               {0x0f00705c, 0x00000000},
+                                                               {0x0f007060, 0x00142bb6},
+                                                               {0x0f007064, 0x20430014},
+                                                               {0x0f007068, 0x00000000},
+                                                               {0x0f00706c, 0x00000001},
+                                                               {0x0f007070, 0x00009000},
+                                                               {0x0f007074, 0x00000000},
+                                                               {0x0f007078, 0x00000000},
+                                                               {0x0f00707c, 0x00000000},
+                                                               {0x0f007080, 0x00000000},
+                                                               {0x0f007084, 0x00000000},
+                                                               {0x0f007088, 0x01000001},
+                                                               {0x0f00708c, 0x00000101},
+                                                               {0x0f007090, 0x00000000},
+                                                               {0x0f007094, 0x00040000},
+                                                               {0x0f007098, 0x00000000},
+                                                               {0x0F0070C8, 0x00000104},
+                                                               {0x0F007018, 0x01010000}
 };
 
 
 #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7  //index for 0x0F007000
-static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[]= {//  # DPLL Clock Setting
-                                                               {0x0f000820,0x03F1365B},
-                                                               {0x0f000810,0x00002F95},
-                                                               {0x0f000880,0x000003DD},
+static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[] = {// # DPLL Clock Setting
+                                                               {0x0f000820, 0x03F1365B},
+                                                               {0x0f000810, 0x00002F95},
+                                                               {0x0f000880, 0x000003DD},
                                                                // Changed source for X-bar and MIPS clock to APLL
-                                                               {0x0f000840,0x0FFF0000},
-                                                               {0x0f000860,0x00000000},
-                                                               {0x0F00a044,0x1fffffff},
-                                                               {0x0F00a040,0x1f000000},
-                                                               {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz
-                                                               {0x0F00a084,0x1Cffffff},//dump from here in internal memory
-                                                               {0x0F00a080,0x1C000000},
-                                                               {0x0F00A000,0x00000016},
+                                                               {0x0f000840, 0x0FFF0000},
+                                                               {0x0f000860, 0x00000000},
+                                                               {0x0F00a044, 0x1fffffff},
+                                                               {0x0F00a040, 0x1f000000},
+                                                               {0x0f003050, 0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz
+                                                               {0x0F00a084, 0x1Cffffff},//dump from here in internal memory
+                                                               {0x0F00a080, 0x1C000000},
+                                                               {0x0F00A000, 0x00000016},
                                                                //Memcontroller Default values
-                                                               {0x0F007000,0x00010001},
-                                                               {0x0F007004,0x01010100},
-                                                               {0x0F007008,0x01000001},
-                                                               {0x0F00700c,0x00000000},
-                                                               {0x0F007010,0x01000000},
-                                                               {0x0F007014,0x01000100},
-                                                               {0x0F007018,0x01000000},
-                                                               {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001
-                                                               {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107
-                                                               {0x0F007024,0x02000007},
-                                                               {0x0F007028,0x02020200},
-                                                               {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a
-                                                               {0x0F007030,0x05000000},
-                                                               {0x0F007034,0x00000003},
-                                                               {0x0F007038,0x190a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
-                                                               {0x0F00703C,0x02101017},//ROB - 0x02101010,//0x02101018,
-                                                               {0x0F007040,0x45171200},//ROB - 0x45751200,//0x450f1200,
-                                                               {0x0F007044,0x11290D00},//ROB - 0x110a0d00//0x111f0d00
-                                                               {0x0F007048,0x04080306},
-                                                               {0x0F00704c,0x00000000},
-                                                               {0x0F007050,0x0100001c},
-                                                               {0x0F007054,0x00000000},
-                                                               {0x0F007058,0x00000000},
-                                                               {0x0F00705c,0x00000000},
-                                                               {0x0F007060,0x0010245F},
-                                                               {0x0F007064,0x00000010},
-                                                               {0x0F007068,0x00000000},
-                                                               {0x0F00706c,0x00000001},
-                                                               {0x0F007070,0x00007000},
-                                                               {0x0F007074,0x00000000},
-                                                               {0x0F007078,0x00000000},
-                                                               {0x0F00707C,0x00000000},
-                                                               {0x0F007080,0x00000000},
-                                                               {0x0F007084,0x00000000},
-                                                               {0x0F007088,0x01000001},
-                                                               {0x0F00708c,0x00000101},
-                                                               {0x0F007090,0x00000000},
+                                                               {0x0F007000, 0x00010001},
+                                                               {0x0F007004, 0x01010100},
+                                                               {0x0F007008, 0x01000001},
+                                                               {0x0F00700c, 0x00000000},
+                                                               {0x0F007010, 0x01000000},
+                                                               {0x0F007014, 0x01000100},
+                                                               {0x0F007018, 0x01000000},
+                                                               {0x0F00701c, 0x01020001},// POP - 0x00020001 Normal 0x01020001
+                                                               {0x0F007020, 0x04030107}, //Normal - 0x04030107 POP - 0x05030107
+                                                               {0x0F007024, 0x02000007},
+                                                               {0x0F007028, 0x02020200},
+                                                               {0x0F00702c, 0x0206060a},//ROB- 0x0205050a,//0x0206060a
+                                                               {0x0F007030, 0x05000000},
+                                                               {0x0F007034, 0x00000003},
+                                                               {0x0F007038, 0x190a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+                                                               {0x0F00703C, 0x02101017},//ROB - 0x02101010,//0x02101018,
+                                                               {0x0F007040, 0x45171200},//ROB - 0x45751200,//0x450f1200,
+                                                               {0x0F007044, 0x11290D00},//ROB - 0x110a0d00//0x111f0d00
+                                                               {0x0F007048, 0x04080306},
+                                                               {0x0F00704c, 0x00000000},
+                                                               {0x0F007050, 0x0100001c},
+                                                               {0x0F007054, 0x00000000},
+                                                               {0x0F007058, 0x00000000},
+                                                               {0x0F00705c, 0x00000000},
+                                                               {0x0F007060, 0x0010245F},
+                                                               {0x0F007064, 0x00000010},
+                                                               {0x0F007068, 0x00000000},
+                                                               {0x0F00706c, 0x00000001},
+                                                               {0x0F007070, 0x00007000},
+                                                               {0x0F007074, 0x00000000},
+                                                               {0x0F007078, 0x00000000},
+                                                               {0x0F00707C, 0x00000000},
+                                                               {0x0F007080, 0x00000000},
+                                                               {0x0F007084, 0x00000000},
+                                                               {0x0F007088, 0x01000001},
+                                                               {0x0F00708c, 0x00000101},
+                                                               {0x0F007090, 0x00000000},
                                                                //# Enable BW improvement within memory controller
-                                                               {0x0F007094,0x00040000},
-                                                               {0x0F007098,0x00000000},
-                                                               {0x0F0070c8,0x00000104},
+                                                               {0x0F007094, 0x00040000},
+                                                               {0x0F007098, 0x00000000},
+                                                               {0x0F0070c8, 0x00000104},
                                                                //# Enable 2 ports within X-bar
                                                                //# Enable start bit within memory controller
-                                                               {0x0F007018,0x01010000}
+                                                               {0x0F007018, 0x01010000}
 };
 
 #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8  //index for 0x0F007000
-static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[]= {//  # DPLL Clock Setting
-                                                               {0x0f000810,0x00002F95},
-                                                               {0x0f000820,0x03F1369B},
-                                                               {0x0f000840,0x0fff0000},
-                                                               {0x0f000860,0x00000000},
-                                                               {0x0f000880,0x000003DD},
+static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[] = {// # DPLL Clock Setting
+                                                               {0x0f000810, 0x00002F95},
+                                                               {0x0f000820, 0x03F1369B},
+                                                               {0x0f000840, 0x0fff0000},
+                                                               {0x0f000860, 0x00000000},
+                                                               {0x0f000880, 0x000003DD},
                                                                // Changed source for X-bar and MIPS clock to APLL
-                                                               {0x0f000840,0x0FFF0000},
-                                                               {0x0F00a044,0x1fffffff},
-                                                               {0x0F00a040,0x1f000000},
-                                                               {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz
-                                                               {0x0F00a084,0x1Cffffff}, //dump from here in internal memory
-                                                               {0x0F00a080,0x1C000000},
+                                                               {0x0f000840, 0x0FFF0000},
+                                                               {0x0F00a044, 0x1fffffff},
+                                                               {0x0F00a040, 0x1f000000},
+                                                               {0x0f003050, 0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz
+                                                               {0x0F00a084, 0x1Cffffff}, //dump from here in internal memory
+                                                               {0x0F00a080, 0x1C000000},
                                                                //Memcontroller Default values
-                                                               {0x0F007000,0x00010001},
-                                                               {0x0F007004,0x01010100},
-                                                               {0x0F007008,0x01000001},
-                                                               {0x0F00700c,0x00000000},
-                                                               {0x0F007010,0x01000000},
-                                                               {0x0F007014,0x01000100},
-                                                               {0x0F007018,0x01000000},
-                                                               {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001
-                                                               {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107
-                                                               {0x0F007024,0x00000007},
-                                                               {0x0F007028,0x01020200},
-                                                               {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a
-                                                               {0x0F007030,0x06000000},
-                                                               {0x0F007034,0x00000004},
-                                                               {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
-                                                               {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018,
-                                                               {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200,
-                                                               {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00
-                                                               {0x0F007048,0x03000305},
-                                                               {0x0F00704c,0x00000000},
-                                                               {0x0F007050,0x0100001c},
-                                                               {0x0F007054,0x00000000},
-                                                               {0x0F007058,0x00000000},
-                                                               {0x0F00705c,0x00000000},
-                                                               {0x0F007060,0x00082ED6},
-                                                               {0x0F007064,0x0000000A},
-                                                               {0x0F007068,0x00000000},
-                                                               {0x0F00706c,0x00000001},
-                                                               {0x0F007070,0x00005000},
-                                                               {0x0F007074,0x00000000},
-                                                               {0x0F007078,0x00000000},
-                                                               {0x0F00707C,0x00000000},
-                                                               {0x0F007080,0x00000000},
-                                                               {0x0F007084,0x00000000},
-                                                               {0x0F007088,0x01000001},
-                                                               {0x0F00708c,0x00000101},
-                                                               {0x0F007090,0x00000000},
-                                                               {0x0F007094,0x00010000},
-                                                               {0x0F007098,0x00000000},
-                                                               {0x0F0070C8,0x00000104},
+                                                               {0x0F007000, 0x00010001},
+                                                               {0x0F007004, 0x01010100},
+                                                               {0x0F007008, 0x01000001},
+                                                               {0x0F00700c, 0x00000000},
+                                                               {0x0F007010, 0x01000000},
+                                                               {0x0F007014, 0x01000100},
+                                                               {0x0F007018, 0x01000000},
+                                                               {0x0F00701c, 0x01020000},// POP - 0x00020001 Normal 0x01020001
+                                                               {0x0F007020, 0x04020107}, //Normal - 0x04030107 POP - 0x05030107
+                                                               {0x0F007024, 0x00000007},
+                                                               {0x0F007028, 0x01020200},
+                                                               {0x0F00702c, 0x0204040a},//ROB- 0x0205050a,//0x0206060a
+                                                               {0x0F007030, 0x06000000},
+                                                               {0x0F007034, 0x00000004},
+                                                               {0x0F007038, 0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+                                                               {0x0F00703C, 0x0203031F},//ROB - 0x02101010,//0x02101018,
+                                                               {0x0F007040, 0x6e001200},//ROB - 0x45751200,//0x450f1200,
+                                                               {0x0F007044, 0x011a0a00},//ROB - 0x110a0d00//0x111f0d00
+                                                               {0x0F007048, 0x03000305},
+                                                               {0x0F00704c, 0x00000000},
+                                                               {0x0F007050, 0x0100001c},
+                                                               {0x0F007054, 0x00000000},
+                                                               {0x0F007058, 0x00000000},
+                                                               {0x0F00705c, 0x00000000},
+                                                               {0x0F007060, 0x00082ED6},
+                                                               {0x0F007064, 0x0000000A},
+                                                               {0x0F007068, 0x00000000},
+                                                               {0x0F00706c, 0x00000001},
+                                                               {0x0F007070, 0x00005000},
+                                                               {0x0F007074, 0x00000000},
+                                                               {0x0F007078, 0x00000000},
+                                                               {0x0F00707C, 0x00000000},
+                                                               {0x0F007080, 0x00000000},
+                                                               {0x0F007084, 0x00000000},
+                                                               {0x0F007088, 0x01000001},
+                                                               {0x0F00708c, 0x00000101},
+                                                               {0x0F007090, 0x00000000},
+                                                               {0x0F007094, 0x00010000},
+                                                               {0x0F007098, 0x00000000},
+                                                               {0x0F0070C8, 0x00000104},
                                                                //# Enable 2 ports within X-bar
-                                                               {0x0F00A000,0x00000016},
+                                                               {0x0F00A000, 0x00000016},
                                                                //# Enable start bit within memory controller
-                                                               {0x0F007018,0x01010000}
+                                                               {0x0F007018, 0x01010000}
 };
 
 #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7  //index for 0x0F007000
-static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[]= {//   # DPLL Clock Setting
-                                                               {0x0f000820,0x07F13FFF},
-                                                               {0x0f000810,0x00002F95},
-                                                               {0x0f000860,0x00000000},
-                                                               {0x0f000880,0x000003DD},
-                                                               {0x0f000840,0x0FFF1F00},
-                                                               {0x0F00a044,0x1fffffff},
-                                                               {0x0F00a040,0x1f000000},
-                                                               {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz
-                                                               {0x0F00a084,0x1Cffffff},// dump from here in internal memory
-                                                               {0x0F00a080,0x1C000000},
-                                                               {0x0F00A000,0x00000016},
-                                                               {0x0f007000,0x00010001},
-                                                               {0x0f007004,0x01000000},
-                                                               {0x0f007008,0x01000001},
-                                                               {0x0f00700c,0x00000000},
-                                                               {0x0f007010,0x01000000},
-                                                               {0x0f007014,0x01000100},
-                                                               {0x0f007018,0x01000000},
-                                                               {0x0f00701c,0x01020000},
-                                                               {0x0f007020,0x04020107},
-                                                               {0x0f007024,0x00000007},
-                                                               {0x0f007028,0x02020200},
-                                                               {0x0f00702c,0x0204040a},
-                                                               {0x0f007030,0x04000000},
-                                                               {0x0f007034,0x00000002},
-                                                               {0x0f007038,0x1d060200},
-                                                               {0x0f00703c,0x1c22221d},
-                                                               {0x0f007040,0x8A116600},
-                                                               {0x0f007044,0x222d0800},
-                                                               {0x0f007048,0x02690204},
-                                                               {0x0f00704c,0x00000000},
-                                                               {0x0f007050,0x0100001c},
-                                                               {0x0f007054,0x00000000},
-                                                               {0x0f007058,0x00000000},
-                                                               {0x0f00705c,0x00000000},
-                                                               {0x0f007060,0x000A15D6},
-                                                               {0x0f007064,0x0000000A},
-                                                               {0x0f007068,0x00000000},
-                                                               {0x0f00706c,0x00000001},
-                                                               {0x0f007070,0x00004000},
-                                                               {0x0f007074,0x00000000},
-                                                               {0x0f007078,0x00000000},
-                                                               {0x0f00707c,0x00000000},
-                                                               {0x0f007080,0x00000000},
-                                                               {0x0f007084,0x00000000},
-                                                               {0x0f007088,0x01000001},
-                                                               {0x0f00708c,0x00000101},
-                                                               {0x0f007090,0x00000000},
-                                                               {0x0f007094,0x00010000},
-                                                               {0x0f007098,0x00000000},
-                                                               {0x0F0070C8,0x00000104},
-                                                               {0x0F007018,0x01010000}
+static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[] = {//  # DPLL Clock Setting
+                                                               {0x0f000820, 0x07F13FFF},
+                                                               {0x0f000810, 0x00002F95},
+                                                               {0x0f000860, 0x00000000},
+                                                               {0x0f000880, 0x000003DD},
+                                                               {0x0f000840, 0x0FFF1F00},
+                                                               {0x0F00a044, 0x1fffffff},
+                                                               {0x0F00a040, 0x1f000000},
+                                                               {0x0f003050, 0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz
+                                                               {0x0F00a084, 0x1Cffffff},// dump from here in internal memory
+                                                               {0x0F00a080, 0x1C000000},
+                                                               {0x0F00A000, 0x00000016},
+                                                               {0x0f007000, 0x00010001},
+                                                               {0x0f007004, 0x01000000},
+                                                               {0x0f007008, 0x01000001},
+                                                               {0x0f00700c, 0x00000000},
+                                                               {0x0f007010, 0x01000000},
+                                                               {0x0f007014, 0x01000100},
+                                                               {0x0f007018, 0x01000000},
+                                                               {0x0f00701c, 0x01020000},
+                                                               {0x0f007020, 0x04020107},
+                                                               {0x0f007024, 0x00000007},
+                                                               {0x0f007028, 0x02020200},
+                                                               {0x0f00702c, 0x0204040a},
+                                                               {0x0f007030, 0x04000000},
+                                                               {0x0f007034, 0x00000002},
+                                                               {0x0f007038, 0x1d060200},
+                                                               {0x0f00703c, 0x1c22221d},
+                                                               {0x0f007040, 0x8A116600},
+                                                               {0x0f007044, 0x222d0800},
+                                                               {0x0f007048, 0x02690204},
+                                                               {0x0f00704c, 0x00000000},
+                                                               {0x0f007050, 0x0100001c},
+                                                               {0x0f007054, 0x00000000},
+                                                               {0x0f007058, 0x00000000},
+                                                               {0x0f00705c, 0x00000000},
+                                                               {0x0f007060, 0x000A15D6},
+                                                               {0x0f007064, 0x0000000A},
+                                                               {0x0f007068, 0x00000000},
+                                                               {0x0f00706c, 0x00000001},
+                                                               {0x0f007070, 0x00004000},
+                                                               {0x0f007074, 0x00000000},
+                                                               {0x0f007078, 0x00000000},
+                                                               {0x0f00707c, 0x00000000},
+                                                               {0x0f007080, 0x00000000},
+                                                               {0x0f007084, 0x00000000},
+                                                               {0x0f007088, 0x01000001},
+                                                               {0x0f00708c, 0x00000101},
+                                                               {0x0f007090, 0x00000000},
+                                                               {0x0f007094, 0x00010000},
+                                                               {0x0f007098, 0x00000000},
+                                                               {0x0F0070C8, 0x00000104},
+                                                               {0x0F007018, 0x01010000}
 };
 
 
 int ddr_init(struct bcm_mini_adapter *Adapter)
 {
-       struct bcm_ddr_setting *psDDRSetting=NULL;
-       ULONG RegCount=0;
+       struct bcm_ddr_setting *psDDRSetting = NULL;
+       ULONG RegCount = 0;
        UINT value = 0;
        UINT  uiResetValue = 0;
        UINT uiClockSetting = 0;
@@ -787,20 +786,20 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
            switch (Adapter->DDRSetting)
            {
                case DDR_80_MHZ:
-                               psDDRSetting=asT3LP_DDRSetting80MHz;
-                           RegCount=(sizeof(asT3LP_DDRSetting80MHz)/
+                               psDDRSetting = asT3LP_DDRSetting80MHz;
+                           RegCount = (sizeof(asT3LP_DDRSetting80MHz)/
                                sizeof(struct bcm_ddr_setting));
                            break;
                    case DDR_100_MHZ:
-                               psDDRSetting=asT3LP_DDRSetting100MHz;
-                           RegCount=(sizeof(asT3LP_DDRSetting100MHz)/
+                               psDDRSetting = asT3LP_DDRSetting100MHz;
+                           RegCount = (sizeof(asT3LP_DDRSetting100MHz)/
                                sizeof(struct bcm_ddr_setting));
                            break;
                    case DDR_133_MHZ:
-                               psDDRSetting=asT3LP_DDRSetting133MHz;
-                           RegCount=(sizeof(asT3LP_DDRSetting133MHz)/
+                               psDDRSetting = asT3LP_DDRSetting133MHz;
+                           RegCount = (sizeof(asT3LP_DDRSetting133MHz)/
                                        sizeof(struct bcm_ddr_setting));
-                               if(Adapter->bMipsConfig == MIPS_200_MHZ)
+                               if (Adapter->bMipsConfig == MIPS_200_MHZ)
                                {
                                        uiClockSetting = 0x03F13652;
                                }
@@ -818,47 +817,47 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
        case BCS220_2:
        case BCS220_2BC:
        case BCS250_BC:
-       case BCS220_3 :
+       case BCS220_3:
                /* Set bit 2 and bit 6 to 1 for BBIC 2mA drive
                 * (please check current value and additionally set these bits)
                 */
-               if(Adapter->chip_id !=  BCS220_2) &&
+               if ((Adapter->chip_id !=  BCS220_2) &&
                        (Adapter->chip_id !=  BCS220_2BC) &&
-                       (Adapter->chip_id != BCS220_3) )
+                       (Adapter->chip_id != BCS220_3))
                {
-                               retval= rdmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
-                               if(retval < 0) {
+                               retval = rdmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
+                               if (retval < 0) {
                                        BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                        return retval;
                                }
                                uiResetValue |= 0x44;
                                retval = wrmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
-                               if(retval < 0) {
+                               if (retval < 0) {
                                        BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                        return retval;
                                }
                }
-               switch(Adapter->DDRSetting)
+               switch (Adapter->DDRSetting)
                {
 
 
 
                        case DDR_80_MHZ:
                                psDDRSetting = asT3LPB_DDRSetting80MHz;
-                       RegCount=(sizeof(asT3B_DDRSetting80MHz)/
+                       RegCount = (sizeof(asT3B_DDRSetting80MHz)/
                                  sizeof(struct bcm_ddr_setting));
                        break;
             case DDR_100_MHZ:
-                               psDDRSetting=asT3LPB_DDRSetting100MHz;
-                       RegCount=(sizeof(asT3B_DDRSetting100MHz)/
+                               psDDRSetting = asT3LPB_DDRSetting100MHz;
+                       RegCount = (sizeof(asT3B_DDRSetting100MHz)/
                                 sizeof(struct bcm_ddr_setting));
                        break;
             case DDR_133_MHZ:
                                psDDRSetting = asT3LPB_DDRSetting133MHz;
-                               RegCount=(sizeof(asT3B_DDRSetting133MHz)/
+                               RegCount = (sizeof(asT3B_DDRSetting133MHz)/
                                                 sizeof(struct bcm_ddr_setting));
 
-                               if(Adapter->bMipsConfig == MIPS_200_MHZ)
+                               if (Adapter->bMipsConfig == MIPS_200_MHZ)
                                {
                                        uiClockSetting = 0x03F13652;
                                }
@@ -872,7 +871,7 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
                                psDDRSetting = asT3LPB_DDRSetting160MHz;
                                RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(struct bcm_ddr_setting);
 
-                               if(Adapter->bMipsConfig == MIPS_200_MHZ)
+                               if (Adapter->bMipsConfig == MIPS_200_MHZ)
                                {
                                        uiClockSetting = 0x03F137D2;
                                }
@@ -915,30 +914,30 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
            {
                case DDR_80_MHZ:
                                psDDRSetting = asT3B_DDRSetting80MHz;
-                       RegCount=(sizeof(asT3B_DDRSetting80MHz)/
+                       RegCount = (sizeof(asT3B_DDRSetting80MHz)/
                                  sizeof(struct bcm_ddr_setting));
                    break;
             case DDR_100_MHZ:
-                               psDDRSetting=asT3B_DDRSetting100MHz;
-                       RegCount=(sizeof(asT3B_DDRSetting100MHz)/
+                               psDDRSetting = asT3B_DDRSetting100MHz;
+                       RegCount = (sizeof(asT3B_DDRSetting100MHz)/
                                 sizeof(struct bcm_ddr_setting));
                        break;
             case DDR_133_MHZ:
 
-                               if(Adapter->bDPLLConfig == PLL_266_MHZ)//266Mhz PLL selected.
+                               if (Adapter->bDPLLConfig == PLL_266_MHZ)//266Mhz PLL selected.
                                {
                                        memcpy(asT3B_DDRSetting133MHz, asDPLL_266MHZ,
                                                                         sizeof(asDPLL_266MHZ));
                                        psDDRSetting = asT3B_DDRSetting133MHz;
-                                       RegCount=(sizeof(asT3B_DDRSetting133MHz)/
+                                       RegCount = (sizeof(asT3B_DDRSetting133MHz)/
                                                                        sizeof(struct bcm_ddr_setting));
                                }
                                else
                                {
                                        psDDRSetting = asT3B_DDRSetting133MHz;
-                                       RegCount=(sizeof(asT3B_DDRSetting133MHz)/
+                                       RegCount = (sizeof(asT3B_DDRSetting133MHz)/
                                                                        sizeof(struct bcm_ddr_setting));
-                                       if(Adapter->bMipsConfig == MIPS_200_MHZ)
+                                       if (Adapter->bMipsConfig == MIPS_200_MHZ)
                                        {
                                                uiClockSetting = 0x07F13652;
                                        }
@@ -958,11 +957,11 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
                return -EINVAL;
        }
 
-       value=0;
+       value = 0;
        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register Count is =%lu\n", RegCount);
-       while(RegCount && !retval)
+       while (RegCount && !retval)
        {
-               if(uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG)
+               if (uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG)
                {
                        value = uiClockSetting;
                }
@@ -971,7 +970,7 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
                        value = psDDRSetting->ulRegValue;
                }
                retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, sizeof(value));
-               if(STATUS_SUCCESS != retval) {
+               if (STATUS_SUCCESS != retval) {
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
                        break;
                }
@@ -980,36 +979,36 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
                psDDRSetting++;
        }
 
-       if(Adapter->chip_id >= 0xbece3300  )
+       if (Adapter->chip_id >= 0xbece3300)
        {
 
                mdelay(3);
-               if( (Adapter->chip_id != BCS220_2)&&
-                       (Adapter->chip_id != BCS220_2BC)&&
+               if ((Adapter->chip_id != BCS220_2) &&
+                       (Adapter->chip_id != BCS220_2BC) &&
                        (Adapter->chip_id != BCS220_3))
                {
                        /* drive MDDR to half in case of UMA-B: */
                        uiResetValue = 0x01010001;
                        retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        uiResetValue = 0x00040020;
                        retval = wrmalt(Adapter, (UINT)0x0F007094, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        uiResetValue = 0x01020101;
                        retval = wrmalt(Adapter, (UINT)0x0F00701c, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        uiResetValue = 0x01010000;
                        retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
@@ -1022,73 +1021,73 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
                 * and since we dont have internal PMU lets do it under UMA-B chip id.
             * we will change this when we will have internal PMU.
             */
-               if(Adapter->PmuMode == HYBRID_MODE_7C)
+               if (Adapter->PmuMode == HYBRID_MODE_7C)
                {
                        retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        uiResetValue = 0x1322a8;
                        retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        uiResetValue = 0x132296;
                        retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                }
-               else if(Adapter->PmuMode == HYBRID_MODE_6 )
+               else if (Adapter->PmuMode == HYBRID_MODE_6)
                {
 
                        retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        uiResetValue = 0x6003229a;
                        retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
                        uiResetValue = 0x1322a8;
                        retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue));
-                       if(retval < 0) {
+                       if (retval < 0) {
                                BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
                                return retval;
                        }
@@ -1101,8 +1100,8 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
 
 int download_ddr_settings(struct bcm_mini_adapter *Adapter)
 {
-       struct bcm_ddr_setting *psDDRSetting=NULL;
-       ULONG RegCount=0;
+       struct bcm_ddr_setting *psDDRSetting = NULL;
+       ULONG RegCount = 0;
        unsigned long ul_ddr_setting_load_addr = DDR_DUMP_INTERNAL_DEVICE_MEMORY;
        UINT  value = 0;
        int retval = STATUS_SUCCESS;
@@ -1116,20 +1115,20 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
                case DDR_80_MHZ:
                                psDDRSetting = asT3LP_DDRSetting80MHz;
                 RegCount = ARRAY_SIZE(asT3LP_DDRSetting80MHz);
-                               RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ;
+                               RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
                 psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
                        break;
                    case DDR_100_MHZ:
                                psDDRSetting = asT3LP_DDRSetting100MHz;
                            RegCount = ARRAY_SIZE(asT3LP_DDRSetting100MHz);
-                               RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ;
+                               RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
                 psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
                            break;
                     case DDR_133_MHZ:
                                bOverrideSelfRefresh = TRUE;
                                psDDRSetting = asT3LP_DDRSetting133MHz;
                            RegCount = ARRAY_SIZE(asT3LP_DDRSetting133MHz);
-                               RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
+                               RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
                        psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
                                break;
                        default:
@@ -1141,26 +1140,26 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
        case BCS220_2:
        case BCS220_2BC:
        case BCS250_BC:
-       case BCS220_3 :
+       case BCS220_3:
            switch (Adapter->DDRSetting)
            {
                case DDR_80_MHZ:
                                psDDRSetting = asT3LPB_DDRSetting80MHz;
-                RegCount=ARRAY_SIZE(asT3LPB_DDRSetting80MHz);
-                               RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ;
+                RegCount = ARRAY_SIZE(asT3LPB_DDRSetting80MHz);
+                               RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
                 psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
                        break;
                    case DDR_100_MHZ:
                                psDDRSetting = asT3LPB_DDRSetting100MHz;
                            RegCount = ARRAY_SIZE(asT3LPB_DDRSetting100MHz);
-                               RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ;
+                               RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
                 psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
                            break;
                     case DDR_133_MHZ:
                                bOverrideSelfRefresh = TRUE;
                                psDDRSetting = asT3LPB_DDRSetting133MHz;
                            RegCount = ARRAY_SIZE(asT3LPB_DDRSetting133MHz);
-                               RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
+                               RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
                        psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
                                break;
 
@@ -1182,20 +1181,20 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
                case DDR_80_MHZ:
                                psDDRSetting = asT3_DDRSetting80MHz;
                 RegCount = ARRAY_SIZE(asT3_DDRSetting80MHz);
-                               RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ;
+                               RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
                 psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
                        break;
                    case DDR_100_MHZ:
                                psDDRSetting = asT3_DDRSetting100MHz;
                            RegCount = ARRAY_SIZE(asT3_DDRSetting100MHz);
-                               RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ;
+                               RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
                 psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
                            break;
                     case DDR_133_MHZ:
                                psDDRSetting = asT3_DDRSetting133MHz;
                            RegCount = ARRAY_SIZE(asT3_DDRSetting133MHz);
-                               RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
-                       psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
+                               RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
+                       psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
                                break;
                        default:
                            return -EINVAL;
@@ -1208,20 +1207,20 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
                        case DDR_80_MHZ:
                                        psDDRSetting = asT3B_DDRSetting80MHz;
                     RegCount = ARRAY_SIZE(asT3B_DDRSetting80MHz);
-                    RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ;
+                    RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
                     psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
                                break;
                        case DDR_100_MHZ:
                                        psDDRSetting = asT3B_DDRSetting100MHz;
                                RegCount = ARRAY_SIZE(asT3B_DDRSetting100MHz);
-                    RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ;
+                    RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
                     psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
                                break;
                        case DDR_133_MHZ:
                                        bOverrideSelfRefresh = TRUE;
                                        psDDRSetting = asT3B_DDRSetting133MHz;
                                RegCount = ARRAY_SIZE(asT3B_DDRSetting133MHz);
-                       RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
+                       RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
                            psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
                                        break;
                      }
@@ -1231,9 +1230,9 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
                return -EINVAL;
        }
        //total number of Register that has to be dumped
-       value =RegCount  ;
+       value = RegCount;
        retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
-       if(retval)
+       if (retval)
        {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
 
@@ -1241,29 +1240,29 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
        }
        ul_ddr_setting_load_addr += sizeof(ULONG);
        /*signature */
-       value =(0x1d1e0dd0);
+       value = (0x1d1e0dd0);
        retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
-       if(retval)
+       if (retval)
        {
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
                return retval;
        }
 
        ul_ddr_setting_load_addr += sizeof(ULONG);
-       RegCount*=(sizeof(struct bcm_ddr_setting)/sizeof(ULONG));
+       RegCount *= (sizeof(struct bcm_ddr_setting)/sizeof(ULONG));
 
-       while(RegCount && !retval)
+       while (RegCount && !retval)
        {
-               value = psDDRSetting->ulRegAddress ;
-               retval = wrmalt( Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
+               value = psDDRSetting->ulRegAddress;
+               retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
                ul_ddr_setting_load_addr += sizeof(ULONG);
-               if(!retval)
+               if (!retval)
                {
-                       if(bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018))
+                       if (bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018))
                        {
                                value = (psDDRSetting->ulRegValue |(1<<8));
-                               if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr,
-                                               &value, sizeof(value))){
+                               if (STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr,
+                                               &value, sizeof(value))) {
                                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
                                        break;
                                }
@@ -1272,8 +1271,8 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
                        {
                                value =  psDDRSetting->ulRegValue;
 
-                               if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr ,
-                                                       &value, sizeof(value))){
+                               if (STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr ,
+                                                       &value, sizeof(value))) {
                                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
                                        break;
                                }
@@ -1285,5 +1284,3 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
        }
        return retval;
 }
-
-
index 7a9bf3b578104bf57939ce032c96dc17c88840be..9a5ebd6cc51235b699756c1c08c7609235b7d1e4 100644 (file)
@@ -1284,9 +1284,8 @@ done:
        kfree_skb(skb);
 }
 
-static int btmtk_usb_send_frame(struct sk_buff *skb)
+static int btmtk_usb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_dev *hdev = (struct hci_dev *)skb->dev;
        struct btmtk_usb_data *data = hci_get_drvdata(hdev);
        struct usb_ctrlrequest *dr;
        struct urb *urb;
index 62efd74b8c04746da6cb1ccfa425139fa67e89bf..043a93230e82d6c5e5cadaf56eaa5f856b089916 100644 (file)
@@ -630,7 +630,7 @@ int ClearArea(DEVICE_EXTENSION *pdx, int nArea)
                        }
                        spin_unlock_irq(&pdx->stagedLock);
 
-                       if (pPages) {   /*  if we decided to release the memory */
+                       if (pPages) {   /*  if we decided to release the memory */
                                /*  Now we must undo the pinning down of the pages. We will assume the worst and mark */
                                /*  all the pages as dirty. Don't be tempted to move this up above as you must not be */
                                /*  holding a spin lock to do this stuff as it is not atomic. */
index e6dfc98f8c8ed8513740cea86ff7eda140ffca92..fae2d9090006848d4f89913ee62a2ea58e19f3ca 100644 (file)
@@ -1,3 +1,5 @@
+ccflags-$(CONFIG_COMEDI_DEBUG)         := -DDEBUG
+
 comedi-y                               := comedi_fops.o range.o drivers.o \
                                           comedi_buf.o
 comedi-$(CONFIG_COMEDI_PCI_DRIVERS)    += comedi_pci.o
index 4e26bd7fc84f3560135296aea5cadd736df7797d..924fce977985b27434c577d176cfd21c7bb49f89 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include "comedidev.h"
 #include "comedi_internal.h"
 #define COMEDI_PAGE_PROTECTION         PAGE_KERNEL
 #endif
 
-static void __comedi_buf_free(struct comedi_device *dev,
-                             struct comedi_subdevice *s,
-                             unsigned n_pages)
+static void comedi_buf_map_kref_release(struct kref *kref)
 {
-       struct comedi_async *async = s->async;
+       struct comedi_buf_map *bm =
+               container_of(kref, struct comedi_buf_map, refcount);
        struct comedi_buf_page *buf;
-       unsigned i;
-
-       if (async->prealloc_buf) {
-               vunmap(async->prealloc_buf);
-               async->prealloc_buf = NULL;
-               async->prealloc_bufsz = 0;
-       }
+       unsigned int i;
 
-       if (!async->buf_page_list)
-               return;
-
-       for (i = 0; i < n_pages; ++i) {
-               buf = &async->buf_page_list[i];
-               if (buf->virt_addr) {
+       if (bm->page_list) {
+               for (i = 0; i < bm->n_pages; i++) {
+                       buf = &bm->page_list[i];
                        clear_bit(PG_reserved,
                                  &(virt_to_page(buf->virt_addr)->flags));
-                       if (s->async_dma_dir != DMA_NONE) {
+                       if (bm->dma_dir != DMA_NONE) {
 #ifdef CONFIG_HAS_DMA
-                               dma_free_coherent(dev->hw_dev,
+                               dma_free_coherent(bm->dma_hw_dev,
                                                  PAGE_SIZE,
                                                  buf->virt_addr,
                                                  buf->dma_addr);
@@ -59,10 +50,26 @@ static void __comedi_buf_free(struct comedi_device *dev,
                                free_page((unsigned long)buf->virt_addr);
                        }
                }
+               vfree(bm->page_list);
        }
-       vfree(async->buf_page_list);
-       async->buf_page_list = NULL;
-       async->n_buf_pages = 0;
+       if (bm->dma_dir != DMA_NONE)
+               put_device(bm->dma_hw_dev);
+       kfree(bm);
+}
+
+static void __comedi_buf_free(struct comedi_device *dev,
+                             struct comedi_subdevice *s)
+{
+       struct comedi_async *async = s->async;
+
+       if (async->prealloc_buf) {
+               vunmap(async->prealloc_buf);
+               async->prealloc_buf = NULL;
+               async->prealloc_bufsz = 0;
+       }
+
+       comedi_buf_map_put(async->buf_map);
+       async->buf_map = NULL;
 }
 
 static void __comedi_buf_alloc(struct comedi_device *dev,
@@ -71,6 +78,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
 {
        struct comedi_async *async = s->async;
        struct page **pages = NULL;
+       struct comedi_buf_map *bm;
        struct comedi_buf_page *buf;
        unsigned i;
 
@@ -80,18 +88,29 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
                return;
        }
 
-       async->buf_page_list = vzalloc(sizeof(*buf) * n_pages);
-       if (async->buf_page_list)
+       bm = kzalloc(sizeof(*async->buf_map), GFP_KERNEL);
+       if (!bm)
+               return;
+
+       async->buf_map = bm;
+       kref_init(&bm->refcount);
+       bm->dma_dir = s->async_dma_dir;
+       if (bm->dma_dir != DMA_NONE)
+               /* Need ref to hardware device to free buffer later. */
+               bm->dma_hw_dev = get_device(dev->hw_dev);
+
+       bm->page_list = vzalloc(sizeof(*buf) * n_pages);
+       if (bm->page_list)
                pages = vmalloc(sizeof(struct page *) * n_pages);
 
        if (!pages)
                return;
 
        for (i = 0; i < n_pages; i++) {
-               buf = &async->buf_page_list[i];
-               if (s->async_dma_dir != DMA_NONE)
+               buf = &bm->page_list[i];
+               if (bm->dma_dir != DMA_NONE)
 #ifdef CONFIG_HAS_DMA
-                       buf->virt_addr = dma_alloc_coherent(dev->hw_dev,
+                       buf->virt_addr = dma_alloc_coherent(bm->dma_hw_dev,
                                                            PAGE_SIZE,
                                                            &buf->dma_addr,
                                                            GFP_KERNEL |
@@ -108,6 +127,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
 
                pages[i] = virt_to_page(buf->virt_addr);
        }
+       bm->n_pages = i;
 
        /* vmap the prealloc_buf if all the pages were allocated */
        if (i == n_pages)
@@ -117,6 +137,26 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
        vfree(pages);
 }
 
+void comedi_buf_map_get(struct comedi_buf_map *bm)
+{
+       if (bm)
+               kref_get(&bm->refcount);
+}
+
+int comedi_buf_map_put(struct comedi_buf_map *bm)
+{
+       if (bm)
+               return kref_put(&bm->refcount, comedi_buf_map_kref_release);
+       return 1;
+}
+
+bool comedi_buf_is_mmapped(struct comedi_async *async)
+{
+       struct comedi_buf_map *bm = async->buf_map;
+
+       return bm && (atomic_read(&bm->refcount.refcount) > 1);
+}
+
 int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
                     unsigned long new_size)
 {
@@ -130,7 +170,7 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
                return 0;
 
        /* deallocate old buffer */
-       __comedi_buf_free(dev, s, async->n_buf_pages);
+       __comedi_buf_free(dev, s);
 
        /* allocate new buffer */
        if (new_size) {
@@ -140,10 +180,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
 
                if (!async->prealloc_buf) {
                        /* allocation failed */
-                       __comedi_buf_free(dev, s, n_pages);
+                       __comedi_buf_free(dev, s);
                        return -ENOMEM;
                }
-               async->n_buf_pages = n_pages;
        }
        async->prealloc_bufsz = new_size;
 
index f3d59e2a1152b5626caa9c7e7e0ebd9f50f587b6..cdaef09c8993a7234ac6b66154e65af76d402e3f 100644 (file)
@@ -16,8 +16,6 @@
     GNU General Public License for more details.
 */
 
-#undef DEBUG
-
 #include "comedi_compat32.h"
 
 #include <linux/module.h>
 #define COMEDI_NUM_SUBDEVICE_MINORS    \
        (COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS)
 
-#ifdef CONFIG_COMEDI_DEBUG
-int comedi_debug;
-EXPORT_SYMBOL_GPL(comedi_debug);
-module_param(comedi_debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(comedi_debug,
-                "enable comedi core and driver debugging if non-zero (default 0)"
-               );
-#endif
-
 static int comedi_num_legacy_minors;
 module_param(comedi_num_legacy_minors, int, S_IRUGO);
 MODULE_PARM_DESC(comedi_num_legacy_minors,
@@ -89,11 +78,37 @@ static struct cdev comedi_cdev;
 
 static void comedi_device_init(struct comedi_device *dev)
 {
+       kref_init(&dev->refcount);
        spin_lock_init(&dev->spinlock);
        mutex_init(&dev->mutex);
+       init_rwsem(&dev->attach_lock);
        dev->minor = -1;
 }
 
+static void comedi_dev_kref_release(struct kref *kref)
+{
+       struct comedi_device *dev =
+               container_of(kref, struct comedi_device, refcount);
+
+       mutex_destroy(&dev->mutex);
+       kfree(dev);
+}
+
+int comedi_dev_put(struct comedi_device *dev)
+{
+       if (dev)
+               return kref_put(&dev->refcount, comedi_dev_kref_release);
+       return 1;
+}
+EXPORT_SYMBOL_GPL(comedi_dev_put);
+
+static struct comedi_device *comedi_dev_get(struct comedi_device *dev)
+{
+       if (dev)
+               kref_get(&dev->refcount);
+       return dev;
+}
+
 static void comedi_device_cleanup(struct comedi_device *dev)
 {
        struct module *driver_module = NULL;
@@ -111,7 +126,6 @@ static void comedi_device_cleanup(struct comedi_device *dev)
                dev->use_count--;
        }
        mutex_unlock(&dev->mutex);
-       mutex_destroy(&dev->mutex);
 }
 
 static bool comedi_clear_board_dev(struct comedi_device *dev)
@@ -147,12 +161,12 @@ static void comedi_free_board_dev(struct comedi_device *dev)
                                       MKDEV(COMEDI_MAJOR, dev->minor));
                }
                comedi_device_cleanup(dev);
-               kfree(dev);
+               comedi_dev_put(dev);
        }
 }
 
 static struct comedi_subdevice
-*comedi_subdevice_from_minor(unsigned minor)
+*comedi_subdevice_from_minor(const struct comedi_device *dev, unsigned minor)
 {
        struct comedi_subdevice *s;
        unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;
@@ -160,37 +174,45 @@ static struct comedi_subdevice
        BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS);
        mutex_lock(&comedi_subdevice_minor_table_lock);
        s = comedi_subdevice_minor_table[i];
+       if (s && s->device != dev)
+               s = NULL;
        mutex_unlock(&comedi_subdevice_minor_table_lock);
        return s;
 }
 
-static struct comedi_device *comedi_dev_from_board_minor(unsigned minor)
+static struct comedi_device *comedi_dev_get_from_board_minor(unsigned minor)
 {
        struct comedi_device *dev;
 
        BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
        mutex_lock(&comedi_board_minor_table_lock);
-       dev = comedi_board_minor_table[minor];
+       dev = comedi_dev_get(comedi_board_minor_table[minor]);
        mutex_unlock(&comedi_board_minor_table_lock);
        return dev;
 }
 
-static struct comedi_device *comedi_dev_from_subdevice_minor(unsigned minor)
+static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor)
 {
+       struct comedi_device *dev;
        struct comedi_subdevice *s;
+       unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;
 
-       s = comedi_subdevice_from_minor(minor);
-       return s ? s->device : NULL;
+       BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS);
+       mutex_lock(&comedi_subdevice_minor_table_lock);
+       s = comedi_subdevice_minor_table[i];
+       dev = comedi_dev_get(s ? s->device : NULL);
+       mutex_unlock(&comedi_subdevice_minor_table_lock);
+       return dev;
 }
 
-struct comedi_device *comedi_dev_from_minor(unsigned minor)
+struct comedi_device *comedi_dev_get_from_minor(unsigned minor)
 {
        if (minor < COMEDI_NUM_BOARD_MINORS)
-               return comedi_dev_from_board_minor(minor);
+               return comedi_dev_get_from_board_minor(minor);
        else
-               return comedi_dev_from_subdevice_minor(minor);
+               return comedi_dev_get_from_subdevice_minor(minor);
 }
-EXPORT_SYMBOL_GPL(comedi_dev_from_minor);
+EXPORT_SYMBOL_GPL(comedi_dev_get_from_minor);
 
 static struct comedi_subdevice *
 comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
@@ -198,10 +220,8 @@ comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
        struct comedi_subdevice *s;
 
        if (minor >= COMEDI_NUM_BOARD_MINORS) {
-               s = comedi_subdevice_from_minor(minor);
-               if (!s || s->device != dev)
-                       return NULL;
-               if (s->subdev_flags & SDF_CMD_READ)
+               s = comedi_subdevice_from_minor(dev, minor);
+               if (s == NULL || (s->subdev_flags & SDF_CMD_READ))
                        return s;
        }
        return dev->read_subdev;
@@ -213,10 +233,8 @@ comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor)
        struct comedi_subdevice *s;
 
        if (minor >= COMEDI_NUM_BOARD_MINORS) {
-               s = comedi_subdevice_from_minor(minor);
-               if (!s || s->device != dev)
-                       return NULL;
-               if (s->subdev_flags & SDF_CMD_WRITE)
+               s = comedi_subdevice_from_minor(dev, minor);
+               if (s == NULL || (s->subdev_flags & SDF_CMD_WRITE))
                        return s;
        }
        return dev->write_subdev;
@@ -232,11 +250,13 @@ static int resize_async_buffer(struct comedi_device *dev,
                return -EPERM;
 
        if (s->busy) {
-               DPRINTK("subdevice is busy, cannot resize buffer\n");
+               dev_dbg(dev->class_dev,
+                       "subdevice is busy, cannot resize buffer\n");
                return -EBUSY;
        }
-       if (async->mmap_count) {
-               DPRINTK("subdevice is mmapped, cannot resize buffer\n");
+       if (comedi_buf_is_mmapped(async)) {
+               dev_dbg(dev->class_dev,
+                       "subdevice is mmapped, cannot resize buffer\n");
                return -EBUSY;
        }
 
@@ -254,8 +274,8 @@ static int resize_async_buffer(struct comedi_device *dev,
                        return retval;
        }
 
-       DPRINTK("comedi%i subd %d buffer resized to %i bytes\n",
-               dev->minor, s->index, async->prealloc_bufsz);
+       dev_dbg(dev->class_dev, "subd %d buffer resized to %i bytes\n",
+               s->index, async->prealloc_bufsz);
        return 0;
 }
 
@@ -269,7 +289,7 @@ static ssize_t max_read_buffer_kb_show(struct device *csdev,
        struct comedi_subdevice *s;
        unsigned int size = 0;
 
-       dev = comedi_dev_from_minor(minor);
+       dev = comedi_dev_get_from_minor(minor);
        if (!dev)
                return -ENODEV;
 
@@ -279,6 +299,7 @@ static ssize_t max_read_buffer_kb_show(struct device *csdev,
                size = s->async->max_bufsize / 1024;
        mutex_unlock(&dev->mutex);
 
+       comedi_dev_put(dev);
        return snprintf(buf, PAGE_SIZE, "%i\n", size);
 }
 
@@ -299,7 +320,7 @@ static ssize_t max_read_buffer_kb_store(struct device *csdev,
                return -EINVAL;
        size *= 1024;
 
-       dev = comedi_dev_from_minor(minor);
+       dev = comedi_dev_get_from_minor(minor);
        if (!dev)
                return -ENODEV;
 
@@ -311,6 +332,7 @@ static ssize_t max_read_buffer_kb_store(struct device *csdev,
                err = -EINVAL;
        mutex_unlock(&dev->mutex);
 
+       comedi_dev_put(dev);
        return err ? err : count;
 }
 static DEVICE_ATTR_RW(max_read_buffer_kb);
@@ -323,7 +345,7 @@ static ssize_t read_buffer_kb_show(struct device *csdev,
        struct comedi_subdevice *s;
        unsigned int size = 0;
 
-       dev = comedi_dev_from_minor(minor);
+       dev = comedi_dev_get_from_minor(minor);
        if (!dev)
                return -ENODEV;
 
@@ -333,6 +355,7 @@ static ssize_t read_buffer_kb_show(struct device *csdev,
                size = s->async->prealloc_bufsz / 1024;
        mutex_unlock(&dev->mutex);
 
+       comedi_dev_put(dev);
        return snprintf(buf, PAGE_SIZE, "%i\n", size);
 }
 
@@ -353,7 +376,7 @@ static ssize_t read_buffer_kb_store(struct device *csdev,
                return -EINVAL;
        size *= 1024;
 
-       dev = comedi_dev_from_minor(minor);
+       dev = comedi_dev_get_from_minor(minor);
        if (!dev)
                return -ENODEV;
 
@@ -365,6 +388,7 @@ static ssize_t read_buffer_kb_store(struct device *csdev,
                err = -EINVAL;
        mutex_unlock(&dev->mutex);
 
+       comedi_dev_put(dev);
        return err ? err : count;
 }
 static DEVICE_ATTR_RW(read_buffer_kb);
@@ -378,7 +402,7 @@ static ssize_t max_write_buffer_kb_show(struct device *csdev,
        struct comedi_subdevice *s;
        unsigned int size = 0;
 
-       dev = comedi_dev_from_minor(minor);
+       dev = comedi_dev_get_from_minor(minor);
        if (!dev)
                return -ENODEV;
 
@@ -388,6 +412,7 @@ static ssize_t max_write_buffer_kb_show(struct device *csdev,
                size = s->async->max_bufsize / 1024;
        mutex_unlock(&dev->mutex);
 
+       comedi_dev_put(dev);
        return snprintf(buf, PAGE_SIZE, "%i\n", size);
 }
 
@@ -408,7 +433,7 @@ static ssize_t max_write_buffer_kb_store(struct device *csdev,
                return -EINVAL;
        size *= 1024;
 
-       dev = comedi_dev_from_minor(minor);
+       dev = comedi_dev_get_from_minor(minor);
        if (!dev)
                return -ENODEV;
 
@@ -420,6 +445,7 @@ static ssize_t max_write_buffer_kb_store(struct device *csdev,
                err = -EINVAL;
        mutex_unlock(&dev->mutex);
 
+       comedi_dev_put(dev);
        return err ? err : count;
 }
 static DEVICE_ATTR_RW(max_write_buffer_kb);
@@ -432,7 +458,7 @@ static ssize_t write_buffer_kb_show(struct device *csdev,
        struct comedi_subdevice *s;
        unsigned int size = 0;
 
-       dev = comedi_dev_from_minor(minor);
+       dev = comedi_dev_get_from_minor(minor);
        if (!dev)
                return -ENODEV;
 
@@ -442,6 +468,7 @@ static ssize_t write_buffer_kb_show(struct device *csdev,
                size = s->async->prealloc_bufsz / 1024;
        mutex_unlock(&dev->mutex);
 
+       comedi_dev_put(dev);
        return snprintf(buf, PAGE_SIZE, "%i\n", size);
 }
 
@@ -462,7 +489,7 @@ static ssize_t write_buffer_kb_store(struct device *csdev,
                return -EINVAL;
        size *= 1024;
 
-       dev = comedi_dev_from_minor(minor);
+       dev = comedi_dev_get_from_minor(minor);
        if (!dev)
                return -ENODEV;
 
@@ -474,6 +501,7 @@ static ssize_t write_buffer_kb_store(struct device *csdev,
                err = -EINVAL;
        mutex_unlock(&dev->mutex);
 
+       comedi_dev_put(dev);
        return err ? err : count;
 }
 static DEVICE_ATTR_RW(write_buffer_kb);
@@ -562,12 +590,13 @@ static void do_become_nonbusy(struct comedi_device *dev,
                async->inttrig = NULL;
                kfree(async->cmd.chanlist);
                async->cmd.chanlist = NULL;
+               s->busy = NULL;
+               wake_up_interruptible_all(&s->async->wait_head);
        } else {
                dev_err(dev->class_dev,
                        "BUG: (?) do_become_nonbusy called with async=NULL\n");
+               s->busy = NULL;
        }
-
-       s->busy = NULL;
 }
 
 static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -582,6 +611,21 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
        return ret;
 }
 
+void comedi_device_cancel_all(struct comedi_device *dev)
+{
+       struct comedi_subdevice *s;
+       int i;
+
+       if (!dev->attached)
+               return;
+
+       for (i = 0; i < dev->n_subdevices; i++) {
+               s = &dev->subdevices[i];
+               if (s->async)
+                       do_cancel(dev, s);
+       }
+}
+
 static int is_device_busy(struct comedi_device *dev)
 {
        struct comedi_subdevice *s;
@@ -594,7 +638,7 @@ static int is_device_busy(struct comedi_device *dev)
                s = &dev->subdevices[i];
                if (s->busy)
                        return 1;
-               if (s->async && s->async->mmap_count)
+               if (s->async && comedi_buf_is_mmapped(s->async))
                        return 1;
        }
 
@@ -684,7 +728,8 @@ static int do_bufconfig_ioctl(struct comedi_device *dev,
        async = s->async;
 
        if (!async) {
-               DPRINTK("subdevice does not have async capability\n");
+               dev_dbg(dev->class_dev,
+                       "subdevice does not have async capability\n");
                bc.size = 0;
                bc.maximum_size = 0;
                goto copyback;
@@ -931,7 +976,8 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
        async = s->async;
 
        if (!async) {
-               DPRINTK("subdevice does not have async capability\n");
+               dev_dbg(dev->class_dev,
+                       "subdevice does not have async capability\n");
                bi.buf_write_ptr = 0;
                bi.buf_read_ptr = 0;
                bi.buf_write_count = 0;
@@ -1083,19 +1129,20 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
                                break;
                        }
                        if (insn->subdev >= dev->n_subdevices) {
-                               DPRINTK("%d not usable subdevice\n",
+                               dev_dbg(dev->class_dev,
+                                       "%d not usable subdevice\n",
                                        insn->subdev);
                                ret = -EINVAL;
                                break;
                        }
                        s = &dev->subdevices[insn->subdev];
                        if (!s->async) {
-                               DPRINTK("no async\n");
+                               dev_dbg(dev->class_dev, "no async\n");
                                ret = -EINVAL;
                                break;
                        }
                        if (!s->async->inttrig) {
-                               DPRINTK("no inttrig\n");
+                               dev_dbg(dev->class_dev, "no inttrig\n");
                                ret = -EAGAIN;
                                break;
                        }
@@ -1104,7 +1151,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
                                ret = 1;
                        break;
                default:
-                       DPRINTK("invalid insn\n");
+                       dev_dbg(dev->class_dev, "invalid insn\n");
                        ret = -EINVAL;
                        break;
                }
@@ -1113,21 +1160,23 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
                unsigned int maxdata;
 
                if (insn->subdev >= dev->n_subdevices) {
-                       DPRINTK("subdevice %d out of range\n", insn->subdev);
+                       dev_dbg(dev->class_dev, "subdevice %d out of range\n",
+                               insn->subdev);
                        ret = -EINVAL;
                        goto out;
                }
                s = &dev->subdevices[insn->subdev];
 
                if (s->type == COMEDI_SUBD_UNUSED) {
-                       DPRINTK("%d not usable subdevice\n", insn->subdev);
+                       dev_dbg(dev->class_dev, "%d not usable subdevice\n",
+                               insn->subdev);
                        ret = -EIO;
                        goto out;
                }
 
                /* are we locked? (ioctl lock) */
                if (s->lock && s->lock != file) {
-                       DPRINTK("device locked\n");
+                       dev_dbg(dev->class_dev, "device locked\n");
                        ret = -EACCES;
                        goto out;
                }
@@ -1135,7 +1184,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
                ret = comedi_check_chanlist(s, 1, &insn->chanspec);
                if (ret < 0) {
                        ret = -EINVAL;
-                       DPRINTK("bad chanspec\n");
+                       dev_dbg(dev->class_dev, "bad chanspec\n");
                        goto out;
                }
 
@@ -1156,7 +1205,8 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
                        for (i = 0; i < insn->n; ++i) {
                                if (data[i] > maxdata) {
                                        ret = -EINVAL;
-                                       DPRINTK("bad data value(s)\n");
+                                       dev_dbg(dev->class_dev,
+                                               "bad data value(s)\n");
                                        break;
                                }
                        }
@@ -1238,35 +1288,35 @@ static int do_insnlist_ioctl(struct comedi_device *dev,
 
        data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
        if (!data) {
-               DPRINTK("kmalloc failed\n");
                ret = -ENOMEM;
                goto error;
        }
 
        insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL);
        if (!insns) {
-               DPRINTK("kmalloc failed\n");
                ret = -ENOMEM;
                goto error;
        }
 
        if (copy_from_user(insns, insnlist.insns,
                           sizeof(*insns) * insnlist.n_insns)) {
-               DPRINTK("copy_from_user failed\n");
+               dev_dbg(dev->class_dev, "copy_from_user failed\n");
                ret = -EFAULT;
                goto error;
        }
 
        for (i = 0; i < insnlist.n_insns; i++) {
                if (insns[i].n > MAX_SAMPLES) {
-                       DPRINTK("number of samples too large\n");
+                       dev_dbg(dev->class_dev,
+                               "number of samples too large\n");
                        ret = -EINVAL;
                        goto error;
                }
                if (insns[i].insn & INSN_MASK_WRITE) {
                        if (copy_from_user(data, insns[i].data,
                                           insns[i].n * sizeof(unsigned int))) {
-                               DPRINTK("copy_from_user failed\n");
+                               dev_dbg(dev->class_dev,
+                                       "copy_from_user failed\n");
                                ret = -EFAULT;
                                goto error;
                        }
@@ -1277,7 +1327,8 @@ static int do_insnlist_ioctl(struct comedi_device *dev,
                if (insns[i].insn & INSN_MASK_READ) {
                        if (copy_to_user(insns[i].data, data,
                                         insns[i].n * sizeof(unsigned int))) {
-                               DPRINTK("copy_to_user failed\n");
+                               dev_dbg(dev->class_dev,
+                                       "copy_to_user failed\n");
                                ret = -EFAULT;
                                goto error;
                        }
@@ -1367,14 +1418,14 @@ static int do_cmd_ioctl(struct comedi_device *dev,
        unsigned int __user *user_chanlist;
 
        if (copy_from_user(&cmd, arg, sizeof(cmd))) {
-               DPRINTK("bad cmd address\n");
+               dev_dbg(dev->class_dev, "bad cmd address\n");
                return -EFAULT;
        }
        /* save user's chanlist pointer so it can be restored later */
        user_chanlist = (unsigned int __user *)cmd.chanlist;
 
        if (cmd.subdev >= dev->n_subdevices) {
-               DPRINTK("%d no such subdevice\n", cmd.subdev);
+               dev_dbg(dev->class_dev, "%d no such subdevice\n", cmd.subdev);
                return -ENODEV;
        }
 
@@ -1382,38 +1433,38 @@ static int do_cmd_ioctl(struct comedi_device *dev,
        async = s->async;
 
        if (s->type == COMEDI_SUBD_UNUSED) {
-               DPRINTK("%d not valid subdevice\n", cmd.subdev);
+               dev_dbg(dev->class_dev, "%d not valid subdevice\n", cmd.subdev);
                return -EIO;
        }
 
        if (!s->do_cmd || !s->do_cmdtest || !s->async) {
-               DPRINTK("subdevice %i does not support commands\n",
-                       cmd.subdev);
+               dev_dbg(dev->class_dev,
+                       "subdevice %i does not support commands\n", cmd.subdev);
                return -EIO;
        }
 
        /* are we locked? (ioctl lock) */
        if (s->lock && s->lock != file) {
-               DPRINTK("subdevice locked\n");
+               dev_dbg(dev->class_dev, "subdevice locked\n");
                return -EACCES;
        }
 
        /* are we busy? */
        if (s->busy) {
-               DPRINTK("subdevice busy\n");
+               dev_dbg(dev->class_dev, "subdevice busy\n");
                return -EBUSY;
        }
 
        /* make sure channel/gain list isn't too long */
        if (cmd.chanlist_len > s->len_chanlist) {
-               DPRINTK("channel/gain list too long %u > %d\n",
+               dev_dbg(dev->class_dev, "channel/gain list too long %u > %d\n",
                        cmd.chanlist_len, s->len_chanlist);
                return -EINVAL;
        }
 
        /* make sure channel/gain list isn't too short */
        if (cmd.chanlist_len < 1) {
-               DPRINTK("channel/gain list too short %u < 1\n",
+               dev_dbg(dev->class_dev, "channel/gain list too short %u < 1\n",
                        cmd.chanlist_len);
                return -EINVAL;
        }
@@ -1425,7 +1476,8 @@ static int do_cmd_ioctl(struct comedi_device *dev,
                                          async->cmd.chanlist_len * sizeof(int));
        if (IS_ERR(async->cmd.chanlist)) {
                ret = PTR_ERR(async->cmd.chanlist);
-               DPRINTK("memdup_user failed with code %d\n", ret);
+               dev_dbg(dev->class_dev, "memdup_user failed with code %d\n",
+                       ret);
                goto cleanup;
        }
 
@@ -1434,20 +1486,20 @@ static int do_cmd_ioctl(struct comedi_device *dev,
                                    async->cmd.chanlist_len,
                                    async->cmd.chanlist);
        if (ret < 0) {
-               DPRINTK("bad chanlist\n");
+               dev_dbg(dev->class_dev, "bad chanlist\n");
                goto cleanup;
        }
 
        ret = s->do_cmdtest(dev, s, &async->cmd);
 
        if (async->cmd.flags & TRIG_BOGUS || ret) {
-               DPRINTK("test returned %d\n", ret);
+               dev_dbg(dev->class_dev, "test returned %d\n", ret);
                cmd = async->cmd;
                /* restore chanlist pointer before copying back */
                cmd.chanlist = (unsigned int __force *)user_chanlist;
                cmd.data = NULL;
                if (copy_to_user(arg, &cmd, sizeof(cmd))) {
-                       DPRINTK("fault writing cmd\n");
+                       dev_dbg(dev->class_dev, "fault writing cmd\n");
                        ret = -EFAULT;
                        goto cleanup;
                }
@@ -1457,7 +1509,7 @@ static int do_cmd_ioctl(struct comedi_device *dev,
 
        if (!async->prealloc_bufsz) {
                ret = -ENOMEM;
-               DPRINTK("no buffer (?)\n");
+               dev_dbg(dev->class_dev, "no buffer (?)\n");
                goto cleanup;
        }
 
@@ -1469,8 +1521,7 @@ static int do_cmd_ioctl(struct comedi_device *dev,
        if (async->cmd.flags & TRIG_WAKE_EOS)
                async->cb_mask |= COMEDI_CB_EOS;
 
-       comedi_set_subdevice_runflags(s, SRF_USER | SRF_ERROR | SRF_RUNNING,
-                                     SRF_USER | SRF_RUNNING);
+       comedi_set_subdevice_runflags(s, SRF_ERROR | SRF_RUNNING, SRF_RUNNING);
 
        /* set s->busy _after_ setting SRF_RUNNING flag to avoid race with
         * comedi_read() or comedi_write() */
@@ -1510,32 +1561,32 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
        unsigned int __user *user_chanlist;
 
        if (copy_from_user(&cmd, arg, sizeof(cmd))) {
-               DPRINTK("bad cmd address\n");
+               dev_dbg(dev->class_dev, "bad cmd address\n");
                return -EFAULT;
        }
        /* save user's chanlist pointer so it can be restored later */
        user_chanlist = (unsigned int __user *)cmd.chanlist;
 
        if (cmd.subdev >= dev->n_subdevices) {
-               DPRINTK("%d no such subdevice\n", cmd.subdev);
+               dev_dbg(dev->class_dev, "%d no such subdevice\n", cmd.subdev);
                return -ENODEV;
        }
 
        s = &dev->subdevices[cmd.subdev];
        if (s->type == COMEDI_SUBD_UNUSED) {
-               DPRINTK("%d not valid subdevice\n", cmd.subdev);
+               dev_dbg(dev->class_dev, "%d not valid subdevice\n", cmd.subdev);
                return -EIO;
        }
 
        if (!s->do_cmd || !s->do_cmdtest) {
-               DPRINTK("subdevice %i does not support commands\n",
-                       cmd.subdev);
+               dev_dbg(dev->class_dev,
+                       "subdevice %i does not support commands\n", cmd.subdev);
                return -EIO;
        }
 
        /* make sure channel/gain list isn't too long */
        if (cmd.chanlist_len > s->len_chanlist) {
-               DPRINTK("channel/gain list too long %d > %d\n",
+               dev_dbg(dev->class_dev, "channel/gain list too long %d > %d\n",
                        cmd.chanlist_len, s->len_chanlist);
                ret = -EINVAL;
                goto cleanup;
@@ -1547,14 +1598,15 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
                                       cmd.chanlist_len * sizeof(int));
                if (IS_ERR(chanlist)) {
                        ret = PTR_ERR(chanlist);
-                       DPRINTK("memdup_user exited with code %d", ret);
+                       dev_dbg(dev->class_dev,
+                               "memdup_user exited with code %d", ret);
                        goto cleanup;
                }
 
                /* make sure each element in channel/gain list is valid */
                ret = comedi_check_chanlist(s, cmd.chanlist_len, chanlist);
                if (ret < 0) {
-                       DPRINTK("bad chanlist\n");
+                       dev_dbg(dev->class_dev, "bad chanlist\n");
                        goto cleanup;
                }
 
@@ -1567,7 +1619,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
        cmd.chanlist = (unsigned int __force *)user_chanlist;
 
        if (copy_to_user(arg, &cmd, sizeof(cmd))) {
-               DPRINTK("bad cmd address\n");
+               dev_dbg(dev->class_dev, "bad cmd address\n");
                ret = -EFAULT;
                goto cleanup;
        }
@@ -1700,8 +1752,6 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg,
                return -EBUSY;
 
        ret = do_cancel(dev, s);
-       if (comedi_get_subdevice_runflags(s) & SRF_USER)
-               wake_up_interruptible(&s->async->wait_head);
 
        return ret;
 }
@@ -1748,12 +1798,9 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
                                  unsigned long arg)
 {
        const unsigned minor = iminor(file_inode(file));
-       struct comedi_device *dev = comedi_dev_from_minor(minor);
+       struct comedi_device *dev = file->private_data;
        int rc;
 
-       if (!dev)
-               return -ENODEV;
-
        mutex_lock(&dev->mutex);
 
        /* Device config is special, because it must work on
@@ -1782,7 +1829,7 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
        }
 
        if (!dev->attached) {
-               DPRINTK("no driver configured on /dev/comedi%i\n", dev->minor);
+               dev_dbg(dev->class_dev, "no driver attached\n");
                rc = -ENODEV;
                goto done;
        }
@@ -1852,28 +1899,18 @@ done:
 
 static void comedi_vm_open(struct vm_area_struct *area)
 {
-       struct comedi_async *async;
-       struct comedi_device *dev;
+       struct comedi_buf_map *bm;
 
-       async = area->vm_private_data;
-       dev = async->subdevice->device;
-
-       mutex_lock(&dev->mutex);
-       async->mmap_count++;
-       mutex_unlock(&dev->mutex);
+       bm = area->vm_private_data;
+       comedi_buf_map_get(bm);
 }
 
 static void comedi_vm_close(struct vm_area_struct *area)
 {
-       struct comedi_async *async;
-       struct comedi_device *dev;
-
-       async = area->vm_private_data;
-       dev = async->subdevice->device;
+       struct comedi_buf_map *bm;
 
-       mutex_lock(&dev->mutex);
-       async->mmap_count--;
-       mutex_unlock(&dev->mutex);
+       bm = area->vm_private_data;
+       comedi_buf_map_put(bm);
 }
 
 static struct vm_operations_struct comedi_vm_ops = {
@@ -1884,22 +1921,20 @@ static struct vm_operations_struct comedi_vm_ops = {
 static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
 {
        const unsigned minor = iminor(file_inode(file));
-       struct comedi_device *dev = comedi_dev_from_minor(minor);
+       struct comedi_device *dev = file->private_data;
        struct comedi_subdevice *s;
        struct comedi_async *async;
+       struct comedi_buf_map *bm;
        unsigned long start = vma->vm_start;
        unsigned long size;
        int n_pages;
        int i;
        int retval;
 
-       if (!dev)
-               return -ENODEV;
-
        mutex_lock(&dev->mutex);
 
        if (!dev->attached) {
-               DPRINTK("no driver configured on comedi%i\n", dev->minor);
+               dev_dbg(dev->class_dev, "no driver attached\n");
                retval = -ENODEV;
                goto done;
        }
@@ -1920,7 +1955,7 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
        }
 
        if (vma->vm_pgoff != 0) {
-               DPRINTK("comedi: mmap() offset must be 0.\n");
+               dev_dbg(dev->class_dev, "mmap() offset must be 0.\n");
                retval = -EINVAL;
                goto done;
        }
@@ -1936,8 +1971,13 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
        }
 
        n_pages = size >> PAGE_SHIFT;
+       bm = async->buf_map;
+       if (!bm || n_pages > bm->n_pages) {
+               retval = -EINVAL;
+               goto done;
+       }
        for (i = 0; i < n_pages; ++i) {
-               struct comedi_buf_page *buf = &async->buf_page_list[i];
+               struct comedi_buf_page *buf = &bm->page_list[i];
 
                if (remap_pfn_range(vma, start,
                                    page_to_pfn(virt_to_page(buf->virt_addr)),
@@ -1949,9 +1989,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
        }
 
        vma->vm_ops = &comedi_vm_ops;
-       vma->vm_private_data = async;
+       vma->vm_private_data = bm;
 
-       async->mmap_count++;
+       vma->vm_ops->open(vma);
 
        retval = 0;
 done:
@@ -1963,16 +2003,13 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
 {
        unsigned int mask = 0;
        const unsigned minor = iminor(file_inode(file));
-       struct comedi_device *dev = comedi_dev_from_minor(minor);
+       struct comedi_device *dev = file->private_data;
        struct comedi_subdevice *s;
 
-       if (!dev)
-               return -ENODEV;
-
        mutex_lock(&dev->mutex);
 
        if (!dev->attached) {
-               DPRINTK("no driver configured on comedi%i\n", dev->minor);
+               dev_dbg(dev->class_dev, "no driver attached\n");
                goto done;
        }
 
@@ -2008,39 +2045,75 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
        int n, m, count = 0, retval = 0;
        DECLARE_WAITQUEUE(wait, current);
        const unsigned minor = iminor(file_inode(file));
-       struct comedi_device *dev = comedi_dev_from_minor(minor);
+       struct comedi_device *dev = file->private_data;
+       bool on_wait_queue = false;
+       bool attach_locked;
+       unsigned int old_detach_count;
 
-       if (!dev)
-               return -ENODEV;
+       /* Protect against device detachment during operation. */
+       down_read(&dev->attach_lock);
+       attach_locked = true;
+       old_detach_count = dev->detach_count;
 
        if (!dev->attached) {
-               DPRINTK("no driver configured on comedi%i\n", dev->minor);
-               return -ENODEV;
+               dev_dbg(dev->class_dev, "no driver attached\n");
+               retval = -ENODEV;
+               goto out;
        }
 
        s = comedi_write_subdevice(dev, minor);
-       if (!s || !s->async)
-               return -EIO;
+       if (!s || !s->async) {
+               retval = -EIO;
+               goto out;
+       }
 
        async = s->async;
 
        if (!s->busy || !nbytes)
-               return 0;
-       if (s->busy != file)
-               return -EACCES;
+               goto out;
+       if (s->busy != file) {
+               retval = -EACCES;
+               goto out;
+       }
 
        add_wait_queue(&async->wait_head, &wait);
+       on_wait_queue = true;
        while (nbytes > 0 && !retval) {
                set_current_state(TASK_INTERRUPTIBLE);
 
                if (!comedi_is_subdevice_running(s)) {
                        if (count == 0) {
-                               mutex_lock(&dev->mutex);
+                               struct comedi_subdevice *new_s;
+
                                if (comedi_is_subdevice_in_error(s))
                                        retval = -EPIPE;
                                else
                                        retval = 0;
-                               do_become_nonbusy(dev, s);
+                               /*
+                                * To avoid deadlock, cannot acquire dev->mutex
+                                * while dev->attach_lock is held.  Need to
+                                * remove task from the async wait queue before
+                                * releasing dev->attach_lock, as it might not
+                                * be valid afterwards.
+                                */
+                               remove_wait_queue(&async->wait_head, &wait);
+                               on_wait_queue = false;
+                               up_read(&dev->attach_lock);
+                               attach_locked = false;
+                               mutex_lock(&dev->mutex);
+                               /*
+                                * Become non-busy unless things have changed
+                                * behind our back.  Checking dev->detach_count
+                                * is unchanged ought to be sufficient (unless
+                                * there have been 2**32 detaches in the
+                                * meantime!), but check the subdevice pointer
+                                * as well just in case.
+                                */
+                               new_s = comedi_write_subdevice(dev, minor);
+                               if (dev->attached &&
+                                   old_detach_count == dev->detach_count &&
+                                   s == new_s && new_s->async == async)
+                                       do_become_nonbusy(dev, s);
                                mutex_unlock(&dev->mutex);
                        }
                        break;
@@ -2090,8 +2163,12 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
                buf += n;
                break;          /* makes device work like a pipe */
        }
+out:
+       if (on_wait_queue)
+               remove_wait_queue(&async->wait_head, &wait);
        set_current_state(TASK_RUNNING);
-       remove_wait_queue(&async->wait_head, &wait);
+       if (attach_locked)
+               up_read(&dev->attach_lock);
 
        return count ? count : retval;
 }
@@ -2104,25 +2181,35 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
        int n, m, count = 0, retval = 0;
        DECLARE_WAITQUEUE(wait, current);
        const unsigned minor = iminor(file_inode(file));
-       struct comedi_device *dev = comedi_dev_from_minor(minor);
+       struct comedi_device *dev = file->private_data;
+       unsigned int old_detach_count;
+       bool become_nonbusy = false;
+       bool attach_locked;
 
-       if (!dev)
-               return -ENODEV;
+       /* Protect against device detachment during operation. */
+       down_read(&dev->attach_lock);
+       attach_locked = true;
+       old_detach_count = dev->detach_count;
 
        if (!dev->attached) {
-               DPRINTK("no driver configured on comedi%i\n", dev->minor);
-               return -ENODEV;
+               dev_dbg(dev->class_dev, "no driver attached\n");
+               retval = -ENODEV;
+               goto out;
        }
 
        s = comedi_read_subdevice(dev, minor);
-       if (!s || !s->async)
-               return -EIO;
+       if (!s || !s->async) {
+               retval = -EIO;
+               goto out;
+       }
 
        async = s->async;
        if (!s->busy || !nbytes)
-               return 0;
-       if (s->busy != file)
-               return -EACCES;
+               goto out;
+       if (s->busy != file) {
+               retval = -EACCES;
+               goto out;
+       }
 
        add_wait_queue(&async->wait_head, &wait);
        while (nbytes > 0 && !retval) {
@@ -2140,13 +2227,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
 
                if (n == 0) {
                        if (!comedi_is_subdevice_running(s)) {
-                               mutex_lock(&dev->mutex);
-                               do_become_nonbusy(dev, s);
                                if (comedi_is_subdevice_in_error(s))
                                        retval = -EPIPE;
                                else
                                        retval = 0;
-                               mutex_unlock(&dev->mutex);
+                               become_nonbusy = true;
                                break;
                        }
                        if (file->f_flags & O_NONBLOCK) {
@@ -2184,14 +2269,37 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
                buf += n;
                break;          /* makes device work like a pipe */
        }
-       if (comedi_is_subdevice_idle(s)) {
+       remove_wait_queue(&async->wait_head, &wait);
+       set_current_state(TASK_RUNNING);
+       if (become_nonbusy || comedi_is_subdevice_idle(s)) {
+               struct comedi_subdevice *new_s;
+
+               /*
+                * To avoid deadlock, cannot acquire dev->mutex
+                * while dev->attach_lock is held.
+                */
+               up_read(&dev->attach_lock);
+               attach_locked = false;
                mutex_lock(&dev->mutex);
-               if (async->buf_read_count - async->buf_write_count == 0)
-                       do_become_nonbusy(dev, s);
+               /*
+                * Check device hasn't become detached behind our back.
+                * Checking dev->detach_count is unchanged ought to be
+                * sufficient (unless there have been 2**32 detaches in the
+                * meantime!), but check the subdevice pointer as well just in
+                * case.
+                */
+               new_s = comedi_read_subdevice(dev, minor);
+               if (dev->attached && old_detach_count == dev->detach_count &&
+                   s == new_s && new_s->async == async) {
+                       if (become_nonbusy ||
+                           async->buf_read_count - async->buf_write_count == 0)
+                               do_become_nonbusy(dev, s);
+               }
                mutex_unlock(&dev->mutex);
        }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&async->wait_head, &wait);
+out:
+       if (attach_locked)
+               up_read(&dev->attach_lock);
 
        return count ? count : retval;
 }
@@ -2199,10 +2307,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
 static int comedi_open(struct inode *inode, struct file *file)
 {
        const unsigned minor = iminor(inode);
-       struct comedi_device *dev = comedi_dev_from_minor(minor);
+       struct comedi_device *dev = comedi_dev_get_from_minor(minor);
+       int rc;
 
        if (!dev) {
-               DPRINTK("invalid minor number\n");
+               pr_debug("invalid minor number\n");
                return -ENODEV;
        }
 
@@ -2223,9 +2332,9 @@ static int comedi_open(struct inode *inode, struct file *file)
        if (dev->attached)
                goto ok;
        if (!capable(CAP_NET_ADMIN) && dev->in_request_module) {
-               DPRINTK("in request module\n");
-               mutex_unlock(&dev->mutex);
-               return -ENODEV;
+               dev_dbg(dev->class_dev, "in request module\n");
+               rc = -ENODEV;
+               goto out;
        }
        if (capable(CAP_NET_ADMIN) && dev->in_request_module)
                goto ok;
@@ -2241,9 +2350,9 @@ static int comedi_open(struct inode *inode, struct file *file)
        dev->in_request_module = false;
 
        if (!dev->attached && !capable(CAP_NET_ADMIN)) {
-               DPRINTK("not attached and not CAP_NET_ADMIN\n");
-               mutex_unlock(&dev->mutex);
-               return -ENODEV;
+               dev_dbg(dev->class_dev, "not attached and not CAP_NET_ADMIN\n");
+               rc = -ENODEV;
+               goto out;
        }
 ok:
        __module_get(THIS_MODULE);
@@ -2251,49 +2360,44 @@ ok:
        if (dev->attached) {
                if (!try_module_get(dev->driver->module)) {
                        module_put(THIS_MODULE);
-                       mutex_unlock(&dev->mutex);
-                       return -ENOSYS;
+                       rc = -ENOSYS;
+                       goto out;
                }
        }
 
        if (dev->attached && dev->use_count == 0 && dev->open) {
-               int rc = dev->open(dev);
+               rc = dev->open(dev);
                if (rc < 0) {
                        module_put(dev->driver->module);
                        module_put(THIS_MODULE);
-                       mutex_unlock(&dev->mutex);
-                       return rc;
+                       goto out;
                }
        }
 
        dev->use_count++;
+       file->private_data = dev;
+       rc = 0;
 
+out:
        mutex_unlock(&dev->mutex);
-
-       return 0;
+       if (rc)
+               comedi_dev_put(dev);
+       return rc;
 }
 
 static int comedi_fasync(int fd, struct file *file, int on)
 {
-       const unsigned minor = iminor(file_inode(file));
-       struct comedi_device *dev = comedi_dev_from_minor(minor);
-
-       if (!dev)
-               return -ENODEV;
+       struct comedi_device *dev = file->private_data;
 
        return fasync_helper(fd, file, on, &dev->async_queue);
 }
 
 static int comedi_close(struct inode *inode, struct file *file)
 {
-       const unsigned minor = iminor(inode);
-       struct comedi_device *dev = comedi_dev_from_minor(minor);
+       struct comedi_device *dev = file->private_data;
        struct comedi_subdevice *s = NULL;
        int i;
 
-       if (!dev)
-               return -ENODEV;
-
        mutex_lock(&dev->mutex);
 
        if (dev->subdevices) {
@@ -2316,6 +2420,7 @@ static int comedi_close(struct inode *inode, struct file *file)
        dev->use_count--;
 
        mutex_unlock(&dev->mutex);
+       comedi_dev_put(dev);
 
        return 0;
 }
@@ -2346,8 +2451,6 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
        unsigned runflags = 0;
        unsigned runflags_mask = 0;
 
-       /* DPRINTK("comedi_event 0x%x\n",mask); */
-
        if (!comedi_is_subdevice_running(s))
                return;
 
@@ -2368,16 +2471,11 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
        }
 
        if (async->cb_mask & s->async->events) {
-               if (comedi_get_subdevice_runflags(s) & SRF_USER) {
-                       wake_up_interruptible(&async->wait_head);
-                       if (s->subdev_flags & SDF_CMD_READ)
-                               kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
-                       if (s->subdev_flags & SDF_CMD_WRITE)
-                               kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
-               } else {
-                       if (async->cb_func)
-                               async->cb_func(s->async->events, async->cb_arg);
-               }
+               wake_up_interruptible(&async->wait_head);
+               if (s->subdev_flags & SDF_CMD_READ)
+                       kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
+               if (s->subdev_flags & SDF_CMD_WRITE)
+                       kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
        }
        s->async->events = 0;
 }
@@ -2408,7 +2506,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
        if (i == COMEDI_NUM_BOARD_MINORS) {
                mutex_unlock(&dev->mutex);
                comedi_device_cleanup(dev);
-               kfree(dev);
+               comedi_dev_put(dev);
                pr_err("comedi: error: ran out of minor numbers for board device files.\n");
                return ERR_PTR(-EBUSY);
        }
index fda1a7ba0e16bb83cec7f5bb21eb9347971a7628..9a746570f1619a90ae3dadefb121edc59d0f3495 100644 (file)
@@ -16,7 +16,11 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s);
 int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
                     unsigned long new_size);
 void comedi_buf_reset(struct comedi_async *async);
+bool comedi_buf_is_mmapped(struct comedi_async *async);
+void comedi_buf_map_get(struct comedi_buf_map *bm);
+int comedi_buf_map_put(struct comedi_buf_map *bm);
 unsigned int comedi_buf_write_n_allocated(struct comedi_async *async);
+void comedi_device_cancel_all(struct comedi_device *dev);
 
 extern unsigned int comedi_default_buf_size_kb;
 extern unsigned int comedi_default_buf_maxsize_kb;
index 143be8076a2e72361d11f88a2b64db8c4b89855b..f00b43c955f430a53adeafba53916355fd5dbc0d 100644 (file)
 #define _COMEDIDEV_H
 
 #include <linux/dma-mapping.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
+#include <linux/rwsem.h>
+#include <linux/kref.h>
 
 #include "comedi.h"
 
-#define DPRINTK(format, args...)       do {            \
-       if (comedi_debug)                               \
-               pr_debug("comedi: " format, ## args);   \
-} while (0)
-
 #define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
 #define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, \
        COMEDI_MINORVERSION, COMEDI_MICROVERSION)
@@ -100,18 +99,22 @@ struct comedi_buf_page {
        dma_addr_t dma_addr;
 };
 
+struct comedi_buf_map {
+       struct device *dma_hw_dev;
+       struct comedi_buf_page *page_list;
+       unsigned int n_pages;
+       enum dma_data_direction dma_dir;
+       struct kref refcount;
+};
+
 struct comedi_async {
        struct comedi_subdevice *subdevice;
 
        void *prealloc_buf;     /* pre-allocated buffer */
        unsigned int prealloc_bufsz;    /* buffer size, in bytes */
-       /* virtual and dma address of each page */
-       struct comedi_buf_page *buf_page_list;
-       unsigned n_buf_pages;   /* num elements in buf_page_list */
+       struct comedi_buf_map *buf_map; /* map of buffer pages */
 
        unsigned int max_bufsize;       /* maximum buffer size, bytes */
-       /* current number of mmaps of prealloc_buf */
-       unsigned int mmap_count;
 
        /* byte count for writer (write completed) */
        unsigned int buf_write_count;
@@ -141,10 +144,7 @@ struct comedi_async {
 
        wait_queue_head_t wait_head;
 
-       /* callback stuff */
        unsigned int cb_mask;
-       int (*cb_func) (unsigned int flags, void *);
-       void *cb_arg;
 
        int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s,
                        unsigned int x);
@@ -173,6 +173,7 @@ struct comedi_device {
 
        struct device *class_dev;
        int minor;
+       unsigned int detach_count;
        /* hw_dev is passed to dma_alloc_coherent when allocating async buffers
         * for subdevices that have async_dma_dir set to something other than
         * DMA_NONE */
@@ -185,6 +186,8 @@ struct comedi_device {
        bool ioenabled:1;
        spinlock_t spinlock;
        struct mutex mutex;
+       struct rw_semaphore attach_lock;
+       struct kref refcount;
 
        int n_subdevices;
        struct comedi_subdevice *subdevices;
@@ -208,12 +211,6 @@ static inline const void *comedi_board(const struct comedi_device *dev)
        return dev->board_ptr;
 }
 
-#ifdef CONFIG_COMEDI_DEBUG
-extern int comedi_debug;
-#else
-static const int comedi_debug;
-#endif
-
 /*
  * function prototypes
  */
@@ -231,7 +228,8 @@ enum comedi_minor_bits {
 static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4;
 static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
 
-struct comedi_device *comedi_dev_from_minor(unsigned minor);
+struct comedi_device *comedi_dev_get_from_minor(unsigned minor);
+int comedi_dev_put(struct comedi_device *dev);
 
 void init_polling(void);
 void cleanup_polling(void);
@@ -240,7 +238,6 @@ void stop_polling(struct comedi_device *);
 
 /* subdevice runflags */
 enum subdevice_runflags {
-       SRF_USER = 0x00000001,
        SRF_RT = 0x00000002,
        /* indicates an COMEDI_CB_ERROR event has occurred since the last
         * command was started */
index 8f02bf66e20b2002b3b52655919a89f95c0fcad9..a5d03b9c3717c99b3fbaa5265981479f1a56ed5f 100644 (file)
@@ -95,7 +95,7 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices)
 }
 EXPORT_SYMBOL_GPL(comedi_alloc_subdevices);
 
-static void cleanup_device(struct comedi_device *dev)
+static void comedi_device_detach_cleanup(struct comedi_device *dev)
 {
        int i;
        struct comedi_subdevice *s;
@@ -133,10 +133,14 @@ static void cleanup_device(struct comedi_device *dev)
 
 void comedi_device_detach(struct comedi_device *dev)
 {
+       comedi_device_cancel_all(dev);
+       down_write(&dev->attach_lock);
        dev->attached = false;
+       dev->detach_count++;
        if (dev->driver)
                dev->driver->detach(dev);
-       cleanup_device(dev);
+       comedi_device_detach_cleanup(dev);
+       up_write(&dev->attach_lock);
 }
 
 static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -355,8 +359,9 @@ static int comedi_device_postconfig(struct comedi_device *dev)
        ret = __comedi_device_postconfig(dev);
        if (ret < 0)
                return ret;
-       smp_wmb();
+       down_write(&dev->attach_lock);
        dev->attached = true;
+       up_write(&dev->attach_lock);
        return 0;
 }
 
@@ -657,7 +662,7 @@ void comedi_driver_unregister(struct comedi_driver *driver)
 
        /* check for devices using this driver */
        for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
-               struct comedi_device *dev = comedi_dev_from_minor(i);
+               struct comedi_device *dev = comedi_dev_get_from_minor(i);
 
                if (!dev)
                        continue;
@@ -671,6 +676,7 @@ void comedi_driver_unregister(struct comedi_driver *driver)
                        comedi_device_detach(dev);
                }
                mutex_unlock(&dev->mutex);
+               comedi_dev_put(dev);
        }
 }
 EXPORT_SYMBOL_GPL(comedi_driver_unregister);
index 94cbd2618fc8b875fad6d43edbe8ef2d4821590f..a16e674e2a2bb45a4d47e60ecb33bc1f33ec9765 100644 (file)
@@ -1,5 +1,6 @@
 # Makefile for individual comedi drivers
 #
+ccflags-$(CONFIG_COMEDI_DEBUG)         := -DDEBUG
 
 # Comedi "helper" modules
 
index 2e4bf284d52c08e5edc7fbd6221563b01cd92e70..9c9559ffc643d55a029bae90152e9338a45dc107 100644 (file)
@@ -513,7 +513,7 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev,
        int event = 0;
 
        spin_lock_irqsave(&subpriv->spinlock, flags);
-       subpriv->active = 1;
+       subpriv->active = true;
 
        /* Set up end of acquisition. */
        switch (cmd->stop_src) {
index 810e397d8fd7009a25f93c49cc0a076283af7fa7..dcccdce53c185bb5e07b78b2811764906f0620eb 100644 (file)
@@ -909,16 +909,14 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                }
                if (errors) {
                        if (errors & dupchan_err) {
-                               DPRINTK("comedi%d: " DRIVER_NAME
-                                       ": ao_cmdtest: "
-                                       "entries in chanlist must contain no "
-                                       "duplicate channels\n", dev->minor);
+                               dev_dbg(dev->class_dev,
+                                       "%s: entries in chanlist must contain no duplicate channels\n",
+                                       __func__);
                        }
                        if (errors & range_err) {
-                               DPRINTK("comedi%d: " DRIVER_NAME
-                                       ": ao_cmdtest: "
-                                       "entries in chanlist must all have "
-                                       "the same range index\n", dev->minor);
+                               dev_dbg(dev->class_dev,
+                                       "%s: entries in chanlist must all have the same range index\n",
+                                       __func__);
                        }
                        err++;
                }
index a97bbd6ca3db5a5a3b6945c5157c25082ac62165..e11d7cec11e682a7c024d50349803f7cad65c3fc 100644 (file)
@@ -818,9 +818,9 @@ static int pci230_ai_rinsn(struct comedi_device *dev,
        if (aref == AREF_DIFF) {
                /* Differential. */
                if (chan >= s->n_chan / 2) {
-                       DPRINTK("comedi%d: amplc_pci230: ai_rinsn: "
-                               "differential channel number out of range "
-                               "0 to %u\n", dev->minor, (s->n_chan / 2) - 1);
+                       dev_dbg(dev->class_dev,
+                               "%s: differential channel number out of range 0 to %u\n",
+                               __func__, (s->n_chan / 2) - 1);
                        return -EINVAL;
                }
        }
@@ -1092,14 +1092,14 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
                if (errors != 0) {
                        err++;
                        if ((errors & seq_err) != 0) {
-                               DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
-                                       "channel numbers must increase\n",
-                                       dev->minor);
+                               dev_dbg(dev->class_dev,
+                                       "%s: channel numbers must increase\n",
+                                       __func__);
                        }
                        if ((errors & range_err) != 0) {
-                               DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
-                                       "channels must have the same range\n",
-                                       dev->minor);
+                               dev_dbg(dev->class_dev,
+                                       "%s: channels must have the same range\n",
+                                       __func__);
                        }
                }
        }
@@ -1835,33 +1835,29 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
                if (errors != 0) {
                        err++;
                        if ((errors & seq_err) != 0) {
-                               DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
-                                       "channel numbers must increase or "
-                                       "sequence must repeat exactly\n",
-                                       dev->minor);
+                               dev_dbg(dev->class_dev,
+                                       "%s: channel numbers must increase or sequence must repeat exactly\n",
+                                       __func__);
                        }
                        if ((errors & rangepair_err) != 0) {
-                               DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
-                                       "single-ended channel pairs must "
-                                       "have the same range\n", dev->minor);
+                               dev_dbg(dev->class_dev,
+                                       "%s: single-ended channel pairs must have the same range\n",
+                                       __func__);
                        }
                        if ((errors & polarity_err) != 0) {
-                               DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
-                                       "channel sequence ranges must be all "
-                                       "bipolar or all unipolar\n",
-                                       dev->minor);
+                               dev_dbg(dev->class_dev,
+                                       "%s: channel sequence ranges must be all bipolar or all unipolar\n",
+                                       __func__);
                        }
                        if ((errors & aref_err) != 0) {
-                               DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
-                                       "channel sequence analogue references "
-                                       "must be all the same (single-ended "
-                                       "or differential)\n", dev->minor);
+                               dev_dbg(dev->class_dev,
+                                       "%s: channel sequence analogue references must be all the same (single-ended or differential)\n",
+                                       __func__);
                        }
                        if ((errors & diffchan_err) != 0) {
-                               DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
-                                       "differential channel number out of "
-                                       "range 0 to %u\n", dev->minor,
-                                       (s->n_chan / 2) - 1);
+                               dev_dbg(dev->class_dev,
+                                       "%s: differential channel number out of range 0 to %u\n",
+                                       __func__, (s->n_chan / 2) - 1);
                        }
                        if ((errors & buggy_chan0_err) != 0) {
                                dev_info(dev->class_dev,
index 217aa19cdc3211af53eae59f6b002b23453fb5fa..a85b9493071f3c7c36e441a5b455c80837ca8bf3 100644 (file)
@@ -322,14 +322,6 @@ static void C6X_encResetAll(unsigned long baseAddr)
        }
 }
 
-static int c6xdigio_pwmo_insn_read(struct comedi_device *dev,
-                                  struct comedi_subdevice *s,
-                                  struct comedi_insn *insn, unsigned int *data)
-{
-       printk(KERN_DEBUG "c6xdigio_pwmo_insn_read %x\n", insn->n);
-       return insn->n;
-}
-
 static int c6xdigio_pwmo_insn_write(struct comedi_device *dev,
                                    struct comedi_subdevice *s,
                                    struct comedi_insn *insn,
@@ -426,7 +418,6 @@ static int c6xdigio_attach(struct comedi_device *dev,
        s->subdev_flags = SDF_WRITEABLE;
        s->n_chan = 2;
        /*      s->trig[0] = c6xdigio_pwmo; */
-       s->insn_read = c6xdigio_pwmo_insn_read;
        s->insn_write = c6xdigio_pwmo_insn_write;
        s->maxdata = 500;
        s->range_table = &range_bipolar10;      /*  A suitable lie */
index ff5206536be36c3c4013efce6ca5fd9081f32ae0..a0053bbb2ede77d4d47fc925b48aec36d4b7e32f 100644 (file)
@@ -94,15 +94,6 @@ TODO:
 #include "plx9080.h"
 #include "comedi_fc.h"
 
-#undef PCIDAS64_DEBUG          /*  disable debugging code */
-/* #define PCIDAS64_DEBUG         enable debugging code */
-
-#ifdef PCIDAS64_DEBUG
-#define DEBUG_PRINT(format, args...)  pr_debug(format, ## args)
-#else
-#define DEBUG_PRINT(format, args...)  no_printk(format, ## args)
-#endif
-
 #define TIMER_BASE 25          /*  40MHz master clock */
 /* 100kHz 'prescaled' clock for slow acquisition,
  * maybe I'll support this someday */
@@ -1252,8 +1243,6 @@ static void disable_ai_interrupts(struct comedi_device *dev)
        writew(devpriv->intr_enable_bits,
               devpriv->main_iobase + INTR_ENABLE_REG);
        spin_unlock_irqrestore(&dev->spinlock, flags);
-
-       DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits);
 }
 
 static void enable_ai_interrupts(struct comedi_device *dev,
@@ -1277,7 +1266,6 @@ static void enable_ai_interrupts(struct comedi_device *dev,
        devpriv->intr_enable_bits |= bits;
        writew(devpriv->intr_enable_bits,
               devpriv->main_iobase + INTR_ENABLE_REG);
-       DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits);
        spin_unlock_irqrestore(&dev->spinlock, flags);
 }
 
@@ -1292,38 +1280,6 @@ static void init_plx9080(struct comedi_device *dev)
        devpriv->plx_control_bits =
                readl(devpriv->plx9080_iobase + PLX_CONTROL_REG);
 
-       /*  plx9080 dump */
-       DEBUG_PRINT(" plx interrupt status 0x%x\n",
-                   readl(plx_iobase + PLX_INTRCS_REG));
-       DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
-       DEBUG_PRINT(" plx control reg 0x%x\n", devpriv->plx_control_bits);
-       DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n",
-                   readl(plx_iobase + PLX_MARB_REG));
-       DEBUG_PRINT(" plx region0 reg 0x%x\n",
-                   readl(plx_iobase + PLX_REGION0_REG));
-       DEBUG_PRINT(" plx region1 reg 0x%x\n",
-                   readl(plx_iobase + PLX_REGION1_REG));
-
-       DEBUG_PRINT(" plx revision 0x%x\n",
-                   readl(plx_iobase + PLX_REVISION_REG));
-       DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_MODE_REG));
-       DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
-                   readl(plx_iobase + PLX_DMA1_MODE_REG));
-       DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
-       DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
-       DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
-       DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
-       DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
-                   readb(plx_iobase + PLX_DMA0_CS_REG));
-       DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
-       DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
-
 #ifdef __BIG_ENDIAN
        bits = BIGEND_DMA0 | BIGEND_DMA1;
 #else
@@ -1417,9 +1373,6 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev,
 
        devpriv->ai_fifo_segment_length = num_increments * increment_size;
 
-       DEBUG_PRINT("set hardware fifo segment length to %i\n",
-                   devpriv->ai_fifo_segment_length);
-
        return devpriv->ai_fifo_segment_length;
 }
 
@@ -1441,8 +1394,6 @@ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples)
 
        num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio;
 
-       DEBUG_PRINT("set hardware fifo size to %i\n", num_samples);
-
        return num_samples;
 }
 
@@ -1538,8 +1489,6 @@ static int alloc_and_init_dma_members(struct comedi_device *dev)
        if (devpriv->ai_dma_desc == NULL)
                return -ENOMEM;
 
-       DEBUG_PRINT("ai dma descriptors start at bus addr 0x%llx\n",
-                   (unsigned long long)devpriv->ai_dma_desc_bus_addr);
        if (ao_cmd_is_supported(thisboard)) {
                devpriv->ao_dma_desc =
                        pci_alloc_consistent(pcidev,
@@ -1548,9 +1497,6 @@ static int alloc_and_init_dma_members(struct comedi_device *dev)
                                             &devpriv->ao_dma_desc_bus_addr);
                if (devpriv->ao_dma_desc == NULL)
                        return -ENOMEM;
-
-               DEBUG_PRINT("ao dma descriptors start at bus addr 0x%llx\n",
-                           (unsigned long long)devpriv->ao_dma_desc_bus_addr);
        }
        /*  initialize dma descriptors */
        for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
@@ -1650,8 +1596,6 @@ static void i2c_write_byte(struct comedi_device *dev, uint8_t byte)
        uint8_t bit;
        unsigned int num_bits = 8;
 
-       DEBUG_PRINT("writing to i2c byte 0x%x\n", byte);
-
        for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
                i2c_set_scl(dev, 0);
                if ((byte & bit))
@@ -1738,7 +1682,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
        unsigned long flags;
        static const int timeout = 100;
 
-       DEBUG_PRINT("chanspec 0x%x\n", insn->chanspec);
        channel = CR_CHAN(insn->chanspec);
        range = CR_RANGE(insn->chanspec);
        aref = CR_AREF(insn->chanspec);
@@ -1766,7 +1709,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
                if (insn->chanspec & CR_ALT_SOURCE) {
                        unsigned int cal_en_bit;
 
-                       DEBUG_PRINT("reading calibration source\n");
                        if (thisboard->layout == LAYOUT_60XX)
                                cal_en_bit = CAL_EN_60XX_BIT;
                        else
@@ -1800,7 +1742,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 
                devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
                if (insn->chanspec & CR_ALT_SOURCE) {
-                       DEBUG_PRINT("reading calibration source\n");
                        devpriv->i2c_cal_range_bits |=
                                adc_src_4020_bits(devpriv->calibration_source);
                } else {        /* select BNC inputs */
@@ -1839,7 +1780,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
                /*  wait for data */
                for (i = 0; i < timeout; i++) {
                        bits = readw(devpriv->main_iobase + HW_STATUS_REG);
-                       DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits));
                        if (thisboard->layout == LAYOUT_4020) {
                                if (readw(devpriv->main_iobase +
                                          ADC_WRITE_PNTR_REG))
@@ -1850,7 +1790,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
                        }
                        udelay(1);
                }
-               DEBUG_PRINT(" looped %i times waiting for data\n", i);
                if (i == timeout) {
                        comedi_error(dev, " analog input read insn timed out");
                        dev_info(dev->class_dev, "status 0x%x\n", bits);
@@ -1884,7 +1823,6 @@ static int ai_config_calibration_source(struct comedi_device *dev,
                return -EINVAL;
        }
 
-       DEBUG_PRINT("setting calibration source to %i\n", source);
        devpriv->calibration_source = source;
 
        return 2;
@@ -2368,7 +2306,6 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
        /*  load lower 16 bits of convert interval */
        writew(convert_counter & 0xffff,
               devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
-       DEBUG_PRINT("convert counter 0x%x\n", convert_counter);
        /*  load upper 8 bits of convert interval */
        writew((convert_counter >> 16) & 0xff,
               devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
@@ -2378,7 +2315,6 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
        /*  load upper 8 bits of scan delay */
        writew((scan_counter >> 16) & 0xff,
               devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
-       DEBUG_PRINT("scan counter 0x%x\n", scan_counter);
 }
 
 static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
@@ -2469,9 +2405,6 @@ static int setup_channel_queue(struct comedi_device *dev,
                                writew(bits,
                                       devpriv->main_iobase +
                                       ADC_QUEUE_FIFO_REG);
-                               DEBUG_PRINT(
-                                           "wrote 0x%x to external channel queue\n",
-                                           bits);
                        }
                        /* doing a queue clear is not specified in board docs,
                         * but required for reliable operation */
@@ -2593,7 +2526,6 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        }
        writew(devpriv->adc_control1_bits,
               devpriv->main_iobase + ADC_CONTROL1_REG);
-       DEBUG_PRINT("control1 bits 0x%x\n", devpriv->adc_control1_bits);
        spin_unlock_irqrestore(&dev->spinlock, flags);
 
        /*  clear adc buffer */
@@ -2645,17 +2577,14 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        if (use_hw_sample_counter(cmd))
                bits |= ADC_SAMPLE_COUNTER_EN_BIT;
        writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG);
-       DEBUG_PRINT("control0 bits 0x%x\n", bits);
 
        devpriv->ai_cmd_running = 1;
 
        spin_unlock_irqrestore(&dev->spinlock, flags);
 
        /*  start acquisition */
-       if (cmd->start_src == TRIG_NOW) {
+       if (cmd->start_src == TRIG_NOW)
                writew(0, devpriv->main_iobase + ADC_START_REG);
-               DEBUG_PRINT("soft trig\n");
-       }
 
        return 0;
 }
@@ -2690,10 +2619,6 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
                read_segment = adc_upper_read_ptr_code(prepost_bits);
                write_segment = adc_upper_write_ptr_code(prepost_bits);
 
-               DEBUG_PRINT(" rd seg %i, wrt seg %i, rd idx %i, wrt idx %i\n",
-                           read_segment, write_segment, read_index,
-                           write_index);
-
                if (read_segment != write_segment)
                        num_samples =
                                devpriv->ai_fifo_segment_length - read_index;
@@ -2715,8 +2640,6 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
                        break;
                }
 
-               DEBUG_PRINT(" read %i samples from fifo\n", num_samples);
-
                for (i = 0; i < num_samples; i++) {
                        cfc_write_to_buffer(s,
                                            readw(devpriv->main_iobase +
@@ -2812,11 +2735,6 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
                                          num_samples * sizeof(uint16_t));
                devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) %
                                        ai_dma_ring_count(thisboard);
-
-               DEBUG_PRINT("next buffer addr 0x%lx\n",
-                           (unsigned long)devpriv->
-                           ai_buffer_bus_addr[devpriv->ai_dma_index]);
-               DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
        }
        /* XXX check for dma ring buffer overrun
         * (use end-of-chain bit to mark last unused buffer) */
@@ -2845,24 +2763,17 @@ static void handle_ai_interrupt(struct comedi_device *dev,
        if (plx_status & ICS_DMA1_A) {  /*  dma chan 1 interrupt */
                writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
                       devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
-               DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
 
                if (dma1_status & PLX_DMA_EN_BIT)
                        drain_dma_buffers(dev, 1);
-
-               DEBUG_PRINT(" cleared dma ch1 interrupt\n");
        }
        spin_unlock_irqrestore(&dev->spinlock, flags);
 
-       if (status & ADC_DONE_BIT)
-               DEBUG_PRINT("adc done interrupt\n");
-
        /*  drain fifo with pio */
        if ((status & ADC_DONE_BIT) ||
            ((cmd->flags & TRIG_WAKE_EOS) &&
             (status & ADC_INTR_PENDING_BIT) &&
             (thisboard->layout != LAYOUT_4020))) {
-               DEBUG_PRINT("pio fifo drain\n");
                spin_lock_irqsave(&dev->spinlock, flags);
                if (devpriv->ai_cmd_running) {
                        spin_unlock_irqrestore(&dev->spinlock, flags);
@@ -2947,7 +2858,6 @@ static void restart_ao_dma(struct comedi_device *dev)
        dma_desc_bits =
                readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
        dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT;
-       DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits);
        load_first_dma_descriptor(dev, 0, dma_desc_bits);
 
        dma_start_sync(dev, 0);
@@ -2963,10 +2873,6 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
        buffer_index = devpriv->ao_dma_index;
        prev_buffer_index = prev_ao_dma_index(dev);
 
-       DEBUG_PRINT("attempting to load ao buffer %i (0x%llx)\n", buffer_index,
-                   (unsigned long long)devpriv->ao_buffer_bus_addr[
-                                                               buffer_index]);
-
        num_bytes = comedi_buf_read_n_available(dev->write_subdev->async);
        if (num_bytes > DMA_BUFFER_SIZE)
                num_bytes = DMA_BUFFER_SIZE;
@@ -2977,8 +2883,6 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
        if (num_bytes == 0)
                return 0;
 
-       DEBUG_PRINT("loading %i bytes\n", num_bytes);
-
        num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
                                               devpriv->
                                               ao_buffer[buffer_index],
@@ -3052,14 +2956,12 @@ static void handle_ao_interrupt(struct comedi_device *dev,
                        writeb(PLX_CLEAR_DMA_INTR_BIT,
                               devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
                spin_unlock_irqrestore(&dev->spinlock, flags);
-               DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
                if (dma0_status & PLX_DMA_EN_BIT) {
                        load_ao_dma(dev, cmd);
                        /* try to recover from dma end-of-chain event */
                        if (ao_dma_needs_restart(dev, dma0_status))
                                restart_ao_dma(dev);
                }
-               DEBUG_PRINT(" cleared dma ch0 interrupt\n");
        } else {
                spin_unlock_irqrestore(&dev->spinlock, flags);
        }
@@ -3068,12 +2970,6 @@ static void handle_ao_interrupt(struct comedi_device *dev,
                async->events |= COMEDI_CB_EOA;
                if (ao_stopped_by_error(dev, cmd))
                        async->events |= COMEDI_CB_ERROR;
-               DEBUG_PRINT("plx dma0 desc reg 0x%x\n",
-                           readl(devpriv->plx9080_iobase +
-                                 PLX_DMA0_DESCRIPTOR_REG));
-               DEBUG_PRINT("plx dma0 address reg 0x%x\n",
-                           readl(devpriv->plx9080_iobase +
-                                 PLX_DMA0_PCI_ADDRESS_REG));
        }
        cfc_handle_events(dev, s);
 }
@@ -3089,15 +2985,12 @@ static irqreturn_t handle_interrupt(int irq, void *d)
        plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG);
        status = readw(devpriv->main_iobase + HW_STATUS_REG);
 
-       DEBUG_PRINT("hw status 0x%x, plx status 0x%x\n", status, plx_status);
-
        /* an interrupt before all the postconfig stuff gets done could
         * cause a NULL dereference if we continue through the
         * interrupt handler */
-       if (!dev->attached) {
-               DEBUG_PRINT("premature interrupt, ignoring\n");
+       if (!dev->attached)
                return IRQ_HANDLED;
-       }
+
        handle_ai_interrupt(dev, status, plx_status);
        handle_ao_interrupt(dev, status, plx_status);
 
@@ -3105,11 +2998,8 @@ static irqreturn_t handle_interrupt(int irq, void *d)
        if (plx_status & ICS_LDIA) {    /*  clear local doorbell interrupt */
                plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
                writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
-               DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
        }
 
-       DEBUG_PRINT("exiting handler\n");
-
        return IRQ_HANDLED;
 }
 
@@ -3130,7 +3020,6 @@ static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 
        abort_dma(dev, 1);
 
-       DEBUG_PRINT("ai canceled\n");
        return 0;
 }
 
@@ -3458,7 +3347,6 @@ static int dio_callback(int dir, int port, int data, unsigned long arg)
        void __iomem *iobase = (void __iomem *)arg;
        if (dir) {
                writeb(data, iobase + port);
-               DEBUG_PRINT("wrote 0x%x to port %i\n", data, port);
                return 0;
        } else {
                return readb(iobase + port);
@@ -4046,11 +3934,6 @@ static int auto_attach(struct comedi_device *dev,
                return -ENOMEM;
        }
 
-       DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase);
-       DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase);
-       DEBUG_PRINT(" diocounter remapped to 0x%p\n",
-                   devpriv->dio_counter_iobase);
-
        /*  figure out what local addresses are */
        local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) &
                      LRNG_MEM_MASK;
@@ -4065,9 +3948,6 @@ static int auto_attach(struct comedi_device *dev,
        devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase &
                                  ~local_range) | local_decode;
 
-       DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase);
-       DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase);
-
        retval = alloc_and_init_dma_members(dev);
        if (retval < 0)
                return retval;
index 30520d4c16a61f7fe46423eb3963e8ceb37257f8..b25fa5d6e1e8f02907b00b3abad53f261e26bad4 100644 (file)
@@ -44,9 +44,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details.
 #include "plx9052.h"
 #include "8255.h"
 
-/* #define CBPCIMDAS_DEBUG */
-#undef CBPCIMDAS_DEBUG
-
 /* Registers for the PCIM-DAS1602/16 */
 
 /* sizes of io regions (bytes) */
index fb25cb847032ee1c86308bdb93fc940facad57d4..e80c19a892cd33fffd1e2059e15a1f6f64afccff 100644 (file)
@@ -152,21 +152,12 @@ static irqreturn_t intr_handler(int irq, void *d)
                dev_warn(dev->class_dev, "BUG: spurious interrupt\n");
                return IRQ_HANDLED;
        }
-#ifdef DEBUG
-       printk("das6402: interrupt! das6402_irqcount=%i\n",
-              devpriv->das6402_irqcount);
-       printk("das6402: iobase+2=%i\n", inw_p(dev->iobase + 2));
-#endif
 
        das6402_ai_fifo_dregs(dev, s);
 
        if (s->async->buf_write_count >= devpriv->ai_bytes_to_read) {
                outw_p(SCANL, dev->iobase + 2); /* clears the fifo */
                outb(0x07, dev->iobase + 8);    /* clears all flip-flops */
-#ifdef DEBUG
-               printk("das6402: Got %i samples\n\n",
-                      devpriv->das6402_wordsread - diff);
-#endif
                s->async->events |= COMEDI_CB_EOA;
                comedi_event(dev, s);
        }
index b04a5633f754ef3c286ca0ef7615ba67152482d4..cac83585ef86191a176cfae753a767a6629fa8fa 100644 (file)
@@ -723,12 +723,6 @@ static int dmm32at_attach(struct comedi_device *dev,
        intstat = inb(dev->iobase + DMM32AT_INTCLOCK);
        airback = inb(dev->iobase + DMM32AT_AIRBACK);
 
-       printk(KERN_DEBUG "dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n",
-              ailo, aihi, fifostat);
-       printk(KERN_DEBUG
-              "dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n",
-              aistat, intstat, airback);
-
        if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) ||
            (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) {
                printk(KERN_ERR "dmmat32: board detection failed\n");
index 811c8c59c01761f87ef8a9936cd3b648d8ea3751..1dd8190970e31f531e4c52d3f2bcee90d9fd15f7 100644 (file)
@@ -359,17 +359,12 @@ static int dt2801_reset(struct comedi_device *dev)
        unsigned int stat;
        int timeout;
 
-       DPRINTK("dt2801: resetting board...\n");
-       DPRINTK("fingerprint: 0x%02x 0x%02x\n", inb_p(dev->iobase),
-               inb_p(dev->iobase + 1));
-
        /* pull random data from data port */
        inb_p(dev->iobase + DT2801_DATA);
        inb_p(dev->iobase + DT2801_DATA);
        inb_p(dev->iobase + DT2801_DATA);
        inb_p(dev->iobase + DT2801_DATA);
 
-       DPRINTK("dt2801: stop\n");
        /* dt2801_writecmd(dev,DT_C_STOP); */
        outb_p(DT_C_STOP, dev->iobase + DT2801_CMD);
 
@@ -387,7 +382,6 @@ static int dt2801_reset(struct comedi_device *dev)
        /* printk("dt2801: reading dummy\n"); */
        /* dt2801_readdata(dev,&board_code); */
 
-       DPRINTK("dt2801: reset\n");
        outb_p(DT_C_RESET, dev->iobase + DT2801_CMD);
        /* dt2801_writecmd(dev,DT_C_RESET); */
 
@@ -401,11 +395,8 @@ static int dt2801_reset(struct comedi_device *dev)
        if (!timeout)
                printk("dt2801: timeout 2 status=0x%02x\n", stat);
 
-       DPRINTK("dt2801: reading code\n");
        dt2801_readdata(dev, &board_code);
 
-       DPRINTK("dt2801: ok.  code=0x%02x\n", board_code);
-
        return board_code;
 }
 
index 6514b9e0055283dfc8d050a2b4b1554f946efbdb..4b414783384318f72a873fadfdd41e4b30a129ff 100644 (file)
@@ -256,26 +256,6 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        i = inb(dev->iobase + DT2814_DATA);
 
        irq = it->options[1];
-#if 0
-       if (irq < 0) {
-               save_flags(flags);
-               sti();
-               irqs = probe_irq_on();
-
-               outb(0, dev->iobase + DT2814_CSR);
-
-               udelay(100);
-
-               irq = probe_irq_off(irqs);
-               restore_flags(flags);
-               if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR)
-                       printk(KERN_DEBUG "error probing irq (bad)\n");
-
-
-               i = inb(dev->iobase + DT2814_DATA);
-               i = inb(dev->iobase + DT2814_DATA);
-       }
-#endif
        dev->irq = 0;
        if (irq > 0) {
                if (request_irq(irq, dt2814_interrupt, 0, "dt2814", dev)) {
@@ -286,12 +266,6 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                }
        } else if (irq == 0) {
                printk(KERN_WARNING "(no irq)\n");
-       } else {
-#if 0
-               printk(KERN_DEBUG "(probe returned multiple irqs--bad)\n");
-#else
-               printk(KERN_WARNING "(irq probe not implemented)\n");
-#endif
        }
 
        ret = comedi_alloc_subdevices(dev, 1);
index a01e6b553887ab23480d8de187ef0079a662715e..c4ffedbdde21f8e5c1906045126efea6b0ff92ce 100644 (file)
@@ -63,8 +63,6 @@ Notes:
 
 #include "comedi_fc.h"
 
-#define DEBUG
-
 #define DT2821_TIMEOUT         100     /* 500 us */
 #define DT2821_SIZE 0x10
 
@@ -1130,14 +1128,6 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
        outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR);
        i = inw(dev->iobase + DT2821_ADCSR);
-#ifdef DEBUG
-       printk(KERN_DEBUG " fingerprint=%x,%x,%x,%x,%x",
-              inw(dev->iobase + DT2821_ADCSR),
-              inw(dev->iobase + DT2821_CHANCSR),
-              inw(dev->iobase + DT2821_DACSR),
-              inw(dev->iobase + DT2821_SUPCSR),
-              inw(dev->iobase + DT2821_TMRCTR));
-#endif
 
        if (((inw(dev->iobase + DT2821_ADCSR) & DT2821_ADCSR_MASK)
             != DT2821_ADCSR_VAL) ||
index 292226eeff924dd6c7b9dccda948d6bbce476016..3073efd792480cc8dfdde65ee4797b4f529d41a2 100644 (file)
@@ -48,8 +48,6 @@ AO commands are not supported.
    you the docs without one, also.
 */
 
-#define DEBUG 1
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
@@ -253,24 +251,6 @@ struct dt3k_private {
        unsigned int ai_rear;
 };
 
-#ifdef DEBUG
-static char *intr_flags[] = {
-       "AdFull", "AdSwError", "AdHwError", "DaEmpty",
-       "DaSwError", "DaHwError", "CtDone", "CmDone",
-};
-
-static void debug_intr_flags(unsigned int flags)
-{
-       int i;
-       printk(KERN_DEBUG "dt3k: intr_flags:");
-       for (i = 0; i < 8; i++) {
-               if (flags & (1 << i))
-                       printk(KERN_CONT " %s", intr_flags[i]);
-       }
-       printk(KERN_CONT "\n");
-}
-#endif
-
 #define TIMEOUT 100
 
 static void dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd)
@@ -380,9 +360,6 @@ static irqreturn_t dt3k_interrupt(int irq, void *d)
 
        s = &dev->subdevices[0];
        status = readw(devpriv->io_addr + DPR_Intr_Flag);
-#ifdef DEBUG
-       debug_intr_flags(status);
-#endif
 
        if (status & DT3000_ADFULL) {
                dt3k_ai_empty_fifo(dev, s);
index f2a9f1c2f3b6dfe2ffa563a53c466ac7bd7fd987..9b1f196dbbc8c2e2563e06a387795934789e9f44 100644 (file)
@@ -90,8 +90,7 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev,
                                goto conv_finish;
                }
                data[n] = 0;
-               printk(KERN_DEBUG "comedi: dyna_pci10xx: "
-                       "timeout reading analog input\n");
+               dev_dbg(dev->class_dev, "timeout reading analog input\n");
                continue;
 conv_finish:
                /* mask the first 4 bits - EOC bits */
index e3ff4c43897978ef7caf355215358bf2595e3a12..aff1e7db138e4ac90ad4af6a94055ae9c35792ed 100644 (file)
@@ -16,8 +16,6 @@ Configuration options:
   [0] - I/O port base address
 */
 
-#define DEBUG 0
-
 #include <linux/module.h>
 #include "../comedidev.h"
 
index 559bf5583530c2e2796ece8ad712dcec22514fa1..4fcf3c876ac90754b51b66fb464ce2e470ee448b 100644 (file)
@@ -60,15 +60,6 @@ static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
 static irqreturn_t handle_interrupt(int irq, void *d);
 static int dio_config_block_size(struct comedi_device *dev, unsigned int *data);
 
-#undef HPDI_DEBUG              /*  disable debugging messages */
-/* #define HPDI_DEBUG      enable debugging code */
-
-#ifdef HPDI_DEBUG
-#define DEBUG_PRINT(format, args...)  pr_debug(format , ## args)
-#else
-#define DEBUG_PRINT(format, args...)  no_printk(pr_fmt(format), ## args)
-#endif
-
 #define TIMER_BASE 50          /*  20MHz master clock */
 #define DMA_BUFFER_SIZE 0x10000
 #define NUM_DMA_BUFFERS 4
@@ -260,32 +251,6 @@ static void init_plx9080(struct comedi_device *dev)
        uint32_t bits;
        void __iomem *plx_iobase = devpriv->plx9080_iobase;
 
-       /*  plx9080 dump */
-       DEBUG_PRINT(" plx interrupt status 0x%x\n",
-                   readl(plx_iobase + PLX_INTRCS_REG));
-       DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
-       DEBUG_PRINT(" plx control reg 0x%x\n",
-                   readl(devpriv->plx9080_iobase + PLX_CONTROL_REG));
-
-       DEBUG_PRINT(" plx revision 0x%x\n",
-                   readl(plx_iobase + PLX_REVISION_REG));
-       DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_MODE_REG));
-       DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
-                   readl(plx_iobase + PLX_DMA1_MODE_REG));
-       DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
-       DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
-       DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
-       DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
-       DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
-                   readb(plx_iobase + PLX_DMA0_CS_REG));
-       DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
-                   readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
-       DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
 #ifdef __BIG_ENDIAN
        bits = BIGEND_DMA0 | BIGEND_DMA1;
 #else
@@ -395,10 +360,6 @@ static int setup_dma_descriptors(struct comedi_device *dev,
        if (transfer_size == 0)
                return -1;
 
-       DEBUG_PRINT(" transfer_size %i\n", transfer_size);
-       DEBUG_PRINT(" descriptors at 0x%lx\n",
-                   (unsigned long)devpriv->dma_desc_phys_addr);
-
        buffer_offset = 0;
        buffer_index = 0;
        for (i = 0; i < NUM_DMA_DESCRIPTORS &&
@@ -423,21 +384,11 @@ static int setup_dma_descriptors(struct comedi_device *dev,
                        buffer_offset = 0;
                        buffer_index++;
                }
-
-               DEBUG_PRINT(" desc %i\n", i);
-               DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n",
-                           devpriv->desc_dio_buffer[i],
-                           (unsigned long)devpriv->dma_desc[i].
-                           pci_start_addr);
-               DEBUG_PRINT(" next 0x%lx\n",
-                           (unsigned long)devpriv->dma_desc[i].next);
        }
        devpriv->num_dma_descriptors = i;
        /*  fix last descriptor to point back to first */
        devpriv->dma_desc[i - 1].next =
            cpu_to_le32(devpriv->dma_desc_phys_addr | next_bits);
-       DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1,
-                   (unsigned long)devpriv->dma_desc[i - 1].next);
 
        devpriv->block_size = transfer_size;
 
@@ -489,9 +440,6 @@ static int hpdi_auto_attach(struct comedi_device *dev,
                return -ENOMEM;
        }
 
-       DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase);
-       DEBUG_PRINT(" hpdi remapped to 0x%p\n", devpriv->hpdi_iobase);
-
        init_plx9080(dev);
 
        /*  get irq */
@@ -510,9 +458,6 @@ static int hpdi_auto_attach(struct comedi_device *dev,
                devpriv->dio_buffer[i] =
                    pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
                                         &devpriv->dio_buffer_phys_addr[i]);
-               DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n",
-                           devpriv->dio_buffer[i],
-                           (unsigned long)devpriv->dio_buffer_phys_addr[i]);
        }
        /*  allocate dma descriptors */
        devpriv->dma_desc = pci_alloc_consistent(pcidev,
@@ -687,8 +632,6 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
        hpdi_writel(dev, RX_FIFO_RESET_BIT, BOARD_CONTROL_REG);
 
-       DEBUG_PRINT("hpdi: in di_cmd\n");
-
        abort_dma(dev, 0);
 
        devpriv->dma_desc_index = 0;
@@ -725,7 +668,6 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        writel(intr_bit(RX_FULL_INTR),
               devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG);
 
-       DEBUG_PRINT("hpdi: starting rx\n");
        hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG);
 
        return 0;
@@ -778,11 +720,6 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
                                          num_samples * sizeof(uint32_t));
                devpriv->dma_desc_index++;
                devpriv->dma_desc_index %= devpriv->num_dma_descriptors;
-
-               DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long)
-                           devpriv->dma_desc[devpriv->dma_desc_index].
-                           next);
-               DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
        }
        /*  XXX check for buffer overrun somehow */
 }
@@ -812,7 +749,6 @@ static irqreturn_t handle_interrupt(int irq, void *d)
        async->events = 0;
 
        if (hpdi_intr_status) {
-               DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status);
                writel(hpdi_intr_status,
                       devpriv->hpdi_iobase + INTERRUPT_STATUS_REG);
        }
@@ -823,10 +759,8 @@ static irqreturn_t handle_interrupt(int irq, void *d)
                writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
                       devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
 
-               DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
                if (dma0_status & PLX_DMA_EN_BIT)
                        drain_dma_buffers(dev, 0);
-               DEBUG_PRINT(" cleared dma ch0 interrupt\n");
        }
        spin_unlock_irqrestore(&dev->spinlock, flags);
 
@@ -836,9 +770,6 @@ static irqreturn_t handle_interrupt(int irq, void *d)
        if (plx_status & ICS_DMA1_A) {  /*  XXX *//*  dma chan 1 interrupt */
                writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
                       devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
-               DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
-
-               DEBUG_PRINT(" cleared dma ch1 interrupt\n");
        }
        spin_unlock_irqrestore(&dev->spinlock, flags);
 
@@ -846,15 +777,11 @@ static irqreturn_t handle_interrupt(int irq, void *d)
        if (plx_status & ICS_LDIA) {    /*  clear local doorbell interrupt */
                plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
                writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
-               DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
        }
 
        if (hpdi_board_status & RX_OVERRUN_BIT) {
                comedi_error(dev, "rx fifo overrun");
                async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
-               DEBUG_PRINT("dma0_status 0x%x\n",
-                           (int)readb(devpriv->plx9080_iobase +
-                                      PLX_DMA0_CS_REG));
        }
 
        if (hpdi_board_status & RX_UNDERRUN_BIT) {
@@ -865,11 +792,6 @@ static irqreturn_t handle_interrupt(int irq, void *d)
        if (devpriv->dio_count == 0)
                async->events |= COMEDI_CB_EOA;
 
-       DEBUG_PRINT("board status 0x%x, ", hpdi_board_status);
-       DEBUG_PRINT("plx status 0x%x\n", plx_status);
-       if (async->events)
-               DEBUG_PRINT(" events 0x%x\n", async->events);
-
        cfc_handle_events(dev, s);
 
        return IRQ_HANDLED;
index 35cb4ace79701d45385ca003ba598051c255c773..9c9a0ee432cf45271cb9b9a37ceaafcec777a9a5 100644 (file)
@@ -288,7 +288,6 @@ void mite_dma_arm(struct mite_channel *mite_chan)
        int chor;
        unsigned long flags;
 
-       MDPRINTK("mite_dma_arm ch%i\n", mite_chan->channel);
        /*
         * memory barrier is intended to insure any twiddling with the buffer
         * is done before writing to the mite to arm dma transfer
@@ -329,8 +328,6 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring,
 
        n_links = async->prealloc_bufsz >> PAGE_SHIFT;
 
-       MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links);
-
        ring->descriptors =
            dma_alloc_coherent(ring->hw_dev,
                               n_links * sizeof(struct mite_dma_descriptor),
@@ -345,7 +342,7 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring,
        for (i = 0; i < n_links; i++) {
                ring->descriptors[i].count = cpu_to_le32(PAGE_SIZE);
                ring->descriptors[i].addr =
-                   cpu_to_le32(async->buf_page_list[i].dma_addr);
+                   cpu_to_le32(async->buf_map->page_list[i].dma_addr);
                ring->descriptors[i].next =
                    cpu_to_le32(ring->descriptors_dma_addr + (i +
                                                              1) *
@@ -368,8 +365,6 @@ void mite_prep_dma(struct mite_channel *mite_chan,
        unsigned int chor, chcr, mcr, dcr, lkcr;
        struct mite_struct *mite = mite_chan->mite;
 
-       MDPRINTK("mite_prep_dma ch%i\n", mite_chan->channel);
-
        /* reset DMA and FIFO */
        chor = CHOR_DMARESET | CHOR_FRESET;
        writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
@@ -448,8 +443,6 @@ void mite_prep_dma(struct mite_channel *mite_chan,
        /* starting address for link chaining */
        writel(mite_chan->ring->descriptors_dma_addr,
               mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
-
-       MDPRINTK("exit mite_prep_dma\n");
 }
 EXPORT_SYMBOL_GPL(mite_prep_dma);
 
@@ -515,8 +508,6 @@ unsigned mite_dma_tcr(struct mite_channel *mite_chan)
 
        lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
        tcr = readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel));
-       MDPRINTK("mite_dma_tcr ch%i, lkar=0x%08x tcr=%d\n", mite_chan->channel,
-                lkar, tcr);
 
        return tcr;
 }
@@ -642,140 +633,6 @@ int mite_done(struct mite_channel *mite_chan)
 }
 EXPORT_SYMBOL_GPL(mite_done);
 
-#ifdef DEBUG_MITE
-
-/* names of bits in mite registers */
-
-static const char *const mite_CHOR_strings[] = {
-       "start", "cont", "stop", "abort",
-       "freset", "clrlc", "clrrb", "clrdone",
-       "clr_lpause", "set_lpause", "clr_send_tc",
-       "set_send_tc", "12", "13", "14",
-       "15", "16", "17", "18",
-       "19", "20", "21", "22",
-       "23", "24", "25", "26",
-       "27", "28", "29", "30",
-       "dmareset",
-};
-
-static const char *const mite_CHCR_strings[] = {
-       "continue", "ringbuff", "2", "3",
-       "4", "5", "6", "7",
-       "8", "9", "10", "11",
-       "12", "13", "bursten", "fifodis",
-       "clr_cont_rb_ie", "set_cont_rb_ie", "clr_lc_ie", "set_lc_ie",
-       "clr_drdy_ie", "set_drdy_ie", "clr_mrdy_ie", "set_mrdy_ie",
-       "clr_done_ie", "set_done_ie", "clr_sar_ie", "set_sar_ie",
-       "clr_linkp_ie", "set_linkp_ie", "clr_dma_ie", "set_dma_ie",
-};
-
-static const char *const mite_MCR_strings[] = {
-       "amdevice", "1", "2", "3",
-       "4", "5", "portio", "portvxi",
-       "psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "11",
-       "12", "13", "blocken", "berhand",
-       "reqsintlim/reqs0", "reqs1", "reqs2", "rd32",
-       "rd512", "rl1", "rl2", "rl8",
-       "24", "25", "26", "27",
-       "28", "29", "30", "stopen",
-};
-
-static const char *const mite_DCR_strings[] = {
-       "amdevice", "1", "2", "3",
-       "4", "5", "portio", "portvxi",
-       "psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "aseqxp2",
-       "aseqxp8", "13", "blocken", "berhand",
-       "reqsintlim", "reqs1", "reqs2", "rd32",
-       "rd512", "rl1", "rl2", "rl8",
-       "23", "24", "25", "27",
-       "28", "wsdevc", "wsdevs", "rwdevpack",
-};
-
-static const char *const mite_LKCR_strings[] = {
-       "amdevice", "1", "2", "3",
-       "4", "5", "portio", "portvxi",
-       "psizebyte", "psizehalf (byte & half = word)", "asequp", "aseqdown",
-       "12", "13", "14", "berhand",
-       "16", "17", "18", "rd32",
-       "rd512", "rl1", "rl2", "rl8",
-       "24", "25", "26", "27",
-       "28", "29", "30", "chngend",
-};
-
-static const char *const mite_CHSR_strings[] = {
-       "d.err0", "d.err1", "m.err0", "m.err1",
-       "l.err0", "l.err1", "drq0", "drq1",
-       "end", "xferr", "operr0", "operr1",
-       "stops", "habort", "sabort", "error",
-       "16", "conts_rb", "18", "linkc",
-       "20", "drdy", "22", "mrdy",
-       "24", "done", "26", "sars",
-       "28", "lpauses", "30", "int",
-};
-
-static void mite_decode(const char *const *bit_str, unsigned int bits)
-{
-       int i;
-
-       for (i = 31; i >= 0; i--) {
-               if (bits & (1 << i))
-                       pr_debug(" %s\n", bit_str[i]);
-       }
-}
-
-void mite_dump_regs(struct mite_channel *mite_chan)
-{
-       void __iomem *mite_io_addr = mite_chan->mite->mite_io_addr;
-       unsigned int offset;
-       unsigned int value;
-       int channel = mite_chan->channel;
-
-       pr_debug("mite_dump_regs ch%i\n", channel);
-       pr_debug("mite address is  =%p\n", mite_io_addr);
-
-       offset = MITE_CHOR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[CHOR] at 0x%08x =0x%08x\n", offset, value);
-       mite_decode(mite_CHOR_strings, value);
-       offset = MITE_CHCR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[CHCR] at 0x%08x =0x%08x\n", offset, value);
-       mite_decode(mite_CHCR_strings, value);
-       offset = MITE_TCR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[TCR] at 0x%08x =0x%08x\n", offset, value);
-       offset = MITE_MCR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[MCR] at 0x%08x =0x%08x\n", offset, value);
-       mite_decode(mite_MCR_strings, value);
-       offset = MITE_MAR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[MAR] at 0x%08x =0x%08x\n", offset, value);
-       offset = MITE_DCR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[DCR] at 0x%08x =0x%08x\n", offset, value);
-       mite_decode(mite_DCR_strings, value);
-       offset = MITE_DAR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[DAR] at 0x%08x =0x%08x\n", offset, value);
-       offset = MITE_LKCR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[LKCR] at 0x%08x =0x%08x\n", offset, value);
-       mite_decode(mite_LKCR_strings, value);
-       offset = MITE_LKAR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[LKAR] at 0x%08x =0x%08x\n", offset, value);
-       offset = MITE_CHSR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[CHSR] at 0x%08x =0x%08x\n", offset, value);
-       mite_decode(mite_CHSR_strings, value);
-       offset = MITE_FCR(channel);
-       value = readl(mite_io_addr + offset);
-       pr_debug("mite status[FCR] at 0x%08x =0x%08x\n", offset, value);
-}
-EXPORT_SYMBOL_GPL(mite_dump_regs);
-#endif
-
 static int __init mite_module_init(void)
 {
        return 0;
index 8423b8bf33845fe2489583385287ea8bbbb8d689..bcf2f972376e7857f2373c2d5fa7cc38d31a7d95 100644 (file)
 #include <linux/slab.h>
 #include "../comedidev.h"
 
-/*  #define DEBUG_MITE */
 #define PCIMIO_COMPAT
 
-#ifdef DEBUG_MITE
-#define MDPRINTK(format, args...)      pr_debug(format , ## args)
-#else
-#define MDPRINTK(format, args...)      do { } while (0)
-#endif
-
 #define MAX_MITE_DMA_CHANNELS 8
 
 struct mite_dma_descriptor {
@@ -129,11 +122,6 @@ void mite_prep_dma(struct mite_channel *mite_chan,
 int mite_buf_change(struct mite_dma_descriptor_ring *ring,
                    struct comedi_async *async);
 
-#ifdef DEBUG_MITE
-void mite_print_chsr(unsigned int chsr);
-void mite_dump_regs(struct mite_channel *mite_chan);
-#endif
-
 static inline int CHAN_OFFSET(int channel)
 {
        return 0x500 + 0x100 * channel;
index 853f62b2b1a982c70ba229f94b4697c9d1e869d3..aae708bfbe15333d7bfd030c17e3ddccfd3ef439 100644 (file)
@@ -43,9 +43,6 @@ except maybe the 6514.
 
  */
 
-#define DEBUG 1
-#define DEBUG_FLAGS
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
index 63c847932eb88983fbe082c969cfb94787293e95..cc69ddef0a67c6415718c66999f49701fd7d0097 100644 (file)
@@ -74,9 +74,6 @@ TRIG_WAKE_EOS
 #define A2150_SIZE           28
 #define A2150_DMA_BUFFER_SIZE  0xff00  /*  size in bytes of dma buffer */
 
-/* #define A2150_DEBUG     enable debugging code */
-#undef A2150_DEBUG             /*  disable debugging code */
-
 /* Registers and bits */
 #define CONFIG_REG             0x0
 #define   CHANNEL_BITS(x)              ((x) & 0x7)
@@ -167,19 +164,6 @@ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
 static int a2150_set_chanlist(struct comedi_device *dev,
                              unsigned int start_channel,
                              unsigned int num_channels);
-#ifdef A2150_DEBUG
-
-static void ni_dump_regs(struct comedi_device *dev)
-{
-       struct a2150_private *devpriv = dev->private;
-
-       printk("config bits 0x%x\n", devpriv->config_bits);
-       printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
-       printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
-}
-
-#endif
-
 /* interrupt service routine */
 static irqreturn_t a2150_interrupt(int irq, void *d)
 {
@@ -506,9 +490,6 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        /*  start acquisition for soft trigger */
        if (cmd->start_src == TRIG_NOW)
                outw(0, dev->iobase + FIFO_START_REG);
-#ifdef A2150_DEBUG
-       ni_dump_regs(dev);
-#endif
 
        return 0;
 }
@@ -573,13 +554,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
                        comedi_error(dev, "timeout");
                        return -ETIME;
                }
-#ifdef A2150_DEBUG
-               ni_dump_regs(dev);
-#endif
                data[n] = inw(dev->iobase + FIFO_DATA_REG);
-#ifdef A2150_DEBUG
-               printk(" data is %i\n", data[n]);
-#endif
                data[n] ^= 0x8000;
        }
 
index 856c73d8b7cd3a6accb460421e236f001a28e032..d03935257b974e4fe480f10f13e5f3dd59a0e600 100644 (file)
@@ -98,8 +98,6 @@ are not supported.
 #include "ni_stc.h"
 #include "8255.h"
 
-#undef DEBUG
-
 #define ATMIO 1
 #undef PCIMIO
 
@@ -437,19 +435,6 @@ static int ni_atmio_attach(struct comedi_device *dev,
        if (ret)
                return ret;
 
-#ifdef DEBUG
-       /* board existence sanity check */
-       {
-               int i;
-
-               printk(" board fingerprint:");
-               for (i = 0; i < 16; i += 2) {
-                       printk(" %04x %02x", inw(dev->iobase + i),
-                              inb(dev->iobase + i + 1));
-               }
-       }
-#endif
-
        /* get board type */
 
        board = ni_getboardtype(dev);
index 5113397bfecf4c864a48aeca9ccd7cd7f718b60c..65db6add0a6852439911691f8192367775d0c127 100644 (file)
                fully tested as yet. Terry Barnaby, BEAM Ltd.
 */
 
-/* #define DEBUG_INTERRUPT */
-/* #define DEBUG_STATUS_A */
-/* #define DEBUG_STATUS_B */
-
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include "mite.h"
 #include "comedi_fc.h"
 
-#ifndef MDPRINTK
-#define MDPRINTK(format, args...)
-#endif
-
 /* A timeout count */
 #define NI_TIMEOUT 1000
 static const unsigned old_RTSI_clock_channel = 7;
@@ -266,17 +258,6 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
 static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s);
 static int ni_read_eeprom(struct comedi_device *dev, int addr);
 
-#ifdef DEBUG_STATUS_A
-static void ni_mio_print_status_a(int status);
-#else
-#define ni_mio_print_status_a(a)
-#endif
-#ifdef DEBUG_STATUS_B
-static void ni_mio_print_status_b(int status);
-#else
-#define ni_mio_print_status_b(a)
-#endif
-
 static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s);
 #ifndef PCIDMA
 static void ni_handle_fifo_half_full(struct comedi_device *dev);
@@ -322,10 +303,6 @@ static int cs5529_do_conversion(struct comedi_device *dev,
 static int cs5529_ai_insn_read(struct comedi_device *dev,
                               struct comedi_subdevice *s,
                               struct comedi_insn *insn, unsigned int *data);
-#ifdef NI_CS5529_DEBUG
-static unsigned int cs5529_config_read(struct comedi_device *dev,
-                                      unsigned int reg_select_bits);
-#endif
 static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
                                unsigned int reg_select_bits);
 
@@ -1050,12 +1027,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
        if (s->type == COMEDI_SUBD_UNUSED)
                return;
 
-#ifdef DEBUG_INTERRUPT
-       printk
-           ("ni_mio_common: interrupt: a_status=%04x ai_mite_status=%08x\n",
-            status, ai_mite_status);
-       ni_mio_print_status_a(status);
-#endif
 #ifdef PCIDMA
        if (ai_mite_status & CHSR_LINKC) {
                ni_sync_ai_dma(dev);
@@ -1067,7 +1038,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
                printk
                    ("unknown mite interrupt, ack! (ai_mite_status=%08x)\n",
                     ai_mite_status);
-               /* mite_print_chsr(ai_mite_status); */
                s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
                /* disable_irq(dev->irq); */
        }
@@ -1092,7 +1062,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
                              AI_SC_TC_Error_St)) {
                        printk("ni_mio_common: ai error a_status=%04x\n",
                               status);
-                       ni_mio_print_status_a(status);
 
                        shutdown_ai_command(dev);
 
@@ -1105,9 +1074,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
                        return;
                }
                if (status & AI_SC_TC_St) {
-#ifdef DEBUG_INTERRUPT
-                       printk("ni_mio_common: SC_TC interrupt\n");
-#endif
                        if (!devpriv->ai_continuous) {
                                shutdown_ai_command(dev);
                        }
@@ -1134,15 +1100,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
        }
 
        ni_event(dev, s);
-
-#ifdef DEBUG_INTERRUPT
-       status = devpriv->stc_readw(dev, AI_Status_1_Register);
-       if (status & Interrupt_A_St) {
-               printk
-                   ("handle_a_interrupt: didn't clear interrupt? status=0x%x\n",
-                    status);
-       }
-#endif
 }
 
 static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
@@ -1182,12 +1139,6 @@ static void handle_b_interrupt(struct comedi_device *dev,
        struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
        /* unsigned short ack=0; */
 
-#ifdef DEBUG_INTERRUPT
-       printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n",
-              b_status, ao_mite_status);
-       ni_mio_print_status_b(b_status);
-#endif
-
 #ifdef PCIDMA
        /* Currently, mite.c requires us to handle LINKC */
        if (ao_mite_status & CHSR_LINKC) {
@@ -1200,7 +1151,6 @@ static void handle_b_interrupt(struct comedi_device *dev,
                printk
                    ("unknown mite interrupt, ack! (ao_mite_status=%08x)\n",
                     ao_mite_status);
-               /* mite_print_chsr(ao_mite_status); */
                s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
        }
 #endif
@@ -1214,12 +1164,9 @@ static void handle_b_interrupt(struct comedi_device *dev,
                s->async->events |= COMEDI_CB_OVERFLOW;
        }
 
-       if (b_status & AO_BC_TC_St) {
-               MDPRINTK
-                   ("ni_mio_common: AO BC_TC status=0x%04x status2=0x%04x\n",
-                    b_status, devpriv->stc_readw(dev, AO_Status_2_Register));
+       if (b_status & AO_BC_TC_St)
                s->async->events |= COMEDI_CB_EOA;
-       }
+
 #ifndef PCIDMA
        if (b_status & AO_FIFO_Request_St) {
                int ret;
@@ -1238,50 +1185,6 @@ static void handle_b_interrupt(struct comedi_device *dev,
        ni_event(dev, s);
 }
 
-#ifdef DEBUG_STATUS_A
-static const char *const status_a_strings[] = {
-       "passthru0", "fifo", "G0_gate", "G0_TC",
-       "stop", "start", "sc_tc", "start1",
-       "start2", "sc_tc_error", "overflow", "overrun",
-       "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_a"
-};
-
-static void ni_mio_print_status_a(int status)
-{
-       int i;
-
-       printk("A status:");
-       for (i = 15; i >= 0; i--) {
-               if (status & (1 << i)) {
-                       printk(" %s", status_a_strings[i]);
-               }
-       }
-       printk("\n");
-}
-#endif
-
-#ifdef DEBUG_STATUS_B
-static const char *const status_b_strings[] = {
-       "passthru1", "fifo", "G1_gate", "G1_TC",
-       "UI2_TC", "UPDATE", "UC_TC", "BC_TC",
-       "start1", "overrun", "start", "bc_tc_error",
-       "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_b"
-};
-
-static void ni_mio_print_status_b(int status)
-{
-       int i;
-
-       printk("B status:");
-       for (i = 15; i >= 0; i--) {
-               if (status & (1 << i)) {
-                       printk(" %s", status_b_strings[i]);
-               }
-       }
-       printk("\n");
-}
-#endif
-
 #ifndef PCIDMA
 
 static void ni_ao_fifo_load(struct comedi_device *dev,
@@ -2392,7 +2295,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        unsigned int stop_count;
        int interrupt_a_enable = 0;
 
-       MDPRINTK("ni_ai_cmd\n");
        if (dev->irq == 0) {
                comedi_error(dev, "cannot run command without an irq");
                return -EIO;
@@ -2630,15 +2532,11 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
                ni_set_bits(dev, Interrupt_A_Enable_Register,
                            interrupt_a_enable, 1);
-
-               MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",
-                        devpriv->int_a_enable_reg);
        } else {
                /* interrupt on nothing */
                ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0);
 
                /* XXX start polling if necessary */
-               MDPRINTK("interrupting on nothing\n");
        }
 
        /* end configuration */
@@ -2664,7 +2562,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                if (retval)
                        return retval;
        }
-       /* mite_dump_regs(devpriv->mite); */
 #endif
 
        switch (cmd->start_src) {
@@ -2682,8 +2579,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                break;
        }
 
-       MDPRINTK("exit ni_ai_cmd\n");
-
        return 0;
 }
 
@@ -3819,10 +3714,6 @@ static int ni_serial_insn_config(struct comedi_device *dev,
 
        switch (data[0]) {
        case INSN_CONFIG_SERIAL_CLOCK:
-
-#ifdef DEBUG_DIO
-               printk("SPI serial clock Config cd\n", data[1]);
-#endif
                devpriv->serial_hw_mode = 1;
                devpriv->dio_control |= DIO_HW_Serial_Enable;
 
@@ -3911,10 +3802,6 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev,
        unsigned int status1;
        int err = 0, count = 20;
 
-#ifdef DEBUG_DIO
-       printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out);
-#endif
-
        devpriv->dio_output &= ~DIO_Serial_Data_Mask;
        devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
        devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
@@ -3948,12 +3835,8 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev,
           DIO_Serial_IO_In_Progress_St goes high one bit too early. */
        udelay((devpriv->serial_interval_ns + 999) / 1000);
 
-       if (data_in != NULL) {
+       if (data_in != NULL)
                *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register);
-#ifdef DEBUG_DIO
-               printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in);
-#endif
-       }
 
 Error:
        devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
@@ -3969,10 +3852,6 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev,
        struct ni_private *devpriv = dev->private;
        unsigned char mask, input = 0;
 
-#ifdef DEBUG_DIO
-       printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out);
-#endif
-
        /* Wait for one bit before transfer */
        udelay((devpriv->serial_interval_ns + 999) / 1000);
 
@@ -4009,9 +3888,7 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev,
                        input |= mask;
                }
        }
-#ifdef DEBUG_DIO
-       printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input);
-#endif
+
        if (data_in)
                *data_in = input;
 
@@ -5873,25 +5750,6 @@ static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
                comedi_error(dev, "time or signal in cs5529_config_write()");
 }
 
-#ifdef NI_CS5529_DEBUG
-/* read from cs5529 register */
-static unsigned int cs5529_config_read(struct comedi_device *dev,
-                                      unsigned int reg_select_bits)
-{
-       unsigned int value;
-
-       reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
-       cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits);
-       if (cs5529_wait_for_idle(dev))
-               comedi_error(dev, "timeout or signal in cs5529_config_read()");
-       value = (ni_ao_win_inw(dev,
-                              CAL_ADC_Config_Data_High_Word_67xx) << 16) &
-           0xff0000;
-       value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff;
-       return value;
-}
-#endif
-
 static int cs5529_do_conversion(struct comedi_device *dev, unsigned short *data)
 {
        int retval;
@@ -5967,13 +5825,6 @@ static int init_cs5529(struct comedi_device *dev)
                            CSCMD_CONFIG_REGISTER);
        if (cs5529_wait_for_idle(dev))
                comedi_error(dev, "timeout or signal in init_cs5529()\n");
-#endif
-#ifdef NI_CS5529_DEBUG
-       printk("config: 0x%x\n", cs5529_config_read(dev,
-                                                   CSCMD_CONFIG_REGISTER));
-       printk("gain: 0x%x\n", cs5529_config_read(dev, CSCMD_GAIN_REGISTER));
-       printk("offset: 0x%x\n", cs5529_config_read(dev,
-                                                   CSCMD_OFFSET_REGISTER));
 #endif
        return 0;
 }
index 229a273f2016831ef43033d9fb89d8517e86ba4c..de421486b7585b3e562190fd501b824d8f877fe3 100644 (file)
@@ -47,8 +47,6 @@ See the notes in the ni_atmio.o driver.
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 
-#undef DEBUG
-
 #define ATMIO 1
 #undef PCIMIO
 
index e3a8fa96d9b398fa13c8e8f564967393d20e1d5c..c7bc23044568e101a9ea8608611b1f47231808a4 100644 (file)
@@ -47,8 +47,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
 */
 
 #define USE_DMA
-/* #define DEBUG 1 */
-/* #define DEBUG_FLAGS */
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -60,13 +58,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
 #include "comedi_fc.h"
 #include "mite.h"
 
-#undef DPRINTK
-#ifdef DEBUG
-#define DPRINTK(format, args...) pr_debug(format, ## args)
-#else
-#define DPRINTK(format, args...) do { } while (0)
-#endif
-
 #define PCI_DIO_SIZE 4096
 #define PCI_MITE_SIZE 4096
 
@@ -319,14 +310,6 @@ static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
 static int setup_mite_dma(struct comedi_device *dev,
                          struct comedi_subdevice *s);
 
-#ifdef DEBUG_FLAGS
-static void ni_pcidio_print_flags(unsigned int flags);
-static void ni_pcidio_print_status(unsigned int status);
-#else
-#define ni_pcidio_print_flags(x)
-#define ni_pcidio_print_status(x)
-#endif
-
 static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
 {
        struct nidio96_private *devpriv = dev->private;
@@ -427,19 +410,10 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
                       Interrupt_And_Window_Status);
        flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
 
-       DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
-               status, flags);
-       ni_pcidio_print_flags(flags);
-       ni_pcidio_print_status(status);
-
        spin_lock(&devpriv->mite_channel_lock);
        if (devpriv->di_mite_chan)
                m_status = mite_get_status(devpriv->di_mite_chan);
-#ifdef MITE_DEBUG
-       mite_print_chsr(m_status);
-#endif
 
-       /* mite_dump_regs(mite); */
        if (m_status & CHSR_INT) {
                if (m_status & CHSR_LINKC) {
                        writel(CHOR_CLRLC,
@@ -450,7 +424,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
                }
                if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
                                 CHSR_DRQ1 | CHSR_MRDY)) {
-                       DPRINTK("unknown mite interrupt, disabling IRQ\n");
+                       dev_dbg(dev->class_dev,
+                               "unknown mite interrupt, disabling IRQ\n");
                        async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
                        disable_irq(dev->irq);
                }
@@ -460,7 +435,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
        while (status & DataLeft) {
                work++;
                if (work > 20) {
-                       DPRINTK("too much work in interrupt\n");
+                       dev_dbg(dev->class_dev, "too much work in interrupt\n");
                        writeb(0x00,
                               devpriv->mite->daq_io_addr +
                               Master_DMA_And_Interrupt_Control);
@@ -470,11 +445,11 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
                flags &= IntEn;
 
                if (flags & TransferReady) {
-                       /* DPRINTK("TransferReady\n"); */
                        while (flags & TransferReady) {
                                work++;
                                if (work > 100) {
-                                       DPRINTK("too much work in interrupt\n");
+                                       dev_dbg(dev->class_dev,
+                                               "too much work in interrupt\n");
                                        writeb(0x00,
                                               devpriv->mite->daq_io_addr +
                                               Master_DMA_And_Interrupt_Control
@@ -488,21 +463,13 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
                                data2 = (auxdata & 0xffff0000) >> 16;
                                comedi_buf_put(async, data1);
                                comedi_buf_put(async, data2);
-                               /* DPRINTK("read:%d, %d\n",data1,data2); */
                                flags = readb(devpriv->mite->daq_io_addr +
                                              Group_1_Flags);
                        }
-                       /* DPRINTK("buf_int_count: %d\n",
-                               async->buf_int_count); */
-                       /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",
-                               IntEn,flags,status); */
-                       /* ni_pcidio_print_flags(flags); */
-                       /* ni_pcidio_print_status(status); */
                        async->events |= COMEDI_CB_BLOCK;
                }
 
                if (flags & CountExpired) {
-                       DPRINTK("CountExpired\n");
                        writeb(ClearExpired,
                               devpriv->mite->daq_io_addr +
                               Group_1_Second_Clear);
@@ -511,41 +478,26 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
                        writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
                        break;
                } else if (flags & Waited) {
-                       DPRINTK("Waited\n");
                        writeb(ClearWaited,
                               devpriv->mite->daq_io_addr +
                               Group_1_First_Clear);
                        async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
                        break;
                } else if (flags & PrimaryTC) {
-                       DPRINTK("PrimaryTC\n");
                        writeb(ClearPrimaryTC,
                               devpriv->mite->daq_io_addr +
                               Group_1_First_Clear);
                        async->events |= COMEDI_CB_EOA;
                } else if (flags & SecondaryTC) {
-                       DPRINTK("SecondaryTC\n");
                        writeb(ClearSecondaryTC,
                               devpriv->mite->daq_io_addr +
                               Group_1_First_Clear);
                        async->events |= COMEDI_CB_EOA;
                }
-#if 0
-               else {
-                       DPRINTK("ni_pcidio: unknown interrupt\n");
-                       async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
-                       writeb(0x00,
-                              devpriv->mite->daq_io_addr +
-                              Master_DMA_And_Interrupt_Control);
-               }
-#endif
+
                flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
                status = readb(devpriv->mite->daq_io_addr +
                               Interrupt_And_Window_Status);
-               /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,"
-                       "status=0x%02x\n", IntEn, flags, status); */
-               /* ni_pcidio_print_flags(flags); */
-               /* ni_pcidio_print_status(status); */
        }
 
 out:
@@ -562,82 +514,6 @@ out:
        return IRQ_HANDLED;
 }
 
-#ifdef DEBUG_FLAGS
-static const char *bit_set_string(unsigned int bits, unsigned int bit,
-                                 const char *const strings[])
-{
-       return (bits & (1U << bit)) ? strings[bit] : "";
-}
-
-static const char *const flags_strings[] = {
-       " TransferReady", " CountExpired", " 2", " 3",
-       " 4", " Waited", " PrimaryTC", " SecondaryTC",
-};
-
-
-static void ni_pcidio_print_flags(unsigned int flags)
-{
-       pr_debug("group_1_flags:%s%s%s%s%s%s%s%s\n",
-                bit_set_string(flags, 7, flags_strings),
-                bit_set_string(flags, 6, flags_strings),
-                bit_set_string(flags, 5, flags_strings),
-                bit_set_string(flags, 4, flags_strings),
-                bit_set_string(flags, 3, flags_strings),
-                bit_set_string(flags, 2, flags_strings),
-                bit_set_string(flags, 1, flags_strings),
-                bit_set_string(flags, 0, flags_strings));
-}
-
-static const char *const status_strings[] = {
-       " DataLeft1", " Reserved1", " Req1", " StopTrig1",
-       " DataLeft2", " Reserved2", " Req2", " StopTrig2",
-};
-
-static void ni_pcidio_print_status(unsigned int flags)
-{
-       pr_debug("group_status:%s%s%s%s%s%s%s%s\n",
-                bit_set_string(flags, 7, status_strings),
-                bit_set_string(flags, 6, status_strings),
-                bit_set_string(flags, 5, status_strings),
-                bit_set_string(flags, 4, status_strings),
-                bit_set_string(flags, 3, status_strings),
-                bit_set_string(flags, 2, status_strings),
-                bit_set_string(flags, 1, status_strings),
-                bit_set_string(flags, 0, status_strings));
-}
-#endif
-
-#ifdef unused
-static void debug_int(struct comedi_device *dev)
-{
-       struct nidio96_private *devpriv = dev->private;
-       int a, b;
-       static int n_int;
-       struct timeval tv;
-
-       do_gettimeofday(&tv);
-       a = readb(devpriv->mite->daq_io_addr + Group_Status);
-       b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
-
-       if (n_int < 10) {
-               DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
-                       (int)tv.tv_usec);
-       }
-
-       while (b & 1) {
-               writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
-               b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
-       }
-
-       b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
-
-       if (n_int < 10) {
-               DPRINTK("new status 0x%02x\n", b);
-               n_int++;
-       }
-}
-#endif
-
 static int ni_pcidio_insn_config(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
                                 struct comedi_insn *insn,
@@ -883,7 +759,6 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                s->async->inttrig = ni_pcidio_inttrig;
        }
 
-       DPRINTK("ni_pcidio: command started\n");
        return 0;
 }
 
index 536be83af54949fdc510e63c10c80284905e1fbb..aa002b275458b22676a7d26ca73fbf16b592835f 100644 (file)
@@ -116,8 +116,6 @@ Bugs:
 #include "ni_stc.h"
 #include "mite.h"
 
-/* #define PCI_DEBUG */
-
 #define PCIDMA
 
 #define PCIMIO 1
index d041b714db29732f91e8739db8dcf1122f55d55b..2baaf1db6fbf34e6a9d8694d560b6a047871bf81 100644 (file)
@@ -173,11 +173,11 @@ static int pcl730_do_insn_bits(struct comedi_device *dev,
        if (mask) {
                if (mask & 0x00ff)
                        outb(s->state & 0xff, dev->iobase + reg);
-               if ((mask & 0xff00) & (s->n_chan > 8))
+               if ((mask & 0xff00) && (s->n_chan > 8))
                        outb((s->state >> 8) & 0xff, dev->iobase + reg + 1);
-               if ((mask & 0xff0000) & (s->n_chan > 16))
+               if ((mask & 0xff0000) && (s->n_chan > 16))
                        outb((s->state >> 16) & 0xff, dev->iobase + reg + 2);
-               if ((mask & 0xff000000) & (s->n_chan > 24))
+               if ((mask & 0xff000000) && (s->n_chan > 24))
                        outb((s->state >> 24) & 0xff, dev->iobase + reg + 3);
        }
 
index ab9d2bd26a207b11ff463f0952cf66f8d95cd456..7b92aa50aa7fc98e5fcd4cddf26e268582b3c581 100644 (file)
@@ -44,8 +44,6 @@ Configuration Options:
 #include "comedi_fc.h"
 #include "8253.h"
 
-#define DEBUG(x) x
-
 /* boards constants */
 /* IO space len */
 #define PCLx1x_RANGE 16
@@ -176,7 +174,6 @@ static int pcl816_ai_insn_read(struct comedi_device *dev,
        int n;
        int timeout;
 
-       DPRINTK("mode 0 analog input\n");
        /*  software trigger, DMA and INT off */
        outb(0, dev->iobase + PCL816_CONTROL);
        /*  clear INT (conversion end) flag */
@@ -372,8 +369,6 @@ static irqreturn_t interrupt_pcl816(int irq, void *d)
        struct comedi_device *dev = d;
        struct pcl816_private *devpriv = dev->private;
 
-       DPRINTK("<I>");
-
        if (!dev->attached) {
                comedi_error(dev, "premature interrupt");
                return IRQ_HANDLED;
@@ -403,22 +398,6 @@ static irqreturn_t interrupt_pcl816(int irq, void *d)
        return IRQ_NONE;
 }
 
-/*
-==============================================================================
-   COMMAND MODE
-*/
-static void pcl816_cmdtest_out(int e, struct comedi_cmd *cmd)
-{
-       printk(KERN_INFO "pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
-              cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
-       printk(KERN_INFO "pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
-              cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
-       printk(KERN_INFO "pcl816 e=%d stopsrc=%x scanend=%x\n", e,
-              cmd->stop_src, cmd->scan_end_src);
-       printk(KERN_INFO "pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",
-              e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
-}
-
 /*
 ==============================================================================
 */
@@ -429,10 +408,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
        int err = 0;
        int tmp, divisor1 = 0, divisor2 = 0;
 
-       DEBUG(printk(KERN_INFO "pcl816 pcl812_ai_cmdtest\n");
-             pcl816_cmdtest_out(-1, cmd);
-            );
-
        /* Step 1 : check if triggers are trivially valid */
 
        err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
@@ -630,7 +605,6 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                break;
        }
 
-       DPRINTK("pcl816 END: pcl812_ai_cmd()\n");
        return 0;
 }
 
@@ -685,8 +659,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
 {
        struct pcl816_private *devpriv = dev->private;
 
-/* DEBUG(printk("pcl816_ai_cancel()\n");) */
-
        if (devpriv->irq_blocked > 0) {
                switch (devpriv->int816_mode) {
                case INT_TYPE_AI1_DMA:
@@ -719,9 +691,7 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
                        break;
                }
        }
-
-       DEBUG(printk("comedi: pcl816_ai_cancel() successful\n");)
-           return 0;
+       return 0;
 }
 
 /*
@@ -788,8 +758,8 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
        udelay(1);
 
        if (mode == 1) {
-               DPRINTK("mode %d, divisor1 %d, divisor2 %d\n", mode, divisor1,
-                       divisor2);
+               dev_dbg(dev->class_dev, "mode %d, divisor1 %d, divisor2 %d\n",
+                       mode, divisor1, divisor2);
                outb(divisor2 & 0xff, dev->iobase + PCL816_CTR2);
                outb((divisor2 >> 8) & 0xff, dev->iobase + PCL816_CTR2);
                outb(divisor1 & 0xff, dev->iobase + PCL816_CTR1);
@@ -823,11 +793,6 @@ check_channel_list(struct comedi_device *dev,
                /*  first channel is every time ok */
                chansegment[0] = chanlist[0];
                for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
-                       /*  build part of chanlist */
-                       DEBUG(printk(KERN_INFO "%d. %d %d\n", i,
-                                    CR_CHAN(chanlist[i]),
-                                    CR_RANGE(chanlist[i]));)
-
                        /*  we detect loop, this must by finish */
                            if (chanlist[0] == chanlist[i])
                                break;
@@ -849,11 +814,6 @@ check_channel_list(struct comedi_device *dev,
 
                /*  check whole chanlist */
                for (i = 0, segpos = 0; i < chanlen; i++) {
-                       DEBUG(printk("%d %d=%d %d\n",
-                                    CR_CHAN(chansegment[i % seglen]),
-                                    CR_RANGE(chansegment[i % seglen]),
-                                    CR_CHAN(chanlist[i]),
-                                    CR_RANGE(chanlist[i]));)
                            if (chanlist[i] != chansegment[i % seglen]) {
                                printk(KERN_WARNING
                                       "comedi%d: pcl816: bad channel or range"
index 9e4d7e8605097bff47e0dedb3e605b90b170da06..be9cb8df877d14d42ada4f218efe3143bfdf8365 100644 (file)
@@ -753,7 +753,7 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev,
        } else {
                devpriv->ai_mode = INT_TYPE_AI3_DMA;
                outb(0x86 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);     /* Ext trig+IRQ+DMA */
-       };
+       }
 }
 
 /*
@@ -1257,8 +1257,6 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                                            (", unable to allocate IRQ %u, DISABLING IT",
                                             irq);
                                        irq = 0;        /* Can't use IRQ */
-                               } else {
-                                       printk(KERN_DEBUG "irq=%u", irq);
                                }
                        }
                }
index 14cee3ac92c52f67fadd05b4b3cec4d92efaec7a..063496d6c00ef003cc83f9149ece2d9461f8446b 100644 (file)
@@ -250,11 +250,6 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev,
        /* The insn data is a mask in data[0] and the new data
         * in data[1], each channel cooresponding to a bit. */
 
-#ifdef DAMMIT_ITS_BROKEN
-       /* DEBUG */
-       printk(KERN_DEBUG "write mask: %08x  data: %08x\n", data[0], data[1]);
-#endif
-
        s->state = 0;
 
        for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) {
@@ -271,14 +266,6 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev,
 
                byte = inb(ioaddr);     /* read all 8-bits for this port */
 
-#ifdef DAMMIT_ITS_BROKEN
-               /* DEBUG */
-               printk
-                   (KERN_DEBUG "byte %d wmb %02x db %02x offset %02d io %04x,"
-                    " data_in %02x ", byte_no, (unsigned)write_mask_byte,
-                    (unsigned)data_byte, offset, ioaddr, (unsigned)byte);
-#endif
-
                if (write_mask_byte) {
                        /*
                         * this byte has some write_bits
@@ -291,10 +278,6 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev,
                        /* Write out the new digital output state */
                        outb(byte, ioaddr);
                }
-#ifdef DAMMIT_ITS_BROKEN
-               /* DEBUG */
-               printk(KERN_DEBUG "data_out_byte %02x\n", (unsigned)byte);
-#endif
                /* save the digital input lines for this byte.. */
                s->state |= ((unsigned int)byte) << offset;
        }
@@ -302,11 +285,6 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev,
        /* now return the DIO lines to data[1] - note they came inverted! */
        data[1] = ~s->state;
 
-#ifdef DAMMIT_ITS_BROKEN
-       /* DEBUG */
-       printk(KERN_DEBUG "s->state %08x data_out %08x\n", s->state, data[1]);
-#endif
-
        return insn->n;
 }
 
@@ -379,13 +357,6 @@ static void init_asics(struct comedi_device *dev)
                                outb(0, baseaddr + reg);
                }
 
-               /* DEBUG  set rising edge interrupts on port0 of both asics */
-               /*switch_page(dev, asic, PAGE_POL);
-                  outb(0xff, baseaddr + REG_POL0);
-                  switch_page(dev, asic, PAGE_ENAB);
-                  outb(0xff, baseaddr + REG_ENAB0); */
-               /* END DEBUG */
-
                /* switch back to default page 0 */
                switch_page(dev, asic, 0);
        }
@@ -505,9 +476,9 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
                                 * TODO here: dispatch io lines to subdevs
                                 * with commands..
                                 */
-                               printk
-                                   (KERN_DEBUG "got edge detect interrupt %d asic %d which_chans: %06x\n",
-                                    irq, asic, triggered);
+                               dev_dbg(dev->class_dev,
+                                       "got edge detect interrupt %d asic %d which_chans: %06x\n",
+                                       irq, asic, triggered);
                                for (i = 2; i < dev->n_subdevices; i++) {
                                        s = &dev->subdevices[i];
                                        /*
index 6815cfe2664e42e632114b3e87ca140b349008f3..b486099b543d56e61a14e94b3bc698c58cc04cb0 100644 (file)
@@ -494,7 +494,7 @@ static void s626_send_dac(struct comedi_device *dev, uint32_t val)
  * Private helper function: Write setpoint to an application DAC channel.
  */
 static void s626_set_dac(struct comedi_device *dev, uint16_t chan,
-                        unsigned short dacdata)
+                        int16_t dacdata)
 {
        struct s626_private *devpriv = dev->private;
        uint16_t signmask;
index 93eec2fc254c187a0dc9f7d6e0367c6cd5cfcf5d..adf7cb7086cc12a66bfc21d804f9dfcdb48da70e 100644 (file)
@@ -38,7 +38,6 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5),
 
 */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -91,12 +90,14 @@ static int __unioxx5_define_chan_offset(int chan_num)
 }
 
 #if 0                          /* not used? */
-static void __unioxx5_digital_config(struct unioxx5_subd_priv *usp, int mode)
+static void __unioxx5_digital_config(struct comedi_subdevice *s, int mode)
 {
+       struct unioxx5_subd_priv *usp = s->private;
+       struct device *csdev = s->device->class_dev;
        int i, mask;
 
        mask = (mode == ALL_2_OUTPUT) ? 0xFF : 0x00;
-       printk("COMEDI: mode = %d\n", mask);
+       dev_dbg(csdev, "mode = %d\n", mask);
 
        outb(1, usp->usp_iobase + 0);
 
@@ -135,15 +136,18 @@ static void __unioxx5_analog_config(struct unioxx5_subd_priv *usp, int channel)
        usp->usp_prev_cn_val[channel_offset - 1] = conf;
 }
 
-static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp,
+static int __unioxx5_digital_read(struct comedi_subdevice *s,
                                  unsigned int *data, int channel, int minor)
 {
+       struct unioxx5_subd_priv *usp = s->private;
+       struct device *csdev = s->device->class_dev;
        int channel_offset, mask = 1 << (channel & 0x07);
 
        channel_offset = __unioxx5_define_chan_offset(channel);
        if (channel_offset < 0) {
-               pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n",
-                      minor, channel);
+               dev_err(csdev,
+                       "undefined channel %d. channel range is 0 .. 23\n",
+                       channel);
                return 0;
        }
 
@@ -157,9 +161,11 @@ static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp,
        return 1;
 }
 
-static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp,
+static int __unioxx5_analog_read(struct comedi_subdevice *s,
                                 unsigned int *data, int channel, int minor)
 {
+       struct unioxx5_subd_priv *usp = s->private;
+       struct device *csdev = s->device->class_dev;
        int module_no, read_ch;
        char control;
 
@@ -168,8 +174,9 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp,
 
        /* defining if given module can work on input */
        if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) {
-               pr_err("comedi%d: module in position %d with id 0x%02x is for output only",
-                      minor, module_no, usp->usp_module_type[module_no]);
+               dev_err(csdev,
+                       "module in position %d with id 0x%02x is for output only",
+                       module_no, usp->usp_module_type[module_no]);
                return 0;
        }
 
@@ -185,7 +192,7 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp,
 
        /* if four bytes readding error occurs - return 0(false) */
        if ((control & Rx4CA_ERR_MASK)) {
-               printk("COMEDI: 4 bytes error\n");
+               dev_err(csdev, "4 bytes error\n");
                return 0;
        }
 
@@ -197,16 +204,19 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp,
        return 1;
 }
 
-static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp,
+static int __unioxx5_digital_write(struct comedi_subdevice *s,
                                   unsigned int *data, int channel, int minor)
 {
+       struct unioxx5_subd_priv *usp = s->private;
+       struct device *csdev = s->device->class_dev;
        int channel_offset, val;
        int mask = 1 << (channel & 0x07);
 
        channel_offset = __unioxx5_define_chan_offset(channel);
        if (channel_offset < 0) {
-               pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n",
-                      minor, channel);
+               dev_err(csdev,
+                       "undefined channel %d. channel range is 0 .. 23\n",
+                       channel);
                return 0;
        }
 
@@ -225,9 +235,11 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp,
        return 1;
 }
 
-static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp,
+static int __unioxx5_analog_write(struct comedi_subdevice *s,
                                  unsigned int *data, int channel, int minor)
 {
+       struct unioxx5_subd_priv *usp = s->private;
+       struct device *csdev = s->device->class_dev;
        int module, i;
 
        module = channel / 2;   /* definig module number(0 .. 11) */
@@ -235,8 +247,9 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp,
 
        /* defining if given module can work on output */
        if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) {
-               pr_err("comedi%d: module in position %d with id 0x%0x is for input only!\n",
-                      minor, module, usp->usp_module_type[module]);
+               dev_err(csdev,
+                       "module in position %d with id 0x%0x is for input only!\n",
+                       module, usp->usp_module_type[module]);
                return 0;
        }
 
@@ -273,10 +286,10 @@ static int unioxx5_subdev_read(struct comedi_device *dev,
        type = usp->usp_module_type[channel / 2];
 
        if (type == MODULE_DIGITAL) {
-               if (!__unioxx5_digital_read(usp, data, channel, dev->minor))
+               if (!__unioxx5_digital_read(subdev, data, channel, dev->minor))
                        return -1;
        } else {
-               if (!__unioxx5_analog_read(usp, data, channel, dev->minor))
+               if (!__unioxx5_analog_read(subdev, data, channel, dev->minor))
                        return -1;
        }
 
@@ -295,10 +308,10 @@ static int unioxx5_subdev_write(struct comedi_device *dev,
        type = usp->usp_module_type[channel / 2];
 
        if (type == MODULE_DIGITAL) {
-               if (!__unioxx5_digital_write(usp, data, channel, dev->minor))
+               if (!__unioxx5_digital_write(subdev, data, channel, dev->minor))
                        return -1;
        } else {
-               if (!__unioxx5_analog_write(usp, data, channel, dev->minor))
+               if (!__unioxx5_analog_write(subdev, data, channel, dev->minor))
                        return -1;
        }
 
@@ -318,16 +331,15 @@ static int unioxx5_insn_config(struct comedi_device *dev,
 
        if (type != MODULE_DIGITAL) {
                dev_err(dev->class_dev,
-                       "comedi%d: channel configuration accessible only for digital modules\n",
-                       dev->minor);
+                       "channel configuration accessible only for digital modules\n");
                return -1;
        }
 
        channel_offset = __unioxx5_define_chan_offset(channel);
        if (channel_offset < 0) {
                dev_err(dev->class_dev,
-                       "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
-                       dev->minor, channel);
+                       "undefined channel %d. channel range is 0 .. 23\n",
+                       channel);
                return -1;
        }
 
@@ -342,8 +354,7 @@ static int unioxx5_insn_config(struct comedi_device *dev,
                flags |= mask;
                break;
        default:
-               dev_err(dev->class_dev,
-                       "comedi%d: unknown flag\n", dev->minor);
+               dev_err(dev->class_dev, "unknown flag\n");
                return -1;
        }
 
@@ -435,9 +446,10 @@ static int unioxx5_attach(struct comedi_device *dev,
 
        dev->iobase = iobase;
        iobase += UNIOXX5_SUBDEV_BASE;
+       n_subd = 0;
 
-       /* defining number of subdevices and getting they types (it must be 'g01')  */
-       for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) {
+       /* getting number of subdevices with types 'g01' */
+       for (i = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) {
                id = inb(ba + 0xE);
                num = inb(ba + 0xF);
 
index 933b01a0f03d4274e4f82ced6240a79f78b2c742..0adf3cffddb07251f09d961eedc490206db88fb3 100644 (file)
@@ -465,7 +465,7 @@ static int vmk80xx_do_insn_bits(struct comedi_device *dev,
        unsigned char *rx_buf = devpriv->usb_rx_buf;
        unsigned char *tx_buf = devpriv->usb_tx_buf;
        int reg, cmd;
-       int ret;
+       int ret = 0;
 
        if (devpriv->model == VMK8061_MODEL) {
                reg = VMK8061_DO_REG;
index 18ee99bdde0841da3279e04bff9ddbafd6d2826a..3aff8ed08e2dec1114c9e503a0c32e477422ab0c 100644 (file)
@@ -1,3 +1,5 @@
+ccflags-$(CONFIG_COMEDI_DEBUG)         := -DDEBUG
+
 obj-$(CONFIG_COMEDI_KCOMEDILIB)        += kcomedilib.o
 
 kcomedilib-objs := kcomedilib_main.o
index cd60677a3ed2f2771120dc5d23597e82a6fd34f9..7dc5a18e69d42bd4bd8e9df3d2458d368f769753 100644 (file)
@@ -35,7 +35,7 @@ MODULE_LICENSE("GPL");
 
 struct comedi_device *comedi_open(const char *filename)
 {
-       struct comedi_device *dev;
+       struct comedi_device *dev, *retval = NULL;
        unsigned int minor;
 
        if (strncmp(filename, "/dev/comedi", 11) != 0)
@@ -46,24 +46,27 @@ struct comedi_device *comedi_open(const char *filename)
        if (minor >= COMEDI_NUM_BOARD_MINORS)
                return NULL;
 
-       dev = comedi_dev_from_minor(minor);
-
-       if (!dev || !dev->attached)
+       dev = comedi_dev_get_from_minor(minor);
+       if (!dev)
                return NULL;
 
-       if (!try_module_get(dev->driver->module))
-               return NULL;
+       down_read(&dev->attach_lock);
+       if (dev->attached)
+               retval = dev;
+       else
+               retval = NULL;
+       up_read(&dev->attach_lock);
+
+       if (retval == NULL)
+               comedi_dev_put(dev);
 
-       return dev;
+       return retval;
 }
 EXPORT_SYMBOL_GPL(comedi_open);
 
-int comedi_close(struct comedi_device *d)
+int comedi_close(struct comedi_device *dev)
 {
-       struct comedi_device *dev = (struct comedi_device *)d;
-
-       module_put(dev->driver->module);
-
+       comedi_dev_put(dev);
        return 0;
 }
 EXPORT_SYMBOL_GPL(comedi_close);
@@ -73,7 +76,14 @@ static int comedi_do_insn(struct comedi_device *dev,
                          unsigned int *data)
 {
        struct comedi_subdevice *s;
-       int ret = 0;
+       int ret;
+
+       mutex_lock(&dev->mutex);
+
+       if (!dev->attached) {
+               ret = -EINVAL;
+               goto error;
+       }
 
        /* a subdevice instruction */
        if (insn->subdev >= dev->n_subdevices) {
@@ -120,6 +130,7 @@ static int comedi_do_insn(struct comedi_device *dev,
        s->busy = NULL;
 error:
 
+       mutex_unlock(&dev->mutex);
        return ret;
 }
 
@@ -169,9 +180,6 @@ int comedi_dio_bitfield2(struct comedi_device *dev, unsigned int subdev,
        unsigned int shift;
        int ret;
 
-       if (subdev >= dev->n_subdevices)
-               return -EINVAL;
-
        base_channel = CR_CHAN(base_channel);
        n_chan = comedi_get_n_channels(dev, subdev);
        if (base_channel >= n_chan)
@@ -211,23 +219,33 @@ int comedi_find_subdevice_by_type(struct comedi_device *dev, int type,
                                  unsigned int subd)
 {
        struct comedi_subdevice *s;
-
-       if (subd > dev->n_subdevices)
-               return -ENODEV;
-
-       for (; subd < dev->n_subdevices; subd++) {
-               s = &dev->subdevices[subd];
-               if (s->type == type)
-                       return subd;
-       }
-       return -1;
+       int ret = -ENODEV;
+
+       down_read(&dev->attach_lock);
+       if (dev->attached)
+               for (; subd < dev->n_subdevices; subd++) {
+                       s = &dev->subdevices[subd];
+                       if (s->type == type) {
+                               ret = subd;
+                               break;
+                       }
+               }
+       up_read(&dev->attach_lock);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(comedi_find_subdevice_by_type);
 
 int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice)
 {
-       struct comedi_subdevice *s = &dev->subdevices[subdevice];
+       int n;
+
+       down_read(&dev->attach_lock);
+       if (!dev->attached || subdevice >= dev->n_subdevices)
+               n = 0;
+       else
+               n = dev->subdevices[subdevice].n_chan;
+       up_read(&dev->attach_lock);
 
-       return s->n_chan;
+       return n;
 }
 EXPORT_SYMBOL_GPL(comedi_get_n_channels);
index ade00035d3bb5863cb2fe5b1fd29581b2e0b8aa6..da6bc5855ebc5e08530515cfb8799dbaeb4deaa6 100644 (file)
@@ -41,16 +41,20 @@ static int comedi_read(struct seq_file *m, void *v)
                     "driver_name, board_name, n_subdevices");
 
        for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
-               struct comedi_device *dev = comedi_dev_from_minor(i);
+               struct comedi_device *dev = comedi_dev_get_from_minor(i);
+
                if (!dev)
                        continue;
 
+               down_read(&dev->attach_lock);
                if (dev->attached) {
                        devices_q = 1;
                        seq_printf(m, "%2d: %-20s %-20s %4d\n",
                                   i, dev->driver->driver_name,
                                   dev->board_name, dev->n_subdevices);
                }
+               up_read(&dev->attach_lock);
+               comedi_dev_put(dev);
        }
        if (!devices_q)
                seq_puts(m, "no devices\n");
index 8fde55495d34bf60e7a83d6f690802f86e79ef76..46b3da686384eac270221784c0ce3372b1a36d56 100644 (file)
@@ -83,8 +83,10 @@ int do_rangeinfo_ioctl(struct comedi_device *dev,
        }
 
        if (RANGE_LENGTH(it.range_type) != lr->length) {
-               DPRINTK("wrong length %d should be %d (0x%08x)\n",
-                       RANGE_LENGTH(it.range_type), lr->length, it.range_type);
+               dev_dbg(dev->class_dev,
+                       "wrong length %d should be %d (0x%08x)\n",
+                       RANGE_LENGTH(it.range_type),
+                       lr->length, it.range_type);
                return -EINVAL;
        }
 
@@ -123,7 +125,8 @@ static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec)
        default:
                break;
        }
-       DPRINTK("subdevice does not support aref %i", aref);
+       dev_dbg(s->device->class_dev, "subdevice does not support aref %i",
+               aref);
        return 1;
 }
 
index 07a2f24d0d47de4d2e4ea119bcc52e3a38a4b911..3972b52e1416aa4059b7107e4b73520ddb381ae9 100644 (file)
@@ -1059,7 +1059,7 @@ bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx)
 {
        if (!ctx) {
                BCMLOG_ERR("Invalid arg..\n");
-               return 0;
+               return false;
        }
 
        return crystalhd_hw_interrupt(ctx->adp, &ctx->hw_ctx);
index 46a0d92173e0979e471eae2e467acbec2b573781..c4c8c0f9c959992361a06185828b2718efc25f14 100644 (file)
@@ -28,9 +28,9 @@ extern int  cxt1e1_log_level;
 #define COMET_NUM_UNITS     5   /* Number of points per entry in table */
 
 /* forward references */
-static void SetPwrLevel(comet_t *comet);
-static void WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table);
-static void WrtXmtWaveformTbl(ci_t *ci, comet_t *comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]);
+static void SetPwrLevel(struct s_comet_reg *comet);
+static void WrtRcvEqualizerTbl(ci_t *ci, struct s_comet_reg *comet, u_int32_t *table);
+static void WrtXmtWaveformTbl(ci_t *ci, struct s_comet_reg *comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]);
 
 
 void       *TWV_table[12] = {
@@ -58,7 +58,7 @@ lbo_tbl_lkup(int t1, int lbo) {
        return lbo - 1;
 }
 
-void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
+void init_comet(void *ci, struct s_comet_reg *comet, u_int32_t port_mode, int clockmaster,
                u_int8_t moreParams)
 {
        u_int8_t isT1mode;
@@ -159,8 +159,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
     /* 60: t1 ALMI cfg */
     /* Configure Line Coding */
 
-       switch (port_mode)
-       {
+       switch (port_mode) {
        /* 1 - T1 B8ZS */
        case CFG_FRAME_SF:
                pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
@@ -286,8 +285,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
 
     /* 0x30: "BRIF cfg"; 0x20 is 'CMODE', 0x03 is (bit) rate */
     /* note "rate bits can only be set once after reset" */
-       if (clockmaster)
-               {
+       if (clockmaster) {
                /* CMODE == clockMode, 0=clock master (so all 3 others should be slave) */
                /* rate = 1.544 Mb/s */
                if (isT1mode)
@@ -302,16 +300,17 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
 
                /* Master Mode i.e.FPMODE=0 (@0x20) */
                pci_write_32((u_int32_t *) &comet->brif_fpcfg, 0x00);
-               if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL)
-                       {
+               if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL) {
                        if (cxt1e1_log_level >= LOG_SBEBUG12)
-                               pr_info(">> %s: clockmaster internal clock\n", __func__);
+                               pr_info(">> %s: clockmaster internal clock\n",
+                                       __func__);
                        /* internal oscillator */
                        pci_write_32((u_int32_t *) &comet->tx_time, 0x0d);
                } else {
                        /* external clock source */
                        if (cxt1e1_log_level >= LOG_SBEBUG12)
-                               pr_info(">> %s: clockmaster external clock\n", __func__);
+                               pr_info(">> %s: clockmaster external clock\n",
+                                       __func__);
                        /* loop timing(external) */
                        pci_write_32((u_int32_t *) &comet->tx_time, 0x09);
                }
@@ -399,7 +398,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
 ** Returns:     Nothing
 */
 static void
-WrtXmtWaveform(ci_t *ci, comet_t *comet, u_int32_t sample, u_int32_t unit, u_int8_t data)
+WrtXmtWaveform(ci_t *ci, struct s_comet_reg *comet, u_int32_t sample, u_int32_t unit, u_int8_t data)
 {
        u_int8_t    WaveformAddr;
 
@@ -417,19 +416,20 @@ WrtXmtWaveform(ci_t *ci, comet_t *comet, u_int32_t sample, u_int32_t unit, u_int
 ** Returns:     Nothing
 */
 static void
-WrtXmtWaveformTbl(ci_t *ci, comet_t *comet,
+WrtXmtWaveformTbl(ci_t *ci, struct s_comet_reg *comet,
                  u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS])
 {
        u_int32_t sample, unit;
 
-       for (sample = 0; sample < COMET_NUM_SAMPLES; sample++)
-               {
+       for (sample = 0; sample < COMET_NUM_SAMPLES; sample++) {
                for (unit = 0; unit < COMET_NUM_UNITS; unit++)
-                       WrtXmtWaveform(ci, comet, sample, unit, table[sample][unit]);
+                       WrtXmtWaveform(ci, comet, sample, unit,
+                                       table[sample][unit]);
                }
 
     /* Enable transmitter and set output amplitude */
-       pci_write_32((u_int32_t *) &comet->xlpg_cfg, table[COMET_NUM_SAMPLES][0]);
+       pci_write_32((u_int32_t *) &comet->xlpg_cfg,
+                       table[COMET_NUM_SAMPLES][0]);
 }
 
 
@@ -444,7 +444,7 @@ WrtXmtWaveformTbl(ci_t *ci, comet_t *comet,
 */
 
 static void
-WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table)
+WrtRcvEqualizerTbl(ci_t *ci, struct s_comet_reg *comet, u_int32_t *table)
 {
        u_int32_t   ramaddr;
        volatile u_int32_t value;
@@ -457,7 +457,8 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table)
                /* for write order preservation when Optimizing driver */
                pci_flush_write(ci);
                /* write the addr, initiate a read */
-               pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr);
+               pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr,
+                               (u_int8_t) ramaddr);
                /* for write order preservation when Optimizing driver */
                pci_flush_write(ci);
                /*
@@ -470,9 +471,12 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table)
        }
 
        value = *table++;
-       pci_write_32((u_int32_t *) &comet->rlps_idata3, (u_int8_t) (value >> 24));
-       pci_write_32((u_int32_t *) &comet->rlps_idata2, (u_int8_t) (value >> 16));
-       pci_write_32((u_int32_t *) &comet->rlps_idata1, (u_int8_t) (value >> 8));
+       pci_write_32((u_int32_t *) &comet->rlps_idata3,
+                       (u_int8_t) (value >> 24));
+       pci_write_32((u_int32_t *) &comet->rlps_idata2,
+                       (u_int8_t) (value >> 16));
+       pci_write_32((u_int32_t *) &comet->rlps_idata1,
+                       (u_int8_t) (value >> 8));
        pci_write_32((u_int32_t *) &comet->rlps_idata0, (u_int8_t) value);
         /* for write order preservation when Optimizing driver */
        pci_flush_write(ci);
@@ -484,7 +488,8 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table)
                /* for write order preservation when optimizing driver */
                pci_flush_write(ci);
                /* write the addr, initiate a read */
-               pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr);
+               pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr,
+                               (u_int8_t) ramaddr);
                 /* for write order preservation when optimizing driver */
                pci_flush_write(ci);
 
@@ -508,7 +513,7 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table)
 */
 
 static void
-SetPwrLevel(comet_t *comet)
+SetPwrLevel(struct s_comet_reg *comet)
 {
        volatile u_int32_t temp;
 
@@ -550,12 +555,11 @@ SetPwrLevel(comet_t *comet)
 */
 #if 0
 static void
-SetCometOps(comet_t *comet)
+SetCometOps(struct s_comet_reg *comet)
 {
        volatile u_int8_t rd_value;
 
-       if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2))
-       {
+       if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2)) {
                /* read the BRIF Configuration */
                rd_value = (u_int8_t) pci_read_32((u_int32_t *) &comet->brif_cfg);
                rd_value &= ~0x20;
index 03b9bb77a8097066c0018bce79f701f39e4bd66e..d5d286e47a4b4483037b97403a65ac6d6eb48145 100644 (file)
 
 #define VINT32  volatile u_int32_t
 
-struct s_comet_reg
-{
-    VINT32 gbl_cfg;      /* 00  Global Cfg */
-    VINT32 clkmon;       /* 01  Clk Monitor */
-    VINT32 rx_opt;       /* 02  RX Options */
-    VINT32 rx_line_cfg;  /* 03  RX Line Interface Cfg */
-    VINT32 tx_line_cfg;  /* 04  TX Line Interface Cfg */
-    VINT32 tx_frpass;    /* 05  TX Framing & Bypass Options */
-    VINT32 tx_time;      /* 06  TX Timing Options */
-    VINT32 intr_1;       /* 07  Intr Source #1 */
-    VINT32 intr_2;       /* 08  Intr Source #2 */
-    VINT32 intr_3;       /* 09  Intr Source #3 */
-    VINT32 mdiag;        /* 0A  Master Diagnostics */
-    VINT32 mtest;        /* 0B  Master Test */
-    VINT32 adiag;        /* 0C  Analog Diagnostics */
-    VINT32 rev_id;       /* 0D  Rev/Chip Id/Global PMON Update */
+struct s_comet_reg {
+       VINT32 gbl_cfg;      /* 00  Global Cfg */
+       VINT32 clkmon;       /* 01  Clk Monitor */
+       VINT32 rx_opt;       /* 02  RX Options */
+       VINT32 rx_line_cfg;  /* 03  RX Line Interface Cfg */
+       VINT32 tx_line_cfg;  /* 04  TX Line Interface Cfg */
+       VINT32 tx_frpass;    /* 05  TX Framing & Bypass Options */
+       VINT32 tx_time;      /* 06  TX Timing Options */
+       VINT32 intr_1;       /* 07  Intr Source #1 */
+       VINT32 intr_2;       /* 08  Intr Source #2 */
+       VINT32 intr_3;       /* 09  Intr Source #3 */
+       VINT32 mdiag;        /* 0A  Master Diagnostics */
+       VINT32 mtest;        /* 0B  Master Test */
+       VINT32 adiag;        /* 0C  Analog Diagnostics */
+       VINT32 rev_id;       /* 0D  Rev/Chip Id/Global PMON Update */
 #define pmon  rev_id
-    VINT32 reset;        /* 0E  Reset */
-    VINT32 prgd_phctl;   /* 0F  PRGD Positioning/Ctl & HDLC Ctl */
-    VINT32 cdrc_cfg;     /* 10  CDRC Cfg */
-    VINT32 cdrc_ien;     /* 11  CDRC Intr Enable */
-    VINT32 cdrc_ists;    /* 12  CDRC Intr Sts */
-    VINT32 cdrc_alos;    /* 13  CDRC Alternate Loss of Signal */
-
-    VINT32 rjat_ists;    /* 14  RJAT Intr Sts */
-    VINT32 rjat_n1clk;   /* 15  RJAT Reference Clk Divisor (N1) Ctl */
-    VINT32 rjat_n2clk;   /* 16  RJAT Output Clk Divisor (N2) Ctl */
-    VINT32 rjat_cfg;     /* 17  RJAT Cfg */
-
-    VINT32 tjat_ists;    /* 18  TJAT Intr Sts */
-    VINT32 tjat_n1clk;   /* 19  TJAT Reference Clk Divisor (N1) Ctl */
-    VINT32 tjat_n2clk;   /* 1A  TJAT Output Clk Divisor (N2) Ctl */
-    VINT32 tjat_cfg;     /* 1B  TJAT Cfg */
-
-    VINT32 rx_elst_cfg;      /* 1C  RX-ELST Cfg */
-    VINT32 rx_elst_ists;     /* 1D  RX-ELST Intr Sts */
-    VINT32 rx_elst_idle;     /* 1E  RX-ELST Idle Code */
-    VINT32 _rx_elst_res1f;   /* 1F     RX-ELST Reserved */
-
-    VINT32 tx_elst_cfg;      /* 20  TX-ELST Cfg */
-    VINT32 tx_elst_ists;     /* 21  TX-ELST Intr Sts */
-    VINT32 _tx_elst_res22;   /* 22     TX-ELST Reserved */
-    VINT32 _tx_elst_res23;   /* 23     TX-ELST Reserved */
-    VINT32 __res24;          /* 24     Reserved */
-    VINT32 __res25;          /* 25     Reserved */
-    VINT32 __res26;          /* 26     Reserved */
-    VINT32 __res27;          /* 27     Reserved */
-
-    VINT32 rxce1_ctl;        /* 28  RXCE RX Data Link 1 Ctl */
-    VINT32 rxce1_bits;       /* 29  RXCE RX Data Link 1 Bit Select */
-    VINT32 rxce2_ctl;        /* 2A  RXCE RX Data Link 2 Ctl */
-    VINT32 rxce2_bits;       /* 2B  RXCE RX Data Link 2 Bit Select */
-    VINT32 rxce3_ctl;        /* 2C  RXCE RX Data Link 3 Ctl */
-    VINT32 rxce3_bits;       /* 2D  RXCE RX Data Link 3 Bit Select */
-    VINT32 _rxce_res2E;      /* 2E     RXCE Reserved */
-    VINT32 _rxce_res2F;      /* 2F     RXCE Reserved */
-
-    VINT32 brif_cfg;         /* 30  BRIF RX Backplane Cfg */
-    VINT32 brif_fpcfg;       /* 31  BRIF RX Backplane Frame Pulse Cfg */
-    VINT32 brif_pfcfg;       /* 32  BRIF RX Backplane Parity/F-Bit Cfg */
-    VINT32 brif_tsoff;       /* 33  BRIF RX Backplane Time Slot Offset */
-    VINT32 brif_boff;        /* 34  BRIF RX Backplane Bit Offset */
-    VINT32 _brif_res35;      /* 35     BRIF RX Backplane Reserved */
-    VINT32 _brif_res36;      /* 36     BRIF RX Backplane Reserved */
-    VINT32 _brif_res37;      /* 37     BRIF RX Backplane Reserved */
-
-    VINT32 txci1_ctl;        /* 38  TXCI TX Data Link 1 Ctl */
-    VINT32 txci1_bits;       /* 39  TXCI TX Data Link 2 Bit Select */
-    VINT32 txci2_ctl;        /* 3A  TXCI TX Data Link 1 Ctl */
-    VINT32 txci2_bits;       /* 3B  TXCI TX Data Link 2 Bit Select */
-    VINT32 txci3_ctl;        /* 3C  TXCI TX Data Link 1 Ctl */
-    VINT32 txci3_bits;       /* 3D  TXCI TX Data Link 2 Bit Select */
-    VINT32 _txci_res3E;      /* 3E     TXCI Reserved */
-    VINT32 _txci_res3F;      /* 3F     TXCI Reserved */
-
-    VINT32 btif_cfg;         /* 40  BTIF TX Backplane Cfg */
-    VINT32 btif_fpcfg;       /* 41  BTIF TX Backplane Frame Pulse Cfg */
-    VINT32 btif_pcfgsts;     /* 42  BTIF TX Backplane Parity Cfg & Sts */
-    VINT32 btif_tsoff;       /* 43  BTIF TX Backplane Time Slot Offset */
-    VINT32 btif_boff;        /* 44  BTIF TX Backplane Bit Offset */
-    VINT32 _btif_res45;      /* 45     BTIF TX Backplane Reserved */
-    VINT32 _btif_res46;      /* 46     BTIF TX Backplane Reserved */
-    VINT32 _btif_res47;      /* 47     BTIF TX Backplane Reserved */
-    VINT32 t1_frmr_cfg;      /* 48  T1 FRMR Cfg */
-    VINT32 t1_frmr_ien;      /* 49  T1 FRMR Intr Enable */
-    VINT32 t1_frmr_ists;     /* 4A  T1 FRMR Intr Sts */
-    VINT32 __res_4B;         /* 4B     Reserved */
-    VINT32 ibcd_cfg;         /* 4C  IBCD Cfg */
-    VINT32 ibcd_ies;         /* 4D  IBCD Intr Enable/Sts */
-    VINT32 ibcd_act;         /* 4E  IBCD Activate Code */
-    VINT32 ibcd_deact;       /* 4F  IBCD Deactivate Code */
-
-    VINT32 sigx_cfg;         /* 50  SIGX Cfg/Change of Signaling State */
-    VINT32 sigx_acc_cos;     /* 51  SIGX uP Access Sts/Change of Signaling State */
-    VINT32 sigx_iac_cos;     /* 52  SIGX Channel Indirect
-                              * Addr/Ctl/Change of Signaling State */
-    VINT32 sigx_idb_cos;     /* 53  SIGX Channel Indirect Data
-                              * Buffer/Change of Signaling State */
-
-    VINT32 t1_xbas_cfg;      /* 54  T1 XBAS Cfg */
-    VINT32 t1_xbas_altx;     /* 55  T1 XBAS Alarm TX */
-    VINT32 t1_xibc_ctl;      /* 56  T1 XIBC Ctl */
-    VINT32 t1_xibc_lbcode;   /* 57  T1 XIBC Loopback Code */
-
-    VINT32 pmon_ies;         /* 58  PMON Intr Enable/Sts */
-    VINT32 pmon_fberr;       /* 59  PMON Framing Bit Err Cnt */
-    VINT32 pmon_feb_lsb;     /* 5A  PMON OFF/COFA/Far End Block Err Cnt (LSB) */
-    VINT32 pmon_feb_msb;     /* 5B  PMON OFF/COFA/Far End Block Err Cnt (MSB) */
-    VINT32 pmon_bed_lsb;     /* 5C  PMON Bit/Err/CRCE Cnt (LSB) */
-    VINT32 pmon_bed_msb;     /* 5D  PMON Bit/Err/CRCE Cnt (MSB) */
-    VINT32 pmon_lvc_lsb;     /* 5E  PMON LVC Cnt (LSB) */
-    VINT32 pmon_lvc_msb;     /* 5F  PMON LVC Cnt (MSB) */
-
-    VINT32 t1_almi_cfg;      /* 60  T1 ALMI Cfg */
-    VINT32 t1_almi_ien;      /* 61  T1 ALMI Intr Enable */
-    VINT32 t1_almi_ists;     /* 62  T1 ALMI Intr Sts */
-    VINT32 t1_almi_detsts;   /* 63  T1 ALMI Alarm Detection Sts */
-
-    VINT32 _t1_pdvd_res64;   /* 64     T1 PDVD Reserved */
-    VINT32 t1_pdvd_ies;      /* 65  T1 PDVD Intr Enable/Sts */
-    VINT32 _t1_xboc_res66;   /* 66     T1 XBOC Reserved */
-    VINT32 t1_xboc_code;     /* 67  T1 XBOC Code */
-    VINT32 _t1_xpde_res68;   /* 68     T1 XPDE Reserved */
-    VINT32 t1_xpde_ies;      /* 69  T1 XPDE Intr Enable/Sts */
-
-    VINT32 t1_rboc_ena;      /* 6A  T1 RBOC Enable */
-    VINT32 t1_rboc_sts;      /* 6B  T1 RBOC Code Sts */
-
-    VINT32 t1_tpsc_cfg;      /* 6C  TPSC Cfg */
-    VINT32 t1_tpsc_sts;      /* 6D  TPSC uP Access Sts */
-    VINT32 t1_tpsc_ciaddr;   /* 6E  TPSC Channel Indirect
-                                          * Addr/Ctl */
-    VINT32 t1_tpsc_cidata;   /* 6F  TPSC Channel Indirect Data
-                                          * Buffer */
-    VINT32 t1_rpsc_cfg;      /* 70  RPSC Cfg */
-    VINT32 t1_rpsc_sts;      /* 71  RPSC uP Access Sts */
-    VINT32 t1_rpsc_ciaddr;   /* 72  RPSC Channel Indirect
-                                          * Addr/Ctl */
-    VINT32 t1_rpsc_cidata;   /* 73  RPSC Channel Indirect Data
-                                          * Buffer */
-    VINT32 __res74;          /* 74     Reserved */
-    VINT32 __res75;          /* 75     Reserved */
-    VINT32 __res76;          /* 76     Reserved */
-    VINT32 __res77;          /* 77     Reserved */
-
-    VINT32 t1_aprm_cfg;      /* 78  T1 APRM Cfg/Ctl */
-    VINT32 t1_aprm_load;     /* 79  T1 APRM Manual Load */
-    VINT32 t1_aprm_ists;     /* 7A  T1 APRM Intr Sts */
-    VINT32 t1_aprm_1sec_2;   /* 7B  T1 APRM One Second Content Octet 2 */
-    VINT32 t1_aprm_1sec_3;   /* 7C  T1 APRM One Second Content Octet 3 */
-    VINT32 t1_aprm_1sec_4;   /* 7D  T1 APRM One Second Content Octet 4 */
-    VINT32 t1_aprm_1sec_5;   /* 7E  T1 APRM One Second Content MSB (Octect 5) */
-    VINT32 t1_aprm_1sec_6;   /* 7F  T1 APRM One Second Content MSB (Octect 6) */
-
-    VINT32 e1_tran_cfg;      /* 80  E1 TRAN Cfg */
-    VINT32 e1_tran_txalarm;  /* 81  E1 TRAN TX Alarm/Diagnostic Ctl */
-    VINT32 e1_tran_intctl;   /* 82  E1 TRAN International Ctl */
-    VINT32 e1_tran_extrab;   /* 83  E1 TRAN Extra Bits Ctl */
-    VINT32 e1_tran_ien;      /* 84  E1 TRAN Intr Enable */
-    VINT32 e1_tran_ists;     /* 85  E1 TRAN Intr Sts */
-    VINT32 e1_tran_nats;     /* 86  E1 TRAN National Bit Codeword
-                                          * Select */
-    VINT32 e1_tran_nat;      /* 87  E1 TRAN National Bit Codeword */
-    VINT32 __res88;          /* 88     Reserved */
-    VINT32 __res89;          /* 89     Reserved */
-    VINT32 __res8A;          /* 8A     Reserved */
-    VINT32 __res8B;          /* 8B     Reserved */
-
-    VINT32 _t1_frmr_res8C;   /* 8C     T1 FRMR Reserved */
-    VINT32 _t1_frmr_res8D;   /* 8D     T1 FRMR Reserved */
-    VINT32 __res8E;          /* 8E     Reserved */
-    VINT32 __res8F;          /* 8F     Reserved */
-
-    VINT32 e1_frmr_aopts;    /* 90  E1 FRMR Frame Alignment Options */
-    VINT32 e1_frmr_mopts;    /* 91  E1 FRMR Maintenance Mode Options */
-    VINT32 e1_frmr_ien;      /* 92  E1 FRMR Framing Sts Intr Enable */
-    VINT32 e1_frmr_mien;     /* 93  E1 FRMR Maintenance/Alarm Sts Intr Enable */
-    VINT32 e1_frmr_ists;     /* 94  E1 FRMR Framing Sts Intr Indication */
-    VINT32 e1_frmr_mists;    /* 95  E1 FRMR Maintenance/Alarm Sts Indication Enable */
-    VINT32 e1_frmr_sts;      /* 96  E1 FRMR Framing Sts */
-    VINT32 e1_frmr_masts;    /* 97  E1 FRMR Maintenance/Alarm Sts */
-    VINT32 e1_frmr_nat_bits; /* 98  E1 FRMR International/National Bits */
-    VINT32 e1_frmr_crc_lsb;  /* 99  E1 FRMR CRC Err Cnt - LSB */
-    VINT32 e1_frmr_crc_msb;  /* 9A  E1 FRMR CRC Err Cnt - MSB */
-    VINT32 e1_frmr_nat_ien;  /* 9B  E1 FRMR National Bit Codeword Intr Enables */
-    VINT32 e1_frmr_nat_ists; /* 9C  E1 FRMR National Bit Codeword Intr/Sts */
-    VINT32 e1_frmr_nat;      /* 9D  E1 FRMR National Bit Codewords */
-    VINT32 e1_frmr_fp_ien;   /* 9E  E1 FRMR Frame Pulse/Alarm Intr Enables */
-    VINT32 e1_frmr_fp_ists;  /* 9F  E1 FRMR Frame Pulse/Alarm Intr/Sts */
-
-    VINT32 __resA0;          /* A0     Reserved */
-    VINT32 __resA1;          /* A1     Reserved */
-    VINT32 __resA2;          /* A2     Reserved */
-    VINT32 __resA3;          /* A3     Reserved */
-    VINT32 __resA4;          /* A4     Reserved */
-    VINT32 __resA5;          /* A5     Reserved */
-    VINT32 __resA6;          /* A6     Reserved */
-    VINT32 __resA7;          /* A7     Reserved */
-
-    VINT32 tdpr1_cfg;        /* A8  TDPR #1 Cfg */
-    VINT32 tdpr1_utl;        /* A9  TDPR #1 Upper TX Threshold */
-    VINT32 tdpr1_ltl;        /* AA  TDPR #1 Lower TX Threshold */
-    VINT32 tdpr1_ien;        /* AB  TDPR #1 Intr Enable */
-    VINT32 tdpr1_ists;       /* AC  TDPR #1 Intr Sts/UDR Clear */
-    VINT32 tdpr1_data;       /* AD  TDPR #1 TX Data */
-    VINT32 __resAE;          /* AE     Reserved */
-    VINT32 __resAF;          /* AF     Reserved */
-    VINT32 tdpr2_cfg;        /* B0  TDPR #2 Cfg */
-    VINT32 tdpr2_utl;        /* B1  TDPR #2 Upper TX Threshold */
-    VINT32 tdpr2_ltl;        /* B2  TDPR #2 Lower TX Threshold */
-    VINT32 tdpr2_ien;        /* B3  TDPR #2 Intr Enable */
-    VINT32 tdpr2_ists;       /* B4  TDPR #2 Intr Sts/UDR Clear */
-    VINT32 tdpr2_data;       /* B5  TDPR #2 TX Data */
-    VINT32 __resB6;          /* B6     Reserved */
-    VINT32 __resB7;          /* B7     Reserved1 */
-    VINT32 tdpr3_cfg;        /* B8  TDPR #3 Cfg */
-    VINT32 tdpr3_utl;        /* B9  TDPR #3 Upper TX Threshold */
-    VINT32 tdpr3_ltl;        /* BA  TDPR #3 Lower TX Threshold */
-    VINT32 tdpr3_ien;        /* BB  TDPR #3 Intr Enable */
-    VINT32 tdpr3_ists;       /* BC  TDPR #3 Intr Sts/UDR Clear */
-    VINT32 tdpr3_data;       /* BD  TDPR #3 TX Data */
-    VINT32 __resBE;          /* BE     Reserved */
-    VINT32 __resBF;          /* BF     Reserved */
-
-    VINT32 rdlc1_cfg;        /* C0  RDLC #1 Cfg */
-    VINT32 rdlc1_intctl;     /* C1  RDLC #1 Intr Ctl */
-    VINT32 rdlc1_sts;        /* C2  RDLC #1 Sts */
-    VINT32 rdlc1_data;       /* C3  RDLC #1 Data */
-    VINT32 rdlc1_paddr;      /* C4  RDLC #1 Primary Addr Match */
-    VINT32 rdlc1_saddr;      /* C5  RDLC #1 Secondary Addr Match */
-    VINT32 __resC6;          /* C6     Reserved */
-    VINT32 __resC7;          /* C7     Reserved */
-    VINT32 rdlc2_cfg;        /* C8  RDLC #2 Cfg */
-    VINT32 rdlc2_intctl;     /* C9  RDLC #2 Intr Ctl */
-    VINT32 rdlc2_sts;        /* CA  RDLC #2 Sts */
-    VINT32 rdlc2_data;       /* CB  RDLC #2 Data */
-    VINT32 rdlc2_paddr;      /* CC  RDLC #2 Primary Addr Match */
-    VINT32 rdlc2_saddr;      /* CD  RDLC #2 Secondary Addr Match */
-    VINT32 __resCE;          /* CE     Reserved */
-    VINT32 __resCF;          /* CF     Reserved */
-    VINT32 rdlc3_cfg;        /* D0  RDLC #3 Cfg */
-    VINT32 rdlc3_intctl;     /* D1  RDLC #3 Intr Ctl */
-    VINT32 rdlc3_sts;        /* D2  RDLC #3 Sts */
-    VINT32 rdlc3_data;       /* D3  RDLC #3 Data */
-    VINT32 rdlc3_paddr;      /* D4  RDLC #3 Primary Addr Match */
-    VINT32 rdlc3_saddr;      /* D5  RDLC #3 Secondary Addr Match */
-
-    VINT32 csu_cfg;          /* D6  CSU Cfg */
-    VINT32 _csu_resD7;       /* D7     CSU Reserved */
-
-    VINT32 rlps_idata3;      /* D8  RLPS Indirect Data, 24-31 */
-    VINT32 rlps_idata2;      /* D9  RLPS Indirect Data, 16-23 */
-    VINT32 rlps_idata1;      /* DA  RLPS Indirect Data, 8-15 */
-    VINT32 rlps_idata0;      /* DB  RLPS Indirect Data, 0-7 */
-    VINT32 rlps_eqvr;        /* DC  RLPS Equalizer Voltage Reference
-                              *    (E1 missing) */
-    VINT32 _rlps_resDD;      /* DD     RLPS Reserved */
-    VINT32 _rlps_resDE;      /* DE     RLPS Reserved */
-    VINT32 _rlps_resDF;      /* DF     RLPS Reserved */
-
-    VINT32 prgd_ctl;         /* E0  PRGD Ctl */
-    VINT32 prgd_ies;         /* E1  PRGD Intr Enable/Sts */
-    VINT32 prgd_shift_len;   /* E2  PRGD Shift Length */
-    VINT32 prgd_tap;         /* E3  PRGD Tap */
-    VINT32 prgd_errin;       /* E4  PRGD Err Insertion */
-    VINT32 _prgd_resE5;      /* E5     PRGD Reserved */
-    VINT32 _prgd_resE6;      /* E6     PRGD Reserved */
-    VINT32 _prgd_resE7;      /* E7     PRGD Reserved */
-    VINT32 prgd_patin1;      /* E8  PRGD Pattern Insertion #1 */
-    VINT32 prgd_patin2;      /* E9  PRGD Pattern Insertion #2 */
-    VINT32 prgd_patin3;      /* EA  PRGD Pattern Insertion #3 */
-    VINT32 prgd_patin4;      /* EB  PRGD Pattern Insertion #4 */
-    VINT32 prgd_patdet1;     /* EC  PRGD Pattern Detector #1 */
-    VINT32 prgd_patdet2;     /* ED  PRGD Pattern Detector #2 */
-    VINT32 prgd_patdet3;     /* EE  PRGD Pattern Detector #3 */
-    VINT32 prgd_patdet4;     /* EF  PRGD Pattern Detector #4 */
-
-    VINT32 xlpg_cfg;         /* F0  XLPG Line Driver Cfg */
-    VINT32 xlpg_ctlsts;      /* F1  XLPG Ctl/Sts */
-    VINT32 xlpg_pwave_addr;  /* F2  XLPG Pulse Waveform Storage Write Addr */
-    VINT32 xlpg_pwave_data;  /* F3  XLPG Pulse Waveform Storage Data */
-    VINT32 xlpg_atest_pctl;  /* F4  XLPG Analog Test Positive Ctl */
-    VINT32 xlpg_atest_nctl;  /* F5  XLPG Analog Test Negative Ctl */
-    VINT32 xlpg_fdata_sel;   /* F6  XLPG Fuse Data Select */
-    VINT32 _xlpg_resF7;      /* F7     XLPG Reserved */
-
-    VINT32 rlps_cfgsts;      /* F8  RLPS Cfg & Sts */
-    VINT32 rlps_alos_thresh; /* F9  RLPS ALOS Detection/Clearance Threshold */
-    VINT32 rlps_alos_dper;   /* FA  RLPS ALOS Detection Period */
-    VINT32 rlps_alos_cper;   /* FB  RLPS ALOS Clearance Period */
-    VINT32 rlps_eq_iaddr;    /* FC  RLPS Equalization Indirect Addr */
-    VINT32 rlps_eq_rwsel;    /* FD  RLPS Equalization Read/WriteB Select */
-    VINT32 rlps_eq_ctlsts;   /* FE  RLPS Equalizer Loop Sts & Ctl */
-    VINT32 rlps_eq_cfg;      /* FF  RLPS Equalizer Cfg */
+       VINT32 reset;        /* 0E  Reset */
+       VINT32 prgd_phctl;   /* 0F  PRGD Positioning/Ctl & HDLC Ctl */
+       VINT32 cdrc_cfg;     /* 10  CDRC Cfg */
+       VINT32 cdrc_ien;     /* 11  CDRC Intr Enable */
+       VINT32 cdrc_ists;    /* 12  CDRC Intr Sts */
+       VINT32 cdrc_alos;    /* 13  CDRC Alternate Loss of Signal */
+
+       VINT32 rjat_ists;    /* 14  RJAT Intr Sts */
+       VINT32 rjat_n1clk;   /* 15  RJAT Reference Clk Divisor (N1) Ctl */
+       VINT32 rjat_n2clk;   /* 16  RJAT Output Clk Divisor (N2) Ctl */
+       VINT32 rjat_cfg;     /* 17  RJAT Cfg */
+
+       VINT32 tjat_ists;    /* 18  TJAT Intr Sts */
+       VINT32 tjat_n1clk;   /* 19  TJAT Reference Clk Divisor (N1) Ctl */
+       VINT32 tjat_n2clk;   /* 1A  TJAT Output Clk Divisor (N2) Ctl */
+       VINT32 tjat_cfg;     /* 1B  TJAT Cfg */
+
+       VINT32 rx_elst_cfg;      /* 1C  RX-ELST Cfg */
+       VINT32 rx_elst_ists;     /* 1D  RX-ELST Intr Sts */
+       VINT32 rx_elst_idle;     /* 1E  RX-ELST Idle Code */
+       VINT32 _rx_elst_res1f;   /* 1F     RX-ELST Reserved */
+
+       VINT32 tx_elst_cfg;      /* 20  TX-ELST Cfg */
+       VINT32 tx_elst_ists;     /* 21  TX-ELST Intr Sts */
+       VINT32 _tx_elst_res22;   /* 22     TX-ELST Reserved */
+       VINT32 _tx_elst_res23;   /* 23     TX-ELST Reserved */
+       VINT32 __res24;          /* 24     Reserved */
+       VINT32 __res25;          /* 25     Reserved */
+       VINT32 __res26;          /* 26     Reserved */
+       VINT32 __res27;          /* 27     Reserved */
+
+       VINT32 rxce1_ctl;        /* 28  RXCE RX Data Link 1 Ctl */
+       VINT32 rxce1_bits;       /* 29  RXCE RX Data Link 1 Bit Select */
+       VINT32 rxce2_ctl;        /* 2A  RXCE RX Data Link 2 Ctl */
+       VINT32 rxce2_bits;       /* 2B  RXCE RX Data Link 2 Bit Select */
+       VINT32 rxce3_ctl;        /* 2C  RXCE RX Data Link 3 Ctl */
+       VINT32 rxce3_bits;       /* 2D  RXCE RX Data Link 3 Bit Select */
+       VINT32 _rxce_res2E;      /* 2E     RXCE Reserved */
+       VINT32 _rxce_res2F;      /* 2F     RXCE Reserved */
+
+       VINT32 brif_cfg;         /* 30  BRIF RX Backplane Cfg */
+       VINT32 brif_fpcfg;       /* 31  BRIF RX Backplane Frame Pulse Cfg */
+       VINT32 brif_pfcfg;       /* 32  BRIF RX Backplane Parity/F-Bit Cfg */
+       VINT32 brif_tsoff;       /* 33  BRIF RX Backplane Time Slot Offset */
+       VINT32 brif_boff;        /* 34  BRIF RX Backplane Bit Offset */
+       VINT32 _brif_res35;      /* 35     BRIF RX Backplane Reserved */
+       VINT32 _brif_res36;      /* 36     BRIF RX Backplane Reserved */
+       VINT32 _brif_res37;      /* 37     BRIF RX Backplane Reserved */
+
+       VINT32 txci1_ctl;        /* 38  TXCI TX Data Link 1 Ctl */
+       VINT32 txci1_bits;       /* 39  TXCI TX Data Link 2 Bit Select */
+       VINT32 txci2_ctl;        /* 3A  TXCI TX Data Link 1 Ctl */
+       VINT32 txci2_bits;       /* 3B  TXCI TX Data Link 2 Bit Select */
+       VINT32 txci3_ctl;        /* 3C  TXCI TX Data Link 1 Ctl */
+       VINT32 txci3_bits;       /* 3D  TXCI TX Data Link 2 Bit Select */
+       VINT32 _txci_res3E;      /* 3E     TXCI Reserved */
+       VINT32 _txci_res3F;      /* 3F     TXCI Reserved */
+
+       VINT32 btif_cfg;         /* 40  BTIF TX Backplane Cfg */
+       VINT32 btif_fpcfg;       /* 41  BTIF TX Backplane Frame Pulse Cfg */
+       VINT32 btif_pcfgsts;     /* 42  BTIF TX Backplane Parity Cfg & Sts */
+       VINT32 btif_tsoff;       /* 43  BTIF TX Backplane Time Slot Offset */
+       VINT32 btif_boff;        /* 44  BTIF TX Backplane Bit Offset */
+       VINT32 _btif_res45;      /* 45     BTIF TX Backplane Reserved */
+       VINT32 _btif_res46;      /* 46     BTIF TX Backplane Reserved */
+       VINT32 _btif_res47;      /* 47     BTIF TX Backplane Reserved */
+       VINT32 t1_frmr_cfg;      /* 48  T1 FRMR Cfg */
+       VINT32 t1_frmr_ien;      /* 49  T1 FRMR Intr Enable */
+       VINT32 t1_frmr_ists;     /* 4A  T1 FRMR Intr Sts */
+       VINT32 __res_4B;         /* 4B     Reserved */
+       VINT32 ibcd_cfg;         /* 4C  IBCD Cfg */
+       VINT32 ibcd_ies;         /* 4D  IBCD Intr Enable/Sts */
+       VINT32 ibcd_act;         /* 4E  IBCD Activate Code */
+       VINT32 ibcd_deact;       /* 4F  IBCD Deactivate Code */
+
+       VINT32 sigx_cfg;         /* 50  SIGX Cfg/Change of Signaling State */
+       VINT32 sigx_acc_cos;     /* 51  SIGX
+                                 * uP Access Sts/Change of Signaling State */
+       VINT32 sigx_iac_cos;     /* 52  SIGX Channel Indirect
+                                 * Addr/Ctl/Change of Signaling State */
+       VINT32 sigx_idb_cos;     /* 53  SIGX Channel Indirect Data
+                                 * Buffer/Change of Signaling State */
+
+       VINT32 t1_xbas_cfg;      /* 54  T1 XBAS Cfg */
+       VINT32 t1_xbas_altx;     /* 55  T1 XBAS Alarm TX */
+       VINT32 t1_xibc_ctl;      /* 56  T1 XIBC Ctl */
+       VINT32 t1_xibc_lbcode;   /* 57  T1 XIBC Loopback Code */
+
+       VINT32 pmon_ies;         /* 58  PMON Intr Enable/Sts */
+       VINT32 pmon_fberr;       /* 59  PMON Framing Bit Err Cnt */
+       VINT32 pmon_feb_lsb;     /* 5A  PMON
+                                 * OFF/COFA/Far End Block Err Cnt (LSB) */
+       VINT32 pmon_feb_msb;     /* 5B  PMON
+                                 * OFF/COFA/Far End Block Err Cnt (MSB) */
+       VINT32 pmon_bed_lsb;     /* 5C  PMON Bit/Err/CRCE Cnt (LSB) */
+       VINT32 pmon_bed_msb;     /* 5D  PMON Bit/Err/CRCE Cnt (MSB) */
+       VINT32 pmon_lvc_lsb;     /* 5E  PMON LVC Cnt (LSB) */
+       VINT32 pmon_lvc_msb;     /* 5F  PMON LVC Cnt (MSB) */
+
+       VINT32 t1_almi_cfg;      /* 60  T1 ALMI Cfg */
+       VINT32 t1_almi_ien;      /* 61  T1 ALMI Intr Enable */
+       VINT32 t1_almi_ists;     /* 62  T1 ALMI Intr Sts */
+       VINT32 t1_almi_detsts;   /* 63  T1 ALMI Alarm Detection Sts */
+
+       VINT32 _t1_pdvd_res64;   /* 64     T1 PDVD Reserved */
+       VINT32 t1_pdvd_ies;      /* 65  T1 PDVD Intr Enable/Sts */
+       VINT32 _t1_xboc_res66;   /* 66     T1 XBOC Reserved */
+       VINT32 t1_xboc_code;     /* 67  T1 XBOC Code */
+       VINT32 _t1_xpde_res68;   /* 68     T1 XPDE Reserved */
+       VINT32 t1_xpde_ies;      /* 69  T1 XPDE Intr Enable/Sts */
+
+       VINT32 t1_rboc_ena;      /* 6A  T1 RBOC Enable */
+       VINT32 t1_rboc_sts;      /* 6B  T1 RBOC Code Sts */
+
+       VINT32 t1_tpsc_cfg;      /* 6C  TPSC Cfg */
+       VINT32 t1_tpsc_sts;      /* 6D  TPSC uP Access Sts */
+       VINT32 t1_tpsc_ciaddr;   /* 6E  TPSC Channel Indirect
+                                 * Addr/Ctl */
+       VINT32 t1_tpsc_cidata;   /* 6F  TPSC Channel Indirect Data
+                                 * Buffer */
+       VINT32 t1_rpsc_cfg;      /* 70  RPSC Cfg */
+       VINT32 t1_rpsc_sts;      /* 71  RPSC uP Access Sts */
+       VINT32 t1_rpsc_ciaddr;   /* 72  RPSC Channel Indirect
+                                 * Addr/Ctl */
+       VINT32 t1_rpsc_cidata;   /* 73  RPSC Channel Indirect Data
+                                 * Buffer */
+       VINT32 __res74;          /* 74     Reserved */
+       VINT32 __res75;          /* 75     Reserved */
+       VINT32 __res76;          /* 76     Reserved */
+       VINT32 __res77;          /* 77     Reserved */
+
+       VINT32 t1_aprm_cfg;      /* 78  T1 APRM Cfg/Ctl */
+       VINT32 t1_aprm_load;     /* 79  T1 APRM Manual Load */
+       VINT32 t1_aprm_ists;     /* 7A  T1 APRM Intr Sts */
+       VINT32 t1_aprm_1sec_2;   /* 7B  T1 APRM One Second Content Octet 2 */
+       VINT32 t1_aprm_1sec_3;   /* 7C  T1 APRM One Second Content Octet 3 */
+       VINT32 t1_aprm_1sec_4;   /* 7D  T1 APRM One Second Content Octet 4 */
+       VINT32 t1_aprm_1sec_5;   /* 7E  T1 APRM
+                                 * One Second Content MSB (Octect 5) */
+       VINT32 t1_aprm_1sec_6;   /* 7F  T1 APRM
+                                 * One Second Content MSB (Octect 6) */
+
+       VINT32 e1_tran_cfg;      /* 80  E1 TRAN Cfg */
+       VINT32 e1_tran_txalarm;  /* 81  E1 TRAN TX Alarm/Diagnostic Ctl */
+       VINT32 e1_tran_intctl;   /* 82  E1 TRAN International Ctl */
+       VINT32 e1_tran_extrab;   /* 83  E1 TRAN Extra Bits Ctl */
+       VINT32 e1_tran_ien;      /* 84  E1 TRAN Intr Enable */
+       VINT32 e1_tran_ists;     /* 85  E1 TRAN Intr Sts */
+       VINT32 e1_tran_nats;     /* 86  E1 TRAN National Bit Codeword
+                                 * Select */
+       VINT32 e1_tran_nat;      /* 87  E1 TRAN National Bit Codeword */
+       VINT32 __res88;          /* 88     Reserved */
+       VINT32 __res89;          /* 89     Reserved */
+       VINT32 __res8A;          /* 8A     Reserved */
+       VINT32 __res8B;          /* 8B     Reserved */
+
+       VINT32 _t1_frmr_res8C;   /* 8C     T1 FRMR Reserved */
+       VINT32 _t1_frmr_res8D;   /* 8D     T1 FRMR Reserved */
+       VINT32 __res8E;          /* 8E     Reserved */
+       VINT32 __res8F;          /* 8F     Reserved */
+
+       VINT32 e1_frmr_aopts;    /* 90  E1 FRMR Frame Alignment Options */
+       VINT32 e1_frmr_mopts;    /* 91  E1 FRMR Maintenance Mode Options */
+       VINT32 e1_frmr_ien;      /* 92  E1 FRMR Framing Sts Intr Enable */
+       VINT32 e1_frmr_mien;     /* 93  E1 FRMR
+                                 * Maintenance/Alarm Sts Intr Enable */
+       VINT32 e1_frmr_ists;     /* 94  E1 FRMR Framing Sts Intr Indication */
+       VINT32 e1_frmr_mists;    /* 95  E1 FRMR
+                                 * Maintenance/Alarm Sts Indication Enable */
+       VINT32 e1_frmr_sts;      /* 96  E1 FRMR Framing Sts */
+       VINT32 e1_frmr_masts;    /* 97  E1 FRMR Maintenance/Alarm Sts */
+       VINT32 e1_frmr_nat_bits; /* 98  E1 FRMR International/National Bits */
+       VINT32 e1_frmr_crc_lsb;  /* 99  E1 FRMR CRC Err Cnt - LSB */
+       VINT32 e1_frmr_crc_msb;  /* 9A  E1 FRMR CRC Err Cnt - MSB */
+       VINT32 e1_frmr_nat_ien;  /* 9B  E1 FRMR
+                                 * National Bit Codeword Intr Enables */
+       VINT32 e1_frmr_nat_ists; /* 9C  E1 FRMR
+                                 * National Bit Codeword Intr/Sts */
+       VINT32 e1_frmr_nat;      /* 9D  E1 FRMR National Bit Codewords */
+       VINT32 e1_frmr_fp_ien;   /* 9E  E1 FRMR
+                                 * Frame Pulse/Alarm Intr Enables */
+       VINT32 e1_frmr_fp_ists;  /* 9F  E1 FRMR Frame Pulse/Alarm Intr/Sts */
+
+       VINT32 __resA0;          /* A0     Reserved */
+       VINT32 __resA1;          /* A1     Reserved */
+       VINT32 __resA2;          /* A2     Reserved */
+       VINT32 __resA3;          /* A3     Reserved */
+       VINT32 __resA4;          /* A4     Reserved */
+       VINT32 __resA5;          /* A5     Reserved */
+       VINT32 __resA6;          /* A6     Reserved */
+       VINT32 __resA7;          /* A7     Reserved */
+
+       VINT32 tdpr1_cfg;        /* A8  TDPR #1 Cfg */
+       VINT32 tdpr1_utl;        /* A9  TDPR #1 Upper TX Threshold */
+       VINT32 tdpr1_ltl;        /* AA  TDPR #1 Lower TX Threshold */
+       VINT32 tdpr1_ien;        /* AB  TDPR #1 Intr Enable */
+       VINT32 tdpr1_ists;       /* AC  TDPR #1 Intr Sts/UDR Clear */
+       VINT32 tdpr1_data;       /* AD  TDPR #1 TX Data */
+       VINT32 __resAE;          /* AE     Reserved */
+       VINT32 __resAF;          /* AF     Reserved */
+       VINT32 tdpr2_cfg;        /* B0  TDPR #2 Cfg */
+       VINT32 tdpr2_utl;        /* B1  TDPR #2 Upper TX Threshold */
+       VINT32 tdpr2_ltl;        /* B2  TDPR #2 Lower TX Threshold */
+       VINT32 tdpr2_ien;        /* B3  TDPR #2 Intr Enable */
+       VINT32 tdpr2_ists;       /* B4  TDPR #2 Intr Sts/UDR Clear */
+       VINT32 tdpr2_data;       /* B5  TDPR #2 TX Data */
+       VINT32 __resB6;          /* B6     Reserved */
+       VINT32 __resB7;          /* B7     Reserved1 */
+       VINT32 tdpr3_cfg;        /* B8  TDPR #3 Cfg */
+       VINT32 tdpr3_utl;        /* B9  TDPR #3 Upper TX Threshold */
+       VINT32 tdpr3_ltl;        /* BA  TDPR #3 Lower TX Threshold */
+       VINT32 tdpr3_ien;        /* BB  TDPR #3 Intr Enable */
+       VINT32 tdpr3_ists;       /* BC  TDPR #3 Intr Sts/UDR Clear */
+       VINT32 tdpr3_data;       /* BD  TDPR #3 TX Data */
+       VINT32 __resBE;          /* BE     Reserved */
+       VINT32 __resBF;          /* BF     Reserved */
+
+       VINT32 rdlc1_cfg;        /* C0  RDLC #1 Cfg */
+       VINT32 rdlc1_intctl;     /* C1  RDLC #1 Intr Ctl */
+       VINT32 rdlc1_sts;        /* C2  RDLC #1 Sts */
+       VINT32 rdlc1_data;       /* C3  RDLC #1 Data */
+       VINT32 rdlc1_paddr;      /* C4  RDLC #1 Primary Addr Match */
+       VINT32 rdlc1_saddr;      /* C5  RDLC #1 Secondary Addr Match */
+       VINT32 __resC6;          /* C6     Reserved */
+       VINT32 __resC7;          /* C7     Reserved */
+       VINT32 rdlc2_cfg;        /* C8  RDLC #2 Cfg */
+       VINT32 rdlc2_intctl;     /* C9  RDLC #2 Intr Ctl */
+       VINT32 rdlc2_sts;        /* CA  RDLC #2 Sts */
+       VINT32 rdlc2_data;       /* CB  RDLC #2 Data */
+       VINT32 rdlc2_paddr;      /* CC  RDLC #2 Primary Addr Match */
+       VINT32 rdlc2_saddr;      /* CD  RDLC #2 Secondary Addr Match */
+       VINT32 __resCE;          /* CE     Reserved */
+       VINT32 __resCF;          /* CF     Reserved */
+       VINT32 rdlc3_cfg;        /* D0  RDLC #3 Cfg */
+       VINT32 rdlc3_intctl;     /* D1  RDLC #3 Intr Ctl */
+       VINT32 rdlc3_sts;        /* D2  RDLC #3 Sts */
+       VINT32 rdlc3_data;       /* D3  RDLC #3 Data */
+       VINT32 rdlc3_paddr;      /* D4  RDLC #3 Primary Addr Match */
+       VINT32 rdlc3_saddr;      /* D5  RDLC #3 Secondary Addr Match */
+
+       VINT32 csu_cfg;          /* D6  CSU Cfg */
+       VINT32 _csu_resD7;       /* D7     CSU Reserved */
+
+       VINT32 rlps_idata3;      /* D8  RLPS Indirect Data, 24-31 */
+       VINT32 rlps_idata2;      /* D9  RLPS Indirect Data, 16-23 */
+       VINT32 rlps_idata1;      /* DA  RLPS Indirect Data, 8-15 */
+       VINT32 rlps_idata0;      /* DB  RLPS Indirect Data, 0-7 */
+       VINT32 rlps_eqvr;        /* DC  RLPS Equalizer Voltage Reference
+                                 *    (E1 missing) */
+       VINT32 _rlps_resDD;      /* DD     RLPS Reserved */
+       VINT32 _rlps_resDE;      /* DE     RLPS Reserved */
+       VINT32 _rlps_resDF;      /* DF     RLPS Reserved */
+
+       VINT32 prgd_ctl;         /* E0  PRGD Ctl */
+       VINT32 prgd_ies;         /* E1  PRGD Intr Enable/Sts */
+       VINT32 prgd_shift_len;   /* E2  PRGD Shift Length */
+       VINT32 prgd_tap;         /* E3  PRGD Tap */
+       VINT32 prgd_errin;       /* E4  PRGD Err Insertion */
+       VINT32 _prgd_resE5;      /* E5     PRGD Reserved */
+       VINT32 _prgd_resE6;      /* E6     PRGD Reserved */
+       VINT32 _prgd_resE7;      /* E7     PRGD Reserved */
+       VINT32 prgd_patin1;      /* E8  PRGD Pattern Insertion #1 */
+       VINT32 prgd_patin2;      /* E9  PRGD Pattern Insertion #2 */
+       VINT32 prgd_patin3;      /* EA  PRGD Pattern Insertion #3 */
+       VINT32 prgd_patin4;      /* EB  PRGD Pattern Insertion #4 */
+       VINT32 prgd_patdet1;     /* EC  PRGD Pattern Detector #1 */
+       VINT32 prgd_patdet2;     /* ED  PRGD Pattern Detector #2 */
+       VINT32 prgd_patdet3;     /* EE  PRGD Pattern Detector #3 */
+       VINT32 prgd_patdet4;     /* EF  PRGD Pattern Detector #4 */
+
+       VINT32 xlpg_cfg;         /* F0  XLPG Line Driver Cfg */
+       VINT32 xlpg_ctlsts;      /* F1  XLPG Ctl/Sts */
+       VINT32 xlpg_pwave_addr;  /* F2  XLPG
+                                 * Pulse Waveform Storage Write Addr */
+       VINT32 xlpg_pwave_data;  /* F3  XLPG Pulse Waveform Storage Data */
+       VINT32 xlpg_atest_pctl;  /* F4  XLPG Analog Test Positive Ctl */
+       VINT32 xlpg_atest_nctl;  /* F5  XLPG Analog Test Negative Ctl */
+       VINT32 xlpg_fdata_sel;   /* F6  XLPG Fuse Data Select */
+       VINT32 _xlpg_resF7;      /* F7     XLPG Reserved */
+
+       VINT32 rlps_cfgsts;      /* F8  RLPS Cfg & Sts */
+       VINT32 rlps_alos_thresh; /* F9  RLPS
+                                 * ALOS Detection/Clearance Threshold */
+       VINT32 rlps_alos_dper;   /* FA  RLPS ALOS Detection Period */
+       VINT32 rlps_alos_cper;   /* FB  RLPS ALOS Clearance Period */
+       VINT32 rlps_eq_iaddr;    /* FC  RLPS Equalization Indirect Addr */
+       VINT32 rlps_eq_rwsel;    /* FD  RLPS Equalization Read/WriteB Select */
+       VINT32 rlps_eq_ctlsts;   /* FE  RLPS Equalizer Loop Sts & Ctl */
+       VINT32 rlps_eq_cfg;      /* FF  RLPS Equalizer Cfg */
 };
 
-typedef struct s_comet_reg comet_t;
-
 /* 00AH: MDIAG Register bit definitions */
 #define COMET_MDIAG_ID5        0x40
 #define COMET_MDIAG_LBMASK     0x3F
@@ -338,7 +347,7 @@ typedef struct s_comet_reg comet_t;
 
 #ifdef __KERNEL__
 extern void
-init_comet(void *, comet_t *, u_int32_t, int, u_int8_t);
+init_comet(void *, struct s_comet_reg *, u_int32_t, int, u_int8_t);
 #endif
 
 #endif                          /* _INC_COMET_H_ */
index d021b312ffa28821b4495ee2c6b08512784ed7a2..95218e2839662f90c48e30a3fac42566980b6f20 100644 (file)
@@ -274,7 +274,7 @@ VMETRO_TRACE (void *x)
 void
 VMETRO_TRIGGER (ci_t *ci, int x)
 {
-    comet_t    *comet;
+    struct s_comet_reg    *comet;
     volatile u_int32_t data;
 
     comet = ci->port[0].cometbase;  /* default to COMET # 0 */
index 0ba8c3ae673bd19cb86617a6b3ad0aea32ecf228..7a3a30cd0f7f557a0f53fcfeacd7223311cee4eb 100644 (file)
@@ -1,5 +1,5 @@
-unsigned int max_intcnt = 0;
-unsigned int max_bh = 0;
+static unsigned int max_intcnt = 0;
+static unsigned int max_bh = 0;
 
 /*-----------------------------------------------------------------------------
  * musycc.c -
index 4028ea11c4423bc14096d80f7423bec5391b4297..a9d95753be20479de7826eab83723ae95e945494 100644 (file)
@@ -194,7 +194,7 @@ checkPorts (ci_t *ci)
      * alarms conflicts with NCOMM's interrupt servicing implementation.
      */
 
-    comet_t    *comet;
+    struct s_comet_reg    *comet;
     volatile u_int32_t value;
     u_int32_t   copyVal, LEDval;
 
@@ -507,7 +507,7 @@ c4_cleanup (void)
 int
 c4_get_portcfg (ci_t *ci)
 {
-    comet_t    *comet;
+    struct s_comet_reg    *comet;
     int         portnum, mask;
     u_int32_t   wdata, rdata;
 
@@ -561,7 +561,7 @@ c4_init (ci_t *ci, u_char *func0, u_char *func1)
         for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++)
         {
             pi = &ci->port[portnum];
-            pi->cometbase = (comet_t *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum)));
+            pi->cometbase = (struct s_comet_reg *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum)));
             pi->reg = (struct musycc_globalr *) ((u_char *) ci->reg + (portnum * 0x800));
             pi->portnum = portnum;
             pi->p.portnum = portnum;
@@ -693,7 +693,7 @@ c4_init2 (ci_t *ci)
 int
 c4_loop_port (ci_t *ci, int portnum, u_int8_t cmd)
 {
-    comet_t    *comet;
+    struct s_comet_reg    *comet;
     volatile u_int32_t loopValue;
 
     comet = ci->port[portnum].cometbase;
@@ -752,7 +752,7 @@ c4_loop_port (ci_t *ci, int portnum, u_int8_t cmd)
 status_t
 c4_frame_rw (ci_t *ci, struct sbecom_port_param *pp)
 {
-    comet_t    *comet;
+    struct s_comet_reg    *comet;
     volatile u_int32_t data;
 
     if (pp->portnum >= ci->max_port)/* sanity check */
index b2b6e3702630a73ed19b776b4aae45bf350a01d3..7edbd4e492e39a62faa01dfd4751ece463818c0e 100644 (file)
@@ -133,7 +133,7 @@ struct c4_port_info
     void       *regram_saved;   /* Original malloc value may have non-2KB
                                  * boundary.  Need to save for use when
                                  * freeing. */
-    comet_t    *cometbase;
+    struct s_comet_reg    *cometbase;
     struct sbe_card_info *up;
 
     /*
index 6ec51bccceb11844270321aab3e7b256d54a1d8d..97c5c6e7e2996b79c002c314dd4bb212a80870fe 100644 (file)
 #include "sbe_bid.h"
 
 char       *
-sbeid_get_bdname (ci_t *ci)
+sbeid_get_bdname(ci_t *ci)
 {
-    char       *np = NULL;
+       char       *np = NULL;
 
-    switch (ci->brd_id)
-    {
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
-        np = "wanPTMC-256T3 <E1>";
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
-        np = "wanPTMC-256T3 <T1>";
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
-        np = "wanPMC-C4T1E1";
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
-        np = "wanPMC-C2T1E1";
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
-        np = "wanPMC-C1T1E1";
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
-        np = "wanPCI-C4T1E1";
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
-        np = "wanPCI-C2T1E1";
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
-        np = "wanPCI-C1T1E1";
-        break;
-    default:
-        /*** np = "<unknown>";  ***/
-        np = "wanPCI-CxT1E1";
-        break;
-    }
+       switch (ci->brd_id) {
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
+               np = "wanPTMC-256T3 <E1>";
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
+               np = "wanPTMC-256T3 <T1>";
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
+               np = "wanPMC-C4T1E1";
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
+               np = "wanPMC-C2T1E1";
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
+               np = "wanPMC-C1T1E1";
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
+               np = "wanPCI-C4T1E1";
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
+               np = "wanPCI-C2T1E1";
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
+               np = "wanPCI-C1T1E1";
+               break;
+       default:
+               /*** np = "<unknown>";  ***/
+               np = "wanPCI-CxT1E1";
+               break;
+       }
 
-    return np;
+       return np;
 }
 
 
 /* given the presetting of brd_id, set the corresponding hdw_id */
 
 void
-sbeid_set_hdwbid (ci_t *ci)
+sbeid_set_hdwbid(ci_t *ci)
 {
-    /*
-     * set SBE's unique hardware identification (for legacy boards might not
-     * have this register implemented)
-     */
+       /*
+        * set SBE's unique hardware identification (for legacy boards might not
+        * have this register implemented)
+        */
 
-    switch (ci->brd_id)
-    {
-        case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
-        ci->hdw_bid = SBE_BID_256T3_E1; /* 0x46 - SBE wanPTMC-256T3 (E1
-                                         * Version) */
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
-        ci->hdw_bid = SBE_BID_256T3_T1; /* 0x42 - SBE wanPTMC-256T3 (T1
-                                         * Version) */
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
-        /*
-         * This Board ID is a generic identification.  Use the found number
-         * of ports to further define this hardware.
-         */
-        switch (ci->max_port)
-        {
-        default:                    /* shouldn't need a default, but have one
-                                     * anyway */
-        case 4:
-            ci->hdw_bid = SBE_BID_PMC_C4T1E1;   /* 0xC4 - SBE wanPMC-C4T1E1 */
-            break;
-        case 2:
-            ci->hdw_bid = SBE_BID_PMC_C2T1E1;   /* 0xC2 - SBE wanPMC-C2T1E1 */
-            ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1);
-            break;
-        case 1:
-            ci->hdw_bid = SBE_BID_PMC_C1T1E1;   /* 0xC1 - SBE wanPMC-C1T1E1 */
-            ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1);
-            break;
-        }
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
-        ci->hdw_bid = SBE_BID_PMC_C2T1E1;       /* 0xC2 - SBE wanPMC-C2T1E1 */
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
-        ci->hdw_bid = SBE_BID_PMC_C1T1E1;       /* 0xC1 - SBE wanPMC-C1T1E1 */
-        break;
+       switch (ci->brd_id) {
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
+               ci->hdw_bid = SBE_BID_256T3_E1; /* 0x46 - SBE wanPTMC-256T3 (E1
+                                                * Version) */
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
+               ci->hdw_bid = SBE_BID_256T3_T1; /* 0x42 - SBE wanPTMC-256T3 (T1
+                                                * Version) */
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
+               /*
+                * This Board ID is a generic identification.  Use the found number
+                * of ports to further define this hardware.
+                */
+               switch (ci->max_port) {
+               default:                    /* shouldn't need a default, but have one
+                                            * anyway */
+               case 4:
+                       ci->hdw_bid = SBE_BID_PMC_C4T1E1;   /* 0xC4 - SBE wanPMC-C4T1E1 */
+                       break;
+               case 2:
+                       ci->hdw_bid = SBE_BID_PMC_C2T1E1;   /* 0xC2 - SBE wanPMC-C2T1E1 */
+                       ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1);
+                       break;
+               case 1:
+                       ci->hdw_bid = SBE_BID_PMC_C1T1E1;   /* 0xC1 - SBE wanPMC-C1T1E1 */
+                       ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1);
+                       break;
+               }
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
+               ci->hdw_bid = SBE_BID_PMC_C2T1E1;       /* 0xC2 - SBE wanPMC-C2T1E1 */
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
+               ci->hdw_bid = SBE_BID_PMC_C1T1E1;       /* 0xC1 - SBE wanPMC-C1T1E1 */
+               break;
 #ifdef SBE_PMCC4_ENABLE
-        /*
-         * This case is entered as a result of the inability to obtain the
-         * <bid> from the board's EEPROM.  Assume a PCI board and set
-         * <hdsbid> according to the number ofr found ports.
-         */
-    case 0:
-        /* start by assuming 4-port for ZERO casing */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
-        /* drop thru to set hdw_bid and alternate PCI CxT1E1 settings */
+               /*
+                * This case is entered as a result of the inability to obtain the
+                * <bid> from the board's EEPROM.  Assume a PCI board and set
+                * <hdsbid> according to the number ofr found ports.
+                */
+       case 0:
+               /* start by assuming 4-port for ZERO casing */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
+               /* drop thru to set hdw_bid and alternate PCI CxT1E1 settings */
 #endif
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
-        /*
-         * This Board ID is a generic identification.  Use the number of
-         * found ports to further define this hardware.
-         */
-        switch (ci->max_port)
-        {
-        default:                    /* shouldn't need a default, but have one
-                                     * anyway */
-        case 4:
-            ci->hdw_bid = SBE_BID_PCI_C4T1E1;   /* 0x04 - SBE wanPCI-C4T1E1 */
-            break;
-        case 2:
-            ci->hdw_bid = SBE_BID_PCI_C2T1E1;   /* 0x02 - SBE wanPCI-C2T1E1 */
-            ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1);
-            break;
-        case 1:
-            ci->hdw_bid = SBE_BID_PCI_C1T1E1;   /* 0x01 - SBE wanPCI-C1T1E1 */
-            ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1);
-            break;
-        }
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
-        ci->hdw_bid = SBE_BID_PCI_C2T1E1;       /* 0x02 - SBE wanPCI-C2T1E1 */
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
-        ci->hdw_bid = SBE_BID_PCI_C1T1E1;       /* 0x01 - SBE wanPCI-C1T1E1 */
-        break;
-    default:
-        /*** bid = "<unknown>";  ***/
-        ci->hdw_bid = SBE_BID_PMC_C4T1E1;       /* 0x41 - SBE wanPTMC-C4T1E1 */
-        break;
-    }
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
+               /*
+                * This Board ID is a generic identification.  Use the number of
+                * found ports to further define this hardware.
+                */
+               switch (ci->max_port) {
+               default:                    /* shouldn't need a default, but have one
+                                            * anyway */
+               case 4:
+                       ci->hdw_bid = SBE_BID_PCI_C4T1E1;   /* 0x04 - SBE wanPCI-C4T1E1 */
+                       break;
+               case 2:
+                       ci->hdw_bid = SBE_BID_PCI_C2T1E1;   /* 0x02 - SBE wanPCI-C2T1E1 */
+                       ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1);
+                       break;
+               case 1:
+                       ci->hdw_bid = SBE_BID_PCI_C1T1E1;   /* 0x01 - SBE wanPCI-C1T1E1 */
+                       ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1);
+                       break;
+               }
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
+               ci->hdw_bid = SBE_BID_PCI_C2T1E1;       /* 0x02 - SBE wanPCI-C2T1E1 */
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
+               ci->hdw_bid = SBE_BID_PCI_C1T1E1;       /* 0x01 - SBE wanPCI-C1T1E1 */
+               break;
+       default:
+               /*** bid = "<unknown>";  ***/
+               ci->hdw_bid = SBE_BID_PMC_C4T1E1;       /* 0x41 - SBE wanPTMC-C4T1E1 */
+               break;
+       }
 }
 
 /* given the presetting of hdw_bid, set the corresponding brd_id */
 
 void
-sbeid_set_bdtype (ci_t *ci)
+sbeid_set_bdtype(ci_t *ci)
 {
-    /* set SBE's unique PCI VENDOR/DEVID */
-    switch (ci->hdw_bid)
-    {
-        case SBE_BID_C1T3:      /* SBE wanPMC-C1T3 */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3);
-        break;
-    case SBE_BID_C24TE1:            /* SBE wanPTMC-C24TE1 */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1);
-        break;
-    case SBE_BID_256T3_E1:          /* SBE wanPTMC-256T3 E1 Version */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1);
-        break;
-    case SBE_BID_256T3_T1:          /* SBE wanPTMC-256T3 T1 Version */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1);
-        break;
-    case SBE_BID_PMC_C4T1E1:        /* 0xC4 - SBE wanPMC-C4T1E1 */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1);
-        break;
-    case SBE_BID_PMC_C2T1E1:        /* 0xC2 - SBE wanPMC-C2T1E1 */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1);
-        break;
-    case SBE_BID_PMC_C1T1E1:        /* 0xC1 - SBE wanPMC-C1T1E1 */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1);
-        break;
-    case SBE_BID_PCI_C4T1E1:        /* 0x04 - SBE wanPCI-C4T1E1 */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
-        break;
-    case SBE_BID_PCI_C2T1E1:        /* 0x02 - SBE wanPCI-C2T1E1 */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1);
-        break;
-    case SBE_BID_PCI_C1T1E1:        /* 0x01 - SBE wanPCI-C1T1E1 */
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1);
-        break;
+       /* set SBE's unique PCI VENDOR/DEVID */
+       switch (ci->hdw_bid) {
+       case SBE_BID_C1T3:      /* SBE wanPMC-C1T3 */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3);
+               break;
+       case SBE_BID_C24TE1:            /* SBE wanPTMC-C24TE1 */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1);
+               break;
+       case SBE_BID_256T3_E1:          /* SBE wanPTMC-256T3 E1 Version */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1);
+               break;
+       case SBE_BID_256T3_T1:          /* SBE wanPTMC-256T3 T1 Version */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1);
+               break;
+       case SBE_BID_PMC_C4T1E1:        /* 0xC4 - SBE wanPMC-C4T1E1 */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1);
+               break;
+       case SBE_BID_PMC_C2T1E1:        /* 0xC2 - SBE wanPMC-C2T1E1 */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1);
+               break;
+       case SBE_BID_PMC_C1T1E1:        /* 0xC1 - SBE wanPMC-C1T1E1 */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1);
+               break;
+       case SBE_BID_PCI_C4T1E1:        /* 0x04 - SBE wanPCI-C4T1E1 */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
+               break;
+       case SBE_BID_PCI_C2T1E1:        /* 0x02 - SBE wanPCI-C2T1E1 */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1);
+               break;
+       case SBE_BID_PCI_C1T1E1:        /* 0x01 - SBE wanPCI-C1T1E1 */
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1);
+               break;
 
-    default:
-        /*** hdw_bid = "<unknown>";  ***/
-        ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
-        break;
-    }
+       default:
+               /*** hdw_bid = "<unknown>";  ***/
+               ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
+               break;
+       }
 }
 
 
index 33ac7fb88cbd3b98b24b1eb50209e4a0b5c6100e..1f61b89eca44c084cb714052d5eb3fb3a7ba2566 100644 (file)
@@ -2232,6 +2232,177 @@ done:
        return rtn;
 }
 
+/*
+ * Common Packet Handling code
+ */
+
+static void handle_data_in_packet(struct nd_struct *nd, struct ch_struct *ch,
+                                 long dlen, long plen, int n1, u8 *dbuf)
+{
+       char *error;
+       long n;
+       long remain;
+       u8 *buf;
+       u8 *b;
+
+       remain = nd->nd_remain;
+       nd->nd_tx_work = 1;
+
+       /*
+        *  Otherwise data should appear only when we are
+        *  in the CS_READY state.
+        */
+
+       if (ch->ch_state < CS_READY) {
+               error = "Data received before RWIN established";
+               nd->nd_remain = 0;
+               nd->nd_state = NS_SEND_ERROR;
+               nd->nd_error = error;
+       }
+
+       /*
+        *  Assure that the data received is within the
+        *  allowable window.
+        */
+
+       n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff;
+
+       if (dlen > n) {
+               error = "Receive data overrun";
+               nd->nd_remain = 0;
+               nd->nd_state = NS_SEND_ERROR;
+               nd->nd_error = error;
+       }
+
+       /*
+        *  If we received 3 or less characters,
+        *  assume it is a human typing, and set RTIME
+        *  to 10 milliseconds.
+        *
+        *  If we receive 10 or more characters,
+        *  assume its not a human typing, and set RTIME
+        *  to 100 milliseconds.
+        */
+
+       if (ch->ch_edelay != DGRP_RTIME) {
+               if (ch->ch_rtime != ch->ch_edelay) {
+                       ch->ch_rtime = ch->ch_edelay;
+                       ch->ch_flag |= CH_PARAM;
+               }
+       } else if (dlen <= 3) {
+               if (ch->ch_rtime != 10) {
+                       ch->ch_rtime = 10;
+                       ch->ch_flag |= CH_PARAM;
+               }
+       } else {
+               if (ch->ch_rtime != DGRP_RTIME) {
+                       ch->ch_rtime = DGRP_RTIME;
+                       ch->ch_flag |= CH_PARAM;
+               }
+       }
+
+       /*
+        *  If a portion of the packet is outside the
+        *  buffer, shorten the effective length of the
+        *  data packet to be the amount of data received.
+        */
+
+       if (remain < plen)
+               dlen -= plen - remain;
+
+       /*
+        *  Detect if receive flush is now complete.
+        */
+
+       if ((ch->ch_flag & CH_RX_FLUSH) != 0 &&
+                       ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >=
+                       ((nd->nd_seq_in    - nd->nd_seq_out) & SEQ_MASK)) {
+               ch->ch_flag &= ~CH_RX_FLUSH;
+       }
+
+       /*
+        *  If we are ready to receive, move the data into
+        *  the receive buffer.
+        */
+
+       ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff;
+
+       if (ch->ch_state == CS_READY &&
+                       (ch->ch_tun.un_open_count != 0) &&
+                       (ch->ch_tun.un_flag & UN_CLOSING) == 0 &&
+                       (ch->ch_cflag & CF_CREAD) != 0 &&
+                       (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 &&
+                       (ch->ch_send & RR_RX_FLUSH) == 0) {
+
+               if (ch->ch_rin + dlen >= RBUF_MAX) {
+                       n = RBUF_MAX - ch->ch_rin;
+
+                       memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n);
+
+                       ch->ch_rin = 0;
+                       dbuf += n;
+                       dlen -= n;
+               }
+
+               memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen);
+
+               ch->ch_rin += dlen;
+
+
+               /*
+                *  If we are not in fastcook mode, or
+                *  if there is a fastcook thread
+                *  waiting for data, send the data to
+                *  the line discipline.
+                */
+
+               if ((ch->ch_flag & CH_FAST_READ) == 0 ||
+                               ch->ch_inwait != 0) {
+                       dgrp_input(ch);
+               }
+
+               /*
+                *  If there is a read thread waiting
+                *  in select, and we are in fastcook
+                *  mode, wake him up.
+                */
+
+               if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) &&
+                               (ch->ch_flag & CH_FAST_READ) != 0)
+                       wake_up_interruptible(&ch->ch_tun.un_tty->read_wait);
+
+               /*
+                * Wake any thread waiting in the
+                * fastcook loop.
+                */
+
+               if ((ch->ch_flag & CH_INPUT) != 0) {
+                       ch->ch_flag &= ~CH_INPUT;
+                       wake_up_interruptible(&ch->ch_flag_wait);
+               }
+       }
+
+       /*
+        *  Fabricate and insert a data packet header to
+        *  preced the remaining data when it comes in.
+        */
+
+       if (remain < plen) {
+               dlen = plen - remain;
+               b = buf;
+
+               b[0] = 0x90 + n1;
+               put_unaligned_be16(dlen, b + 1);
+
+               remain = 3;
+               if (remain > 0 && b != buf)
+                       memcpy(buf, b, remain);
+
+               nd->nd_remain = remain;
+               return;
+       }
+}
+
 /**
  * dgrp_receive() -- decode data packets received from the remote PortServer.
  * @nd: pointer to a node structure
@@ -2306,7 +2477,8 @@ static void dgrp_receive(struct nd_struct *nd)
                        plen = dlen + 1;
 
                        dbuf = b + 1;
-                       goto data;
+                       handle_data_in_packet(nd, ch, dlen, plen, n1, dbuf);
+                       break;
 
                /*
                 *  Process 2-byte header data packet.
@@ -2320,7 +2492,8 @@ static void dgrp_receive(struct nd_struct *nd)
                        plen = dlen + 2;
 
                        dbuf = b + 2;
-                       goto data;
+                       handle_data_in_packet(nd, ch, dlen, plen, n1, dbuf);
+                       break;
 
                /*
                 *  Process 3-byte header data packet.
@@ -2335,159 +2508,6 @@ static void dgrp_receive(struct nd_struct *nd)
 
                        dbuf = b + 3;
 
-               /*
-                *  Common packet handling code.
-                */
-
-data:
-                       nd->nd_tx_work = 1;
-
-                       /*
-                        *  Otherwise data should appear only when we are
-                        *  in the CS_READY state.
-                        */
-
-                       if (ch->ch_state < CS_READY) {
-                               error = "Data received before RWIN established";
-                               goto prot_error;
-                       }
-
-                       /*
-                        *  Assure that the data received is within the
-                        *  allowable window.
-                        */
-
-                       n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff;
-
-                       if (dlen > n) {
-                               error = "Receive data overrun";
-                               goto prot_error;
-                       }
-
-                       /*
-                        *  If we received 3 or less characters,
-                        *  assume it is a human typing, and set RTIME
-                        *  to 10 milliseconds.
-                        *
-                        *  If we receive 10 or more characters,
-                        *  assume its not a human typing, and set RTIME
-                        *  to 100 milliseconds.
-                        */
-
-                       if (ch->ch_edelay != DGRP_RTIME) {
-                               if (ch->ch_rtime != ch->ch_edelay) {
-                                       ch->ch_rtime = ch->ch_edelay;
-                                       ch->ch_flag |= CH_PARAM;
-                               }
-                       } else if (dlen <= 3) {
-                               if (ch->ch_rtime != 10) {
-                                       ch->ch_rtime = 10;
-                                       ch->ch_flag |= CH_PARAM;
-                               }
-                       } else {
-                               if (ch->ch_rtime != DGRP_RTIME) {
-                                       ch->ch_rtime = DGRP_RTIME;
-                                       ch->ch_flag |= CH_PARAM;
-                               }
-                       }
-
-                       /*
-                        *  If a portion of the packet is outside the
-                        *  buffer, shorten the effective length of the
-                        *  data packet to be the amount of data received.
-                        */
-
-                       if (remain < plen)
-                               dlen -= plen - remain;
-
-                       /*
-                        *  Detect if receive flush is now complete.
-                        */
-
-                       if ((ch->ch_flag & CH_RX_FLUSH) != 0 &&
-                           ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >=
-                           ((nd->nd_seq_in    - nd->nd_seq_out) & SEQ_MASK)) {
-                               ch->ch_flag &= ~CH_RX_FLUSH;
-                       }
-
-                       /*
-                        *  If we are ready to receive, move the data into
-                        *  the receive buffer.
-                        */
-
-                       ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff;
-
-                       if (ch->ch_state == CS_READY &&
-                           (ch->ch_tun.un_open_count != 0) &&
-                           (ch->ch_tun.un_flag & UN_CLOSING) == 0 &&
-                           (ch->ch_cflag & CF_CREAD) != 0 &&
-                           (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 &&
-                           (ch->ch_send & RR_RX_FLUSH) == 0) {
-
-                               if (ch->ch_rin + dlen >= RBUF_MAX) {
-                                       n = RBUF_MAX - ch->ch_rin;
-
-                                       memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n);
-
-                                       ch->ch_rin = 0;
-                                       dbuf += n;
-                                       dlen -= n;
-                               }
-
-                               memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen);
-
-                               ch->ch_rin += dlen;
-
-
-                               /*
-                                *  If we are not in fastcook mode, or
-                                *  if there is a fastcook thread
-                                *  waiting for data, send the data to
-                                *  the line discipline.
-                                */
-
-                               if ((ch->ch_flag & CH_FAST_READ) == 0 ||
-                                   ch->ch_inwait != 0) {
-                                       dgrp_input(ch);
-                               }
-
-                               /*
-                                *  If there is a read thread waiting
-                                *  in select, and we are in fastcook
-                                *  mode, wake him up.
-                                */
-
-                               if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) &&
-                                   (ch->ch_flag & CH_FAST_READ) != 0)
-                                       wake_up_interruptible(&ch->ch_tun.un_tty->read_wait);
-
-                               /*
-                                * Wake any thread waiting in the
-                                * fastcook loop.
-                                */
-
-                               if ((ch->ch_flag & CH_INPUT) != 0) {
-                                       ch->ch_flag &= ~CH_INPUT;
-
-                                       wake_up_interruptible(&ch->ch_flag_wait);
-                               }
-                       }
-
-                       /*
-                        *  Fabricate and insert a data packet header to
-                        *  preced the remaining data when it comes in.
-                        */
-
-                       if (remain < plen) {
-                               dlen = plen - remain;
-                               b = buf;
-
-                               b[0] = 0x90 + n1;
-                               put_unaligned_be16(dlen, b + 1);
-
-                               remain = 3;
-                               goto done;
-                       }
                        break;
 
                /*
index 6d001b52f6524a564360658eee2b37c55ddaf8a6..c0b122a67996a2945df03009a98950148d367493 100644 (file)
@@ -114,7 +114,7 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg)
  * Do core a soft reset of the core.  Be careful with this because it
  * resets all the internal state machines of the core.
  */
-static void dwc2_core_reset(struct dwc2_hsotg *hsotg)
+static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
 {
        u32 greset;
        int count = 0;
@@ -129,7 +129,7 @@ static void dwc2_core_reset(struct dwc2_hsotg *hsotg)
                        dev_warn(hsotg->dev,
                                 "%s() HANG! AHB Idle GRSTCTL=%0x\n",
                                 __func__, greset);
-                       return;
+                       return -EBUSY;
                }
        } while (!(greset & GRSTCTL_AHBIDLE));
 
@@ -144,7 +144,7 @@ static void dwc2_core_reset(struct dwc2_hsotg *hsotg)
                        dev_warn(hsotg->dev,
                                 "%s() HANG! Soft Reset GRSTCTL=%0x\n",
                                 __func__, greset);
-                       break;
+                       return -EBUSY;
                }
        } while (greset & GRSTCTL_CSFTRST);
 
@@ -153,11 +153,14 @@ static void dwc2_core_reset(struct dwc2_hsotg *hsotg)
         * not stay in host mode after a connector ID change!
         */
        usleep_range(150000, 200000);
+
+       return 0;
 }
 
-static void dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 {
        u32 usbcfg, i2cctl;
+       int retval = 0;
 
        /*
         * core_init() is now called on every switch so only call the
@@ -170,7 +173,12 @@ static void dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
                writel(usbcfg, hsotg->regs + GUSBCFG);
 
                /* Reset after a PHY select */
-               dwc2_core_reset(hsotg);
+               retval = dwc2_core_reset(hsotg);
+               if (retval) {
+                       dev_err(hsotg->dev, "%s() Reset failed, aborting",
+                                       __func__);
+                       return retval;
+               }
        }
 
        /*
@@ -198,14 +206,17 @@ static void dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
                i2cctl |= GI2CCTL_I2CEN;
                writel(i2cctl, hsotg->regs + GI2CCTL);
        }
+
+       return retval;
 }
 
-static void dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 {
        u32 usbcfg;
+       int retval = 0;
 
        if (!select_phy)
-               return;
+               return -ENODEV;
 
        usbcfg = readl(hsotg->regs + GUSBCFG);
 
@@ -238,20 +249,32 @@ static void dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
        writel(usbcfg, hsotg->regs + GUSBCFG);
 
        /* Reset after setting the PHY parameters */
-       dwc2_core_reset(hsotg);
+       retval = dwc2_core_reset(hsotg);
+       if (retval) {
+               dev_err(hsotg->dev, "%s() Reset failed, aborting",
+                               __func__);
+               return retval;
+       }
+
+       return retval;
 }
 
-static void dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 {
        u32 usbcfg;
+       int retval = 0;
 
        if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL &&
            hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) {
                /* If FS mode with FS PHY */
-               dwc2_fs_phy_init(hsotg, select_phy);
+               retval = dwc2_fs_phy_init(hsotg, select_phy);
+               if (retval)
+                       return retval;
        } else {
                /* High speed PHY */
-               dwc2_hs_phy_init(hsotg, select_phy);
+               retval = dwc2_hs_phy_init(hsotg, select_phy);
+               if (retval)
+                       return retval;
        }
 
        if (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI &&
@@ -268,6 +291,8 @@ static void dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
                usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M;
                writel(usbcfg, hsotg->regs + GUSBCFG);
        }
+
+       return retval;
 }
 
 static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
@@ -382,12 +407,19 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq)
        writel(usbcfg, hsotg->regs + GUSBCFG);
 
        /* Reset the Controller */
-       dwc2_core_reset(hsotg);
+       retval = dwc2_core_reset(hsotg);
+       if (retval) {
+               dev_err(hsotg->dev, "%s(): Reset failed, aborting\n",
+                               __func__);
+               return retval;
+       }
 
        /*
         * This needs to happen in FS mode before any other programming occurs
         */
-       dwc2_phy_init(hsotg, select_phy);
+       retval = dwc2_phy_init(hsotg, select_phy);
+       if (retval)
+               return retval;
 
        /* Program the GAHBCFG Register */
        retval = dwc2_gahbcfg_init(hsotg);
@@ -451,9 +483,6 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg)
        writel(0, hsotg->regs + GINTMSK);
        writel(0, hsotg->regs + HAINTMSK);
 
-       /* Clear any pending interrupts */
-       writel(0xffffffff, hsotg->regs + GINTSTS);
-
        /* Enable the common interrupts */
        dwc2_enable_common_interrupts(hsotg);
 
@@ -1912,13 +1941,12 @@ void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg)
        udelay(1);
 }
 
-#define DWC2_PARAM_TEST(a, b, c)       ((a) < (b) || (a) > (c))
+#define DWC2_OUT_OF_BOUNDS(a, b, c)    ((a) < (b) || (a) > (c))
 
 /* Parameter access functions */
-int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        switch (val) {
        case DWC2_CAP_PARAM_HNP_SRP_CAPABLE:
@@ -1964,17 +1992,14 @@ int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val)
                        break;
                }
                dev_dbg(hsotg->dev, "Setting otg_cap to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->otg_cap = val;
-       return retval;
 }
 
-int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        if (val > 0 && hsotg->hw_params.arch == GHWCFG2_SLAVE_ONLY_ARCH)
                valid = 0;
@@ -1988,17 +2013,14 @@ int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val)
                                val);
                val = hsotg->hw_params.arch != GHWCFG2_SLAVE_ONLY_ARCH;
                dev_dbg(hsotg->dev, "Setting dma_enable to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->dma_enable = val;
-       return retval;
 }
 
-int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        if (val > 0 && (hsotg->core_params->dma_enable <= 0 ||
                        !hsotg->hw_params.dma_desc_enable))
@@ -2014,19 +2036,15 @@ int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val)
                val = (hsotg->core_params->dma_enable > 0 &&
                        hsotg->hw_params.dma_desc_enable);
                dev_dbg(hsotg->dev, "Setting dma_desc_enable to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->dma_desc_enable = val;
-       return retval;
 }
 
-int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg,
-                                               int val)
+void dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg,
+                                                int val)
 {
-       int retval = 0;
-
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev,
                                "Wrong value for host_support_fs_low_power\n");
@@ -2036,17 +2054,14 @@ int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg,
                val = 0;
                dev_dbg(hsotg->dev,
                        "Setting host_support_fs_low_power to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->host_support_fs_ls_low_power = val;
-       return retval;
 }
 
-int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        if (val > 0 && !hsotg->hw_params.enable_dynamic_fifo)
                valid = 0;
@@ -2060,17 +2075,14 @@ int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val)
                                val);
                val = hsotg->hw_params.enable_dynamic_fifo;
                dev_dbg(hsotg->dev, "Setting enable_dynamic_fifo to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->enable_dynamic_fifo = val;
-       return retval;
 }
 
-int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        if (val < 16 || val > hsotg->hw_params.host_rx_fifo_size)
                valid = 0;
@@ -2082,17 +2094,14 @@ int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val)
                                val);
                val = hsotg->hw_params.host_rx_fifo_size;
                dev_dbg(hsotg->dev, "Setting host_rx_fifo_size to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->host_rx_fifo_size = val;
-       return retval;
 }
 
-int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        if (val < 16 || val > hsotg->hw_params.host_nperio_tx_fifo_size)
                valid = 0;
@@ -2105,17 +2114,14 @@ int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
                val = hsotg->hw_params.host_nperio_tx_fifo_size;
                dev_dbg(hsotg->dev, "Setting host_nperio_tx_fifo_size to %d\n",
                        val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->host_nperio_tx_fifo_size = val;
-       return retval;
 }
 
-int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        if (val < 16 || val > hsotg->hw_params.host_perio_tx_fifo_size)
                valid = 0;
@@ -2128,17 +2134,14 @@ int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
                val = hsotg->hw_params.host_perio_tx_fifo_size;
                dev_dbg(hsotg->dev, "Setting host_perio_tx_fifo_size to %d\n",
                        val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->host_perio_tx_fifo_size = val;
-       return retval;
 }
 
-int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        if (val < 2047 || val > hsotg->hw_params.max_transfer_size)
                valid = 0;
@@ -2150,17 +2153,14 @@ int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val)
                                val);
                val = hsotg->hw_params.max_transfer_size;
                dev_dbg(hsotg->dev, "Setting max_transfer_size to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->max_transfer_size = val;
-       return retval;
 }
 
-int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        if (val < 15 || val > hsotg->hw_params.max_packet_count)
                valid = 0;
@@ -2172,17 +2172,14 @@ int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val)
                                val);
                val = hsotg->hw_params.max_packet_count;
                dev_dbg(hsotg->dev, "Setting max_packet_count to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->max_packet_count = val;
-       return retval;
 }
 
-int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
        if (val < 1 || val > hsotg->hw_params.host_channels)
                valid = 0;
@@ -2194,38 +2191,26 @@ int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val)
                                val);
                val = hsotg->hw_params.host_channels;
                dev_dbg(hsotg->dev, "Setting host_channels to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->host_channels = val;
-       return retval;
 }
 
-int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val)
 {
-#ifndef NO_FS_PHY_HW_CHECKS
        int valid = 0;
        u32 hs_phy_type, fs_phy_type;
-#endif
-       int retval = 0;
 
-       if (DWC2_PARAM_TEST(val, DWC2_PHY_TYPE_PARAM_FS,
-                           DWC2_PHY_TYPE_PARAM_ULPI)) {
+       if (DWC2_OUT_OF_BOUNDS(val, DWC2_PHY_TYPE_PARAM_FS,
+                              DWC2_PHY_TYPE_PARAM_ULPI)) {
                if (val >= 0) {
                        dev_err(hsotg->dev, "Wrong value for phy_type\n");
                        dev_err(hsotg->dev, "phy_type must be 0, 1 or 2\n");
                }
 
-#ifndef NO_FS_PHY_HW_CHECKS
                valid = 0;
-#else
-               val = DWC2_PHY_TYPE_PARAM_FS;
-               dev_dbg(hsotg->dev, "Setting phy_type to %d\n", val);
-               retval = -EINVAL;
-#endif
        }
 
-#ifndef NO_FS_PHY_HW_CHECKS
        hs_phy_type = hsotg->hw_params.hs_phy_type;
        fs_phy_type = hsotg->hw_params.fs_phy_type;
        if (val == DWC2_PHY_TYPE_PARAM_UTMI &&
@@ -2254,12 +2239,9 @@ int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val)
                                val = DWC2_PHY_TYPE_PARAM_ULPI;
                }
                dev_dbg(hsotg->dev, "Setting phy_type to %d\n", val);
-               retval = -EINVAL;
        }
-#endif
 
        hsotg->core_params->phy_type = val;
-       return retval;
 }
 
 static int dwc2_get_param_phy_type(struct dwc2_hsotg *hsotg)
@@ -2267,12 +2249,11 @@ static int dwc2_get_param_phy_type(struct dwc2_hsotg *hsotg)
        return hsotg->core_params->phy_type;
 }
 
-int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev, "Wrong value for speed parameter\n");
                        dev_err(hsotg->dev, "max_speed parameter must be 0 or 1\n");
@@ -2292,20 +2273,17 @@ int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val)
                val = dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS ?
                                DWC2_SPEED_PARAM_FULL : DWC2_SPEED_PARAM_HIGH;
                dev_dbg(hsotg->dev, "Setting speed to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->speed = val;
-       return retval;
 }
 
-int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
-       if (DWC2_PARAM_TEST(val, DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ,
-                           DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) {
+       if (DWC2_OUT_OF_BOUNDS(val, DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ,
+                              DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) {
                if (val >= 0) {
                        dev_err(hsotg->dev,
                                "Wrong value for host_ls_low_power_phy_clk parameter\n");
@@ -2329,36 +2307,28 @@ int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, int val)
                        : DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
                dev_dbg(hsotg->dev, "Setting host_ls_low_power_phy_clk to %d\n",
                        val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->host_ls_low_power_phy_clk = val;
-       return retval;
 }
 
-int dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val)
 {
-       int retval = 0;
-
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev, "Wrong value for phy_ulpi_ddr\n");
                        dev_err(hsotg->dev, "phy_upli_ddr must be 0 or 1\n");
                }
                val = 0;
                dev_dbg(hsotg->dev, "Setting phy_upli_ddr to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->phy_ulpi_ddr = val;
-       return retval;
 }
 
-int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val)
 {
-       int retval = 0;
-
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev,
                                "Wrong value for phy_ulpi_ext_vbus\n");
@@ -2367,17 +2337,14 @@ int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val)
                }
                val = 0;
                dev_dbg(hsotg->dev, "Setting phy_ulpi_ext_vbus to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->phy_ulpi_ext_vbus = val;
-       return retval;
 }
 
-int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 0;
-       int retval = 0;
 
        switch (hsotg->hw_params.utmi_phy_data_width) {
        case GHWCFG4_UTMI_PHY_DATA_WIDTH_8:
@@ -2400,72 +2367,52 @@ int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val)
                val = (hsotg->hw_params.utmi_phy_data_width ==
                       GHWCFG4_UTMI_PHY_DATA_WIDTH_8) ? 8 : 16;
                dev_dbg(hsotg->dev, "Setting phy_utmi_width to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->phy_utmi_width = val;
-       return retval;
 }
 
-int dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val)
 {
-       int retval = 0;
-
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev, "Wrong value for ulpi_fs_ls\n");
                        dev_err(hsotg->dev, "ulpi_fs_ls must be 0 or 1\n");
                }
                val = 0;
                dev_dbg(hsotg->dev, "Setting ulpi_fs_ls to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->ulpi_fs_ls = val;
-       return retval;
 }
 
-int dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val)
 {
-       int retval = 0;
-
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev, "Wrong value for ts_dline\n");
                        dev_err(hsotg->dev, "ts_dline must be 0 or 1\n");
                }
                val = 0;
                dev_dbg(hsotg->dev, "Setting ts_dline to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->ts_dline = val;
-       return retval;
 }
 
-int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val)
 {
-#ifndef NO_FS_PHY_HW_CHECKS
        int valid = 1;
-#endif
-       int retval = 0;
 
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev, "Wrong value for i2c_enable\n");
                        dev_err(hsotg->dev, "i2c_enable must be 0 or 1\n");
                }
 
-#ifndef NO_FS_PHY_HW_CHECKS
                valid = 0;
-#else
-               val = 0;
-               dev_dbg(hsotg->dev, "Setting i2c_enable to %d\n", val);
-               retval = -EINVAL;
-#endif
        }
 
-#ifndef NO_FS_PHY_HW_CHECKS
        if (val == 1 && !(hsotg->hw_params.i2c_enable))
                valid = 0;
 
@@ -2476,20 +2423,16 @@ int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val)
                                val);
                val = hsotg->hw_params.i2c_enable;
                dev_dbg(hsotg->dev, "Setting i2c_enable to %d\n", val);
-               retval = -EINVAL;
        }
-#endif
 
        hsotg->core_params->i2c_enable = val;
-       return retval;
 }
 
-int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev,
                                "Wrong value for en_multiple_tx_fifo,\n");
@@ -2509,19 +2452,16 @@ int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val)
                                val);
                val = hsotg->hw_params.en_multiple_tx_fifo;
                dev_dbg(hsotg->dev, "Setting en_multiple_tx_fifo to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->en_multiple_tx_fifo = val;
-       return retval;
 }
 
-int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val)
 {
        int valid = 1;
-       int retval = 0;
 
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev,
                                "'%d' invalid for parameter reload_ctl\n", val);
@@ -2540,28 +2480,23 @@ int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val)
                                val);
                val = hsotg->hw_params.snpsid >= DWC2_CORE_REV_2_92a;
                dev_dbg(hsotg->dev, "Setting reload_ctl to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->reload_ctl = val;
-       return retval;
 }
 
-int dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val)
 {
        if (val != -1)
                hsotg->core_params->ahbcfg = val;
        else
                hsotg->core_params->ahbcfg = GAHBCFG_HBSTLEN_INCR4 <<
                                                GAHBCFG_HBSTLEN_SHIFT;
-       return 0;
 }
 
-int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val)
 {
-       int retval = 0;
-
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev,
                                "'%d' invalid for parameter otg_ver\n", val);
@@ -2570,11 +2505,9 @@ int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val)
                }
                val = 0;
                dev_dbg(hsotg->dev, "Setting otg_ver to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->otg_ver = val;
-       return retval;
 }
 
 /**
@@ -2736,11 +2669,9 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
        return 0;
 }
 
-int dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val)
+void dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val)
 {
-       int retval = 0;
-
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
+       if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
                if (val >= 0) {
                        dev_err(hsotg->dev,
                                "'%d' invalid for parameter uframe_sched\n",
@@ -2749,75 +2680,68 @@ int dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val)
                }
                val = 1;
                dev_dbg(hsotg->dev, "Setting uframe_sched to %d\n", val);
-               retval = -EINVAL;
        }
 
        hsotg->core_params->uframe_sched = val;
-       return retval;
 }
 
 /*
  * This function is called during module intialization to pass module parameters
  * for the DWC_otg core. It returns non-0 if any parameters are invalid.
  */
-int dwc2_set_parameters(struct dwc2_hsotg *hsotg,
-                       const struct dwc2_core_params *params)
+void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
+                        const struct dwc2_core_params *params)
 {
-       int retval = 0;
-
        dev_dbg(hsotg->dev, "%s()\n", __func__);
 
-       retval |= dwc2_set_param_otg_cap(hsotg, params->otg_cap);
-       retval |= dwc2_set_param_dma_enable(hsotg, params->dma_enable);
-       retval |= dwc2_set_param_dma_desc_enable(hsotg,
-                                                params->dma_desc_enable);
-       retval |= dwc2_set_param_host_support_fs_ls_low_power(hsotg,
+       dwc2_set_param_otg_cap(hsotg, params->otg_cap);
+       dwc2_set_param_dma_enable(hsotg, params->dma_enable);
+       dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable);
+       dwc2_set_param_host_support_fs_ls_low_power(hsotg,
                        params->host_support_fs_ls_low_power);
-       retval |= dwc2_set_param_enable_dynamic_fifo(hsotg,
+       dwc2_set_param_enable_dynamic_fifo(hsotg,
                        params->enable_dynamic_fifo);
-       retval |= dwc2_set_param_host_rx_fifo_size(hsotg,
+       dwc2_set_param_host_rx_fifo_size(hsotg,
                        params->host_rx_fifo_size);
-       retval |= dwc2_set_param_host_nperio_tx_fifo_size(hsotg,
+       dwc2_set_param_host_nperio_tx_fifo_size(hsotg,
                        params->host_nperio_tx_fifo_size);
-       retval |= dwc2_set_param_host_perio_tx_fifo_size(hsotg,
+       dwc2_set_param_host_perio_tx_fifo_size(hsotg,
                        params->host_perio_tx_fifo_size);
-       retval |= dwc2_set_param_max_transfer_size(hsotg,
+       dwc2_set_param_max_transfer_size(hsotg,
                        params->max_transfer_size);
-       retval |= dwc2_set_param_max_packet_count(hsotg,
+       dwc2_set_param_max_packet_count(hsotg,
                        params->max_packet_count);
-       retval |= dwc2_set_param_host_channels(hsotg, params->host_channels);
-       retval |= dwc2_set_param_phy_type(hsotg, params->phy_type);
-       retval |= dwc2_set_param_speed(hsotg, params->speed);
-       retval |= dwc2_set_param_host_ls_low_power_phy_clk(hsotg,
+       dwc2_set_param_host_channels(hsotg, params->host_channels);
+       dwc2_set_param_phy_type(hsotg, params->phy_type);
+       dwc2_set_param_speed(hsotg, params->speed);
+       dwc2_set_param_host_ls_low_power_phy_clk(hsotg,
                        params->host_ls_low_power_phy_clk);
-       retval |= dwc2_set_param_phy_ulpi_ddr(hsotg, params->phy_ulpi_ddr);
-       retval |= dwc2_set_param_phy_ulpi_ext_vbus(hsotg,
+       dwc2_set_param_phy_ulpi_ddr(hsotg, params->phy_ulpi_ddr);
+       dwc2_set_param_phy_ulpi_ext_vbus(hsotg,
                        params->phy_ulpi_ext_vbus);
-       retval |= dwc2_set_param_phy_utmi_width(hsotg, params->phy_utmi_width);
-       retval |= dwc2_set_param_ulpi_fs_ls(hsotg, params->ulpi_fs_ls);
-       retval |= dwc2_set_param_ts_dline(hsotg, params->ts_dline);
-       retval |= dwc2_set_param_i2c_enable(hsotg, params->i2c_enable);
-       retval |= dwc2_set_param_en_multiple_tx_fifo(hsotg,
+       dwc2_set_param_phy_utmi_width(hsotg, params->phy_utmi_width);
+       dwc2_set_param_ulpi_fs_ls(hsotg, params->ulpi_fs_ls);
+       dwc2_set_param_ts_dline(hsotg, params->ts_dline);
+       dwc2_set_param_i2c_enable(hsotg, params->i2c_enable);
+       dwc2_set_param_en_multiple_tx_fifo(hsotg,
                        params->en_multiple_tx_fifo);
-       retval |= dwc2_set_param_reload_ctl(hsotg, params->reload_ctl);
-       retval |= dwc2_set_param_ahbcfg(hsotg, params->ahbcfg);
-       retval |= dwc2_set_param_otg_ver(hsotg, params->otg_ver);
-       retval |= dwc2_set_param_uframe_sched(hsotg, params->uframe_sched);
-
-       return retval;
+       dwc2_set_param_reload_ctl(hsotg, params->reload_ctl);
+       dwc2_set_param_ahbcfg(hsotg, params->ahbcfg);
+       dwc2_set_param_otg_ver(hsotg, params->otg_ver);
+       dwc2_set_param_uframe_sched(hsotg, params->uframe_sched);
 }
 
 u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg)
 {
-       return (u16)(hsotg->core_params->otg_ver == 1 ? 0x0200 : 0x0103);
+       return hsotg->core_params->otg_ver == 1 ? 0x0200 : 0x0103;
 }
 
-int dwc2_check_core_status(struct dwc2_hsotg *hsotg)
+bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
 {
        if (readl(hsotg->regs + GSNPSID) == 0xffffffff)
-               return -1;
+               return false;
        else
-               return 0;
+               return true;
 }
 
 /**
index fab718d9b326344860ed6af876a9a2e840893bb1..648519c024b533c72dba9d0ff5dc28f29b9a174e 100644 (file)
@@ -544,7 +544,7 @@ extern void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg);
 extern void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg);
 
 extern u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg);
-extern int dwc2_check_core_status(struct dwc2_hsotg *hsotg);
+extern bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg);
 
 /*
  * Common core Functions.
@@ -571,7 +571,7 @@ extern irqreturn_t dwc2_handle_common_intr(int irq, void *dev);
  * 1 - SRP Only capable
  * 2 - No HNP/SRP capable
  */
-extern int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val);
 #define DWC2_CAP_PARAM_HNP_SRP_CAPABLE         0
 #define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE                1
 #define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE      2
@@ -583,7 +583,7 @@ extern int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val);
  * 0 - Slave
  * 1 - DMA (default, if available)
  */
-extern int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * When DMA mode is enabled specifies whether to use
@@ -593,7 +593,7 @@ extern int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val);
  * 0 - address DMA
  * 1 - DMA Descriptor(default, if available)
  */
-extern int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * Specifies the maximum speed of operation in host and device mode.
@@ -603,7 +603,7 @@ extern int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val);
  * 0 - High Speed (default)
  * 1 - Full Speed
  */
-extern int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val);
 #define DWC2_SPEED_PARAM_HIGH  0
 #define DWC2_SPEED_PARAM_FULL  1
 
@@ -614,8 +614,8 @@ extern int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val);
  * 0 - Don't support low power mode (default)
  * 1 - Support low power mode
  */
-extern int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg,
-                                                      int val);
+extern void dwc2_set_param_host_support_fs_ls_low_power(
+               struct dwc2_hsotg *hsotg, int val);
 
 /*
  * Specifies the PHY clock rate in low power mode when connected to a
@@ -626,8 +626,8 @@ extern int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg,
  * 0 - 48 MHz
  * 1 - 6 MHz
  */
-extern int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg,
-                                                   int val);
+extern void dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg,
+                                                    int val);
 #define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ     0
 #define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ      1
 
@@ -635,50 +635,50 @@ extern int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg,
  * 0 - Use cC FIFO size parameters
  * 1 - Allow dynamic FIFO sizing (default)
  */
-extern int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg,
-                                             int val);
+extern void dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg,
+                                              int val);
 
 /*
  * Number of 4-byte words in the Rx FIFO in host mode when dynamic
  * FIFO sizing is enabled.
  * 16 to 32768 (default 1024)
  */
-extern int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * Number of 4-byte words in the non-periodic Tx FIFO in host mode
  * when Dynamic FIFO sizing is enabled in the core.
  * 16 to 32768 (default 256)
  */
-extern int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg,
-                                                  int val);
+extern void dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg,
+                                                   int val);
 
 /*
  * Number of 4-byte words in the host periodic Tx FIFO when dynamic
  * FIFO sizing is enabled.
  * 16 to 32768 (default 256)
  */
-extern int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg,
-                                                 int val);
+extern void dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg,
+                                                  int val);
 
 /*
  * The maximum transfer size supported in bytes.
  * 2047 to 65,535  (default 65,535)
  */
-extern int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * The maximum number of packets in a transfer.
  * 15 to 511  (default 511)
  */
-extern int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * The number of host channel registers to use.
  * 1 to 16 (default 11)
  * Note: The FPGA configuration supports a maximum of 11 host channels.
  */
-extern int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * Specifies the type of PHY interface to use. By default, the driver
@@ -688,7 +688,7 @@ extern int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val);
  * 1 - UTMI+ (default)
  * 2 - ULPI
  */
-extern int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val);
 #define DWC2_PHY_TYPE_PARAM_FS         0
 #define DWC2_PHY_TYPE_PARAM_UTMI       1
 #define DWC2_PHY_TYPE_PARAM_ULPI       2
@@ -704,7 +704,7 @@ extern int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val);
  *
  * 8 or 16 bits (default 16)
  */
-extern int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * Specifies whether the ULPI operates at double or single
@@ -716,13 +716,13 @@ extern int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val);
  * 1 - double data rate ULPI interface with 4 bit wide data
  * bus
  */
-extern int dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * Specifies whether to use the internal or external supply to
  * drive the vbus with a ULPI phy.
  */
-extern int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val);
 #define DWC2_PHY_ULPI_INTERNAL_VBUS    0
 #define DWC2_PHY_ULPI_EXTERNAL_VBUS    1
 
@@ -732,11 +732,11 @@ extern int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val);
  * 0 - No (default)
  * 1 - Yes
  */
-extern int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val);
 
-extern int dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val);
 
-extern int dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * Specifies whether dedicated transmit FIFOs are
@@ -744,14 +744,14 @@ extern int dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val);
  * 0 - No
  * 1 - Yes
  */
-extern int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg,
-                                             int val);
+extern void dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg,
+                                              int val);
 
-extern int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val);
 
-extern int dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val);
 
-extern int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val);
+extern void dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val);
 
 /*
  * Dump core registers and SPRAM
index 07cfa2f6aa2ba7ea56a174df106263c58bd4f80e..8205799e6db32082cfd36aa9343464fa16283cf0 100644 (file)
@@ -55,7 +55,6 @@
 
 static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg)
 {
-#ifdef DEBUG
        switch (hsotg->op_state) {
        case OTG_STATE_A_HOST:
                return "a_host";
@@ -70,9 +69,6 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg)
        default:
                return "unknown";
        }
-#else
-       return "";
-#endif
 }
 
 /**
@@ -419,12 +415,10 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg)
        gintmsk = readl(hsotg->regs + GINTMSK);
        gahbcfg = readl(hsotg->regs + GAHBCFG);
 
-#ifdef DEBUG
        /* If any common interrupts set */
        if (gintsts & gintmsk_common)
                dev_dbg(hsotg->dev, "gintsts=%08x  gintmsk=%08x\n",
                        gintsts, gintmsk);
-#endif
 
        if (gahbcfg & GAHBCFG_GLBL_INTR_EN)
                return gintsts & gintmsk & gintmsk_common;
@@ -451,8 +445,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev)
        u32 gintsts;
        irqreturn_t retval = IRQ_NONE;
 
-       if (dwc2_check_core_status(hsotg) < 0) {
-               dev_warn(hsotg->dev, "Controller is disconnected\n");
+       if (!dwc2_is_controller_alive(hsotg)) {
+               dev_warn(hsotg->dev, "Controller is dead\n");
                goto out;
        }
 
index 3cfd2d5152c92b001ce3fba0752665612a04d2c7..24a4efe874d66fbb292b7a6d2943a5ad1549fd4d 100644 (file)
@@ -369,7 +369,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
        dwc2_hcd_qtd_init(qtd, urb);
        retval = dwc2_hcd_qtd_add(hsotg, qtd, (struct dwc2_qh **)ep_handle,
                                  mem_flags);
-       if (retval < 0) {
+       if (retval) {
                dev_err(hsotg->dev,
                        "DWC OTG HCD URB Enqueue failed adding QTD. Error status %d\n",
                        retval);
@@ -378,7 +378,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
        }
 
        intr_mask = readl(hsotg->regs + GINTMSK);
-       if (!(intr_mask & GINTSTS_SOF) && retval == 0) {
+       if (!(intr_mask & GINTSTS_SOF)) {
                enum dwc2_transaction_type tr_type;
 
                if (qtd->qh->ep_type == USB_ENDPOINT_XFER_BULK &&
@@ -396,7 +396,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
                spin_unlock_irqrestore(&hsotg->lock, flags);
        }
 
-       return retval;
+       return 0;
 }
 
 /* Must be called with interrupt disabled and spinlock held */
index 89a5484f5b740eeb30f742d4308d212c6cee2480..fdc6d489084aea61d2afa528a74f416089321d7a 100644 (file)
@@ -452,8 +452,8 @@ static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe)
 extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
                         const struct dwc2_core_params *params);
 extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg);
-extern int dwc2_set_parameters(struct dwc2_hsotg *hsotg,
-                              const struct dwc2_core_params *params);
+extern void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
+                               const struct dwc2_core_params *params);
 extern void dwc2_set_all_params(struct dwc2_core_params *params, int value);
 extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg);
 
index c7d434519776eb4fdf42fa69a5566639dc6a7e06..72e9788c1a13fdcd8b138c905aa2c6baba2b6c4c 100644 (file)
@@ -1103,8 +1103,10 @@ static void dwc2_complete_non_isoc_xfer_ddma(struct dwc2_hsotg *hsotg,
                for (i = 0; i < qtd->n_desc; i++) {
                        if (dwc2_process_non_isoc_desc(hsotg, chan, chnum, qtd,
                                                       desc_num, halt_status,
-                                                      &xfer_done))
+                                                      &xfer_done)) {
+                               qtd = NULL;
                                break;
+                       }
                        desc_num++;
                }
        }
index dda18540f5a7f306b3b003cd9b47f7e0b7c87c05..e672e6db2943fdb2f904f6e8b31c27d1cd92fea1 100644 (file)
@@ -2059,8 +2059,8 @@ irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg)
        u32 gintsts, dbg_gintsts;
        irqreturn_t retval = IRQ_NONE;
 
-       if (dwc2_check_core_status(hsotg) < 0) {
-               dev_warn(hsotg->dev, "Controller is disconnected\n");
+       if (!dwc2_is_controller_alive(hsotg) < 0) {
+               dev_warn(hsotg->dev, "Controller is dead\n");
                return retval;
        }
 
index f200f1f6e1c67ddf3d151552e3aeed0088b5b8f8..9540f7e1e20e5c65cd60b4c5d291d82784331df4 100644 (file)
@@ -344,25 +344,17 @@ void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg)
 static int dwc2_find_single_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 {
        unsigned short utime = qh->usecs;
-       int done = 0;
-       int i = 0;
-       int ret = -1;
+       int i;
 
-       while (!done) {
+       for (i = 0; i < 8; i++) {
                /* At the start hsotg->frame_usecs[i] = max_uframe_usecs[i] */
                if (utime <= hsotg->frame_usecs[i]) {
                        hsotg->frame_usecs[i] -= utime;
                        qh->frame_usecs[i] += utime;
-                       ret = i;
-                       done = 1;
-               } else {
-                       i++;
-                       if (i == 8)
-                               done = 1;
+                       return i;
                }
        }
-
-       return ret;
+       return -ENOSPC;
 }
 
 /*
@@ -372,21 +364,14 @@ static int dwc2_find_multi_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 {
        unsigned short utime = qh->usecs;
        unsigned short xtime;
-       int t_left = utime;
-       int done = 0;
-       int i = 0;
+       int t_left;
+       int i;
        int j;
-       int ret = -1;
-
-       while (!done) {
-               if (hsotg->frame_usecs[i] <= 0) {
-                       i++;
-                       if (i == 8) {
-                               ret = -1;
-                               done = 1;
-                       }
+       int k;
+
+       for (i = 0; i < 8; i++) {
+               if (hsotg->frame_usecs[i] <= 0)
                        continue;
-               }
 
                /*
                 * we need n consecutive slots so use j as a start slot
@@ -400,50 +385,35 @@ static int dwc2_find_multi_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
                         */
                        if (xtime + hsotg->frame_usecs[j] < utime) {
                                if (hsotg->frame_usecs[j] <
-                                                       max_uframe_usecs[j]) {
-                                       ret = -1;
-                                       break;
-                               }
+                                                       max_uframe_usecs[j])
+                                       continue;
                        }
                        if (xtime >= utime) {
-                               ret = i;
-                               break;
+                               t_left = utime;
+                               for (k = i; k < 8; k++) {
+                                       t_left -= hsotg->frame_usecs[k];
+                                       if (t_left <= 0) {
+                                               qh->frame_usecs[k] +=
+                                                       hsotg->frame_usecs[k]
+                                                               + t_left;
+                                               hsotg->frame_usecs[k] = -t_left;
+                                               return i;
+                                       } else {
+                                               qh->frame_usecs[k] +=
+                                                       hsotg->frame_usecs[k];
+                                               hsotg->frame_usecs[k] = 0;
+                                       }
+                               }
                        }
                        /* add the frame time to x time */
                        xtime += hsotg->frame_usecs[j];
                        /* we must have a fully available next frame or break */
                        if (xtime < utime &&
-                          hsotg->frame_usecs[j] == max_uframe_usecs[j]) {
-                               ret = -1;
-                               break;
-                       }
-               }
-               if (ret >= 0) {
-                       t_left = utime;
-                       for (j = i; t_left > 0 && j < 8; j++) {
-                               t_left -= hsotg->frame_usecs[j];
-                               if (t_left <= 0) {
-                                       qh->frame_usecs[j] +=
-                                               hsotg->frame_usecs[j] + t_left;
-                                       hsotg->frame_usecs[j] = -t_left;
-                                       ret = i;
-                                       done = 1;
-                               } else {
-                                       qh->frame_usecs[j] +=
-                                               hsotg->frame_usecs[j];
-                                       hsotg->frame_usecs[j] = 0;
-                               }
-                       }
-               } else {
-                       i++;
-                       if (i == 8) {
-                               ret = -1;
-                               done = 1;
-                       }
+                          hsotg->frame_usecs[j] == max_uframe_usecs[j])
+                               continue;
                }
        }
-
-       return ret;
+       return -ENOSPC;
 }
 
 static int dwc2_find_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
@@ -517,12 +487,12 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
                        frame = status - 1;
 
                /* Set the new frame up */
-               if (frame > -1) {
+               if (frame >= 0) {
                        qh->sched_frame &= ~0x7;
                        qh->sched_frame |= (frame & 7);
                }
 
-               if (status != -1)
+               if (status > 0)
                        status = 0;
        } else {
                status = dwc2_periodic_channel_available(hsotg);
@@ -609,7 +579,7 @@ static void dwc2_deschedule_periodic(struct dwc2_hsotg *hsotg,
  */
 int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 {
-       int status = 0;
+       int status;
        u32 intr_mask;
 
        if (dbg_qh(qh))
@@ -617,26 +587,27 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 
        if (!list_empty(&qh->qh_list_entry))
                /* QH already in a schedule */
-               return status;
+               return 0;
 
        /* Add the new QH to the appropriate schedule */
        if (dwc2_qh_is_non_per(qh)) {
                /* Always start in inactive schedule */
                list_add_tail(&qh->qh_list_entry,
                              &hsotg->non_periodic_sched_inactive);
-       } else {
-               status = dwc2_schedule_periodic(hsotg, qh);
-               if (status == 0) {
-                       if (!hsotg->periodic_qh_count) {
-                               intr_mask = readl(hsotg->regs + GINTMSK);
-                               intr_mask |= GINTSTS_SOF;
-                               writel(intr_mask, hsotg->regs + GINTMSK);
-                       }
-                       hsotg->periodic_qh_count++;
-               }
+               return 0;
        }
 
-       return status;
+       status = dwc2_schedule_periodic(hsotg, qh);
+       if (status)
+               return status;
+       if (!hsotg->periodic_qh_count) {
+               intr_mask = readl(hsotg->regs + GINTMSK);
+               intr_mask |= GINTSTS_SOF;
+               writel(intr_mask, hsotg->regs + GINTMSK);
+       }
+       hsotg->periodic_qh_count++;
+
+       return 0;
 }
 
 /**
@@ -661,14 +632,15 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
                        hsotg->non_periodic_qh_ptr =
                                        hsotg->non_periodic_qh_ptr->next;
                list_del_init(&qh->qh_list_entry);
-       } else {
-               dwc2_deschedule_periodic(hsotg, qh);
-               hsotg->periodic_qh_count--;
-               if (!hsotg->periodic_qh_count) {
-                       intr_mask = readl(hsotg->regs + GINTMSK);
-                       intr_mask &= ~GINTSTS_SOF;
-                       writel(intr_mask, hsotg->regs + GINTMSK);
-               }
+               return;
+       }
+
+       dwc2_deschedule_periodic(hsotg, qh);
+       hsotg->periodic_qh_count--;
+       if (!hsotg->periodic_qh_count) {
+               intr_mask = readl(hsotg->regs + GINTMSK);
+               intr_mask &= ~GINTSTS_SOF;
+               writel(intr_mask, hsotg->regs + GINTMSK);
        }
 }
 
@@ -723,6 +695,8 @@ static void dwc2_sched_periodic_split(struct dwc2_hsotg *hsotg,
 void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
                            int sched_next_periodic_split)
 {
+       u16 frame_number;
+
        if (dbg_qh(qh))
                dev_vdbg(hsotg->dev, "%s()\n", __func__);
 
@@ -731,37 +705,36 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
                if (!list_empty(&qh->qtd_list))
                        /* Add back to inactive non-periodic schedule */
                        dwc2_hcd_qh_add(hsotg, qh);
+               return;
+       }
+
+       frame_number = dwc2_hcd_get_frame_number(hsotg);
+
+       if (qh->do_split) {
+               dwc2_sched_periodic_split(hsotg, qh, frame_number,
+                                         sched_next_periodic_split);
        } else {
-               u16 frame_number = dwc2_hcd_get_frame_number(hsotg);
-
-               if (qh->do_split) {
-                       dwc2_sched_periodic_split(hsotg, qh, frame_number,
-                                                 sched_next_periodic_split);
-               } else {
-                       qh->sched_frame = dwc2_frame_num_inc(qh->sched_frame,
-                                                            qh->interval);
-                       if (dwc2_frame_num_le(qh->sched_frame, frame_number))
-                               qh->sched_frame = frame_number;
-               }
+               qh->sched_frame = dwc2_frame_num_inc(qh->sched_frame,
+                                                    qh->interval);
+               if (dwc2_frame_num_le(qh->sched_frame, frame_number))
+                       qh->sched_frame = frame_number;
+       }
 
-               if (list_empty(&qh->qtd_list)) {
-                       dwc2_hcd_qh_unlink(hsotg, qh);
-               } else {
-                       /*
-                        * Remove from periodic_sched_queued and move to
-                        * appropriate queue
-                        */
-                       if ((hsotg->core_params->uframe_sched > 0 &&
-                            dwc2_frame_num_le(qh->sched_frame, frame_number))
-                        || (hsotg->core_params->uframe_sched <= 0 &&
-                            qh->sched_frame == frame_number))
-                               list_move(&qh->qh_list_entry,
-                                         &hsotg->periodic_sched_ready);
-                       else
-                               list_move(&qh->qh_list_entry,
-                                         &hsotg->periodic_sched_inactive);
-               }
+       if (list_empty(&qh->qtd_list)) {
+               dwc2_hcd_qh_unlink(hsotg, qh);
+               return;
        }
+       /*
+        * Remove from periodic_sched_queued and move to
+        * appropriate queue
+        */
+       if ((hsotg->core_params->uframe_sched > 0 &&
+            dwc2_frame_num_le(qh->sched_frame, frame_number)) ||
+           (hsotg->core_params->uframe_sched <= 0 &&
+            qh->sched_frame == frame_number))
+               list_move(&qh->qh_list_entry, &hsotg->periodic_sched_ready);
+       else
+               list_move(&qh->qh_list_entry, &hsotg->periodic_sched_inactive);
 }
 
 /**
index 83ca1053bb1d2c04be6eeef97103ae1bf6bfd58f..4d9fac017044a527b6c2ea6d39a5f880a1632af5 100644 (file)
@@ -135,7 +135,7 @@ MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
 
 static struct platform_driver dwc2_platform_driver = {
        .driver = {
-               .name = (char *)dwc2_driver_name,
+               .name = dwc2_driver_name,
                .of_match_table = dwc2_of_match_table,
        },
        .probe = dwc2_driver_probe,
index 9dce54eae1cf5b9d6f2897f9e678643cf3952ecc..915165e387044cdad004760d7a478e175a201bcc 100644 (file)
 #define _BOOTH_
 
 // Official bootloader
-static unsigned char bootimage [] = {
-0x00,0x00,0x01,0x5E,0x00,0x00
-,0x00,0x00,0x00,0x00,0x02,0xD7
-,0x00,0x00,0x01,0x5E,0x46,0xB3
-,0xE6,0x02,0x00,0x98,0xE6,0x8C
-,0x00,0x98,0xFB,0x92,0xFF,0xFF
-,0x98,0xFB,0x94,0xFF,0xFF,0x98
-,0xFB,0x06,0x08,0x00,0x98,0xFB
-,0x96,0x84,0x00,0x98,0xFB,0x08
-,0x1C,0x00,0x98,0xFB,0x51,0x25
-,0x10,0x1C,0x00,0xE6,0x51,0x01
-,0x07,0xFD,0x4C,0xFF,0x20,0xF5
-,0x51,0x02,0x20,0x08,0x00,0x4C
-,0xFF,0x20,0x3C,0x00,0xC0,0x64
-,0x98,0xC0,0x66,0x98,0xC0,0x68
-,0x98,0xC0,0x6A,0x98,0xC0,0x6C
-,0x98,0x90,0x08,0x90,0x09,0x90
-,0x0A,0x90,0x0B,0x90,0x0C,0x90
-,0x0D,0x90,0x0E,0x90,0x0F,0x90
-,0x04,0x90,0x06,0xFB,0x51,0x22
-,0x16,0x08,0x03,0xFB,0x51,0x52
-,0x16,0x08,0x04,0xFB,0x51,0x24
-,0x2B,0x08,0x06,0xFB,0x51,0x54
-,0x2B,0x08,0x07,0xFB,0x51,0x24
-,0x2B,0x08,0x09,0xFB,0x51,0x54
-,0x2B,0x08,0x0A,0xFB,0x51,0x12
-,0x16,0x08,0x0C,0xFB,0x51,0x52
-,0x16,0x08,0x0D,0x78,0x00,0x00
-,0x00,0x16,0x00,0x00,0xEC,0x31
-,0xAE,0x00,0x00,0x81,0x4C,0x0F
-,0xE6,0x43,0xFF,0xEC,0x31,0x4E
-,0x00,0x00,0x91,0xEC,0x31,0xAE
-,0x00,0x00,0x91,0x4C,0x0F,0xE6
-,0x43,0xFF,0xEC,0x31,0x5E,0x00
-,0x00,0xA1,0xEB,0x31,0x08,0x00
-,0x00,0xA6,0xEB,0x31,0x08,0x00
-,0x00,0xAC,0x3C,0x00,0xEB,0x31
-,0x08,0x00,0x00,0xA8,0x76,0xFE
-,0xFE,0x08,0xEB,0x31,0x08,0x20
-,0x00,0x00,0x76,0xFF,0xFF,0x18
-,0xED,0x31,0x08,0x20,0x00,0x00
-,0x26,0x10,0x04,0x10,0xF5,0x3C
-,0x01,0x3C,0x00,0x08,0x01,0x12
-,0x3C,0x11,0x3C,0x00,0x08,0x01
-,0x0B,0x08,0x00,0x6D,0xEC,0x31
-,0xAE,0x20,0x00,0x06,0xED,0x4D
-,0x08,0x00,0x00,0x67,0x80,0x6F
-,0x00,0x01,0x0B,0x6F,0x00,0x02
-,0x2E,0x76,0xEE,0x01,0x48,0x06
-,0x01,0x39,0xED,0x4D,0x18,0x00
-,0x02,0xED,0x4D,0x08,0x00,0x04
-,0x14,0x06,0xA4,0xED,0x31,0x22
-,0x00,0x00,0xAC,0x76,0xEE,0x07
-,0x48,0x6D,0x22,0x01,0x1E,0x08
-,0x01,0x58,0xEB,0x31,0x08,0x00
-,0x00,0xAC,0x06,0xFF,0xBA,0x3C
-,0x00,0xEB,0x31,0x08,0x20,0x00
-,0x04,0x3C,0x30,0xEB,0x31,0x08
-,0x20,0x00,0x02,0x3C,0x10,0xEB
-,0x31,0x08,0x20,0x00,0x00,0xED
-,0x31,0x08,0x20,0x00,0x00,0x04
-,0x10,0xF7,0xED,0x31,0x08,0x00
-,0x00,0xA2,0x91,0x00,0x9C,0x3C
-,0x80,0xEB,0x31,0x08,0x20,0x00
-,0x04,0x3C,0x20,0xEB,0x31,0x08
-,0x20,0x00,0x02,0x3C,0x10,0xEB
-,0x31,0x08,0x20,0x00,0x00,0xED
-,0x31,0x08,0x20,0x00,0x00,0x04
-,0x10,0xF7,0xED,0x31,0x08,0x20
-,0x00,0x04,0x42,0x10,0x90,0x08
-,0xEC,0x31,0xAE,0x20,0x00,0x06
-,0xA4,0x41,0x08,0x00,0xB6,0xED
-,0x41,0x28,0x7D,0xFF,0xFF,0x22
-,0xB3,0x40,0x98,0x2A,0x32,0xEB
-,0x41,0x28,0xB4,0x43,0xFC,0x05
-,0xFF,0xE6,0xA0,0x31,0x20,0x00
-,0x06,0xEB,0x31,0x08,0x20,0x00
-,0x04,0x3C,0x20,0xEB,0x31,0x08
-,0x20,0x00,0x02,0x3C,0x10,0xEB
-,0x31,0x08,0x20,0x00,0x00,0xED
-,0x31,0x08,0x20,0x00,0x00,0x04
-,0x10,0xF7,0xED,0x31,0x08,0x20
-,0x00,0x04,0x42,0x10,0x90,0x08
-,0xEC,0x31,0xAE,0x20,0x00,0x06
-,0xA4,0x41,0x08,0x00,0x68,0xED
-,0x41,0x28,0x7D,0xFF,0xFF,0x22
-,0xB3,0x40,0x98,0x2A,0x32,0xEB
-,0x41,0x28,0xB4,0x43,0xFC,0x05
-,0xFF,0xE6,0x48,0x04,0xEB,0x31
-,0x08,0x20,0x00,0x04,0xEB,0x31
-,0x18,0x20,0x00,0x02,0x3C,0x11
-,0xEB,0x31,0x18,0x20,0x00,0x00
-,0xED,0x31,0x08,0x20,0x00,0x00
-,0x04,0x10,0xF7,0xED,0x31,0x08
-,0x20,0x00,0x02,0x66,0x00,0x6F
-,0x00,0x01,0x16,0x76,0xEE,0x06
-,0x48,0x4A,0x1E,0x48,0x04,0xED
-,0x31,0x08,0x20,0x00,0x04,0xEB
-,0x31,0x08,0x00,0x00,0xA4,0x48
-,0x04,0xED,0x31,0x08,0x20,0x00
-,0x04,0xEB,0x31,0x08,0x00,0x00
-,0xA2,0x48,0x04,0x20,0x20,0x4A
-,0x7C,0x46,0x82,0x50,0x05,0x50
-,0x15,0xB5,0x1E,0x98,0xED,0x31
-,0x08,0x00,0x00,0xA8,0x10,0x47
-,0x3B,0x2C,0x01,0xDB,0x40,0x11
-,0x98,0xC1,0x1E,0x98,0x10,0x07
-,0x30,0xF9,0x40,0x07,0x18,0x98
-,0x2A,0x10,0xEB,0x31,0x08,0x00
-,0x00,0xA8,0xA4,0x1E,0x98,0xBB
-,0x1E,0x98,0x50,0x14,0x50,0x04
-,0x46,0x83,0x48,0x04,0x02,0x01
-,0x00,0x50,0x05,0x50,0x15,0x10
-,0x87,0x3F,0x90,0x2B,0x18,0x01
-,0x00,0xC0,0x31,0x00,0x00,0xAE
-,0xDF,0x41,0x00,0x08,0x00,0x1A
-,0x42,0x11,0x67,0x01,0xDF,0x41
-,0x02,0x08,0x00,0x10,0x42,0x11
-,0x62,0x01,0xB4,0x43,0x4A,0x68
-,0x50,0x14,0x50,0x04,0x24,0x10
-,0x48,0x04,0xF2,0x31,0x00,0x01
-,0x00,0x00,0xAE,0xF6,0x31,0x00
-,0x01,0x00,0x00,0xAE,0x62,0xE4
-,0xE5,0x61,0x04,0x48,0x04,0xE5
-,0x63,0x05,0x48,0x04,0x20,0x20
-,0x00,0x00,0x00,0x00
+static unsigned char bootimage[] = {
+       0x00, 0x00, 0x01, 0x5E, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x02, 0xD7,
+       0x00, 0x00, 0x01, 0x5E, 0x46, 0xB3,
+       0xE6, 0x02, 0x00, 0x98, 0xE6, 0x8C,
+       0x00, 0x98, 0xFB, 0x92, 0xFF, 0xFF,
+       0x98, 0xFB, 0x94, 0xFF, 0xFF, 0x98,
+       0xFB, 0x06, 0x08, 0x00, 0x98, 0xFB,
+       0x96, 0x84, 0x00, 0x98, 0xFB, 0x08,
+       0x1C, 0x00, 0x98, 0xFB, 0x51, 0x25,
+       0x10, 0x1C, 0x00, 0xE6, 0x51, 0x01,
+       0x07, 0xFD, 0x4C, 0xFF, 0x20, 0xF5,
+       0x51, 0x02, 0x20, 0x08, 0x00, 0x4C,
+       0xFF, 0x20, 0x3C, 0x00, 0xC0, 0x64,
+       0x98, 0xC0, 0x66, 0x98, 0xC0, 0x68,
+       0x98, 0xC0, 0x6A, 0x98, 0xC0, 0x6C,
+       0x98, 0x90, 0x08, 0x90, 0x09, 0x90,
+       0x0A, 0x90, 0x0B, 0x90, 0x0C, 0x90,
+       0x0D, 0x90, 0x0E, 0x90, 0x0F, 0x90,
+       0x04, 0x90, 0x06, 0xFB, 0x51, 0x22,
+       0x16, 0x08, 0x03, 0xFB, 0x51, 0x52,
+       0x16, 0x08, 0x04, 0xFB, 0x51, 0x24,
+       0x2B, 0x08, 0x06, 0xFB, 0x51, 0x54,
+       0x2B, 0x08, 0x07, 0xFB, 0x51, 0x24,
+       0x2B, 0x08, 0x09, 0xFB, 0x51, 0x54,
+       0x2B, 0x08, 0x0A, 0xFB, 0x51, 0x12,
+       0x16, 0x08, 0x0C, 0xFB, 0x51, 0x52,
+       0x16, 0x08, 0x0D, 0x78, 0x00, 0x00,
+       0x00, 0x16, 0x00, 0x00, 0xEC, 0x31,
+       0xAE, 0x00, 0x00, 0x81, 0x4C, 0x0F,
+       0xE6, 0x43, 0xFF, 0xEC, 0x31, 0x4E,
+       0x00, 0x00, 0x91, 0xEC, 0x31, 0xAE,
+       0x00, 0x00, 0x91, 0x4C, 0x0F, 0xE6,
+       0x43, 0xFF, 0xEC, 0x31, 0x5E, 0x00,
+       0x00, 0xA1, 0xEB, 0x31, 0x08, 0x00,
+       0x00, 0xA6, 0xEB, 0x31, 0x08, 0x00,
+       0x00, 0xAC, 0x3C, 0x00, 0xEB, 0x31,
+       0x08, 0x00, 0x00, 0xA8, 0x76, 0xFE,
+       0xFE, 0x08, 0xEB, 0x31, 0x08, 0x20,
+       0x00, 0x00, 0x76, 0xFF, 0xFF, 0x18,
+       0xED, 0x31, 0x08, 0x20, 0x00, 0x00,
+       0x26, 0x10, 0x04, 0x10, 0xF5, 0x3C,
+       0x01, 0x3C, 0x00, 0x08, 0x01, 0x12,
+       0x3C, 0x11, 0x3C, 0x00, 0x08, 0x01,
+       0x0B, 0x08, 0x00, 0x6D, 0xEC, 0x31,
+       0xAE, 0x20, 0x00, 0x06, 0xED, 0x4D,
+       0x08, 0x00, 0x00, 0x67, 0x80, 0x6F,
+       0x00, 0x01, 0x0B, 0x6F, 0x00, 0x02,
+       0x2E, 0x76, 0xEE, 0x01, 0x48, 0x06,
+       0x01, 0x39, 0xED, 0x4D, 0x18, 0x00,
+       0x02, 0xED, 0x4D, 0x08, 0x00, 0x04,
+       0x14, 0x06, 0xA4, 0xED, 0x31, 0x22,
+       0x00, 0x00, 0xAC, 0x76, 0xEE, 0x07,
+       0x48, 0x6D, 0x22, 0x01, 0x1E, 0x08,
+       0x01, 0x58, 0xEB, 0x31, 0x08, 0x00,
+       0x00, 0xAC, 0x06, 0xFF, 0xBA, 0x3C,
+       0x00, 0xEB, 0x31, 0x08, 0x20, 0x00,
+       0x04, 0x3C, 0x30, 0xEB, 0x31, 0x08,
+       0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB,
+       0x31, 0x08, 0x20, 0x00, 0x00, 0xED,
+       0x31, 0x08, 0x20, 0x00, 0x00, 0x04,
+       0x10, 0xF7, 0xED, 0x31, 0x08, 0x00,
+       0x00, 0xA2, 0x91, 0x00, 0x9C, 0x3C,
+       0x80, 0xEB, 0x31, 0x08, 0x20, 0x00,
+       0x04, 0x3C, 0x20, 0xEB, 0x31, 0x08,
+       0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB,
+       0x31, 0x08, 0x20, 0x00, 0x00, 0xED,
+       0x31, 0x08, 0x20, 0x00, 0x00, 0x04,
+       0x10, 0xF7, 0xED, 0x31, 0x08, 0x20,
+       0x00, 0x04, 0x42, 0x10, 0x90, 0x08,
+       0xEC, 0x31, 0xAE, 0x20, 0x00, 0x06,
+       0xA4, 0x41, 0x08, 0x00, 0xB6, 0xED,
+       0x41, 0x28, 0x7D, 0xFF, 0xFF, 0x22,
+       0xB3, 0x40, 0x98, 0x2A, 0x32, 0xEB,
+       0x41, 0x28, 0xB4, 0x43, 0xFC, 0x05,
+       0xFF, 0xE6, 0xA0, 0x31, 0x20, 0x00,
+       0x06, 0xEB, 0x31, 0x08, 0x20, 0x00,
+       0x04, 0x3C, 0x20, 0xEB, 0x31, 0x08,
+       0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB,
+       0x31, 0x08, 0x20, 0x00, 0x00, 0xED,
+       0x31, 0x08, 0x20, 0x00, 0x00, 0x04,
+       0x10, 0xF7, 0xED, 0x31, 0x08, 0x20,
+       0x00, 0x04, 0x42, 0x10, 0x90, 0x08,
+       0xEC, 0x31, 0xAE, 0x20, 0x00, 0x06,
+       0xA4, 0x41, 0x08, 0x00, 0x68, 0xED,
+       0x41, 0x28, 0x7D, 0xFF, 0xFF, 0x22,
+       0xB3, 0x40, 0x98, 0x2A, 0x32, 0xEB,
+       0x41, 0x28, 0xB4, 0x43, 0xFC, 0x05,
+       0xFF, 0xE6, 0x48, 0x04, 0xEB, 0x31,
+       0x08, 0x20, 0x00, 0x04, 0xEB, 0x31,
+       0x18, 0x20, 0x00, 0x02, 0x3C, 0x11,
+       0xEB, 0x31, 0x18, 0x20, 0x00, 0x00,
+       0xED, 0x31, 0x08, 0x20, 0x00, 0x00,
+       0x04, 0x10, 0xF7, 0xED, 0x31, 0x08,
+       0x20, 0x00, 0x02, 0x66, 0x00, 0x6F,
+       0x00, 0x01, 0x16, 0x76, 0xEE, 0x06,
+       0x48, 0x4A, 0x1E, 0x48, 0x04, 0xED,
+       0x31, 0x08, 0x20, 0x00, 0x04, 0xEB,
+       0x31, 0x08, 0x00, 0x00, 0xA4, 0x48,
+       0x04, 0xED, 0x31, 0x08, 0x20, 0x00,
+       0x04, 0xEB, 0x31, 0x08, 0x00, 0x00,
+       0xA2, 0x48, 0x04, 0x20, 0x20, 0x4A,
+       0x7C, 0x46, 0x82, 0x50, 0x05, 0x50,
+       0x15, 0xB5, 0x1E, 0x98, 0xED, 0x31,
+       0x08, 0x00, 0x00, 0xA8, 0x10, 0x47,
+       0x3B, 0x2C, 0x01, 0xDB, 0x40, 0x11,
+       0x98, 0xC1, 0x1E, 0x98, 0x10, 0x07,
+       0x30, 0xF9, 0x40, 0x07, 0x18, 0x98,
+       0x2A, 0x10, 0xEB, 0x31, 0x08, 0x00,
+       0x00, 0xA8, 0xA4, 0x1E, 0x98, 0xBB,
+       0x1E, 0x98, 0x50, 0x14, 0x50, 0x04,
+       0x46, 0x83, 0x48, 0x04, 0x02, 0x01,
+       0x00, 0x50, 0x05, 0x50, 0x15, 0x10,
+       0x87, 0x3F, 0x90, 0x2B, 0x18, 0x01,
+       0x00, 0xC0, 0x31, 0x00, 0x00, 0xAE,
+       0xDF, 0x41, 0x00, 0x08, 0x00, 0x1A,
+       0x42, 0x11, 0x67, 0x01, 0xDF, 0x41,
+       0x02, 0x08, 0x00, 0x10, 0x42, 0x11,
+       0x62, 0x01, 0xB4, 0x43, 0x4A, 0x68,
+       0x50, 0x14, 0x50, 0x04, 0x24, 0x10,
+       0x48, 0x04, 0xF2, 0x31, 0x00, 0x01,
+       0x00, 0x00, 0xAE, 0xF6, 0x31, 0x00,
+       0x01, 0x00, 0x00, 0xAE, 0x62, 0xE4,
+       0xE5, 0x61, 0x04, 0x48, 0x04, 0xE5,
+       0x63, 0x05, 0x48, 0x04, 0x20, 0x20,
+       0x00, 0x00, 0x00, 0x00
 };
 
 #endif
index 68ded17c0f5c7f9302613d37ed48238f9f54422b..21f4a3bbd0644a4efe98ee892229ee2f0a52a804 100644 (file)
 #define  DWNLD_MAG1_PS_HDR_LOC        0x03
 
 struct dsp_file_hdr {
-   long              version_id;          // Version ID of this image format.
-   long              package_id;          // Package ID of code release.
-   long              build_date;          // Date/time stamp when file was built.
-   long              commands_offset;     // Offset to attached commands in Pseudo Hdr format.
-   long              loader_offset;       // Offset to bootloader code.
-   long              loader_code_address; // Start address of bootloader.
-   long              loader_code_end;     // Where bootloader code ends.
-   long              loader_code_size;
-   long              version_data_offset; // Offset were scrambled version data begins.
-   long              version_data_size;   // Size, in words, of scrambled version data.
-   long              nDspImages;          // Number of DSP images in file.
+       long              version_id;          // Version ID of this image format.
+       long              package_id;          // Package ID of code release.
+       long              build_date;          // Date/time stamp when file was built.
+       long              commands_offset;     // Offset to attached commands in Pseudo Hdr format.
+       long              loader_offset;       // Offset to bootloader code.
+       long              loader_code_address; // Start address of bootloader.
+       long              loader_code_end;     // Where bootloader code ends.
+       long              loader_code_size;
+       long              version_data_offset; // Offset were scrambled version data begins.
+       long              version_data_size;   // Size, in words, of scrambled version data.
+       long              nDspImages;          // Number of DSP images in file.
 };
 
 #pragma pack(1)
 struct dsp_image_info {
-   long              coff_date;           // Date/time when DSP Coff image was built.
-   long              begin_offset;        // Offset in file where image begins.
-   long              end_offset;          // Offset in file where image begins.
-   long              run_address;         // On chip Start address of DSP code.
-   long              image_size;          // Size of image.
-   long              version;             // Embedded version # of DSP code.
-   unsigned short    checksum;            // DSP File checksum
-   unsigned short    pad1;
+       long              coff_date;           // Date/time when DSP Coff image was built.
+       long              begin_offset;        // Offset in file where image begins.
+       long              end_offset;          // Offset in file where image begins.
+       long              run_address;         // On chip Start address of DSP code.
+       long              image_size;          // Size of image.
+       long              version;             // Embedded version # of DSP code.
+       unsigned short    checksum;            // DSP File checksum
+       unsigned short    pad1;
 };
 
 
@@ -151,7 +151,7 @@ static int check_usb_db(struct ft1000_usb *ft1000dev)
                }
        }
 
-       return HANDSHAKE_MAG_TIMEOUT_VALUE;
+       return -1;
 }
 
 /* gets the handshake and compares it with the expected value */
@@ -172,9 +172,8 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value)
                                ft1000dev->fcodeldr);
                        ft1000dev->fcodeldr = 0;
                        status = check_usb_db(ft1000dev);
-                       if (status != STATUS_SUCCESS) {
+                       if (status != 0) {
                                DEBUG("get_handshake: check_usb_db failed\n");
-                               status = STATUS_FAILURE;
                                break;
                        }
                        status = ft1000_write_register(ft1000dev,
@@ -202,7 +201,7 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value)
 }
 
 /* write the handshake value to the handshake location */
-static void put_handshake(struct ft1000_usb *ft1000dev,u16 handshake_value)
+static void put_handshake(struct ft1000_usb *ft1000dev, u16 handshake_value)
 {
        u32 tempx;
        u16 tempword;
@@ -268,11 +267,12 @@ static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value)
        return HANDSHAKE_TIMEOUT_VALUE;
 }
 
-static void put_handshake_usb(struct ft1000_usb *ft1000dev,u16 handshake_value)
+static void put_handshake_usb(struct ft1000_usb *ft1000dev, u16 handshake_value)
 {
        int i;
 
-        for (i=0; i<1000; i++);
+       for (i = 0; i < 1000; i++)
+               ;
 }
 
 static u16 get_request_type(struct ft1000_usb *ft1000dev)
@@ -450,7 +450,7 @@ static int write_dpram32_and_check(struct ft1000_usb *ft1000dev,
 static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile,
                long word_length)
 {
-       int status = STATUS_SUCCESS;
+       int status = 0;
        u16 dpram;
        int loopcnt, i;
        u16 tempword;
@@ -499,7 +499,7 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile,
                } else {
                        status = write_dpram32_and_check(ft1000dev, tempbuffer,
                                        dpram);
-                       if (status != STATUS_SUCCESS) {
+                       if (status != 0) {
                                DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]);
                                break;
                        }
@@ -509,9 +509,9 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile,
        return status;
 }
 
-static void usb_dnld_complete (struct urb *urb)
+static void usb_dnld_complete(struct urb *urb)
 {
-    //DEBUG("****** usb_dnld_complete\n");
+       //DEBUG("****** usb_dnld_complete\n");
 }
 
 /* writes a block of DSP image to DPRAM
@@ -523,7 +523,7 @@ static void usb_dnld_complete (struct urb *urb)
 static int write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile,
                          u8 **pUcFile, long word_length)
 {
-       int Status = STATUS_SUCCESS;
+       int Status = 0;
        int byte_length;
 
        byte_length = word_length * 4;
@@ -578,7 +578,7 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file,
                 u8 **c_file, const u8 *endpoint, bool boot_case)
 {
        long word_length;
-       int status;
+       int status = 0;
 
        /*DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");i*/
        word_length = get_request_value(ft1000dev);
@@ -586,12 +586,12 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file,
        /*NdisMSleep (100); */
        if (word_length > MAX_LENGTH) {
                DEBUG("FT1000:download:Download error: Max length exceeded\n");
-               return STATUS_FAILURE;
+               return -1;
        }
        if ((word_length * 2 + (long)c_file) > (long)endpoint) {
                /* Error, beyond boot code range.*/
                DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n", (int)word_length);
-               return STATUS_FAILURE;
+               return -1;
        }
        if (word_length & 0x1)
                word_length++;
@@ -601,11 +601,11 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file,
                status = write_blk(ft1000dev, s_file, c_file, word_length);
                /*DEBUG("write_blk returned %d\n", status); */
        } else {
-               write_blk_fifo(ft1000dev, s_file, c_file, word_length);
+               status = write_blk_fifo(ft1000dev, s_file, c_file, word_length);
                if (ft1000dev->usbboot == 0)
                        ft1000dev->usbboot++;
                if (ft1000dev->usbboot == 1)
-                       ft1000_write_dpram16(ft1000dev,
+                       status |= ft1000_write_dpram16(ft1000dev,
                                        DWNLD_MAG1_PS_HDR_LOC, 0, 0);
        }
        return status;
@@ -615,7 +615,7 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file,
 int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                u32 FileLength)
 {
-       int status = STATUS_SUCCESS;
+       int status = 0;
        u32 state;
        u16 handshake;
        struct pseudo_hdr *pseudo_header;
@@ -670,7 +670,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
        loader_code_size = file_hdr->loader_code_size;
        correct_version = false;
 
-       while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) {
+       while ((status == 0) && (state != STATE_DONE_FILE)) {
                switch (state) {
                case STATE_START_DWNLD:
                        status = scram_start_dwnld(ft1000dev, &handshake,
@@ -717,7 +717,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                        DEBUG
                                            ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",
                                             request);
-                                       status = STATUS_FAILURE;
+                                       status = -1;
                                        break;
                                }
                                if (ft1000dev->usbboot)
@@ -729,7 +729,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                        } else {
                                DEBUG
                                    ("FT1000:download:Download error: Handshake failed\n");
-                               status = STATUS_FAILURE;
+                               status = -1;
                        }
 
                        break;
@@ -773,7 +773,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                        } else {
                                                DEBUG
                                                    ("FT1000:download:Download error: Got Run address request before image offset request.\n");
-                                               status = STATUS_FAILURE;
+                                               status = -1;
                                                break;
                                        }
                                        break;
@@ -789,7 +789,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                        } else {
                                                DEBUG
                                                    ("FT1000:download:Download error: Got Size request before image offset request.\n");
-                                               status = STATUS_FAILURE;
+                                               status = -1;
                                                break;
                                        }
                                        break;
@@ -809,7 +809,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                        if (!correct_version) {
                                                DEBUG
                                                    ("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
-                                               status = STATUS_FAILURE;
+                                               status = -1;
                                                break;
                                        }
 
@@ -836,7 +836,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                         * Position ASIC DPRAM auto-increment pointer.
                                         */
 
-                                       data = (u16 *) & mailbox_data->data[0];
+                                       data = (u16 *) &mailbox_data->data[0];
                                        dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
                                        if (word_length & 0x1)
                                                word_length++;
@@ -850,7 +850,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                                status =
                                                    fix_ft1000_write_dpram32
                                                    (ft1000dev, dpram++,
-                                                    (u8 *) & templong);
+                                                    (u8 *) &templong);
 
                                        }
                                        break;
@@ -948,7 +948,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                                DEBUG
                                                    ("FT1000:download:Download error: Bad Version Request = 0x%x.\n",
                                                     (int)requested_version);
-                                               status = STATUS_FAILURE;
+                                               status = -1;
                                                break;
                                        }
                                        break;
@@ -957,7 +957,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                        DEBUG
                                            ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",
                                             request);
-                                       status = STATUS_FAILURE;
+                                       status = -1;
                                        break;
                                }
                                if (ft1000dev->usbboot)
@@ -969,7 +969,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                        } else {
                                DEBUG
                                    ("FT1000:download:Download error: Handshake failed\n");
-                               status = STATUS_FAILURE;
+                               status = -1;
                        }
 
                        break;
@@ -1026,14 +1026,14 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                                }
                                        } else {
                                                kfree(pbuffer);
-                                               status = STATUS_FAILURE;
+                                               status = -1;
                                        }
                                } else {
-                                       status = STATUS_FAILURE;
+                                       status = -1;
                                }
                        } else {
                                /* Checksum did not compute */
-                               status = STATUS_FAILURE;
+                               status = -1;
                        }
                        DEBUG
                            ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n",
@@ -1046,23 +1046,23 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                        break;
 
                default:
-                       status = STATUS_FAILURE;
+                       status = -1;
                        break;
                }               /* End Switch */
 
-               if (status != STATUS_SUCCESS)
+               if (status != 0)
                        break;
 
 /****
       // Check if Card is present
       status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
       if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
-          break;
+       break;
       }
 
       status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
       if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
-          break;
+       break;
       }
 ****/
 
@@ -1074,4 +1074,3 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
 
        return status;
 }
-
index 0d4931b2c2e26f766f161d4b9c97b473e78952be..0d6c1d12170d24b391785ef244b43fa754aa5a4b 100644 (file)
@@ -1,11 +1,9 @@
-//=====================================================
-// CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
-//
-//
-// This file is part of Express Card USB Driver
-//
-// $Id:
-//====================================================
+/* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
+*
+*
+* This file is part of Express Card USB Driver
+*/
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -27,7 +25,9 @@
 #define HARLEY_READ_OPERATION    0xc1
 #define HARLEY_WRITE_OPERATION   0x41
 
-//#define JDEBUG
+#if 0
+#define JDEBUG
+#endif
 
 static int ft1000_submit_rx_urb(struct ft1000_info *info);
 
@@ -35,32 +35,22 @@ static u8 tempbuffer[1600];
 
 #define MAX_RCV_LOOP   100
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_control
-//
-// Parameters:  ft1000_usb  - device structure
-//              pipe - usb control message pipe
-//              request - control request
-//              requesttype - control message request type
-//              value - value to be written or 0
-//              index - register index
-//              data - data buffer to hold the read/write values
-//              size - data size
-//              timeout - control message time out value
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function sends a control message via USB interface synchronously
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* send a control message via USB interface synchronously
+*  Parameters:  ft1000_usb  - device structure
+*               pipe - usb control message pipe
+*               request - control request
+*               requesttype - control message request type
+*               value - value to be written or 0
+*               index - register index
+*               data - data buffer to hold the read/write values
+*               size - data size
+*               timeout - control message time out value
+*/
 static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe,
                          u8 request, u8 requesttype, u16 value, u16 index,
                          void *data, u16 size, int timeout)
 {
-       u16 ret;
+       int ret;
 
        if ((ft1000dev == NULL) || (ft1000dev->dev == NULL)) {
                DEBUG("ft1000dev or ft1000dev->dev == NULL, failure\n");
@@ -76,26 +66,11 @@ static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe,
        return ret;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_read_register
-//
-// Parameters:  ft1000_usb  - device structure
-//              Data - data buffer to hold the value read
-//              nRegIndex - register index
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function returns the value in a register
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-
-int ft1000_read_register(struct ft1000_usb *ft1000dev, u16* Data,
+/* returns the value in a register */
+int ft1000_read_register(struct ft1000_usb *ft1000dev, u16 *Data,
                         u16 nRegIndx)
 {
-       int ret = STATUS_SUCCESS;
+       int ret = 0;
 
        ret = ft1000_control(ft1000dev,
                             usb_rcvctrlpipe(ft1000dev->dev, 0),
@@ -110,25 +85,11 @@ int ft1000_read_register(struct ft1000_usb *ft1000dev, u16* Data,
        return ret;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_write_register
-//
-// Parameters:  ft1000_usb  - device structure
-//              value - value to write into a register
-//              nRegIndex - register index
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function writes the value in a register
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* writes the value in a register */
 int ft1000_write_register(struct ft1000_usb *ft1000dev, u16 value,
                          u16 nRegIndx)
 {
-       int ret = STATUS_SUCCESS;
+       int ret = 0;
 
        ret = ft1000_control(ft1000dev,
                             usb_sndctrlpipe(ft1000dev->dev, 0),
@@ -143,27 +104,11 @@ int ft1000_write_register(struct ft1000_usb *ft1000dev, u16 value,
        return ret;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_read_dpram32
-//
-// Parameters:  ft1000_usb  - device structure
-//              indx - starting address to read
-//              buffer - data buffer to hold the data read
-//              cnt - number of byte read from DPRAM
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function read a number of bytes from DPRAM
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-
+/* read a number of bytes from DPRAM */
 int ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer,
                        u16 cnt)
 {
-       int ret = STATUS_SUCCESS;
+       int ret = 0;
 
        ret = ft1000_control(ft1000dev,
                             usb_rcvctrlpipe(ft1000dev->dev, 0),
@@ -178,26 +123,11 @@ int ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer,
        return ret;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_write_dpram32
-//
-// Parameters:  ft1000_usb  - device structure
-//              indx - starting address to write the data
-//              buffer - data buffer to write into DPRAM
-//              cnt - number of bytes to write
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function writes into DPRAM a number of bytes
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* writes into DPRAM a number of bytes */
 int ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer,
                         u16 cnt)
 {
-       int ret = STATUS_SUCCESS;
+       int ret = 0;
 
        if (cnt % 4)
                cnt += cnt - (cnt % 4);
@@ -215,26 +145,11 @@ int ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer,
        return ret;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_read_dpram16
-//
-// Parameters:  ft1000_usb  - device structure
-//              indx - starting address to read
-//              buffer - data buffer to hold the data read
-//              hightlow - high or low 16 bit word
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function read 16 bits from DPRAM
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* read 16 bits from DPRAM */
 int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer,
                        u8 highlow)
 {
-       int ret = STATUS_SUCCESS;
+       int ret = 0;
        u8 request;
 
        if (highlow == 0)
@@ -255,25 +170,11 @@ int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer,
        return ret;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_write_dpram16
-//
-// Parameters:  ft1000_usb  - device structure
-//              indx - starting address to write the data
-//              value - 16bits value to write
-//              hightlow - high or low 16 bit word
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function writes into DPRAM a number of bytes
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, u8 highlow)
+/* write into DPRAM a number of bytes */
+int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value,
+               u8 highlow)
 {
-       int ret = STATUS_SUCCESS;
+       int ret = 0;
        u8 request;
 
        if (highlow == 0)
@@ -294,33 +195,18 @@ int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, u8 h
        return ret;
 }
 
-//---------------------------------------------------------------------------
-// Function:    fix_ft1000_read_dpram32
-//
-// Parameters:  ft1000_usb  - device structure
-//              indx - starting address to read
-//              buffer - data buffer to hold the data read
-//
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function read DPRAM 4 words at a time
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* read DPRAM 4 words at a time */
 int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx,
                            u8 *buffer)
 {
        u8 buf[16];
        u16 pos;
-       int ret = STATUS_SUCCESS;
+       int ret = 0;
 
        pos = (indx / 4) * 4;
        ret = ft1000_read_dpram32(ft1000dev, pos, buf, 16);
 
-       if (ret == STATUS_SUCCESS) {
+       if (ret == 0) {
                pos = (indx % 4) * 4;
                *buffer++ = buf[pos++];
                *buffer++ = buf[pos++];
@@ -338,22 +224,7 @@ int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx,
 }
 
 
-//---------------------------------------------------------------------------
-// Function:    fix_ft1000_write_dpram32
-//
-// Parameters:  ft1000_usb  - device structure
-//              indx - starting address to write
-//              buffer - data buffer to write
-//
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function write to DPRAM 4 words at a time
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* Description: This function write to DPRAM 4 words at a time */
 int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer)
 {
        u16 pos1;
@@ -362,13 +233,13 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer)
        u8 buf[32];
        u8 resultbuffer[32];
        u8 *pdata;
-       int ret  = STATUS_SUCCESS;
+       int ret  = 0;
 
        pos1 = (indx / 4) * 4;
        pdata = buffer;
        ret = ft1000_read_dpram32(ft1000dev, pos1, buf, 16);
 
-       if (ret == STATUS_SUCCESS) {
+       if (ret == 0) {
                pos2 = (indx % 4)*4;
                buf[pos2++] = *buffer++;
                buf[pos2++] = *buffer++;
@@ -382,24 +253,24 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer)
 
        ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16);
 
-       if (ret == STATUS_SUCCESS) {
+       if (ret == 0) {
                buffer = pdata;
                for (i = 0; i < 16; i++) {
                        if (buf[i] != resultbuffer[i])
-                               ret = STATUS_FAILURE;
+                               ret = -1;
                }
        }
 
-       if (ret == STATUS_FAILURE) {
+       if (ret == -1) {
                ret = ft1000_write_dpram32(ft1000dev, pos1,
                                           (u8 *)&tempbuffer[0], 16);
                ret = ft1000_read_dpram32(ft1000dev, pos1,
                                          (u8 *)&resultbuffer[0], 16);
-               if (ret == STATUS_SUCCESS) {
+               if (ret == 0) {
                        buffer = pdata;
                        for (i = 0; i < 16; i++) {
                                if (tempbuffer[i] != resultbuffer[i]) {
-                                       ret = STATUS_FAILURE;
+                                       ret = -1;
                                        DEBUG("%s Failed to write\n",
                                              __func__);
                                }
@@ -410,20 +281,10 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer)
        return ret;
 }
 
-
-//------------------------------------------------------------------------
-//
-//  Function:   card_reset_dsp
-//
-//  Synopsis:   This function is called to reset or activate the DSP
-//
-//  Arguments:  value                  - reset or activate
-//
-//  Returns:    None
-//-----------------------------------------------------------------------
+/* reset or activate the DSP */
 static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value)
 {
-       u16 status = STATUS_SUCCESS;
+       int status = 0;
        u16 tempword;
 
        status = ft1000_write_register(ft1000dev, HOST_INTF_BE,
@@ -457,21 +318,11 @@ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value)
        }
 }
 
-//---------------------------------------------------------------------------
-// Function:    card_send_command
-//
-// Parameters:  ft1000_usb  - device structure
-//              ptempbuffer - command buffer
-//              size - command buffer size
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function sends a command to ASIC
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* send a command to ASIC
+*  Parameters:  ft1000_usb  - device structure
+*               ptempbuffer - command buffer
+*               size - command buffer size
+*/
 void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
                       int size)
 {
@@ -486,7 +337,7 @@ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
        ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
 
        if (temp & 0x0100)
-               msleep(10);
+               usleep_range(900, 1100);
 
        /* check for odd word */
        size = size + 2;
@@ -496,29 +347,21 @@ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
                size += 4 - (size % 4);
 
        ft1000_write_dpram32(ft1000dev, 0, commandbuf, size);
-       msleep(1);
+       usleep_range(900, 1100);
        ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX,
                              FT1000_REG_DOORBELL);
-       msleep(1);
+       usleep_range(900, 1100);
 
        ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
 
-       if ((temp & 0x0100) == 0) {
-               //DEBUG("card_send_command: Message sent\n");
-       }
+#if 0
+       if ((temp & 0x0100) == 0)
+               DEBUG("card_send_command: Message sent\n");
+#endif
 
 }
 
-//--------------------------------------------------------------------------
-//
-//  Function:   dsp_reload
-//
-//  Synopsis:   This function is called to load or reload the DSP
-//
-//  Arguments:  ft1000dev - device structure
-//
-//  Returns:    None
-//-----------------------------------------------------------------------
+/* load or reload the DSP */
 int dsp_reload(struct ft1000_usb *ft1000dev)
 {
        int status;
@@ -559,7 +402,7 @@ int dsp_reload(struct ft1000_usb *ft1000dev)
        /* call codeloader */
        status = scram_dnldr(ft1000dev, pFileStart, FileLength);
 
-       if (status != STATUS_SUCCESS)
+       if (status != 0)
                return -EIO;
 
        msleep(1000);
@@ -569,17 +412,7 @@ int dsp_reload(struct ft1000_usb *ft1000dev)
        return 0;
 }
 
-//---------------------------------------------------------------------------
-//
-// Function:   ft1000_reset_asic
-// Description: This function will call the Card Service function to reset the
-//             ASIC.
-// Input:
-//     dev    - device structure
-// Output:
-//     none
-//
-//---------------------------------------------------------------------------
+/* call the Card Service function to reset the ASIC. */
 static void ft1000_reset_asic(struct net_device *dev)
 {
        struct ft1000_info *info = netdev_priv(dev);
@@ -607,18 +440,6 @@ static void ft1000_reset_asic(struct net_device *dev)
        DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword);
 }
 
-
-//---------------------------------------------------------------------------
-//
-// Function:   ft1000_reset_card
-// Description: This function will reset the card
-// Input:
-//     dev    - device structure
-// Output:
-//     status - FALSE (card reset fail)
-//              TRUE  (card reset successful)
-//
-//---------------------------------------------------------------------------
 static int ft1000_reset_card(struct net_device *dev)
 {
        struct ft1000_info *info = netdev_priv(dev);
@@ -666,19 +487,7 @@ static int ft1000_reset_card(struct net_device *dev)
        return TRUE;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_usb_transmit_complete
-//
-// Parameters:  urb  - transmitted usb urb
-//
-//
-// Returns:     none
-//
-// Description: This is the callback function when a urb is transmitted
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* callback function when a urb is transmitted */
 static void ft1000_usb_transmit_complete(struct urb *urb)
 {
 
@@ -690,22 +499,10 @@ static void ft1000_usb_transmit_complete(struct urb *urb)
        netif_wake_queue(ft1000dev->net);
 }
 
-//---------------------------------------------------------------------------
-//
-// Function:   ft1000_copy_down_pkt
-// Description: This function will take an ethernet packet and convert it to
-//             a Flarion packet prior to sending it to the ASIC Downlink
-//             FIFO.
-// Input:
-//     dev    - device structure
-//     packet - address of ethernet packet
-//     len    - length of IP packet
-// Output:
-//     status - FAILURE
-//              SUCCESS
-//
-//---------------------------------------------------------------------------
-static int ft1000_copy_down_pkt(struct net_device *netdev, u8 * packet, u16 len)
+/* take an ethernet packet and convert it to a Flarion
+*  packet prior to sending it to the ASIC Downlink FIFO.
+*/
+static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len)
 {
        struct ft1000_info *pInfo = netdev_priv(netdev);
        struct ft1000_usb *pFt1000Dev = pInfo->priv;
@@ -769,20 +566,10 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 * packet, u16 len)
        return 0;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_start_xmit
-//
-// Parameters:  skb - socket buffer to be sent
-//              dev - network device
-//
-//
-// Returns:     none
-//
-// Description: transmit a ethernet packet
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* transmit an ethernet packet
+*  Parameters:  skb - socket buffer to be sent
+*               dev - network device
+*/
 static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ft1000_info *pInfo = netdev_priv(dev);
@@ -827,20 +614,7 @@ err:
        return NETDEV_TX_OK;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_open
-//
-// Parameters:
-//              dev - network device
-//
-//
-// Returns:     none
-//
-// Description: open the network driver
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* open the network driver */
 static int ft1000_open(struct net_device *dev)
 {
        struct ft1000_info *pInfo = netdev_priv(dev);
@@ -871,29 +645,14 @@ static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev)
        return &(info->stats);
 }
 
-static const struct net_device_ops ftnet_ops =
-{
+static const struct net_device_ops ftnet_ops = {
        .ndo_open = &ft1000_open,
        .ndo_stop = &ft1000_close,
        .ndo_start_xmit = &ft1000_start_xmit,
        .ndo_get_stats = &ft1000_netdev_stats,
 };
 
-//---------------------------------------------------------------------------
-// Function:    init_ft1000_netdev
-//
-// Parameters:  ft1000dev  - device structure
-//
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function initialize the network device
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-
+/* initialize the network device */
 static int ft1000_reset(void *dev)
 {
        ft1000_reset_card(dev);
@@ -931,14 +690,14 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev)
                card_nr[1] = '\0';
                ret_val = kstrtou8(card_nr, 10, &gCardIndex);
                if (ret_val) {
-                       printk(KERN_ERR "Can't parse netdev\n");
+                       netdev_err(ft1000dev->net, "Can't parse netdev\n");
                        goto err_net;
                }
 
                ft1000dev->CardNumber = gCardIndex;
                DEBUG("card number = %d\n", ft1000dev->CardNumber);
        } else {
-               printk(KERN_ERR "ft1000: Invalid device name\n");
+               netdev_err(ft1000dev->net, "ft1000: Invalid device name\n");
                ret_val = -ENXIO;
                goto err_net;
        }
@@ -1014,20 +773,7 @@ err_net:
        return ret_val;
 }
 
-//---------------------------------------------------------------------------
-// Function:    reg_ft1000_netdev
-//
-// Parameters:  ft1000dev  - device structure
-//
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function register the network driver
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* register the network driver */
 int reg_ft1000_netdev(struct ft1000_usb *ft1000dev,
                      struct usb_interface *intf)
 {
@@ -1060,19 +806,9 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev,
        return 0;
 }
 
-//---------------------------------------------------------------------------
-//
-// Function:   ft1000_copy_up_pkt
-// Description: This function will take a packet from the FIFO up link and
-//             convert it into an ethernet packet and deliver it to the IP stack
-// Input:
-//     urb - the receiving usb urb
-//
-// Output:
-//     status - FAILURE
-//              SUCCESS
-//
-//---------------------------------------------------------------------------
+/* take a packet from the FIFO up link and
+*  convert it into an ethernet packet and deliver it to the IP stack
+*/
 static int ft1000_copy_up_pkt(struct urb *urb)
 {
        struct ft1000_info *info = urb->context;
@@ -1090,9 +826,9 @@ static int ft1000_copy_up_pkt(struct urb *urb)
 
        if (ft1000dev->status & FT1000_STATUS_CLOSING) {
                DEBUG("network driver is closed, return\n");
-               return STATUS_SUCCESS;
+               return 0;
        }
-       // Read length
+       /* Read length */
        len = urb->transfer_buffer_length;
        lena = urb->actual_length;
 
@@ -1105,7 +841,7 @@ static int ft1000_copy_up_pkt(struct urb *urb)
        if (tempword != *chksum) {
                info->stats.rx_errors++;
                ft1000_submit_rx_urb(info);
-               return STATUS_FAILURE;
+               return -1;
        }
 
        skb = dev_alloc_skb(len + 12 + 2);
@@ -1114,7 +850,7 @@ static int ft1000_copy_up_pkt(struct urb *urb)
                DEBUG("ft1000_copy_up_pkt: No Network buffers available\n");
                info->stats.rx_errors++;
                ft1000_submit_rx_urb(info);
-               return STATUS_FAILURE;
+               return -1;
        }
 
        pbuffer = (u8 *) skb_put(skb, len + 12);
@@ -1151,23 +887,11 @@ static int ft1000_copy_up_pkt(struct urb *urb)
 
        ft1000_submit_rx_urb(info);
 
-       return SUCCESS;
+       return 0;
 }
 
 
-//---------------------------------------------------------------------------
-//
-// Function:   ft1000_submit_rx_urb
-// Description: the receiving function of the network driver
-//
-// Input:
-//     info - a private structure contains the device information
-//
-// Output:
-//     status - FAILURE
-//              SUCCESS
-//
-//---------------------------------------------------------------------------
+/* the receiving function of the network driver */
 static int ft1000_submit_rx_urb(struct ft1000_info *info)
 {
        int result;
@@ -1196,20 +920,7 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info)
        return 0;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_close
-//
-// Parameters:
-//              net - network device
-//
-//
-// Returns:     none
-//
-// Description: close the network driver
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* close the network driver */
 int ft1000_close(struct net_device *net)
 {
        struct ft1000_info *pInfo = netdev_priv(net);
@@ -1227,26 +938,14 @@ int ft1000_close(struct net_device *net)
        return 0;
 }
 
-//---------------------------------------------------------------------------
-//
-// Function:   ft1000_chkcard
-// Description: This function will check if the device is presently available on
-//             the system.
-// Input:
-//     dev    - device structure
-// Output:
-//     status - FALSE (device is not present)
-//              TRUE  (device is present)
-//
-//---------------------------------------------------------------------------
+/* check if the device is presently available on the system. */
 static int ft1000_chkcard(struct ft1000_usb *dev)
 {
        u16 tempword;
-       u16 status;
+       int status;
 
        if (dev->fCondResetPend) {
-               DEBUG
-                   ("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n");
+               DEBUG("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n");
                return TRUE;
        }
        /* Mask register is used to check for device presence since it is never
@@ -1254,8 +953,7 @@ static int ft1000_chkcard(struct ft1000_usb *dev)
         */
        status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK);
        if (tempword == 0) {
-               DEBUG
-                   ("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n");
+               DEBUG("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n");
                return FALSE;
        }
        /* The system will return the value of 0xffff for the version register
@@ -1264,30 +962,22 @@ static int ft1000_chkcard(struct ft1000_usb *dev)
        status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID);
        if (tempword != 0x1b01) {
                dev->status |= FT1000_STATUS_CLOSING;
-               DEBUG
-                   ("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n");
+               DEBUG("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n");
                return FALSE;
        }
        return TRUE;
 }
 
-//---------------------------------------------------------------------------
-//
-// Function:   ft1000_receive_cmd
-// Description: This function will read a message from the dpram area.
-// Input:
-//    dev - network device structure
-//    pbuffer - caller supply address to buffer
-//    pnxtph - pointer to next pseudo header
-// Output:
-//   Status = 0 (unsuccessful)
-//          = 1 (successful)
-//
-//---------------------------------------------------------------------------
+/* read a message from the dpram area.
+*  Input:
+*    dev - network device structure
+*    pbuffer - caller supply address to buffer
+*/
 static bool ft1000_receive_cmd(struct ft1000_usb *dev, u16 *pbuffer,
-                              int maxsz, u16 *pnxtph)
+                              int maxsz)
 {
-       u16 size, ret;
+       u16 size;
+       int ret;
        u16 *ppseudohdr;
        int i;
        u16 tempword;
@@ -1359,7 +1049,7 @@ static int ft1000_dsp_prov(void *arg)
        struct prov_record *ptr;
        struct pseudo_hdr *ppseudo_hdr;
        u16 *pmsg;
-       u16 status;
+       int status;
        u16 TempShortBuf[256];
 
        DEBUG("*** DspProv Entered\n");
@@ -1381,7 +1071,7 @@ static int ft1000_dsp_prov(void *arg)
                        i++;
                        if (i == 10) {
                                DEBUG("FT1000:ft1000_dsp_prov:message drop\n");
-                               return STATUS_FAILURE;
+                               return -1;
                        }
                        ft1000_read_register(dev, &tempword,
                                             FT1000_REG_DOORBELL);
@@ -1405,9 +1095,8 @@ static int ft1000_dsp_prov(void *arg)
                        ppseudo_hdr->portsrc = 0;
                        /* Calculate new checksum */
                        ppseudo_hdr->checksum = *pmsg++;
-                       for (i = 1; i < 7; i++) {
+                       for (i = 1; i < 7; i++)
                                ppseudo_hdr->checksum ^= *pmsg++;
-                       }
 
                        TempShortBuf[0] = 0;
                        TempShortBuf[1] = htons(len);
@@ -1425,7 +1114,7 @@ static int ft1000_dsp_prov(void *arg)
                        kfree(ptr->pprov_data);
                        kfree(ptr);
                }
-               msleep(10);
+               usleep_range(9000, 11000);
        }
 
        DEBUG("DSP Provisioning List Entry finished\n");
@@ -1435,7 +1124,7 @@ static int ft1000_dsp_prov(void *arg)
        dev->fProvComplete = true;
        info->CardReady = 1;
 
-       return STATUS_SUCCESS;
+       return 0;
 }
 
 static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size)
@@ -1449,7 +1138,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size)
        u16 i;
        struct pseudo_hdr *ppseudo_hdr;
        u16 *pmsg;
-       u16 status;
+       int status;
        union {
                u8 byte[2];
                u16 wrd;
@@ -1457,7 +1146,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size)
 
        char *cmdbuffer = kmalloc(1600, GFP_KERNEL);
        if (!cmdbuffer)
-               return STATUS_FAILURE;
+               return -1;
 
        status = ft1000_read_dpram32(dev, 0x200, cmdbuffer, size);
 
@@ -1481,154 +1170,179 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size)
        DEBUG("ft1000_proc_drvmsg:Command message type = 0x%x\n", msgtype);
        switch (msgtype) {
        case MEDIA_STATE:{
-                       DEBUG
-                           ("ft1000_proc_drvmsg:Command message type = MEDIA_STATE");
-
-                       pmediamsg = (struct media_msg *)&cmdbuffer[0];
-                       if (info->ProgConStat != 0xFF) {
-                               if (pmediamsg->state) {
-                                       DEBUG("Media is up\n");
-                                       if (info->mediastate == 0) {
-                                               if (dev->NetDevRegDone) {
-                                                       netif_wake_queue(dev->
-                                                                        net);
-                                               }
-                                               info->mediastate = 1;
-                                       }
-                               } else {
-                                       DEBUG("Media is down\n");
-                                       if (info->mediastate == 1) {
-                                               info->mediastate = 0;
-                                               if (dev->NetDevRegDone) {
-                                               }
-                                               info->ConTm = 0;
-                                       }
+               DEBUG("ft1000_proc_drvmsg:Command message type = MEDIA_STATE");
+               pmediamsg = (struct media_msg *)&cmdbuffer[0];
+               if (info->ProgConStat != 0xFF) {
+                       if (pmediamsg->state) {
+                               DEBUG("Media is up\n");
+                               if (info->mediastate == 0) {
+                                       if (dev->NetDevRegDone)
+                                               netif_wake_queue(dev->net);
+                                       info->mediastate = 1;
                                }
                        } else {
                                DEBUG("Media is down\n");
                                if (info->mediastate == 1) {
                                        info->mediastate = 0;
-                                       info->ConTm = 0;
+                                       if (dev->NetDevRegDone)
+                                               info->ConTm = 0;
                                }
                        }
-                       break;
+               } else {
+                       DEBUG("Media is down\n");
+                       if (info->mediastate == 1) {
+                               info->mediastate = 0;
+                               info->ConTm = 0;
+                       }
                }
+               break;
+       }
        case DSP_INIT_MSG:{
-                       DEBUG
-                           ("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG");
-
-                       pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2];
-                       memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
-                       DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n",
-                             info->DspVer[0], info->DspVer[1], info->DspVer[2],
-                             info->DspVer[3]);
-                       memcpy(info->HwSerNum, pdspinitmsg->HwSerNum,
-                              HWSERNUMSZ);
-                       memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
-                       memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
-                       DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n",
-                             info->eui64[0], info->eui64[1], info->eui64[2],
-                             info->eui64[3], info->eui64[4], info->eui64[5],
-                             info->eui64[6], info->eui64[7]);
-                       dev->net->dev_addr[0] = info->eui64[0];
-                       dev->net->dev_addr[1] = info->eui64[1];
-                       dev->net->dev_addr[2] = info->eui64[2];
-                       dev->net->dev_addr[3] = info->eui64[5];
-                       dev->net->dev_addr[4] = info->eui64[6];
-                       dev->net->dev_addr[5] = info->eui64[7];
-
-                       if (ntohs(pdspinitmsg->length) ==
-                           (sizeof(struct dsp_init_msg) - 20)) {
-                               memcpy(info->ProductMode,
-                                      pdspinitmsg->ProductMode, MODESZ);
-                               memcpy(info->RfCalVer, pdspinitmsg->RfCalVer,
-                                      CALVERSZ);
-                               memcpy(info->RfCalDate, pdspinitmsg->RfCalDate,
-                                      CALDATESZ);
-                               DEBUG("RFCalVer = 0x%2x 0x%2x\n",
-                                     info->RfCalVer[0], info->RfCalVer[1]);
-                       }
-                       break;
+               DEBUG("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG");
+               pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2];
+               memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
+               DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n",
+                     info->DspVer[0], info->DspVer[1], info->DspVer[2],
+                     info->DspVer[3]);
+               memcpy(info->HwSerNum, pdspinitmsg->HwSerNum,
+                      HWSERNUMSZ);
+               memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
+               memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
+               DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n",
+                     info->eui64[0], info->eui64[1], info->eui64[2],
+                     info->eui64[3], info->eui64[4], info->eui64[5],
+                     info->eui64[6], info->eui64[7]);
+               dev->net->dev_addr[0] = info->eui64[0];
+               dev->net->dev_addr[1] = info->eui64[1];
+               dev->net->dev_addr[2] = info->eui64[2];
+               dev->net->dev_addr[3] = info->eui64[5];
+               dev->net->dev_addr[4] = info->eui64[6];
+               dev->net->dev_addr[5] = info->eui64[7];
+
+               if (ntohs(pdspinitmsg->length) ==
+                   (sizeof(struct dsp_init_msg) - 20)) {
+                       memcpy(info->ProductMode, pdspinitmsg->ProductMode,
+                                       MODESZ);
+                       memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, CALVERSZ);
+                       memcpy(info->RfCalDate, pdspinitmsg->RfCalDate,
+                              CALDATESZ);
+                       DEBUG("RFCalVer = 0x%2x 0x%2x\n", info->RfCalVer[0],
+                                       info->RfCalVer[1]);
                }
+               break;
+       }
        case DSP_PROVISION:{
-                       DEBUG
-                           ("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n");
+               DEBUG("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n");
 
-                       /* kick off dspprov routine to start provisioning
-                        * Send provisioning data to DSP
-                        */
-                       if (list_empty(&info->prov_list) == 0) {
-                               dev->fProvComplete = false;
-                               status = ft1000_dsp_prov(dev);
-                               if (status != STATUS_SUCCESS)
-                                       goto out;
-                       } else {
-                               dev->fProvComplete = true;
-                               status =
-                                   ft1000_write_register(dev, FT1000_DB_HB,
-                                                         FT1000_REG_DOORBELL);
-                               DEBUG
-                                   ("FT1000:drivermsg:No more DSP provisioning data in dsp image\n");
-                       }
-                       DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n");
-                       break;
+               /* kick off dspprov routine to start provisioning
+                * Send provisioning data to DSP
+                */
+               if (list_empty(&info->prov_list) == 0) {
+                       dev->fProvComplete = false;
+                       status = ft1000_dsp_prov(dev);
+                       if (status != 0)
+                               goto out;
+               } else {
+                       dev->fProvComplete = true;
+                       status = ft1000_write_register(dev, FT1000_DB_HB,
+                                       FT1000_REG_DOORBELL);
+                       DEBUG("FT1000:drivermsg:No more DSP provisioning data in dsp image\n");
                }
+               DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n");
+               break;
+       }
        case DSP_STORE_INFO:{
-                       DEBUG
-                           ("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO");
-
-                       DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n");
-                       tempword = ntohs(pdrvmsg->length);
-                       info->DSPInfoBlklen = tempword;
-                       if (tempword < (MAX_DSP_SESS_REC - 4)) {
-                               pmsg = (u16 *) &pdrvmsg->data[0];
-                               for (i = 0; i < ((tempword + 1) / 2); i++) {
-                                       DEBUG
-                                           ("FT1000:drivermsg:dsp info data = 0x%x\n",
-                                            *pmsg);
-                                       info->DSPInfoBlk[i + 10] = *pmsg++;
-                               }
-                       } else {
-                               info->DSPInfoBlklen = 0;
+               DEBUG("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO");
+               DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n");
+               tempword = ntohs(pdrvmsg->length);
+               info->DSPInfoBlklen = tempword;
+               if (tempword < (MAX_DSP_SESS_REC - 4)) {
+                       pmsg = (u16 *) &pdrvmsg->data[0];
+                       for (i = 0; i < ((tempword + 1) / 2); i++) {
+                               DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg);
+                               info->DSPInfoBlk[i + 10] = *pmsg++;
                        }
-                       break;
+               } else {
+                       info->DSPInfoBlklen = 0;
                }
+               break;
+       }
        case DSP_GET_INFO:{
-                       DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n");
-                       /* copy dsp info block to dsp */
-                       dev->DrvMsgPend = 1;
-                       /* allow any outstanding ioctl to finish */
+               DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n");
+               /* copy dsp info block to dsp */
+               dev->DrvMsgPend = 1;
+               /* allow any outstanding ioctl to finish */
+               mdelay(10);
+               status = ft1000_read_register(dev, &tempword,
+                               FT1000_REG_DOORBELL);
+               if (tempword & FT1000_DB_DPRAM_TX) {
                        mdelay(10);
-                       status =
-                           ft1000_read_register(dev, &tempword,
-                                                FT1000_REG_DOORBELL);
+                       status = ft1000_read_register(dev, &tempword,
+                                       FT1000_REG_DOORBELL);
                        if (tempword & FT1000_DB_DPRAM_TX) {
                                mdelay(10);
-                               status =
-                                   ft1000_read_register(dev, &tempword,
-                                                        FT1000_REG_DOORBELL);
-                               if (tempword & FT1000_DB_DPRAM_TX) {
-                                       mdelay(10);
-                                       status =
-                                           ft1000_read_register(dev, &tempword,
-                                                                FT1000_REG_DOORBELL);
-                                       if (tempword & FT1000_DB_DPRAM_TX)
-                                               break;
-                               }
+                               status = ft1000_read_register(dev, &tempword,
+                                               FT1000_REG_DOORBELL);
+                               if (tempword & FT1000_DB_DPRAM_TX)
+                                       break;
                        }
-                       /* Put message into Slow Queue
-                        * Form Pseudo header
-                        */
-                       pmsg = (u16 *) info->DSPInfoBlk;
-                       *pmsg++ = 0;
-                       *pmsg++ =
-                           htons(info->DSPInfoBlklen + 20 +
-                                 info->DSPInfoBlklen);
-                       ppseudo_hdr =
-                           (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2];
-                       ppseudo_hdr->length =
-                           htons(info->DSPInfoBlklen + 4 +
-                                 info->DSPInfoBlklen);
+               }
+               /* Put message into Slow Queue Form Pseudo header */
+               pmsg = (u16 *) info->DSPInfoBlk;
+               *pmsg++ = 0;
+               *pmsg++ = htons(info->DSPInfoBlklen + 20 + info->DSPInfoBlklen);
+               ppseudo_hdr =
+                   (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2];
+               ppseudo_hdr->length = htons(info->DSPInfoBlklen + 4
+                               + info->DSPInfoBlklen);
+               ppseudo_hdr->source = 0x10;
+               ppseudo_hdr->destination = 0x20;
+               ppseudo_hdr->portdest = 0;
+               ppseudo_hdr->portsrc = 0;
+               ppseudo_hdr->sh_str_id = 0;
+               ppseudo_hdr->control = 0;
+               ppseudo_hdr->rsvd1 = 0;
+               ppseudo_hdr->rsvd2 = 0;
+               ppseudo_hdr->qos_class = 0;
+               /* Insert slow queue sequence number */
+               ppseudo_hdr->seq_num = info->squeseqnum++;
+               /* Insert application id */
+               ppseudo_hdr->portsrc = 0;
+               /* Calculate new checksum */
+               ppseudo_hdr->checksum = *pmsg++;
+               for (i = 1; i < 7; i++)
+                       ppseudo_hdr->checksum ^= *pmsg++;
+
+               info->DSPInfoBlk[10] = 0x7200;
+               info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen);
+               status = ft1000_write_dpram32(dev, 0,
+                               (u8 *)&info->DSPInfoBlk[0],
+                               (unsigned short)(info->DSPInfoBlklen + 22));
+               status = ft1000_write_register(dev, FT1000_DB_DPRAM_TX,
+                               FT1000_REG_DOORBELL);
+               dev->DrvMsgPend = 0;
+               break;
+       }
+       case GET_DRV_ERR_RPT_MSG:{
+               DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n");
+               /* copy driver error message to dsp */
+               dev->DrvMsgPend = 1;
+               /* allow any outstanding ioctl to finish */
+               mdelay(10);
+               status = ft1000_read_register(dev, &tempword,
+                               FT1000_REG_DOORBELL);
+               if (tempword & FT1000_DB_DPRAM_TX) {
+                       mdelay(10);
+                       status = ft1000_read_register(dev, &tempword,
+                                       FT1000_REG_DOORBELL);
+                       if (tempword & FT1000_DB_DPRAM_TX)
+                               mdelay(10);
+               }
+               if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
+                       /* Put message into Slow Queue Form Pseudo header */
+                       pmsg = (u16 *) &tempbuffer[0];
+                       ppseudo_hdr = (struct pseudo_hdr *)pmsg;
+                       ppseudo_hdr->length = htons(0x0012);
                        ppseudo_hdr->source = 0x10;
                        ppseudo_hdr->destination = 0x20;
                        ppseudo_hdr->portdest = 0;
@@ -1647,293 +1361,245 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size)
                        for (i = 1; i < 7; i++)
                                ppseudo_hdr->checksum ^= *pmsg++;
 
-                       info->DSPInfoBlk[10] = 0x7200;
-                       info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen);
-                       status =
-                           ft1000_write_dpram32(dev, 0,
-                                                (u8 *) &info->DSPInfoBlk[0],
-                                                (unsigned short)(info->
-                                                                 DSPInfoBlklen
-                                                                 + 22));
-                       status =
-                           ft1000_write_register(dev, FT1000_DB_DPRAM_TX,
-                                                 FT1000_REG_DOORBELL);
-                       dev->DrvMsgPend = 0;
-
-                       break;
+                       pmsg = (u16 *) &tempbuffer[16];
+                       *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
+                       *pmsg++ = htons(0x000e);
+                       *pmsg++ = htons(info->DSP_TIME[0]);
+                       *pmsg++ = htons(info->DSP_TIME[1]);
+                       *pmsg++ = htons(info->DSP_TIME[2]);
+                       *pmsg++ = htons(info->DSP_TIME[3]);
+                       convert.byte[0] = info->DspVer[0];
+                       convert.byte[1] = info->DspVer[1];
+                       *pmsg++ = convert.wrd;
+                       convert.byte[0] = info->DspVer[2];
+                       convert.byte[1] = info->DspVer[3];
+                       *pmsg++ = convert.wrd;
+                       *pmsg++ = htons(info->DrvErrNum);
+
+                       card_send_command(dev, (unsigned char *)&tempbuffer[0],
+                                       (u16)(0x0012 + PSEUDOSZ));
+                       info->DrvErrNum = 0;
                }
-
-       case GET_DRV_ERR_RPT_MSG:{
-                       DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n");
-                       /* copy driver error message to dsp */
-                       dev->DrvMsgPend = 1;
-                       /* allow any outstanding ioctl to finish */
-                       mdelay(10);
-                       status =
-                           ft1000_read_register(dev, &tempword,
-                                                FT1000_REG_DOORBELL);
-                       if (tempword & FT1000_DB_DPRAM_TX) {
-                               mdelay(10);
-                               status =
-                                   ft1000_read_register(dev, &tempword,
-                                                        FT1000_REG_DOORBELL);
-                               if (tempword & FT1000_DB_DPRAM_TX)
-                                       mdelay(10);
-                       }
-
-                       if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
-                               /* Put message into Slow Queue
-                                * Form Pseudo header
-                                */
-                               pmsg = (u16 *) &tempbuffer[0];
-                               ppseudo_hdr = (struct pseudo_hdr *)pmsg;
-                               ppseudo_hdr->length = htons(0x0012);
-                               ppseudo_hdr->source = 0x10;
-                               ppseudo_hdr->destination = 0x20;
-                               ppseudo_hdr->portdest = 0;
-                               ppseudo_hdr->portsrc = 0;
-                               ppseudo_hdr->sh_str_id = 0;
-                               ppseudo_hdr->control = 0;
-                               ppseudo_hdr->rsvd1 = 0;
-                               ppseudo_hdr->rsvd2 = 0;
-                               ppseudo_hdr->qos_class = 0;
-                               /* Insert slow queue sequence number */
-                               ppseudo_hdr->seq_num = info->squeseqnum++;
-                               /* Insert application id */
-                               ppseudo_hdr->portsrc = 0;
-                               /* Calculate new checksum */
-                               ppseudo_hdr->checksum = *pmsg++;
-                               for (i = 1; i < 7; i++)
-                                       ppseudo_hdr->checksum ^= *pmsg++;
-
-                               pmsg = (u16 *) &tempbuffer[16];
-                               *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
-                               *pmsg++ = htons(0x000e);
-                               *pmsg++ = htons(info->DSP_TIME[0]);
-                               *pmsg++ = htons(info->DSP_TIME[1]);
-                               *pmsg++ = htons(info->DSP_TIME[2]);
-                               *pmsg++ = htons(info->DSP_TIME[3]);
-                               convert.byte[0] = info->DspVer[0];
-                               convert.byte[1] = info->DspVer[1];
-                               *pmsg++ = convert.wrd;
-                               convert.byte[0] = info->DspVer[2];
-                               convert.byte[1] = info->DspVer[3];
-                               *pmsg++ = convert.wrd;
-                               *pmsg++ = htons(info->DrvErrNum);
-
-                               card_send_command(dev,
-                                                (unsigned char *)&tempbuffer[0],
-                                                (u16) (0x0012 + PSEUDOSZ));
-                               info->DrvErrNum = 0;
-                       }
-                       dev->DrvMsgPend = 0;
-
-                       break;
-               }
-
+               dev->DrvMsgPend = 0;
+               break;
+       }
        default:
                break;
        }
 
-       status = STATUS_SUCCESS;
+       status = 0;
 out:
        kfree(cmdbuffer);
        DEBUG("return from ft1000_proc_drvmsg\n");
        return status;
 }
 
-int ft1000_poll(void* dev_id)
+/* Check which application has registered for dsp broadcast messages */
+static int dsp_broadcast_msg_id(struct ft1000_usb *dev)
 {
-    struct ft1000_usb *dev = (struct ft1000_usb *)dev_id;
-       struct ft1000_info *info = netdev_priv(dev->net);
+       struct dpram_blk *pdpram_blk;
+       unsigned long flags;
+       int i;
 
-    u16 tempword;
-    u16 status;
-    u16 size;
-    int i;
-    u16 data;
-    u16 modulo;
-    u16 portid;
-    u16 nxtph;
+       for (i = 0; i < MAX_NUM_APP; i++) {
+               if ((dev->app_info[i].DspBCMsgFlag)
+                               && (dev->app_info[i].fileobject)
+                               && (dev->app_info[i].NumOfMsg
+                                       < MAX_MSG_LIMIT)) {
+                       pdpram_blk = ft1000_get_buffer(&freercvpool);
+                       if (pdpram_blk == NULL) {
+                               DEBUG("Out of memory in free receive command pool\n");
+                               dev->app_info[i].nRxMsgMiss++;
+                               return -1;
+                       }
+                       if (ft1000_receive_cmd(dev, pdpram_blk->pbuffer,
+                                               MAX_CMD_SQSIZE)) {
+                               /* Put message into the
+                                * appropriate application block
+                                */
+                               dev->app_info[i].nRxMsg++;
+                               spin_lock_irqsave(&free_buff_lock, flags);
+                               list_add_tail(&pdpram_blk->list,
+                                               &dev->app_info[i] .app_sqlist);
+                               dev->app_info[i].NumOfMsg++;
+                               spin_unlock_irqrestore(&free_buff_lock, flags);
+                               wake_up_interruptible(&dev->app_info[i]
+                                               .wait_dpram_msg);
+                       } else {
+                               dev->app_info[i].nRxMsgMiss++;
+                               ft1000_free_buffer(pdpram_blk, &freercvpool);
+                               DEBUG("pdpram_blk::ft1000_get_buffer NULL\n");
+                               return -1;
+                       }
+               }
+       }
+       return 0;
+}
+
+static int handle_misc_portid(struct ft1000_usb *dev)
+{
        struct dpram_blk *pdpram_blk;
-       struct pseudo_hdr *ppseudo_hdr;
-    unsigned long flags;
-
-    if (ft1000_chkcard(dev) == FALSE) {
-        DEBUG("ft1000_poll::ft1000_chkcard: failed\n");
-        return STATUS_FAILURE;
-    }
-
-    status = ft1000_read_register (dev, &tempword, FT1000_REG_DOORBELL);
-
-    if ( !status )
-    {
-
-        if (tempword & FT1000_DB_DPRAM_RX) {
-
-            status = ft1000_read_dpram16(dev, 0x200, (u8 *)&data, 0);
-            size = ntohs(data) + 16 + 2;
-            if (size % 4) {
-                modulo = 4 - (size % 4);
-                size = size + modulo;
-            }
-            status = ft1000_read_dpram16(dev, 0x201, (u8 *)&portid, 1);
-            portid &= 0xff;
-
-            if (size < MAX_CMD_SQSIZE) {
-                switch (portid)
-                {
-                    case DRIVERID:
-                        DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n");
-
-                        status = ft1000_proc_drvmsg (dev, size);
-                        if (status != STATUS_SUCCESS )
-                            return status;
-                        break;
-                    case DSPBCMSGID:
-                        // This is a dsp broadcast message
-                        // Check which application has registered for dsp broadcast messages
-
-                       for (i=0; i<MAX_NUM_APP; i++) {
-                          if ( (dev->app_info[i].DspBCMsgFlag) && (dev->app_info[i].fileobject) &&
-                                         (dev->app_info[i].NumOfMsg < MAX_MSG_LIMIT)  )
-                          {
-                              nxtph = FT1000_DPRAM_RX_BASE + 2;
-                              pdpram_blk = ft1000_get_buffer (&freercvpool);
-                              if (pdpram_blk != NULL) {
-                                  if ( ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE, &nxtph) ) {
-                                       ppseudo_hdr = (struct pseudo_hdr *)pdpram_blk->pbuffer;
-                                      // Put message into the appropriate application block
-                                      dev->app_info[i].nRxMsg++;
-                                      spin_lock_irqsave(&free_buff_lock, flags);
-                                      list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist);
-                                      dev->app_info[i].NumOfMsg++;
-                                      spin_unlock_irqrestore(&free_buff_lock, flags);
-                                      wake_up_interruptible(&dev->app_info[i].wait_dpram_msg);
-                                   }
-                                   else {
-                                      dev->app_info[i].nRxMsgMiss++;
-                                      // Put memory back to free pool
-                                      ft1000_free_buffer(pdpram_blk, &freercvpool);
-                                      DEBUG("pdpram_blk::ft1000_get_buffer NULL\n");
-                                   }
-                               }
-                               else {
-                                   DEBUG("Out of memory in free receive command pool\n");
-                                   dev->app_info[i].nRxMsgMiss++;
-                               }
-                           }
-                       }
-                        break;
-                    default:
-                        pdpram_blk = ft1000_get_buffer (&freercvpool);
-
-                        if (pdpram_blk != NULL) {
-                           if ( ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE, &nxtph) ) {
-                               ppseudo_hdr = (struct pseudo_hdr *)pdpram_blk->pbuffer;
-                               // Search for correct application block
-                               for (i=0; i<MAX_NUM_APP; i++) {
-                                   if (dev->app_info[i].app_id == ppseudo_hdr->portdest) {
-                                       break;
-                                   }
-                               }
-
-                               if (i == MAX_NUM_APP) {
-                                   DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ppseudo_hdr->portdest);
-                                   // Put memory back to free pool
-                                   ft1000_free_buffer(pdpram_blk, &freercvpool);
-                               }
-                               else {
-                                   if (dev->app_info[i].NumOfMsg > MAX_MSG_LIMIT) {
-                                      // Put memory back to free pool
-                                      ft1000_free_buffer(pdpram_blk, &freercvpool);
-                                   }
-                                   else {
-                                       dev->app_info[i].nRxMsg++;
-                                       // Put message into the appropriate application block
-                                       list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist);
-                                      dev->app_info[i].NumOfMsg++;
-                                   }
-                               }
-                           }
-                           else {
-                               // Put memory back to free pool
-                               ft1000_free_buffer(pdpram_blk, &freercvpool);
-                           }
-                        }
-                        else {
-                            DEBUG("Out of memory in free receive command pool\n");
-                        }
-                        break;
-                }
-            }
-            else {
-                DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size);
-            }
-            status = ft1000_write_register (dev, FT1000_DB_DPRAM_RX, FT1000_REG_DOORBELL);
-        }
-        else if (tempword & FT1000_DSP_ASIC_RESET) {
-
-            // Let's reset the ASIC from the Host side as well
-            status = ft1000_write_register (dev, ASIC_RESET_BIT, FT1000_REG_RESET);
-            status = ft1000_read_register (dev, &tempword, FT1000_REG_RESET);
-            i = 0;
-            while (tempword & ASIC_RESET_BIT) {
-                status = ft1000_read_register (dev, &tempword, FT1000_REG_RESET);
-                msleep(10);
-                i++;
-                if (i==100)
-                    break;
-            }
-            if (i==100) {
-                DEBUG("Unable to reset ASIC\n");
-                return STATUS_SUCCESS;
-            }
-            msleep(10);
-            // Program WMARK register
-            status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK);
-            // clear ASIC reset doorbell
-            status = ft1000_write_register (dev, FT1000_DSP_ASIC_RESET, FT1000_REG_DOORBELL);
-            msleep(10);
-        }
-        else if (tempword & FT1000_ASIC_RESET_REQ) {
-            DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_ASIC_RESET_REQ\n");
-
-            // clear ASIC reset request from DSP
-            status = ft1000_write_register (dev, FT1000_ASIC_RESET_REQ, FT1000_REG_DOORBELL);
-            status = ft1000_write_register (dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL);
-            // copy dsp session record from Adapter block
-            status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPSess.Rec[0], 1024);
-            // Program WMARK register
-            status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK);
-            // ring doorbell to tell DSP that ASIC is out of reset
-            status = ft1000_write_register (dev, FT1000_ASIC_RESET_DSP, FT1000_REG_DOORBELL);
-        }
-        else if (tempword & FT1000_DB_COND_RESET) {
-            DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_DB_COND_RESET\n");
-
-           if (!dev->fAppMsgPend) {
-               // Reset ASIC and DSP
-
-                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER0, (u8 *)&(info->DSP_TIME[0]), FT1000_MAG_DSP_TIMER0_INDX);
-                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER1, (u8 *)&(info->DSP_TIME[1]), FT1000_MAG_DSP_TIMER1_INDX);
-                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER2, (u8 *)&(info->DSP_TIME[2]), FT1000_MAG_DSP_TIMER2_INDX);
-                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER3, (u8 *)&(info->DSP_TIME[3]), FT1000_MAG_DSP_TIMER3_INDX);
-                info->CardReady = 0;
-                info->DrvErrNum = DSP_CONDRESET_INFO;
-                DEBUG("ft1000_hw:DSP conditional reset requested\n");
-                info->ft1000_reset(dev->net);
-            }
-            else {
-                dev->fProvComplete = false;
-                dev->fCondResetPend = true;
-            }
-
-            ft1000_write_register(dev, FT1000_DB_COND_RESET, FT1000_REG_DOORBELL);
-        }
-
-    }
-
-    return STATUS_SUCCESS;
+       int i;
+
+       pdpram_blk = ft1000_get_buffer(&freercvpool);
+       if (pdpram_blk == NULL) {
+               DEBUG("Out of memory in free receive command pool\n");
+               return -1;
+       }
+       if (!ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE))
+               goto exit_failure;
 
+       /* Search for correct application block */
+       for (i = 0; i < MAX_NUM_APP; i++) {
+               if (dev->app_info[i].app_id == ((struct pseudo_hdr *)
+                                       pdpram_blk->pbuffer)->portdest)
+                       break;
+       }
+       if (i == MAX_NUM_APP) {
+               DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ((struct pseudo_hdr *)pdpram_blk->pbuffer)->portdest);
+               goto exit_failure;
+       } else if (dev->app_info[i].NumOfMsg > MAX_MSG_LIMIT) {
+               goto exit_failure;
+       } else {
+               dev->app_info[i].nRxMsg++;
+               /* Put message into the appropriate application block */
+               list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist);
+               dev->app_info[i].NumOfMsg++;
+       }
+       return 0;
+
+exit_failure:
+       ft1000_free_buffer(pdpram_blk, &freercvpool);
+       return -1;
+}
+
+int ft1000_poll(void *dev_id)
+{
+       struct ft1000_usb *dev = (struct ft1000_usb *)dev_id;
+       struct ft1000_info *info = netdev_priv(dev->net);
+       u16 tempword;
+       int status;
+       u16 size;
+       int i;
+       u16 data;
+       u16 modulo;
+       u16 portid;
+
+       if (ft1000_chkcard(dev) == FALSE) {
+               DEBUG("ft1000_poll::ft1000_chkcard: failed\n");
+               return -1;
+       }
+       status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL);
+       if (!status) {
+               if (tempword & FT1000_DB_DPRAM_RX) {
+                       status = ft1000_read_dpram16(dev,
+                                       0x200, (u8 *)&data, 0);
+                       size = ntohs(data) + 16 + 2;
+                       if (size % 4) {
+                               modulo = 4 - (size % 4);
+                               size = size + modulo;
+                       }
+                       status = ft1000_read_dpram16(dev, 0x201,
+                                       (u8 *)&portid, 1);
+                       portid &= 0xff;
+                       if (size < MAX_CMD_SQSIZE) {
+                               switch (portid) {
+                               case DRIVERID:
+                                       DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n");
+                                       status = ft1000_proc_drvmsg(dev, size);
+                                       if (status != 0)
+                                               return status;
+                                       break;
+                               case DSPBCMSGID:
+                                       status = dsp_broadcast_msg_id(dev);
+                                       break;
+                               default:
+                                       status = handle_misc_portid(dev);
+                                       break;
+                               }
+                       } else
+                               DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size);
+                       status = ft1000_write_register(dev,
+                                       FT1000_DB_DPRAM_RX,
+                                       FT1000_REG_DOORBELL);
+               } else if (tempword & FT1000_DSP_ASIC_RESET) {
+                       /* Let's reset the ASIC from the Host side as well */
+                       status = ft1000_write_register(dev, ASIC_RESET_BIT,
+                                       FT1000_REG_RESET);
+                       status = ft1000_read_register(dev, &tempword,
+                                       FT1000_REG_RESET);
+                       i = 0;
+                       while (tempword & ASIC_RESET_BIT) {
+                               status = ft1000_read_register(dev, &tempword,
+                                               FT1000_REG_RESET);
+                               usleep_range(9000, 11000);
+                               i++;
+                               if (i == 100)
+                                       break;
+                       }
+                       if (i == 100) {
+                               DEBUG("Unable to reset ASIC\n");
+                               return 0;
+                       }
+                       usleep_range(9000, 11000);
+                       /* Program WMARK register */
+                       status = ft1000_write_register(dev, 0x600,
+                                       FT1000_REG_MAG_WATERMARK);
+                       /* clear ASIC reset doorbell */
+                       status = ft1000_write_register(dev,
+                                       FT1000_DSP_ASIC_RESET,
+                                       FT1000_REG_DOORBELL);
+                       usleep_range(9000, 11000);
+               } else if (tempword & FT1000_ASIC_RESET_REQ) {
+                       DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_ASIC_RESET_REQ\n");
+                       /* clear ASIC reset request from DSP */
+                       status = ft1000_write_register(dev,
+                                       FT1000_ASIC_RESET_REQ,
+                                       FT1000_REG_DOORBELL);
+                       status = ft1000_write_register(dev, HOST_INTF_BE,
+                                       FT1000_REG_SUP_CTRL);
+                       /* copy dsp session record from Adapter block */
+                       status = ft1000_write_dpram32(dev, 0,
+                                       (u8 *)&info->DSPSess.Rec[0], 1024);
+                       status = ft1000_write_register(dev, 0x600,
+                                       FT1000_REG_MAG_WATERMARK);
+                       /* ring doorbell to tell DSP that
+                        * ASIC is out of reset
+                        * */
+                       status = ft1000_write_register(dev,
+                                       FT1000_ASIC_RESET_DSP,
+                                       FT1000_REG_DOORBELL);
+               } else if (tempword & FT1000_DB_COND_RESET) {
+                       DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_DB_COND_RESET\n");
+                       if (!dev->fAppMsgPend) {
+                               /* Reset ASIC and DSP */
+                               status = ft1000_read_dpram16(dev,
+                                               FT1000_MAG_DSP_TIMER0,
+                                               (u8 *)&(info->DSP_TIME[0]),
+                                               FT1000_MAG_DSP_TIMER0_INDX);
+                               status = ft1000_read_dpram16(dev,
+                                               FT1000_MAG_DSP_TIMER1,
+                                               (u8 *)&(info->DSP_TIME[1]),
+                                               FT1000_MAG_DSP_TIMER1_INDX);
+                               status = ft1000_read_dpram16(dev,
+                                               FT1000_MAG_DSP_TIMER2,
+                                               (u8 *)&(info->DSP_TIME[2]),
+                                               FT1000_MAG_DSP_TIMER2_INDX);
+                               status = ft1000_read_dpram16(dev,
+                                               FT1000_MAG_DSP_TIMER3,
+                                               (u8 *)&(info->DSP_TIME[3]),
+                                               FT1000_MAG_DSP_TIMER3_INDX);
+                               info->CardReady = 0;
+                               info->DrvErrNum = DSP_CONDRESET_INFO;
+                               DEBUG("ft1000_hw:DSP conditional reset requested\n");
+                               info->ft1000_reset(dev->net);
+                       } else {
+                               dev->fProvComplete = false;
+                               dev->fCondResetPend = true;
+                       }
+                       ft1000_write_register(dev, FT1000_DB_COND_RESET,
+                                       FT1000_REG_DOORBELL);
+               }
+       }
+       return 0;
 }
index 5ead942be680c38962c251349033e44faec9c807..2575d0d6bff3b124f18020785a10771e0e958f69 100644 (file)
 
 #define seq_putx(m, message, size, var) \
        seq_printf(m, message); \
-       for(i = 0; i < (size - 1); i++) \
+       for (i = 0; i < (size - 1); i++) \
                seq_printf(m, "%02x:", var[i]); \
        seq_printf(m, "%02x\n", var[i])
 
 #define seq_putd(m, message, size, var) \
        seq_printf(m, message); \
-       for(i = 0; i < (size - 1); i++) \
+       for (i = 0; i < (size - 1); i++) \
                seq_printf(m, "%d.", var[i]); \
        seq_printf(m, "%d\n", var[i])
 
 #define FTNET_PROC init_net.proc_net
 
 
-int ft1000_read_dpram16 (struct ft1000_usb *ft1000dev, u16 indx,
+int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx,
                         u8 *buffer, u8 highlow);
 
 
 static int ft1000ReadProc(struct seq_file *m, void *v)
 {
-       static const char *status[] = { 
-               "Idle (Disconnect)", 
+       static const char *status[] = {
+               "Idle (Disconnect)",
                "Searching",
                "Active (Connected)",
                "Waiting for L2",
@@ -127,10 +127,10 @@ static int ft1000ReadProc(struct seq_file *m, void *v)
        }
 
        seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n",
-               ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60));
+               ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60));
        seq_printf(m, "Connection Time[s]: %ld\n", delta);
        seq_printf(m, "Asic ID: %s\n",
-       (info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC");
+       (info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC");
        seq_putx(m, "SKU: ", SKUSZ, info->Sku);
        seq_putx(m, "EUI64: ", EUISZ, info->eui64);
        seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer);
index a8dd1e54878cb7a3a3914c097896bd6377216b8f..da6cc370c535ea316a917b184f7a4bfcdab8c59d 100644 (file)
@@ -45,13 +45,13 @@ static int ft1000_poll_thread(void *arg)
                msleep(10);
                if (!gPollingfailed) {
                        ret = ft1000_poll(arg);
-                       if (ret != STATUS_SUCCESS) {
+                       if (ret != 0) {
                                DEBUG("ft1000_poll_thread: polling failed\n");
                                gPollingfailed = true;
                        }
                }
        }
-       return STATUS_SUCCESS;
+       return 0;
 }
 
 static int ft1000_probe(struct usb_interface *interface,
index e8d00a930dc64bb08e5b7b34d42896dc3cd5b6c4..a6fdd524ee6f10024bb94c9e79a491c301942c08 100644 (file)
@@ -11,8 +11,6 @@
 
 #define PSEUDOSZ                16
 
-#define  SUCCESS             0x00
-
 struct app_info_block {
        u32 nTxMsg;                    /* DPRAM msg sent to DSP with app_id */
        u32 nRxMsg;                    /* DPRAM msg rcv from dsp with app_id */
@@ -31,9 +29,6 @@ struct app_info_block {
 #define FALSE           0
 #define TRUE            1
 
-#define STATUS_SUCCESS  0
-#define STATUS_FAILURE   0x1001
-
 #define FT1000_STATUS_CLOSING  0x01
 
 #define DSPBCMSGID              0x10
index c57a6ba5d010e84464632590c20e48e805d8681e..74a03608b2ddc9ff679a1cd6621f0a7122b27613 100644 (file)
  */
 #define DEFAULT_MTU_SIZE 1500
 
-#define gdm_dev_endian(n) (\
-       n->phy_dev->get_endian(n->phy_dev->priv_dev))
-
-#define gdm_lte_hci_send(n, d, l) (\
-       n->phy_dev->send_hci_func(n->phy_dev->priv_dev, d, l, NULL, NULL))
-
-#define gdm_lte_sdu_send(n, d, l, c, b, i, t) (\
-       n->phy_dev->send_sdu_func(n->phy_dev->priv_dev, d, l, n->pdn_table.dft_eps_id, 0, c, b, i, t))
-
-#define gdm_lte_rcv_with_cb(n, c, b, e) (\
-       n->rcv_func(n->priv_dev, c, b, e))
-
 #define IP_VERSION_4   4
 #define IP_VERSION_6   6
 
@@ -458,13 +446,11 @@ static int gdm_lte_tx(struct sk_buff *skb, struct net_device *dev)
 
        sscanf(dev->name, "lte%d", &idx);
 
-       ret = gdm_lte_sdu_send(nic,
-                              data_buf,
-                              data_len,
-                              tx_complete,
-                              nic,
-                              idx,
-                              nic_type);
+       ret = nic->phy_dev->send_sdu_func(nic->phy_dev->priv_dev,
+                                         data_buf, data_len,
+                                         nic->pdn_table.dft_eps_id, 0,
+                                         tx_complete, nic, idx,
+                                         nic_type);
 
        if (ret == TX_NO_BUFFER || ret == TX_NO_SPC) {
                netif_stop_queue(dev);
@@ -503,14 +489,18 @@ static int gdm_lte_event_send(struct net_device *dev, char *buf, int len)
        sscanf(dev->name, "lte%d", &idx);
 
        return netlink_send(lte_event.sock, idx, 0, buf,
-                           gdm_dev16_to_cpu(gdm_dev_endian(nic), hci->len) + HCI_HEADER_SIZE);
+                           gdm_dev16_to_cpu(
+                                   nic->phy_dev->get_endian(
+                                           nic->phy_dev->priv_dev), hci->len)
+                           + HCI_HEADER_SIZE);
 }
 
 static void gdm_lte_event_rcv(struct net_device *dev, u16 type, void *msg, int len)
 {
        struct nic *nic = netdev_priv(dev);
 
-       gdm_lte_hci_send(nic, msg, len);
+       nic->phy_dev->send_hci_func(nic->phy_dev->priv_dev, msg, len, NULL,
+                                   NULL);
 }
 
 int gdm_lte_event_init(void)
@@ -688,8 +678,14 @@ static void gdm_lte_pdn_table(struct net_device *dev, char *buf, int len)
 
        if (pdn_table->activate) {
                nic->pdn_table.activate = pdn_table->activate;
-               nic->pdn_table.dft_eps_id = gdm_dev32_to_cpu(gdm_dev_endian(nic), pdn_table->dft_eps_id);
-               nic->pdn_table.nic_type = gdm_dev32_to_cpu(gdm_dev_endian(nic), pdn_table->nic_type);
+               nic->pdn_table.dft_eps_id = gdm_dev32_to_cpu(
+                                               nic->phy_dev->get_endian(
+                                                       nic->phy_dev->priv_dev),
+                                               pdn_table->dft_eps_id);
+               nic->pdn_table.nic_type = gdm_dev32_to_cpu(
+                                               nic->phy_dev->get_endian(
+                                                       nic->phy_dev->priv_dev),
+                                               pdn_table->nic_type);
 
                netdev_info(dev, "pdn activated, nic_type=0x%x\n",
                            nic->pdn_table.nic_type);
@@ -762,7 +758,7 @@ void start_rx_proc(struct phy_dev *phy_dev)
        int i;
 
        for (i = 0; i < MAX_RX_SUBMIT_COUNT; i++)
-               gdm_lte_rcv_with_cb(phy_dev, rx_complete, phy_dev, USB_COMPLETE);
+               phy_dev->rcv_func(phy_dev->priv_dev, rx_complete, phy_dev, USB_COMPLETE);
 }
 
 static struct net_device_ops gdm_netdev_ops = {
index 62163673976c309e93f004ba5082b80f2a8f240d..2fa3a5a6580fa5531dfa20b9d144929948440898 100644 (file)
@@ -158,7 +158,6 @@ static int up_to_host(struct mux_rx *r)
        unsigned int start_flag;
        unsigned int payload_size;
        unsigned short packet_type;
-       int remain;
        int dummy_cnt;
        u32 packet_size_sum = r->offset;
        int index;
@@ -176,8 +175,7 @@ static int up_to_host(struct mux_rx *r)
                        break;
                }
 
-               remain = (MUX_HEADER_SIZE + payload_size) % 4;
-               dummy_cnt = remain ? (4-remain) : 0;
+               dummy_cnt = ALIGN(MUX_HEADER_SIZE + payload_size, 4);
 
                if (len - packet_size_sum <
                        MUX_HEADER_SIZE + payload_size + dummy_cnt) {
@@ -361,7 +359,6 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index,
        struct mux_pkt_header *mux_header;
        struct mux_tx *t = NULL;
        static u32 seq_num = 1;
-       int remain;
        int dummy_cnt;
        int total_len;
        int ret;
@@ -375,8 +372,7 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index,
 
        spin_lock_irqsave(&mux_dev->write_lock, flags);
 
-       remain = (MUX_HEADER_SIZE + len) % 4;
-       dummy_cnt = remain ? (4 - remain) : 0;
+       dummy_cnt = ALIGN(MUX_HEADER_SIZE + len, 4);
 
        total_len = len + MUX_HEADER_SIZE + dummy_cnt;
 
index 781134af69d13fe37481ed06f4685fc746f34f64..33458a583142db31db6c1b4c722849bb1e462372 100644 (file)
@@ -830,24 +830,19 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id
 
        if (bInterfaceNumber > NETWORK_INTERFACE) {
                pr_info("not a network device\n");
-               return -1;
+               return -ENODEV;
        }
 
-       phy_dev = kmalloc(sizeof(struct phy_dev), GFP_ATOMIC);
-       if (!phy_dev) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       phy_dev = kzalloc(sizeof(struct phy_dev), GFP_KERNEL);
+       if (!phy_dev)
+               return -ENOMEM;
 
-       udev = kmalloc(sizeof(struct lte_udev), GFP_ATOMIC);
+       udev = kzalloc(sizeof(struct lte_udev), GFP_KERNEL);
        if (!udev) {
                ret = -ENOMEM;
-               goto out;
+               goto err_udev;
        }
 
-       memset(phy_dev, 0, sizeof(struct phy_dev));
-       memset(udev, 0, sizeof(struct lte_udev));
-
        phy_dev->priv_dev = (void *)udev;
        phy_dev->send_hci_func = gdm_usb_hci_send;
        phy_dev->send_sdu_func = gdm_usb_sdu_send;
@@ -858,7 +853,7 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id
        ret = init_usb(udev);
        if (ret < 0) {
                pr_err("init_usb func failed\n");
-               goto out;
+               goto err_init_usb;
        }
        udev->intf = intf;
 
@@ -875,23 +870,22 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id
        ret = request_mac_address(udev);
        if (ret < 0) {
                pr_err("request Mac address failed\n");
-               goto out;
+               goto err_mac_address;
        }
 
        start_rx_proc(phy_dev);
-out:
-
-       if (ret < 0) {
-               kfree(phy_dev);
-               if (udev) {
-                       release_usb(udev);
-                       kfree(udev);
-               }
-       }
-
        usb_get_dev(usbdev);
        usb_set_intfdata(intf, phy_dev);
 
+       return 0;
+
+err_mac_address:
+       release_usb(udev);
+err_init_usb:
+       kfree(udev);
+err_udev:
+       kfree(phy_dev);
+
        return ret;
 }
 
index 4c9364b63c77d61a1088298993ad46435c0cca6e..6f38ca95f9bb39eb1379e75d7b9175be1a07aa8f 100644 (file)
@@ -439,13 +439,13 @@ static int adis16220_probe(struct spi_device *spi)
        indio_dev->channels = adis16220_channels;
        indio_dev->num_channels = ARRAY_SIZE(adis16220_channels);
 
-       ret = iio_device_register(indio_dev);
+       ret = devm_iio_device_register(&spi->dev, indio_dev);
        if (ret)
                return ret;
 
        ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &accel_bin);
        if (ret)
-               goto error_unregister_dev;
+               return ret;
 
        ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc1_bin);
        if (ret)
@@ -470,8 +470,6 @@ error_rm_adc1_bin:
        sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin);
 error_rm_accel_bin:
        sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin);
-error_unregister_dev:
-       iio_device_unregister(indio_dev);
        return ret;
 }
 
@@ -482,7 +480,6 @@ static int adis16220_remove(struct spi_device *spi)
        sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin);
        sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin);
        sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin);
-       iio_device_unregister(indio_dev);
 
        return 0;
 }
index 9f48e5c74eed85c8f164208d4ddbaf4ed108dfb8..2369cf28412ed682046e99c715b21a0b778faee5 100644 (file)
@@ -412,7 +412,7 @@ static int ad7816_probe(struct spi_device *spi_dev)
                        return ret;
        }
 
-       ret = iio_device_register(indio_dev);
+       ret = devm_iio_device_register(&spi_dev->dev, indio_dev);
        if (ret)
                return ret;
 
@@ -422,15 +422,6 @@ static int ad7816_probe(struct spi_device *spi_dev)
        return 0;
 }
 
-static int ad7816_remove(struct spi_device *spi_dev)
-{
-       struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev);
-
-       iio_device_unregister(indio_dev);
-
-       return 0;
-}
-
 static const struct spi_device_id ad7816_id[] = {
        { "ad7816", 0 },
        { "ad7817", 0 },
@@ -446,7 +437,6 @@ static struct spi_driver ad7816_driver = {
                .owner = THIS_MODULE,
        },
        .probe = ad7816_probe,
-       .remove = ad7816_remove,
        .id_table = ad7816_id,
 };
 module_spi_driver(ad7816_driver);
index ef0a21d8ce15ce76ea4ae39bb72d0523f3bfc230..a876ce7553517523b14428b101e4fc77b25fe234 100644 (file)
@@ -183,7 +183,7 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
        iodev->channels = lpc32xx_adc_iio_channels;
        iodev->num_channels = ARRAY_SIZE(lpc32xx_adc_iio_channels);
 
-       retval = iio_device_register(iodev);
+       retval = devm_iio_device_register(&pdev->dev, iodev);
        if (retval)
                return retval;
 
@@ -192,15 +192,6 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int lpc32xx_adc_remove(struct platform_device *pdev)
-{
-       struct iio_dev *iodev = platform_get_drvdata(pdev);
-
-       iio_device_unregister(iodev);
-
-       return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id lpc32xx_adc_match[] = {
        { .compatible = "nxp,lpc3220-adc" },
@@ -211,7 +202,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_adc_match);
 
 static struct platform_driver lpc32xx_adc_driver = {
        .probe          = lpc32xx_adc_probe,
-       .remove         = lpc32xx_adc_remove,
        .driver         = {
                .name   = MOD_NAME,
                .owner  = THIS_MODULE,
index 0feea5541d02d5f98f24023ffcd4623480a0cc6b..75ddd4f801a3daf9346c186e3a7dc9510b36817a 100644 (file)
@@ -108,11 +108,6 @@ static int adt7316_i2c_probe(struct i2c_client *client,
        return adt7316_probe(&client->dev, &bus, id->name);
 }
 
-static int adt7316_i2c_remove(struct i2c_client *client)
-{
-       return adt7316_remove(&client->dev);
-}
-
 static const struct i2c_device_id adt7316_i2c_id[] = {
        { "adt7316", 0 },
        { "adt7317", 0 },
@@ -132,7 +127,6 @@ static struct i2c_driver adt7316_driver = {
                .owner  = THIS_MODULE,
        },
        .probe = adt7316_i2c_probe,
-       .remove = adt7316_i2c_remove,
        .id_table = adt7316_i2c_id,
 };
 module_i2c_driver(adt7316_driver);
index 7f4f0a8245b480090387c0f03aab24dbbb8ee178..e480abb72e4a495e772a02fd7ce7896b5f69cc43 100644 (file)
@@ -116,11 +116,6 @@ static int adt7316_spi_probe(struct spi_device *spi_dev)
        return adt7316_probe(&spi_dev->dev, &bus, spi_dev->modalias);
 }
 
-static int adt7316_spi_remove(struct spi_device *spi_dev)
-{
-       return adt7316_remove(&spi_dev->dev);
-}
-
 static const struct spi_device_id adt7316_spi_id[] = {
        { "adt7316", 0 },
        { "adt7317", 0 },
@@ -140,7 +135,6 @@ static struct spi_driver adt7316_driver = {
                .owner = THIS_MODULE,
        },
        .probe = adt7316_spi_probe,
-       .remove = adt7316_spi_remove,
        .id_table = adt7316_spi_id,
 };
 module_spi_driver(adt7316_driver);
index 80266e801d5673919533c9208241b3a0e3868d7f..16a8201228ffc18f912eb1ea69794a706096a048 100644 (file)
@@ -2166,7 +2166,7 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
        if (ret)
                return -EIO;
 
-       ret = iio_device_register(indio_dev);
+       ret = devm_iio_device_register(dev, indio_dev);
        if (ret)
                return ret;
 
@@ -2177,16 +2177,6 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
 }
 EXPORT_SYMBOL(adt7316_probe);
 
-int adt7316_remove(struct device *dev)
-{
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
-
-       iio_device_unregister(indio_dev);
-
-       return 0;
-}
-EXPORT_SYMBOL(adt7316_remove);
-
 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
 MODULE_DESCRIPTION("Analog Devices ADT7316/7/8 and ADT7516/7/9 digital"
                        " temperature sensor, ADC and DAC driver");
index 4d3efff46ae7144b8c218434dc8e8fa22ef21ae4..2dbfb499528d2be1afc954b06a67c99a574de7d9 100644 (file)
@@ -31,6 +31,5 @@ extern const struct dev_pm_ops adt7316_pm_ops;
 #define ADT7316_PM_OPS NULL
 #endif
 int adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name);
-int adt7316_remove(struct device *dev);
 
 #endif
index 6d3d771154f3c3b45eaa9c7f667b34749f1e8301..d5d395c2e3e4088ee69dfc3484483b875f80328f 100644 (file)
@@ -167,7 +167,7 @@ static int adis16060_r_probe(struct spi_device *spi)
        indio_dev->channels = adis16060_channels;
        indio_dev->num_channels = ARRAY_SIZE(adis16060_channels);
 
-       ret = iio_device_register(indio_dev);
+       ret = devm_iio_device_register(&spi->dev, indio_dev);
        if (ret)
                return ret;
 
@@ -175,13 +175,6 @@ static int adis16060_r_probe(struct spi_device *spi)
        return 0;
 }
 
-/* fixme, confirm ordering in this function */
-static int adis16060_r_remove(struct spi_device *spi)
-{
-       iio_device_unregister(spi_get_drvdata(spi));
-       return 0;
-}
-
 static int adis16060_w_probe(struct spi_device *spi)
 {
        int ret;
@@ -211,7 +204,6 @@ static struct spi_driver adis16060_r_driver = {
                .owner = THIS_MODULE,
        },
        .probe = adis16060_r_probe,
-       .remove = adis16060_r_remove,
 };
 
 static struct spi_driver adis16060_w_driver = {
index 488e690388c948dc3cda08afdc334cebc15966ef..3660a43b5f08058ee4d2af1d313169188c1bf47b 100644 (file)
@@ -585,7 +585,7 @@ static int isl29018_probe(struct i2c_client *client,
        indio_dev->name = id->name;
        indio_dev->dev.parent = &client->dev;
        indio_dev->modes = INDIO_DIRECT_MODE;
-       err = iio_device_register(indio_dev);
+       err = devm_iio_device_register(&client->dev, indio_dev);
        if (err) {
                dev_err(&client->dev, "iio registration fails\n");
                return err;
@@ -594,16 +594,6 @@ static int isl29018_probe(struct i2c_client *client,
        return 0;
 }
 
-static int isl29018_remove(struct i2c_client *client)
-{
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-
-       dev_dbg(&client->dev, "%s()\n", __func__);
-       iio_device_unregister(indio_dev);
-
-       return 0;
-}
-
 #ifdef CONFIG_PM_SLEEP
 static int isl29018_suspend(struct device *dev)
 {
@@ -664,7 +654,6 @@ static struct i2c_driver isl29018_driver = {
                        .of_match_table = isl29018_of_match,
                    },
        .probe   = isl29018_probe,
-       .remove  = isl29018_remove,
        .id_table = isl29018_id,
 };
 module_i2c_driver(isl29018_driver);
index a3ea69e9d800ef3ae992efbacb4575bc7ad94782..34634da1f9f733fd0268a728fc5e3653aeedff58 100644 (file)
@@ -6,6 +6,8 @@ menu "Magnetometer sensors"
 config SENSORS_HMC5843
        tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer"
        depends on I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say Y here to add support for the Honeywell HMC5843, HMC5883 and
          HMC5883L 3-Axis Magnetometer (digital compass).
index 99421f90d1895f6a0691d4443c457f5aac2335db..bdb01887829635c5489f45afbd391a07de086288 100644 (file)
@@ -624,10 +624,17 @@ static const struct i2c_device_id hmc5843_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, hmc5843_id);
 
+static const struct of_device_id hmc5843_of_match[] = {
+       { .compatible = "honeywell,hmc5843" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, hmc5843_of_match);
+
 static struct i2c_driver hmc5843_driver = {
        .driver = {
                .name   = "hmc5843",
                .pm     = HMC5843_PM_OPS,
+               .of_match_table = of_match_ptr(hmc5843_of_match),
        },
        .id_table       = hmc5843_id,
        .probe          = hmc5843_probe,
index 62d30179301fa52e0d6b9322d553371641b952e2..36eedd8a0ea9815c168889d3ed614597a93847a6 100644 (file)
@@ -131,7 +131,7 @@ static int ad2s1200_probe(struct spi_device *spi)
        indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels);
        indio_dev->name = spi_get_device_id(spi)->name;
 
-       ret = iio_device_register(indio_dev);
+       ret = devm_iio_device_register(&spi->dev, indio_dev);
        if (ret)
                return ret;
 
@@ -142,13 +142,6 @@ static int ad2s1200_probe(struct spi_device *spi)
        return 0;
 }
 
-static int ad2s1200_remove(struct spi_device *spi)
-{
-       iio_device_unregister(spi_get_drvdata(spi));
-
-       return 0;
-}
-
 static const struct spi_device_id ad2s1200_id[] = {
        { "ad2s1200" },
        { "ad2s1205" },
@@ -162,7 +155,6 @@ static struct spi_driver ad2s1200_driver = {
                .owner = THIS_MODULE,
        },
        .probe = ad2s1200_probe,
-       .remove = ad2s1200_remove,
        .id_table = ad2s1200_id,
 };
 module_spi_driver(ad2s1200_driver);
index 2c3a9e178fb5e65a073dc777b1c7dd86c7a9f34f..8742432d7b0170f72144675d8d9b591f976a0af7 100644 (file)
@@ -8,4 +8,6 @@ obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o
 obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
 obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o
 obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/
-obj-$(CONFIG_DRM_IMX_IPUV3)    += ipuv3-crtc.o ipuv3-plane.o
+
+imx-ipuv3-crtc-objs  := ipuv3-crtc.o ipuv3-plane.o
+obj-$(CONFIG_DRM_IMX_IPUV3)    += imx-ipuv3-crtc.o
index 51aa9772f959520db89a91e2be69a8c20bb9774c..0507b662ae40d331ca257b751c2fb95af9cafe41 100644 (file)
@@ -72,6 +72,7 @@ int imx_drm_crtc_id(struct imx_drm_crtc *crtc)
 {
        return crtc->pipe;
 }
+EXPORT_SYMBOL_GPL(imx_drm_crtc_id);
 
 static void imx_drm_driver_lastclose(struct drm_device *drm)
 {
@@ -443,6 +444,8 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
        if (!imx_drm_device_get())
                ret = -EINVAL;
 
+       platform_set_drvdata(drm->platformdev, drm);
+
        ret = 0;
 
 err_init:
@@ -828,7 +831,7 @@ static int imx_drm_platform_probe(struct platform_device *pdev)
 
 static int imx_drm_platform_remove(struct platform_device *pdev)
 {
-       drm_platform_exit(&imx_drm_driver, pdev);
+       drm_put_dev(platform_get_drvdata(pdev));
 
        return 0;
 }
index 654bf03e05ff8b34450674ce3142f5942b924420..7e593296ac47287f4929b91270ff79d34752fd56 100644 (file)
@@ -167,9 +167,8 @@ static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
 
        /* set display clock mux to LDB input clock */
        ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk[chno]);
-       if (ret) {
+       if (ret)
                dev_err(ldb->dev, "unable to set di%d parent clock to ldb_di%d\n", mux, chno);
-       }
 }
 
 static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
@@ -414,7 +413,7 @@ enum {
        LVDS_BIT_MAP_JEIDA
 };
 
-static const char *imx_ldb_bit_mappings[] = {
+static const char * const imx_ldb_bit_mappings[] = {
        [LVDS_BIT_MAP_SPWG]  = "spwg",
        [LVDS_BIT_MAP_JEIDA] = "jeida",
 };
index 1538d7bd600f10d7202d9b2bd9efe8441f526672..fff6c9e6164a08b55d6e5a71af583c057377d027 100644 (file)
@@ -189,12 +189,6 @@ struct keucr_media_area {
        WORD PhyBlock;  /* Physical Block Number on Zone 0 */
 };
 
-
-extern BYTE IsSSFDCCompliance;
-extern BYTE IsXDCompliance;
-
-extern DWORD   ErrXDCode;
-extern DWORD   ErrCode;
 extern WORD    ReadBlock;
 extern WORD    WriteBlock;
 extern DWORD   MediaChange;
index 2786808fde9f017ff680084c8bd70a9dd6ab06cc..9434cda885ca73ace4b84936f7d872185725cd6e 100644 (file)
@@ -4,49 +4,28 @@
 #include "smcommon.h"
 #include "smil.h"
 
-int         Check_D_LogCHS(WORD *, BYTE *, BYTE *);
-void        Initialize_D_Media(void);
-void        PowerOff_D_Media(void);
-int         Check_D_MediaPower(void);
-int         Check_D_MediaExist(void);
-int         Check_D_MediaWP(void);
-int         Check_D_MediaFmt(struct us_data *);
-int         Check_D_MediaFmtForEraseAll(struct us_data *);
-int         Conv_D_MediaAddr(struct us_data *, DWORD);
-int         Inc_D_MediaAddr(struct us_data *);
-int         Check_D_FirstSect(void);
-int         Check_D_LastSect(void);
-int         Media_D_ReadOneSect(struct us_data *, WORD, BYTE *);
-int         Media_D_WriteOneSect(struct us_data *, WORD, BYTE *);
-int         Media_D_CopyBlockHead(struct us_data *);
-int         Media_D_CopyBlockTail(struct us_data *);
-int         Media_D_EraseOneBlock(void);
-int         Media_D_EraseAllBlock(void);
-
-int  Copy_D_BlockAll(struct us_data *, DWORD);
-int  Copy_D_BlockHead(struct us_data *);
-int  Copy_D_BlockTail(struct us_data *);
-int  Reassign_D_BlockHead(struct us_data *);
-
-int  Assign_D_WriteBlock(void);
-int  Release_D_ReadBlock(struct us_data *);
-int  Release_D_WriteBlock(struct us_data *);
-int  Release_D_CopySector(struct us_data *);
-
-int  Copy_D_PhyOneSect(struct us_data *);
-int  Read_D_PhyOneSect(struct us_data *, WORD, BYTE *);
-int  Write_D_PhyOneSect(struct us_data *, WORD, BYTE *);
-int  Erase_D_PhyOneBlock(struct us_data *);
-
-int  Set_D_PhyFmtValue(struct us_data *);
-int  Search_D_CIS(struct us_data *);
-int  Make_D_LogTable(struct us_data *);
-void Check_D_BlockIsFull(void);
-
-int  MarkFail_D_PhyOneBlock(struct us_data *);
-
-DWORD ErrXDCode;
-DWORD ErrCode;
+static int         Conv_D_MediaAddr(struct us_data *, DWORD);
+static int         Inc_D_MediaAddr(struct us_data *);
+static int         Media_D_ReadOneSect(struct us_data *, WORD, BYTE *);
+
+static int  Copy_D_BlockAll(struct us_data *, DWORD);
+
+static int  Assign_D_WriteBlock(void);
+static int  Release_D_ReadBlock(struct us_data *);
+static int  Release_D_WriteBlock(struct us_data *);
+static int  Release_D_CopySector(struct us_data *);
+
+static int  Copy_D_PhyOneSect(struct us_data *);
+static int  Read_D_PhyOneSect(struct us_data *, WORD, BYTE *);
+static int  Erase_D_PhyOneBlock(struct us_data *);
+
+static int  Set_D_PhyFmtValue(struct us_data *);
+static int  Search_D_CIS(struct us_data *);
+static int  Make_D_LogTable(struct us_data *);
+
+static int  MarkFail_D_PhyOneBlock(struct us_data *);
+
+static DWORD ErrCode;
 static BYTE  WorkBuf[SECTSIZE];
 static BYTE  Redundant[REDTSIZE];
 static BYTE  WorkRedund[REDTSIZE];
@@ -65,10 +44,6 @@ static BYTE BitData[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
 #define Clr_D_Bit(a, b)    (a[(BYTE)((b) / 8)] &= ~BitData[(b) % 8])
 #define Chk_D_Bit(a, b)    (a[(BYTE)((b) / 8)] & BitData[(b) % 8])
 
-BYTE     IsSSFDCCompliance;
-BYTE     IsXDCompliance;
-
-
 /* ----- SM_FreeMem() ------------------------------------------------- */
 int SM_FreeMem(void)
 {
@@ -167,7 +142,7 @@ int Media_D_CopySector(struct us_data *us, DWORD start, WORD count, BYTE *buf)
 }
 
 /* ----- Release_D_CopySector() ------------------------------------------ */
-int Release_D_CopySector(struct us_data *us)
+static int Release_D_CopySector(struct us_data *us)
 {
        Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock;
        Media.PhyBlock = ReadBlock;
@@ -211,7 +186,7 @@ int Check_D_MediaFmt(struct us_data *us)
 
 /* SmartMedia Physical Address Control Subroutine */
 /* ----- Conv_D_MediaAddr() --------------------------------------------- */
-int Conv_D_MediaAddr(struct us_data *us, DWORD addr)
+static int Conv_D_MediaAddr(struct us_data *us, DWORD addr)
 {
        DWORD temp;
 
@@ -240,7 +215,7 @@ int Conv_D_MediaAddr(struct us_data *us, DWORD addr)
 }
 
 /* ----- Inc_D_MediaAddr() ---------------------------------------------- */
-int Inc_D_MediaAddr(struct us_data *us)
+static int Inc_D_MediaAddr(struct us_data *us)
 {
        WORD        LogBlock = Media.LogBlock;
 
@@ -290,7 +265,7 @@ int Inc_D_MediaAddr(struct us_data *us)
 
 /* SmartMedia Read/Write Subroutine with Retry */
 /* ----- Media_D_ReadOneSect() ------------------------------------------ */
-int Media_D_ReadOneSect(struct us_data *us, WORD count, BYTE *buf)
+static int Media_D_ReadOneSect(struct us_data *us, WORD count, BYTE *buf)
 {
        DWORD err, retry;
 
@@ -334,7 +309,7 @@ int Media_D_ReadOneSect(struct us_data *us, WORD count, BYTE *buf)
 
 /* SmartMedia Physical Sector Data Copy Subroutine */
 /* ----- Copy_D_BlockAll() ---------------------------------------------- */
-int Copy_D_BlockAll(struct us_data *us, DWORD mode)
+static int Copy_D_BlockAll(struct us_data *us, DWORD mode)
 {
        BYTE sect;
 
@@ -371,7 +346,7 @@ int Copy_D_BlockAll(struct us_data *us, DWORD mode)
 
 /* SmartMedia Physical Block Assign/Release Subroutine */
 /* ----- Assign_D_WriteBlock() ------------------------------------------ */
-int Assign_D_WriteBlock(void)
+static int Assign_D_WriteBlock(void)
 {
        ReadBlock = Media.PhyBlock;
 
@@ -404,7 +379,7 @@ int Assign_D_WriteBlock(void)
 }
 
 /* ----- Release_D_ReadBlock() ------------------------------------------ */
-int Release_D_ReadBlock(struct us_data *us)
+static int Release_D_ReadBlock(struct us_data *us)
 {
        DWORD mode;
 
@@ -438,7 +413,7 @@ int Release_D_ReadBlock(struct us_data *us)
 }
 
 /* ----- Release_D_WriteBlock() ----------------------------------------- */
-int Release_D_WriteBlock(struct us_data *us)
+static int Release_D_WriteBlock(struct us_data *us)
 {
        SectCopyMode = COMPLETED;
        Media.PhyBlock = WriteBlock;
@@ -452,7 +427,7 @@ int Release_D_WriteBlock(struct us_data *us)
 
 /* SmartMedia Physical Sector Data Copy Subroutine */
 /* ----- Copy_D_PhyOneSect() -------------------------------------------- */
-int Copy_D_PhyOneSect(struct us_data *us)
+static int Copy_D_PhyOneSect(struct us_data *us)
 {
        int           i;
        DWORD  err, retry;
@@ -529,7 +504,7 @@ int Copy_D_PhyOneSect(struct us_data *us)
 
 /* SmartMedia Physical Sector Read/Write/Erase Subroutine */
 /* ----- Read_D_PhyOneSect() -------------------------------------------- */
-int Read_D_PhyOneSect(struct us_data *us, WORD count, BYTE *buf)
+static int Read_D_PhyOneSect(struct us_data *us, WORD count, BYTE *buf)
 {
        int           i;
        DWORD  retry;
@@ -580,7 +555,7 @@ int Read_D_PhyOneSect(struct us_data *us, WORD count, BYTE *buf)
 }
 
 /* ----- Erase_D_PhyOneBlock() ------------------------------------------ */
-int Erase_D_PhyOneBlock(struct us_data *us)
+static int Erase_D_PhyOneBlock(struct us_data *us)
 {
        if (Ssfdc_D_EraseBlock(us)) {
                ErrCode = ERR_HwError;
@@ -597,7 +572,7 @@ int Erase_D_PhyOneBlock(struct us_data *us)
 
 /* SmartMedia Physical Format Check Local Subroutine */
 /* ----- Set_D_PhyFmtValue() -------------------------------------------- */
-int Set_D_PhyFmtValue(struct us_data *us)
+static int Set_D_PhyFmtValue(struct us_data *us)
 {
        if (Set_D_SsfdcModel(us->SM_DeviceID))
                return ERROR;
@@ -606,7 +581,7 @@ int Set_D_PhyFmtValue(struct us_data *us)
 }
 
 /* ----- Search_D_CIS() ------------------------------------------------- */
-int Search_D_CIS(struct us_data *us)
+static int Search_D_CIS(struct us_data *us)
 {
        Media.Zone = 0;
        Media.Sector = 0;
@@ -660,7 +635,7 @@ int Search_D_CIS(struct us_data *us)
 }
 
 /* ----- Make_D_LogTable() ---------------------------------------------- */
-int Make_D_LogTable(struct us_data *us)
+static int Make_D_LogTable(struct us_data *us)
 {
        WORD  phyblock, logblock;
 
@@ -761,7 +736,7 @@ int Make_D_LogTable(struct us_data *us)
 }
 
 /* ----- MarkFail_D_PhyOneBlock() --------------------------------------- */
-int MarkFail_D_PhyOneBlock(struct us_data *us)
+static int MarkFail_D_PhyOneBlock(struct us_data *us)
 {
        BYTE sect;
 
index 346c5702f41116ad549dcf5bf3c9caf7fb5920e8..16da9a9b4033faf3e2b3cc975f3fbcde724f5a75 100644 (file)
@@ -6,45 +6,16 @@
 #include "smcommon.h"
 #include "smil.h"
 
-void   _Set_D_SsfdcRdCmd(BYTE);
-void   _Set_D_SsfdcRdAddr(BYTE);
-void   _Set_D_SsfdcRdChip(void);
-void   _Set_D_SsfdcRdStandby(void);
-void   _Start_D_SsfdcRdHwECC(void);
-void   _Stop_D_SsfdcRdHwECC(void);
-void   _Load_D_SsfdcRdHwECC(BYTE);
-void   _Set_D_SsfdcWrCmd(BYTE);
-void   _Set_D_SsfdcWrAddr(BYTE);
-void   _Set_D_SsfdcWrBlock(void);
-void   _Set_D_SsfdcWrStandby(void);
-void   _Start_D_SsfdcWrHwECC(void);
-void   _Load_D_SsfdcWrHwECC(BYTE);
-int    _Check_D_SsfdcBusy(WORD);
-int    _Check_D_SsfdcStatus(void);
-void   _Reset_D_SsfdcErr(void);
-void   _Read_D_SsfdcBuf(BYTE *);
-void   _Write_D_SsfdcBuf(BYTE *);
-void   _Read_D_SsfdcByte(BYTE *);
-void   _ReadRedt_D_SsfdcBuf(BYTE *);
-void   _WriteRedt_D_SsfdcBuf(BYTE *);
-BYTE   _Check_D_DevCode(BYTE);
-
-void   _Set_D_ECCdata(BYTE, BYTE *);
-void   _Calc_D_ECCdata(BYTE *);
-
+static BYTE   _Check_D_DevCode(BYTE);
+static DWORD   ErrXDCode;
+static BYTE    IsSSFDCCompliance;
+static BYTE    IsXDCompliance;
 
 struct keucr_media_info         Ssfdc;
 struct keucr_media_address      Media;
 struct keucr_media_area         CisArea;
 
 static BYTE                            EccBuf[6];
-extern PBYTE                    SMHostAddr;
-extern DWORD                    ErrXDCode;
-
-extern WORD  ReadBlock;
-extern WORD  WriteBlock;
-
-
 
 #define EVEN                    0             /* Even Page for 256byte/page */
 #define ODD                     1             /* Odd Page for 256byte/page */
index 572d6489b66b0e618df083e874fb5f0f5e14faf5..5c03eca4dba8b38e5148dc9de20eb3387be7b512 100644 (file)
 #include "transport.h"
 #include "smil.h"
 
-int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb);
-int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb);
-int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb);
-int SM_SCSI_Start_Stop(struct us_data *us, struct scsi_cmnd *srb);
-int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb);
-int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb);
-int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb);
-
-extern PBYTE                SMHostAddr;
-extern DWORD                ErrXDCode;
+static int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb);
+static int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb);
+static int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb);
+static int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb);
+static int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb);
+static int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb);
 
 /* ----- SM_SCSIIrp() -------------------------------------------------- */
 int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb)
@@ -57,7 +53,7 @@ int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb)
 }
 
 /* ----- SM_SCSI_Test_Unit_Ready() ------------------------------------- */
-int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
+static int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
 {
        if (us->SM_Status.Insert && us->SM_Status.Ready)
                return USB_STOR_TRANSPORT_GOOD;
@@ -70,7 +66,7 @@ int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
 }
 
 /* ----- SM_SCSI_Inquiry() --------------------------------------------- */
-int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
+static int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
 {
        BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00,
                                 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20,
@@ -84,7 +80,7 @@ int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
 
 
 /* ----- SM_SCSI_Mode_Sense() ------------------------------------------ */
-int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
+static int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
 {
        BYTE    mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00,
                                0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
@@ -101,7 +97,7 @@ int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
 }
 
 /* ----- SM_SCSI_Read_Capacity() --------------------------------------- */
-int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
+static int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
 {
        unsigned int offset = 0;
        struct scatterlist *sg = NULL;
@@ -133,7 +129,7 @@ int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
 }
 
 /* ----- SM_SCSI_Read() -------------------------------------------------- */
-int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
+static int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
 {
        int result = 0;
        PBYTE   Cdb = srb->cmnd;
@@ -165,7 +161,7 @@ int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
 }
 
 /* ----- SM_SCSI_Write() -------------------------------------------------- */
-int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
+static int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
 {
        int result = 0;
        PBYTE   Cdb = srb->cmnd;
index de8e35b796ab475b9bbe79f3ba91c2ec3ba41d4f..507d16b9213c4b5445ca6b9ba91b2c2e0d385a3a 100644 (file)
@@ -61,7 +61,6 @@ int    cfs_curproc_groups_nr(void);
  */
 
 /* check if task is running in compat mode.*/
-int current_is_32bit(void);
 #define current_pid()          (current->pid)
 #define current_comm()         (current->comm)
 int cfs_get_environ(const char *key, char *value, int *val_len);
index 5be367973508660e5110e58611fa381fe5be19bd..dd1a1f1ef1f689b08ec035f7fb44c974df16d3bd 100644 (file)
@@ -110,41 +110,38 @@ struct libcfs_ioctl_handler {
 #define IOC_LIBCFS_TYPE                   'e'
 #define IOC_LIBCFS_MIN_NR               30
 /* libcfs ioctls */
-#define IOC_LIBCFS_PANIC                  _IOWR('e', 30, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_CLEAR_DEBUG      _IOWR('e', 31, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_MARK_DEBUG        _IOWR('e', 32, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_LWT_CONTROL      _IOWR('e', 33, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_LWT_SNAPSHOT            _IOWR('e', 34, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_LWT_LOOKUP_STRING       _IOWR('e', 35, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_MEMHOG                _IOWR('e', 36, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_PING_TEST          _IOWR('e', 37, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_PANIC                  _IOWR('e', 30, long)
+#define IOC_LIBCFS_CLEAR_DEBUG      _IOWR('e', 31, long)
+#define IOC_LIBCFS_MARK_DEBUG        _IOWR('e', 32, long)
+#define IOC_LIBCFS_MEMHOG                _IOWR('e', 36, long)
+#define IOC_LIBCFS_PING_TEST          _IOWR('e', 37, long)
 /* lnet ioctls */
-#define IOC_LIBCFS_GET_NI                _IOWR('e', 50, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_FAIL_NID            _IOWR('e', 51, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_ADD_ROUTE          _IOWR('e', 52, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_DEL_ROUTE          _IOWR('e', 53, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_GET_ROUTE          _IOWR('e', 54, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_NOTIFY_ROUTER          _IOWR('e', 55, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_UNCONFIGURE      _IOWR('e', 56, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_PORTALS_COMPATIBILITY   _IOWR('e', 57, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_LNET_DIST          _IOWR('e', 58, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_CONFIGURE          _IOWR('e', 59, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_TESTPROTOCOMPAT      _IOWR('e', 60, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_PING                    _IOWR('e', 61, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_DEBUG_PEER        _IOWR('e', 62, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_LNETST                _IOWR('e', 63, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_NI                _IOWR('e', 50, long)
+#define IOC_LIBCFS_FAIL_NID            _IOWR('e', 51, long)
+#define IOC_LIBCFS_ADD_ROUTE          _IOWR('e', 52, long)
+#define IOC_LIBCFS_DEL_ROUTE          _IOWR('e', 53, long)
+#define IOC_LIBCFS_GET_ROUTE          _IOWR('e', 54, long)
+#define IOC_LIBCFS_NOTIFY_ROUTER          _IOWR('e', 55, long)
+#define IOC_LIBCFS_UNCONFIGURE      _IOWR('e', 56, long)
+#define IOC_LIBCFS_PORTALS_COMPATIBILITY   _IOWR('e', 57, long)
+#define IOC_LIBCFS_LNET_DIST          _IOWR('e', 58, long)
+#define IOC_LIBCFS_CONFIGURE          _IOWR('e', 59, long)
+#define IOC_LIBCFS_TESTPROTOCOMPAT      _IOWR('e', 60, long)
+#define IOC_LIBCFS_PING                    _IOWR('e', 61, long)
+#define IOC_LIBCFS_DEBUG_PEER        _IOWR('e', 62, long)
+#define IOC_LIBCFS_LNETST                _IOWR('e', 63, long)
 /* lnd ioctls */
-#define IOC_LIBCFS_REGISTER_MYNID        _IOWR('e', 70, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_CLOSE_CONNECTION    _IOWR('e', 71, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_PUSH_CONNECTION      _IOWR('e', 72, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_GET_CONN            _IOWR('e', 73, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_DEL_PEER            _IOWR('e', 74, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_ADD_PEER            _IOWR('e', 75, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_GET_PEER            _IOWR('e', 76, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_GET_TXDESC        _IOWR('e', 77, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_ADD_INTERFACE          _IOWR('e', 78, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_DEL_INTERFACE          _IOWR('e', 79, IOCTL_LIBCFS_TYPE)
-#define IOC_LIBCFS_GET_INTERFACE          _IOWR('e', 80, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_REGISTER_MYNID        _IOWR('e', 70, long)
+#define IOC_LIBCFS_CLOSE_CONNECTION    _IOWR('e', 71, long)
+#define IOC_LIBCFS_PUSH_CONNECTION      _IOWR('e', 72, long)
+#define IOC_LIBCFS_GET_CONN            _IOWR('e', 73, long)
+#define IOC_LIBCFS_DEL_PEER            _IOWR('e', 74, long)
+#define IOC_LIBCFS_ADD_PEER            _IOWR('e', 75, long)
+#define IOC_LIBCFS_GET_PEER            _IOWR('e', 76, long)
+#define IOC_LIBCFS_GET_TXDESC        _IOWR('e', 77, long)
+#define IOC_LIBCFS_ADD_INTERFACE          _IOWR('e', 78, long)
+#define IOC_LIBCFS_DEL_INTERFACE          _IOWR('e', 79, long)
+#define IOC_LIBCFS_GET_INTERFACE          _IOWR('e', 80, long)
 
 #define IOC_LIBCFS_MAX_NR                           80
 
index c204b677796fd9375996bba03a0096013013636d..5cc7ba0004855643482acd3f8593c6fb8f822ded 100644 (file)
 #include <linux/smp.h>
 #include <linux/ctype.h>
 #include <linux/compiler.h>
-#ifdef HAVE_MM_INLINE
-# include <linux/mm_inline.h>
-#endif
+#include <linux/mm_inline.h>
 #include <linux/kallsyms.h>
 #include <linux/moduleparam.h>
 #include <linux/scatterlist.h>
 
 #include <linux/libcfs/linux/portals_compat25.h>
 
-
-/******************************************************************************/
-/* Module parameter support */
-#define CFS_MODULE_PARM(name, t, type, perm, desc) \
-       module_param(name, type, perm);\
-       MODULE_PARM_DESC(name, desc)
-
-#define CFS_SYSFS_MODULE_PARM  1 /* module parameters accessible via sysfs */
-
-/******************************************************************************/
-/* Light-weight trace
- * Support for temporary event tracing with minimal Heisenberg effect. */
-#define LWT_SUPPORT  0
-
-#define LWT_MEMORY   (16<<20)
-
-#ifndef KLWT_SUPPORT
-#  if !defined(BITS_PER_LONG)
-#   error "BITS_PER_LONG not defined"
-#  endif
-
-/* kernel hasn't defined this? */
-typedef struct {
-       long long   lwte_when;
-       char       *lwte_where;
-       void       *lwte_task;
-       long    lwte_p1;
-       long    lwte_p2;
-       long    lwte_p3;
-       long    lwte_p4;
-# if BITS_PER_LONG > 32
-       long    lwte_pad;
-# endif
-} lwt_event_t;
-#endif /* !KLWT_SUPPORT */
-
-#if LWT_SUPPORT
-#  if !KLWT_SUPPORT
-
-typedef struct _lwt_page {
-       struct list_head               lwtp_list;
-       struct page          *lwtp_page;
-       lwt_event_t          *lwtp_events;
-} lwt_page_t;
-
-typedef struct {
-       int             lwtc_current_index;
-       lwt_page_t      *lwtc_current_page;
-} lwt_cpu_t;
-
-extern int       lwt_enabled;
-extern lwt_cpu_t lwt_cpus[];
-
-/* Note that we _don't_ define LWT_EVENT at all if LWT_SUPPORT isn't set.
- * This stuff is meant for finding specific problems; it never stays in
- * production code... */
-
-#define LWTSTR(n)       #n
-#define LWTWHERE(f,l)   f ":" LWTSTR(l)
-#define LWT_EVENTS_PER_PAGE (PAGE_CACHE_SIZE / sizeof (lwt_event_t))
-
-#define LWT_EVENT(p1, p2, p3, p4)                                     \
-do {                                                               \
-       unsigned long    flags;                                  \
-       lwt_cpu_t       *cpu;                                      \
-       lwt_page_t      *p;                                          \
-       lwt_event_t     *e;                                          \
-                                                                       \
-       if (lwt_enabled) {                                            \
-               local_irq_save (flags);                          \
-                                                                       \
-               cpu = &lwt_cpus[smp_processor_id()];                \
-               p = cpu->lwtc_current_page;                          \
-               e = &p->lwtp_events[cpu->lwtc_current_index++];  \
-                                                                       \
-               if (cpu->lwtc_current_index >= LWT_EVENTS_PER_PAGE) {   \
-                       cpu->lwtc_current_page =                        \
-                               list_entry (p->lwtp_list.next,      \
-                                               lwt_page_t, lwtp_list); \
-                       cpu->lwtc_current_index = 0;                \
-               }                                                      \
-                                                                       \
-               e->lwte_when  = get_cycles();                      \
-               e->lwte_where = LWTWHERE(__FILE__,__LINE__);        \
-               e->lwte_task  = current;                                \
-               e->lwte_p1    = (long)(p1);                          \
-               e->lwte_p2    = (long)(p2);                          \
-               e->lwte_p3    = (long)(p3);                          \
-               e->lwte_p4    = (long)(p4);                          \
-                                                                       \
-               local_irq_restore (flags);                            \
-       }                                                              \
-} while (0)
-
-#endif /* !KLWT_SUPPORT */
-
-extern int  lwt_init (void);
-extern void lwt_fini (void);
-extern int  lwt_lookup_string (int *size, char *knlptr,
-                              char *usrptr, int usrsize);
-extern int  lwt_control (int enable, int clear);
-extern int  lwt_snapshot (cfs_cycles_t *now, int *ncpu, int *total_size,
-                         void *user_ptr, int user_size);
-#endif /* LWT_SUPPORT */
-
-/* ------------------------------------------------------------------ */
-
-#define IOCTL_LIBCFS_TYPE long
-
-#ifdef __CYGWIN__
-# ifndef BITS_PER_LONG
-#   define BITS_PER_LONG 64
-# endif
-#endif
-
-# define LI_POISON 0x5a5a5a5a
-#if BITS_PER_LONG > 32
-# define LL_POISON 0x5a5a5a5a5a5a5a5aL
-#else
-# define LL_POISON 0x5a5a5a5aL
-#endif
-# define LP_POISON ((void *)LL_POISON)
-
 /* this is a bit chunky */
 
-#define _LWORDSIZE BITS_PER_LONG
-
 # define LPU64 "%llu"
 # define LPD64 "%lld"
 # define LPX64 "%#llx"
@@ -218,24 +91,4 @@ extern int  lwt_snapshot (cfs_cycles_t *now, int *ncpu, int *total_size,
  */
 # define LPPID "%d"
 
-
-#undef _LWORDSIZE
-
-/* compat macroses */
-
-
-#ifndef get_cpu
-# ifdef CONFIG_PREEMPT
-#  define get_cpu()  ({ preempt_disable(); smp_processor_id(); })
-#  define put_cpu()  preempt_enable()
-# else
-#  define get_cpu()  smp_processor_id()
-#  define put_cpu()
-# endif
-#else
-#endif /* get_cpu & put_cpu */
-
-#define INIT_CTL_NAME(a)
-#define INIT_STRATEGY(a)
-
 #endif
index 60ecaf63f9fb10d996cbc6a2b6aeb43cfe186a66..a7bca40e9fb7d08f5c2f8b00002bb2b449a892be 100644 (file)
@@ -49,7 +49,6 @@
 #include <linux/libcfs/linux/linux-mem.h>
 #include <linux/libcfs/linux/linux-prim.h>
 #include <linux/libcfs/linux/linux-lock.h>
-#include <linux/libcfs/linux/linux-fs.h>
 #include <linux/libcfs/linux/linux-tcpip.h>
 #include <linux/libcfs/linux/linux-bitops.h>
 #include <linux/libcfs/linux/linux-types.h>
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h
deleted file mode 100644 (file)
index eebf138..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/linux/linux-fs.h
- *
- * Basic library routines.
- */
-
-#ifndef __LIBCFS_LINUX_CFS_FS_H__
-#define __LIBCFS_LINUX_CFS_FS_H__
-
-#ifndef __LIBCFS_LIBCFS_H__
-#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
-#endif
-
-
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/mount.h>
-#include <linux/backing-dev.h>
-#include <linux/posix_acl_xattr.h>
-
-#define filp_size(f)                                   \
-       (i_size_read((f)->f_dentry->d_inode))
-#define filp_poff(f)                                   \
-       (&(f)->f_pos)
-
-# define do_fsync(fp, flag)                            \
-       ((fp)->f_op->fsync(fp, 0, LLONG_MAX, flag))
-
-#define filp_read(fp, buf, size, pos)                  \
-       ((fp)->f_op->read((fp), (buf), (size), pos))
-
-#define filp_write(fp, buf, size, pos)                 \
-       ((fp)->f_op->write((fp), (buf), (size), pos))
-
-#define filp_fsync(fp)                                 \
-       do_fsync(fp, 1)
-
-#define flock_type(fl)                 ((fl)->fl_type)
-#define flock_set_type(fl, type)       do { (fl)->fl_type = (type); } while (0)
-#define flock_pid(fl)                  ((fl)->fl_pid)
-#define flock_set_pid(fl, pid)         do { (fl)->fl_pid = (pid); } while (0)
-#define flock_start(fl)                        ((fl)->fl_start)
-#define flock_set_start(fl, st)                do { (fl)->fl_start = (st); } while (0)
-#define flock_end(fl)                  ((fl)->fl_end)
-#define flock_set_end(fl, end)         do { (fl)->fl_end = (end); } while (0)
-
-#ifndef IFSHIFT
-#define IFSHIFT                        12
-#endif
-
-#ifndef IFTODT
-#define IFTODT(type)           (((type) & S_IFMT) >> IFSHIFT)
-#endif
-#ifndef DTTOIF
-#define DTTOIF(dirtype)                ((dirtype) << IFSHIFT)
-#endif
-
-#endif
index 4f63b7acb9d79956437c5760c906a0576535f8d2..c833ce8544d3cb3a92df25e3040954c1cce07ce1 100644 (file)
@@ -383,14 +383,6 @@ typedef enum {
 typedef unsigned LNET_SEQ_BASETYPE lnet_seq_t;
 #define LNET_SEQ_GT(a,b)       (((signed LNET_SEQ_BASETYPE)((a) - (b))) > 0)
 
-/* XXX
- * cygwin need the pragma line, not clear if it's needed in other places.
- * checking!!!
- */
-#ifdef __CYGWIN__
-#pragma pack(push, 4)
-#endif
-
 /**
  * Information about an event on a MD.
  */
@@ -462,9 +454,6 @@ typedef struct {
         */
        volatile lnet_seq_t sequence;
 } lnet_event_t;
-#ifdef __CYGWIN__
-#pragma pop
-#endif
 
 /**
  * Event queue handler function type.
index 86397f96b0331e217b38061aa434a6cfb0143518..644a0000130a469cee58b18b760020dc823d3d8d 100644 (file)
@@ -3230,7 +3230,6 @@ void __exit
 kiblnd_module_fini (void)
 {
        lnet_unregister_lnd(&the_o2iblnd);
-       kiblnd_tunables_fini();
 }
 
 int __init
index 938df0cf8c64c4a18f1fa60b02d16fdb3487005a..3f83ce4871cf118a841e4c8d8782213ee1654ebd 100644 (file)
@@ -106,9 +106,6 @@ typedef struct
        int           *kib_fmr_pool_size;    /* # FMRs in pool */
        int           *kib_fmr_flush_trigger; /* When to trigger FMR flush */
        int           *kib_fmr_cache;   /* enable FMR pool cache? */
-#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
-       ctl_table_header_t *kib_sysctl;  /* sysctl interface */
-#endif
        int           *kib_require_priv_port;/* accept only privileged ports */
        int           *kib_use_priv_port;    /* use privileged port for active connect */
        /* # threads on each CPT */
index 92dc5672e2ddf893f0304f10be53f466c266605f..cefdfb6b1becc401468e46162177f0fcf7f29ba0 100644 (file)
 #include "o2iblnd.h"
 
 static int service = 987;
-CFS_MODULE_PARM(service, "i", int, 0444,
-               "service number (within RDMA_PS_TCP)");
+module_param(service, int, 0444);
+MODULE_PARM_DESC(service, "service number (within RDMA_PS_TCP)");
 
 static int cksum = 0;
-CFS_MODULE_PARM(cksum, "i", int, 0644,
-               "set non-zero to enable message (not RDMA) checksums");
+module_param(cksum, int, 0644);
+MODULE_PARM_DESC(cksum, "set non-zero to enable message (not RDMA) checksums");
 
 static int timeout = 50;
-CFS_MODULE_PARM(timeout, "i", int, 0644,
-               "timeout (seconds)");
+module_param(timeout, int, 0644);
+MODULE_PARM_DESC(timeout, "timeout (seconds)");
 
 /* Number of threads in each scheduler pool which is percpt,
  * we will estimate reasonable value based on CPUs if it's set to zero. */
 static int nscheds;
-CFS_MODULE_PARM(nscheds, "i", int, 0444,
-               "number of threads in each scheduler pool");
+module_param(nscheds, int, 0444);
+MODULE_PARM_DESC(nscheds, "number of threads in each scheduler pool");
 
 /* NB: this value is shared by all CPTs, it can grow at runtime */
 static int ntx = 512;
-CFS_MODULE_PARM(ntx, "i", int, 0444,
-               "# of message descriptors allocated for each pool");
+module_param(ntx, int, 0444);
+MODULE_PARM_DESC(ntx, "# of message descriptors allocated for each pool");
 
 /* NB: this value is shared by all CPTs */
 static int credits = 256;
-CFS_MODULE_PARM(credits, "i", int, 0444,
-               "# concurrent sends");
+module_param(credits, int, 0444);
+MODULE_PARM_DESC(credits, "# concurrent sends");
 
 static int peer_credits = 8;
-CFS_MODULE_PARM(peer_credits, "i", int, 0444,
-               "# concurrent sends to 1 peer");
+module_param(peer_credits, int, 0444);
+MODULE_PARM_DESC(peer_credits, "# concurrent sends to 1 peer");
 
 static int peer_credits_hiw = 0;
-CFS_MODULE_PARM(peer_credits_hiw, "i", int, 0444,
-               "when eagerly to return credits");
+module_param(peer_credits_hiw, int, 0444);
+MODULE_PARM_DESC(peer_credits_hiw, "when eagerly to return credits");
 
 static int peer_buffer_credits = 0;
-CFS_MODULE_PARM(peer_buffer_credits, "i", int, 0444,
-               "# per-peer router buffer credits");
+module_param(peer_buffer_credits, int, 0444);
+MODULE_PARM_DESC(peer_buffer_credits, "# per-peer router buffer credits");
 
 static int peer_timeout = 180;
-CFS_MODULE_PARM(peer_timeout, "i", int, 0444,
-               "Seconds without aliveness news to declare peer dead (<=0 to disable)");
+module_param(peer_timeout, int, 0444);
+MODULE_PARM_DESC(peer_timeout, "Seconds without aliveness news to declare peer dead (<=0 to disable)");
 
 static char *ipif_name = "ib0";
-CFS_MODULE_PARM(ipif_name, "s", charp, 0444,
-               "IPoIB interface name");
+module_param(ipif_name, charp, 0444);
+MODULE_PARM_DESC(ipif_name, "IPoIB interface name");
 
 static int retry_count = 5;
-CFS_MODULE_PARM(retry_count, "i", int, 0644,
-               "Retransmissions when no ACK received");
+module_param(retry_count, int, 0644);
+MODULE_PARM_DESC(retry_count, "Retransmissions when no ACK received");
 
 static int rnr_retry_count = 6;
-CFS_MODULE_PARM(rnr_retry_count, "i", int, 0644,
-               "RNR retransmissions");
+module_param(rnr_retry_count, int, 0644);
+MODULE_PARM_DESC(rnr_retry_count, "RNR retransmissions");
 
 static int keepalive = 100;
-CFS_MODULE_PARM(keepalive, "i", int, 0644,
-               "Idle time in seconds before sending a keepalive");
+module_param(keepalive, int, 0644);
+MODULE_PARM_DESC(keepalive, "Idle time in seconds before sending a keepalive");
 
 static int ib_mtu = 0;
-CFS_MODULE_PARM(ib_mtu, "i", int, 0444,
-               "IB MTU 256/512/1024/2048/4096");
+module_param(ib_mtu, int, 0444);
+MODULE_PARM_DESC(ib_mtu, "IB MTU 256/512/1024/2048/4096");
 
 static int concurrent_sends = 0;
-CFS_MODULE_PARM(concurrent_sends, "i", int, 0444,
-               "send work-queue sizing");
+module_param(concurrent_sends, int, 0444);
+MODULE_PARM_DESC(concurrent_sends, "send work-queue sizing");
 
 static int map_on_demand = 0;
-CFS_MODULE_PARM(map_on_demand, "i", int, 0444,
-               "map on demand");
+module_param(map_on_demand, int, 0444);
+MODULE_PARM_DESC(map_on_demand, "map on demand");
 
 /* NB: this value is shared by all CPTs, it can grow at runtime */
 static int fmr_pool_size = 512;
-CFS_MODULE_PARM(fmr_pool_size, "i", int, 0444,
-               "size of fmr pool on each CPT (>= ntx / 4)");
+module_param(fmr_pool_size, int, 0444);
+MODULE_PARM_DESC(fmr_pool_size, "size of fmr pool on each CPT (>= ntx / 4)");
 
 /* NB: this value is shared by all CPTs, it can grow at runtime */
 static int fmr_flush_trigger = 384;
-CFS_MODULE_PARM(fmr_flush_trigger, "i", int, 0444,
-               "# dirty FMRs that triggers pool flush");
+module_param(fmr_flush_trigger, int, 0444);
+MODULE_PARM_DESC(fmr_flush_trigger, "# dirty FMRs that triggers pool flush");
 
 static int fmr_cache = 1;
-CFS_MODULE_PARM(fmr_cache, "i", int, 0444,
-               "non-zero to enable FMR caching");
+module_param(fmr_cache, int, 0444);
+MODULE_PARM_DESC(fmr_cache, "non-zero to enable FMR caching");
 
 /* NB: this value is shared by all CPTs, it can grow at runtime */
 static int pmr_pool_size = 512;
-CFS_MODULE_PARM(pmr_pool_size, "i", int, 0444,
-               "size of MR cache pmr pool on each CPT");
+module_param(pmr_pool_size, int, 0444);
+MODULE_PARM_DESC(pmr_pool_size, "size of MR cache pmr pool on each CPT");
 
 /*
  * 0: disable failover
@@ -137,17 +137,17 @@ CFS_MODULE_PARM(pmr_pool_size, "i", int, 0444,
  * 2: force to failover (for debug)
  */
 static int dev_failover = 0;
-CFS_MODULE_PARM(dev_failover, "i", int, 0444,
-              "HCA failover for bonding (0 off, 1 on, other values reserved)");
+module_param(dev_failover, int, 0444);
+MODULE_PARM_DESC(dev_failover, "HCA failover for bonding (0 off, 1 on, other values reserved)");
 
 
 static int require_privileged_port = 0;
-CFS_MODULE_PARM(require_privileged_port, "i", int, 0644,
-               "require privileged port when accepting connection");
+module_param(require_privileged_port, int, 0644);
+MODULE_PARM_DESC(require_privileged_port, "require privileged port when accepting connection");
 
 static int use_privileged_port = 1;
-CFS_MODULE_PARM(use_privileged_port, "i", int, 0644,
-               "use privileged port when initiating connection");
+module_param(use_privileged_port, int, 0644);
+MODULE_PARM_DESC(use_privileged_port, "use privileged port when initiating connection");
 
 kib_tunables_t kiblnd_tunables = {
        .kib_dev_failover          = &dev_failover,
@@ -176,261 +176,6 @@ kib_tunables_t kiblnd_tunables = {
        .kib_nscheds                = &nscheds
 };
 
-#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
-
-static char ipif_basename_space[32];
-
-
-enum {
-       O2IBLND_SERVICE  = 1,
-       O2IBLND_CKSUM,
-       O2IBLND_TIMEOUT,
-       O2IBLND_NTX,
-       O2IBLND_CREDITS,
-       O2IBLND_PEER_TXCREDITS,
-       O2IBLND_PEER_CREDITS_HIW,
-       O2IBLND_PEER_RTRCREDITS,
-       O2IBLND_PEER_TIMEOUT,
-       O2IBLND_IPIF_BASENAME,
-       O2IBLND_RETRY_COUNT,
-       O2IBLND_RNR_RETRY_COUNT,
-       O2IBLND_KEEPALIVE,
-       O2IBLND_CONCURRENT_SENDS,
-       O2IBLND_IB_MTU,
-       O2IBLND_MAP_ON_DEMAND,
-       O2IBLND_FMR_POOL_SIZE,
-       O2IBLND_FMR_FLUSH_TRIGGER,
-       O2IBLND_FMR_CACHE,
-       O2IBLND_PMR_POOL_SIZE,
-       O2IBLND_DEV_FAILOVER
-};
-
-static ctl_table_t kiblnd_ctl_table[] = {
-       {
-               .ctl_name = O2IBLND_SERVICE,
-               .procname = "service",
-               .data     = &service,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_CKSUM,
-               .procname = "cksum",
-               .data     = &cksum,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_TIMEOUT,
-               .procname = "timeout",
-               .data     = &timeout,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_NTX,
-               .procname = "ntx",
-               .data     = &ntx,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_CREDITS,
-               .procname = "credits",
-               .data     = &credits,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_PEER_TXCREDITS,
-               .procname = "peer_credits",
-               .data     = &peer_credits,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_PEER_CREDITS_HIW,
-               .procname = "peer_credits_hiw",
-               .data     = &peer_credits_hiw,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_PEER_RTRCREDITS,
-               .procname = "peer_buffer_credits",
-               .data     = &peer_buffer_credits,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_PEER_TIMEOUT,
-               .procname = "peer_timeout",
-               .data     = &peer_timeout,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_IPIF_BASENAME,
-               .procname = "ipif_name",
-               .data     = ipif_basename_space,
-               .maxlen   = sizeof(ipif_basename_space),
-               .mode     = 0444,
-               .proc_handler = &proc_dostring
-       },
-       {
-               .ctl_name = O2IBLND_RETRY_COUNT,
-               .procname = "retry_count",
-               .data     = &retry_count,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_RNR_RETRY_COUNT,
-               .procname = "rnr_retry_count",
-               .data     = &rnr_retry_count,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_KEEPALIVE,
-               .procname = "keepalive",
-               .data     = &keepalive,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_CONCURRENT_SENDS,
-               .procname = "concurrent_sends",
-               .data     = &concurrent_sends,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_IB_MTU,
-               .procname = "ib_mtu",
-               .data     = &ib_mtu,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_MAP_ON_DEMAND,
-               .procname = "map_on_demand",
-               .data     = &map_on_demand,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-
-       {
-               .ctl_name = O2IBLND_FMR_POOL_SIZE,
-               .procname = "fmr_pool_size",
-               .data     = &fmr_pool_size,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_FMR_FLUSH_TRIGGER,
-               .procname = "fmr_flush_trigger",
-               .data     = &fmr_flush_trigger,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_FMR_CACHE,
-               .procname = "fmr_cache",
-               .data     = &fmr_cache,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_PMR_POOL_SIZE,
-               .procname = "pmr_pool_size",
-               .data     = &pmr_pool_size,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {
-               .ctl_name = O2IBLND_DEV_FAILOVER,
-               .procname = "dev_failover",
-               .data     = &dev_failover,
-               .maxlen   = sizeof(int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-       },
-       {0}
-};
-
-static ctl_table_t kiblnd_top_ctl_table[] = {
-       {
-               .ctl_name = CTL_O2IBLND,
-               .procname = "o2iblnd",
-               .data     = NULL,
-               .maxlen   = 0,
-               .mode     = 0555,
-               .child    = kiblnd_ctl_table
-       },
-       {0}
-};
-
-void
-kiblnd_initstrtunable(char *space, char *str, int size)
-{
-       strncpy(space, str, size);
-       space[size-1] = 0;
-}
-
-void
-kiblnd_sysctl_init (void)
-{
-       kiblnd_initstrtunable(ipif_basename_space, ipif_name,
-                             sizeof(ipif_basename_space));
-
-       kiblnd_tunables.kib_sysctl =
-               register_sysctl_table(kiblnd_top_ctl_table);
-
-       if (kiblnd_tunables.kib_sysctl == NULL)
-               CWARN("Can't setup /proc tunables\n");
-}
-
-void
-kiblnd_sysctl_fini (void)
-{
-       if (kiblnd_tunables.kib_sysctl != NULL)
-               unregister_sysctl_table(kiblnd_tunables.kib_sysctl);
-}
-
-#else
-
-void
-kiblnd_sysctl_init (void)
-{
-}
-
-void
-kiblnd_sysctl_fini (void)
-{
-}
-
-#endif
-
 int
 kiblnd_tunables_init (void)
 {
@@ -482,12 +227,5 @@ kiblnd_tunables_init (void)
                      *kiblnd_tunables.kib_concurrent_sends, *kiblnd_tunables.kib_peertxcredits);
        }
 
-       kiblnd_sysctl_init();
        return 0;
 }
-
-void
-kiblnd_tunables_fini (void)
-{
-       kiblnd_sysctl_fini();
-}
index 2ddc3aadb8d6a19c1b40f91c57d52fa091972dfb..8f74d0be32f10a12b2c78fb1bce45792d7d9dd6b 100644 (file)
@@ -2866,7 +2866,6 @@ void __exit
 ksocknal_module_fini (void)
 {
        lnet_unregister_lnd(&the_ksocklnd);
-       ksocknal_tunables_fini();
 }
 
 int __init
index b483e0c3a69a2ef0245f64e9468b1409a6cb2216..df2be7a7f46eb6a7b77f8040976dbd00e8ab22e9 100644 (file)
@@ -124,9 +124,6 @@ typedef struct
        unsigned int     *ksnd_zc_min_payload;  /* minimum zero copy payload size */
        int           *ksnd_zc_recv;     /* enable ZC receive (for Chelsio TOE) */
        int           *ksnd_zc_recv_min_nfrags; /* minimum # of fragments to enable ZC receive */
-#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
-       ctl_table_header_t *ksnd_sysctl;   /* sysctl interface */
-#endif
 } ksock_tunables_t;
 
 typedef struct
@@ -592,9 +589,6 @@ extern int ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem,
                                           int *rxmem, int *nagle);
 
 extern int ksocknal_tunables_init(void);
-extern void ksocknal_tunables_fini(void);
-extern int ksocknal_lib_tunables_init(void);
-extern void ksocknal_lib_tunables_fini(void);
 
 extern void ksocknal_lib_csum_tx(ksock_tx_t *tx);
 
index a1c6a519bf5b76d35a7095cf31b3b66dace85a58..80141aa32c21dad0c14e90e392e4e886b4df27b7 100644 (file)
 
 #include "socklnd.h"
 
-# if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
-
-
-enum {
-       SOCKLND_TIMEOUT = 1,
-       SOCKLND_CREDITS,
-       SOCKLND_PEER_TXCREDITS,
-       SOCKLND_PEER_RTRCREDITS,
-       SOCKLND_PEER_TIMEOUT,
-       SOCKLND_NCONNDS,
-       SOCKLND_RECONNECTS_MIN,
-       SOCKLND_RECONNECTS_MAX,
-       SOCKLND_EAGER_ACK,
-       SOCKLND_ZERO_COPY,
-       SOCKLND_TYPED,
-       SOCKLND_BULK_MIN,
-       SOCKLND_RX_BUFFER_SIZE,
-       SOCKLND_TX_BUFFER_SIZE,
-       SOCKLND_NAGLE,
-       SOCKLND_IRQ_AFFINITY,
-       SOCKLND_ROUND_ROBIN,
-       SOCKLND_KEEPALIVE,
-       SOCKLND_KEEPALIVE_IDLE,
-       SOCKLND_KEEPALIVE_COUNT,
-       SOCKLND_KEEPALIVE_INTVL,
-       SOCKLND_BACKOFF_INIT,
-       SOCKLND_BACKOFF_MAX,
-       SOCKLND_PROTOCOL,
-       SOCKLND_ZERO_COPY_RECV,
-       SOCKLND_ZERO_COPY_RECV_MIN_NFRAGS
-};
-
-static ctl_table_t ksocknal_ctl_table[] = {
-       {
-               .ctl_name = SOCKLND_TIMEOUT,
-               .procname = "timeout",
-               .data     = &ksocknal_tunables.ksnd_timeout,
-               .maxlen   = sizeof (int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_CREDITS,
-               .procname = "credits",
-               .data     = &ksocknal_tunables.ksnd_credits,
-               .maxlen   = sizeof (int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-        {
-               .ctl_name = SOCKLND_PEER_TXCREDITS,
-               .procname = "peer_credits",
-               .data     = &ksocknal_tunables.ksnd_peertxcredits,
-               .maxlen   = sizeof (int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-        {
-               .ctl_name = SOCKLND_PEER_RTRCREDITS,
-               .procname = "peer_buffer_credits",
-               .data     = &ksocknal_tunables.ksnd_peerrtrcredits,
-               .maxlen   = sizeof (int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_PEER_TIMEOUT,
-               .procname = "peer_timeout",
-               .data     = &ksocknal_tunables.ksnd_peertimeout,
-               .maxlen   = sizeof (int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_NCONNDS,
-               .procname = "nconnds",
-               .data     = &ksocknal_tunables.ksnd_nconnds,
-               .maxlen   = sizeof (int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_RECONNECTS_MIN,
-               .procname = "min_reconnectms",
-               .data     = &ksocknal_tunables.ksnd_min_reconnectms,
-               .maxlen   = sizeof (int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_RECONNECTS_MAX,
-               .procname = "max_reconnectms",
-               .data     = &ksocknal_tunables.ksnd_max_reconnectms,
-               .maxlen   = sizeof (int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_EAGER_ACK,
-               .procname = "eager_ack",
-               .data     = &ksocknal_tunables.ksnd_eager_ack,
-               .maxlen   = sizeof (int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_ZERO_COPY,
-               .procname = "zero_copy",
-               .data     = &ksocknal_tunables.ksnd_zc_min_payload,
-               .maxlen   = sizeof (int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_ZERO_COPY_RECV,
-               .procname = "zero_copy_recv",
-               .data     = &ksocknal_tunables.ksnd_zc_recv,
-               .maxlen   = sizeof (int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-
-       {
-               .ctl_name = SOCKLND_ZERO_COPY_RECV_MIN_NFRAGS,
-               .procname = "zero_copy_recv",
-               .data     = &ksocknal_tunables.ksnd_zc_recv_min_nfrags,
-               .maxlen   = sizeof (int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_TYPED,
-               .procname = "typed",
-               .data     = &ksocknal_tunables.ksnd_typed_conns,
-               .maxlen   = sizeof (int),
-               .mode     = 0444,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_BULK_MIN,
-               .procname = "min_bulk",
-               .data     = &ksocknal_tunables.ksnd_min_bulk,
-               .maxlen   = sizeof (int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_RX_BUFFER_SIZE,
-               .procname = "rx_buffer_size",
-               .data     = &ksocknal_tunables.ksnd_rx_buffer_size,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_TX_BUFFER_SIZE,
-               .procname = "tx_buffer_size",
-               .data     = &ksocknal_tunables.ksnd_tx_buffer_size,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_NAGLE,
-               .procname = "nagle",
-               .data     = &ksocknal_tunables.ksnd_nagle,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_ROUND_ROBIN,
-               .procname = "round_robin",
-               .data     = &ksocknal_tunables.ksnd_round_robin,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_KEEPALIVE,
-               .procname = "keepalive",
-               .data     = &ksocknal_tunables.ksnd_keepalive,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_KEEPALIVE_IDLE,
-               .procname = "keepalive_idle",
-               .data     = &ksocknal_tunables.ksnd_keepalive_idle,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_KEEPALIVE_COUNT,
-               .procname = "keepalive_count",
-               .data     = &ksocknal_tunables.ksnd_keepalive_count,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-       {
-               .ctl_name = SOCKLND_KEEPALIVE_INTVL,
-               .procname = "keepalive_intvl",
-               .data     = &ksocknal_tunables.ksnd_keepalive_intvl,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-#if SOCKNAL_VERSION_DEBUG
-       {
-               .ctl_name = SOCKLND_PROTOCOL,
-               .procname = "protocol",
-               .data     = &ksocknal_tunables.ksnd_protocol,
-               .maxlen   = sizeof(int),
-               .mode     = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
-       },
-#endif
-       {0}
-};
-
-
-ctl_table_t ksocknal_top_ctl_table[] = {
-       {
-               .ctl_name = CTL_SOCKLND,
-               .procname = "socknal",
-               .data     = NULL,
-               .maxlen   = 0,
-               .mode     = 0555,
-               .child    = ksocknal_ctl_table
-       },
-       { 0 }
-};
-
-int
-ksocknal_lib_tunables_init ()
-{
-       if (!*ksocknal_tunables.ksnd_typed_conns) {
-               int rc = -EINVAL;
-#if SOCKNAL_VERSION_DEBUG
-               if (*ksocknal_tunables.ksnd_protocol < 3)
-                       rc = 0;
-#endif
-               if (rc != 0) {
-                       CERROR("Protocol V3.x MUST have typed connections\n");
-                       return rc;
-               }
-       }
-
-       if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags < 2)
-               *ksocknal_tunables.ksnd_zc_recv_min_nfrags = 2;
-       if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags > LNET_MAX_IOV)
-               *ksocknal_tunables.ksnd_zc_recv_min_nfrags = LNET_MAX_IOV;
-
-       ksocknal_tunables.ksnd_sysctl =
-               register_sysctl_table(ksocknal_top_ctl_table);
-
-       if (ksocknal_tunables.ksnd_sysctl == NULL)
-               CWARN("Can't setup /proc tunables\n");
-
-       return 0;
-}
-
-void
-ksocknal_lib_tunables_fini(void)
-{
-       if (ksocknal_tunables.ksnd_sysctl != NULL)
-               unregister_sysctl_table(ksocknal_tunables.ksnd_sysctl);
-}
-#else
-int
-ksocknal_lib_tunables_init(void)
-{
-       return 0;
-}
-
-void
-ksocknal_lib_tunables_fini(void)
-{
-}
-#endif /* # if CONFIG_SYSCTL && !CFS_SYSFS_MODULE_PARM */
-
 int
 ksocknal_lib_get_conn_addrs (ksock_conn_t *conn)
 {
index 8a474f64abbe116565bd7f206719b48e85428db0..54c0019904ff23b70cc2d2f260015b050e15bcb9 100644 (file)
 #include "socklnd.h"
 
 static int sock_timeout = 50;
-CFS_MODULE_PARM(sock_timeout, "i", int, 0644,
-               "dead socket timeout (seconds)");
+module_param(sock_timeout, int, 0644);
+MODULE_PARM_DESC(sock_timeout, "dead socket timeout (seconds)");
 
 static int credits = 256;
-CFS_MODULE_PARM(credits, "i", int, 0444,
-               "# concurrent sends");
+module_param(credits, int, 0444);
+MODULE_PARM_DESC(credits, "# concurrent sends");
 
 static int peer_credits = 8;
-CFS_MODULE_PARM(peer_credits, "i", int, 0444,
-               "# concurrent sends to 1 peer");
+module_param(peer_credits, int, 0444);
+MODULE_PARM_DESC(peer_credits, "# concurrent sends to 1 peer");
 
 static int peer_buffer_credits = 0;
-CFS_MODULE_PARM(peer_buffer_credits, "i", int, 0444,
-               "# per-peer router buffer credits");
+module_param(peer_buffer_credits, int, 0444);
+MODULE_PARM_DESC(peer_buffer_credits, "# per-peer router buffer credits");
 
 static int peer_timeout = 180;
-CFS_MODULE_PARM(peer_timeout, "i", int, 0444,
-               "Seconds without aliveness news to declare peer dead (<=0 to disable)");
+module_param(peer_timeout, int, 0444);
+MODULE_PARM_DESC(peer_timeout, "Seconds without aliveness news to declare peer dead (<=0 to disable)");
 
 /* Number of daemons in each thread pool which is percpt,
  * we will estimate reasonable value based on CPUs if it's not set. */
 static unsigned int nscheds;
-CFS_MODULE_PARM(nscheds, "i", int, 0444,
-               "# scheduler daemons in each pool while starting");
+module_param(nscheds, int, 0444);
+MODULE_PARM_DESC(nscheds, "# scheduler daemons in each pool while starting");
 
 static int nconnds = 4;
-CFS_MODULE_PARM(nconnds, "i", int, 0444,
-               "# connection daemons while starting");
+module_param(nconnds, int, 0444);
+MODULE_PARM_DESC(nconnds, "# connection daemons while starting");
 
 static int nconnds_max = 64;
-CFS_MODULE_PARM(nconnds_max, "i", int, 0444,
-               "max # connection daemons");
+module_param(nconnds_max, int, 0444);
+MODULE_PARM_DESC(nconnds_max, "max # connection daemons");
 
 static int min_reconnectms = 1000;
-CFS_MODULE_PARM(min_reconnectms, "i", int, 0644,
-               "min connection retry interval (mS)");
+module_param(min_reconnectms, int, 0644);
+MODULE_PARM_DESC(min_reconnectms, "min connection retry interval (mS)");
 
 static int max_reconnectms = 60000;
-CFS_MODULE_PARM(max_reconnectms, "i", int, 0644,
-               "max connection retry interval (mS)");
+module_param(max_reconnectms, int, 0644);
+MODULE_PARM_DESC(max_reconnectms, "max connection retry interval (mS)");
 
 # define DEFAULT_EAGER_ACK 0
 static int eager_ack = DEFAULT_EAGER_ACK;
-CFS_MODULE_PARM(eager_ack, "i", int, 0644,
-               "send tcp ack packets eagerly");
+module_param(eager_ack, int, 0644);
+MODULE_PARM_DESC(eager_ack, "send tcp ack packets eagerly");
 
 static int typed_conns = 1;
-CFS_MODULE_PARM(typed_conns, "i", int, 0444,
-               "use different sockets for bulk");
+module_param(typed_conns, int, 0444);
+MODULE_PARM_DESC(typed_conns, "use different sockets for bulk");
 
 static int min_bulk = (1<<10);
-CFS_MODULE_PARM(min_bulk, "i", int, 0644,
-               "smallest 'large' message");
+module_param(min_bulk, int, 0644);
+MODULE_PARM_DESC(min_bulk, "smallest 'large' message");
 
 # define DEFAULT_BUFFER_SIZE 0
 static int tx_buffer_size = DEFAULT_BUFFER_SIZE;
-CFS_MODULE_PARM(tx_buffer_size, "i", int, 0644,
-               "socket tx buffer size (0 for system default)");
+module_param(tx_buffer_size, int, 0644);
+MODULE_PARM_DESC(tx_buffer_size, "socket tx buffer size (0 for system default)");
 
 static int rx_buffer_size = DEFAULT_BUFFER_SIZE;
-CFS_MODULE_PARM(rx_buffer_size, "i", int, 0644,
-               "socket rx buffer size (0 for system default)");
+module_param(rx_buffer_size, int, 0644);
+MODULE_PARM_DESC(rx_buffer_size, "socket rx buffer size (0 for system default)");
 
 static int nagle = 0;
-CFS_MODULE_PARM(nagle, "i", int, 0644,
-               "enable NAGLE?");
+module_param(nagle, int, 0644);
+MODULE_PARM_DESC(nagle, "enable NAGLE?");
 
 static int round_robin = 1;
-CFS_MODULE_PARM(round_robin, "i", int, 0644,
-               "Round robin for multiple interfaces");
+module_param(round_robin, int, 0644);
+MODULE_PARM_DESC(round_robin, "Round robin for multiple interfaces");
 
 static int keepalive = 30;
-CFS_MODULE_PARM(keepalive, "i", int, 0644,
-               "# seconds before send keepalive");
+module_param(keepalive, int, 0644);
+MODULE_PARM_DESC(keepalive, "# seconds before send keepalive");
 
 static int keepalive_idle = 30;
-CFS_MODULE_PARM(keepalive_idle, "i", int, 0644,
-               "# idle seconds before probe");
+module_param(keepalive_idle, int, 0644);
+MODULE_PARM_DESC(keepalive_idle, "# idle seconds before probe");
 
 #define DEFAULT_KEEPALIVE_COUNT  5
 static int keepalive_count = DEFAULT_KEEPALIVE_COUNT;
-CFS_MODULE_PARM(keepalive_count, "i", int, 0644,
-               "# missed probes == dead");
+module_param(keepalive_count, int, 0644);
+MODULE_PARM_DESC(keepalive_count, "# missed probes == dead");
 
 static int keepalive_intvl = 5;
-CFS_MODULE_PARM(keepalive_intvl, "i", int, 0644,
-               "seconds between probes");
+module_param(keepalive_intvl, int, 0644);
+MODULE_PARM_DESC(keepalive_intvl, "seconds between probes");
 
 static int enable_csum = 0;
-CFS_MODULE_PARM(enable_csum, "i", int, 0644,
-               "enable check sum");
+module_param(enable_csum, int, 0644);
+MODULE_PARM_DESC(enable_csum, "enable check sum");
 
 static int inject_csum_error = 0;
-CFS_MODULE_PARM(inject_csum_error, "i", int, 0644,
-               "set non-zero to inject a checksum error");
+module_param(inject_csum_error, int, 0644);
+MODULE_PARM_DESC(inject_csum_error, "set non-zero to inject a checksum error");
 
 static int nonblk_zcack = 1;
-CFS_MODULE_PARM(nonblk_zcack, "i", int, 0644,
-               "always send ZC-ACK on non-blocking connection");
+module_param(nonblk_zcack, int, 0644);
+MODULE_PARM_DESC(nonblk_zcack, "always send ZC-ACK on non-blocking connection");
 
 static unsigned int zc_min_payload = (16 << 10);
-CFS_MODULE_PARM(zc_min_payload, "i", int, 0644,
-               "minimum payload size to zero copy");
+module_param(zc_min_payload, int, 0644);
+MODULE_PARM_DESC(zc_min_payload, "minimum payload size to zero copy");
 
 static unsigned int zc_recv = 0;
-CFS_MODULE_PARM(zc_recv, "i", int, 0644,
-               "enable ZC recv for Chelsio driver");
+module_param(zc_recv, int, 0644);
+MODULE_PARM_DESC(zc_recv, "enable ZC recv for Chelsio driver");
 
 static unsigned int zc_recv_min_nfrags = 16;
-CFS_MODULE_PARM(zc_recv_min_nfrags, "i", int, 0644,
-               "minimum # of fragments to enable ZC recv");
+module_param(zc_recv_min_nfrags, int, 0644);
+MODULE_PARM_DESC(zc_recv_min_nfrags, "minimum # of fragments to enable ZC recv");
 
 
 #if SOCKNAL_VERSION_DEBUG
 static int protocol = 3;
-CFS_MODULE_PARM(protocol, "i", int, 0644,
-               "protocol version");
+module_param(protocol, int, 0644);
+MODULE_PARM_DESC(protocol, "protocol version");
 #endif
 
 ksock_tunables_t ksocknal_tunables;
@@ -181,18 +181,8 @@ int ksocknal_tunables_init(void)
        ksocknal_tunables.ksnd_protocol    = &protocol;
 #endif
 
-#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
-       ksocknal_tunables.ksnd_sysctl        =  NULL;
-#endif
-
        if (*ksocknal_tunables.ksnd_zc_min_payload < (2 << 10))
                *ksocknal_tunables.ksnd_zc_min_payload = (2 << 10);
 
-       /* initialize platform-sepcific tunables */
-       return ksocknal_lib_tunables_init();
+       return 0;
 };
-
-void ksocknal_tunables_fini(void)
-{
-       ksocknal_lib_tunables_fini();
-}
index 92c60a756644400b0f73122d258794948addf069..cb2ecd717714c39c308f80362affaee2b0db123e 100644 (file)
@@ -64,14 +64,14 @@ lnet_accept_magic(__u32 magic, __u32 constant)
 
 static char *accept = "secure";
 
-CFS_MODULE_PARM(accept, "s", charp, 0444,
-               "Accept connections (secure|all|none)");
-CFS_MODULE_PARM(accept_port, "i", int, 0444,
-               "Acceptor's port (same on all nodes)");
-CFS_MODULE_PARM(accept_backlog, "i", int, 0444,
-               "Acceptor's listen backlog");
-CFS_MODULE_PARM(accept_timeout, "i", int, 0644,
-               "Acceptor's timeout (seconds)");
+module_param(accept, charp, 0444);
+MODULE_PARM_DESC(accept, "Accept connections (secure|all|none)");
+module_param(accept_port, int, 0444);
+MODULE_PARM_DESC(accept_port, "Acceptor's port (same on all nodes)");
+module_param(accept_backlog, int, 0444);
+MODULE_PARM_DESC(accept_backlog, "Acceptor's listen backlog");
+module_param(accept_timeout, int, 0644);
+MODULE_PARM_DESC(accept_timeout, "Acceptor's timeout (seconds)");
 
 static char *accept_type;
 
index 160a4292c6ce696ff3504cfff96485e97bd443e0..5719959c80057f500660628633bb41657f41cb2f 100644 (file)
@@ -45,20 +45,20 @@ EXPORT_SYMBOL(the_lnet);
 
 
 static char *ip2nets = "";
-CFS_MODULE_PARM(ip2nets, "s", charp, 0444,
-               "LNET network <- IP table");
+module_param(ip2nets, charp, 0444);
+MODULE_PARM_DESC(ip2nets, "LNET network <- IP table");
 
 static char *networks = "";
-CFS_MODULE_PARM(networks, "s", charp, 0444,
-               "local networks");
+module_param(networks, charp, 0444);
+MODULE_PARM_DESC(networks, "local networks");
 
 static char *routes = "";
-CFS_MODULE_PARM(routes, "s", charp, 0444,
-               "routes to non-local networks");
+module_param(routes, charp, 0444);
+MODULE_PARM_DESC(routes, "routes to non-local networks");
 
 static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
-CFS_MODULE_PARM(rnet_htable_size, "i", int, 0444,
-               "size of remote network hash table");
+module_param(rnet_htable_size, int, 0444);
+MODULE_PARM_DESC(rnet_htable_size, "size of remote network hash table");
 
 char *
 lnet_get_routes(void)
index b6f8ad38628baec5cce918aca15e7462872680b3..2d611136da8f2f67d4c792397d9477895ab6ac72 100644 (file)
@@ -43,8 +43,8 @@
 #include <linux/lnet/lib-lnet.h>
 
 static int local_nid_dist_zero = 1;
-CFS_MODULE_PARM(local_nid_dist_zero, "i", int, 0444,
-               "Reserved");
+module_param(local_nid_dist_zero, int, 0444);
+MODULE_PARM_DESC(local_nid_dist_zero, "Reserved");
 
 int
 lnet_fail_nid(lnet_nid_t nid, unsigned int threshold)
index 9b9e7d3139b0b015dd4943768123d4e946bdfa25..6fffd5e96f9c4f25f4a147882cea7f50048d372c 100644 (file)
@@ -40,8 +40,8 @@
 
 /* NB: add /proc interfaces in upcoming patches */
 int    portal_rotor    = LNET_PTL_ROTOR_HASH_RT;
-CFS_MODULE_PARM(portal_rotor, "i", int, 0644,
-               "redirect PUTs to different cpu-partitions");
+module_param(portal_rotor, int, 0644);
+MODULE_PARM_DESC(portal_rotor, "redirect PUTs to different cpu-partitions");
 
 static int
 lnet_ptl_match_type(unsigned int index, lnet_process_id_t match_id,
index 6db8774ff7b7161f8ec71f90cf4224a08af34ccb..3bd42a485a3296d24d100b04706f9f446e481c8f 100644 (file)
@@ -38,8 +38,8 @@
 #include <linux/lnet/lib-lnet.h>
 
 static int config_on_load;
-CFS_MODULE_PARM(config_on_load, "i", int, 0444,
-               "configure network at module load");
+module_param(config_on_load, int, 0444);
+MODULE_PARM_DESC(config_on_load, "configure network at module load");
 
 static struct mutex lnet_config_mutex;
 
index a326ce06bc76e21c680ef1e00cad8a295cf765ec..80b5ed1e9d640eb149143491f57ee4e5e65bbf92 100644 (file)
 #define LNET_NRB_LARGE         (LNET_NRB_LARGE_MIN * 4)
 
 static char *forwarding = "";
-CFS_MODULE_PARM(forwarding, "s", charp, 0444,
-               "Explicitly enable/disable forwarding between networks");
+module_param(forwarding, charp, 0444);
+MODULE_PARM_DESC(forwarding, "Explicitly enable/disable forwarding between networks");
 
 static int tiny_router_buffers;
-CFS_MODULE_PARM(tiny_router_buffers, "i", int, 0444,
-               "# of 0 payload messages to buffer in the router");
+module_param(tiny_router_buffers, int, 0444);
+MODULE_PARM_DESC(tiny_router_buffers, "# of 0 payload messages to buffer in the router");
 static int small_router_buffers;
-CFS_MODULE_PARM(small_router_buffers, "i", int, 0444,
-               "# of small (1 page) messages to buffer in the router");
+module_param(small_router_buffers, int, 0444);
+MODULE_PARM_DESC(small_router_buffers, "# of small (1 page) messages to buffer in the router");
 static int large_router_buffers;
-CFS_MODULE_PARM(large_router_buffers, "i", int, 0444,
-               "# of large messages to buffer in the router");
+module_param(large_router_buffers, int, 0444);
+MODULE_PARM_DESC(large_router_buffers, "# of large messages to buffer in the router");
 static int peer_buffer_credits = 0;
-CFS_MODULE_PARM(peer_buffer_credits, "i", int, 0444,
-               "# router buffer credits per peer");
+module_param(peer_buffer_credits, int, 0444);
+MODULE_PARM_DESC(peer_buffer_credits, "# router buffer credits per peer");
 
 static int auto_down = 1;
-CFS_MODULE_PARM(auto_down, "i", int, 0444,
-               "Automatically mark peers down on comms error");
+module_param(auto_down, int, 0444);
+MODULE_PARM_DESC(auto_down, "Automatically mark peers down on comms error");
 
 int
 lnet_peer_buffer_credits(lnet_ni_t *ni)
@@ -81,24 +81,24 @@ lnet_peer_buffer_credits(lnet_ni_t *ni)
 #endif
 
 static int check_routers_before_use = 0;
-CFS_MODULE_PARM(check_routers_before_use, "i", int, 0444,
-               "Assume routers are down and ping them before use");
+module_param(check_routers_before_use, int, 0444);
+MODULE_PARM_DESC(check_routers_before_use, "Assume routers are down and ping them before use");
 
 static int avoid_asym_router_failure = 1;
-CFS_MODULE_PARM(avoid_asym_router_failure, "i", int, 0644,
-               "Avoid asymmetrical router failures (0 to disable)");
+module_param(avoid_asym_router_failure, int, 0644);
+MODULE_PARM_DESC(avoid_asym_router_failure, "Avoid asymmetrical router failures (0 to disable)");
 
 static int dead_router_check_interval = 60;
-CFS_MODULE_PARM(dead_router_check_interval, "i", int, 0644,
-               "Seconds between dead router health checks (<= 0 to disable)");
+module_param(dead_router_check_interval, int, 0644);
+MODULE_PARM_DESC(dead_router_check_interval, "Seconds between dead router health checks (<= 0 to disable)");
 
 static int live_router_check_interval = 60;
-CFS_MODULE_PARM(live_router_check_interval, "i", int, 0644,
-               "Seconds between live router health checks (<= 0 to disable)");
+module_param(live_router_check_interval, int, 0644);
+MODULE_PARM_DESC(live_router_check_interval, "Seconds between live router health checks (<= 0 to disable)");
 
 static int router_ping_timeout = 50;
-CFS_MODULE_PARM(router_ping_timeout, "i", int, 0644,
-               "Seconds to wait for the reply to a router health query");
+module_param(router_ping_timeout, int, 0644);
+MODULE_PARM_DESC(router_ping_timeout, "Seconds to wait for the reply to a router health query");
 
 int
 lnet_peers_start_down(void)
index 5e47de36c184526cf09d8293782d135842c77a44..daaa043ad11813abec781cad2aa4a6cda8b83110 100644 (file)
@@ -855,55 +855,46 @@ static ctl_table_t lnet_table[] = {
         * to go via /proc for portability.
         */
        {
-               INIT_CTL_NAME(PSDEV_LNET_STATS)
                .procname = "stats",
                .mode     = 0644,
                .proc_handler = &proc_lnet_stats,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_ROUTES)
                .procname = "routes",
                .mode     = 0444,
                .proc_handler = &proc_lnet_routes,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_ROUTERS)
                .procname = "routers",
                .mode     = 0444,
                .proc_handler = &proc_lnet_routers,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_PEERS)
                .procname = "peers",
                .mode     = 0444,
                .proc_handler = &proc_lnet_peers,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_PEERS)
                .procname = "buffers",
                .mode     = 0444,
                .proc_handler = &proc_lnet_buffers,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_NIS)
                .procname = "nis",
                .mode     = 0444,
                .proc_handler = &proc_lnet_nis,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_PTL_ROTOR)
                .procname = "portal_rotor",
                .mode     = 0644,
                .proc_handler = &proc_lnet_portal_rotor,
        },
        {
-               INIT_CTL_NAME(0)
        }
 };
 
 static ctl_table_t top_table[] = {
        {
-               INIT_CTL_NAME(CTL_LNET)
                .procname = "lnet",
                .mode     = 0555,
                .data     = NULL,
@@ -911,7 +902,6 @@ static ctl_table_t top_table[] = {
                .child    = lnet_table,
        },
        {
-               INIT_CTL_NAME(0)
        }
 };
 
index b7613c828e763431c766607604e636f073036f68..3f8020cb93e6f3000ce87ebdc0afa0eda1029b12 100644 (file)
 #include "selftest.h"
 
 static int brw_srv_workitems = SFW_TEST_WI_MAX;
-CFS_MODULE_PARM(brw_srv_workitems, "i", int, 0644, "# BRW server workitems");
+module_param(brw_srv_workitems, int, 0644);
+MODULE_PARM_DESC(brw_srv_workitems, "# BRW server workitems");
 
 static int brw_inject_errors;
-CFS_MODULE_PARM(brw_inject_errors, "i", int, 0644,
-               "# data errors to inject randomly, zero by default");
+module_param(brw_inject_errors, int, 0644);
+MODULE_PARM_DESC(brw_inject_errors, "# data errors to inject randomly, zero by default");
 
 static void
 brw_client_fini(sfw_test_instance_t *tsi)
index bce3d3bde6b2187bbebb9fa2b1930961d019ea71..cbc416de7008a09306d69296a6785464b254a4fc 100644 (file)
@@ -723,12 +723,12 @@ lst_stat_query_ioctl(lstio_stat_args_t *args)
 
 int lst_test_add_ioctl(lstio_test_args_t *args)
 {
-       char       *name;
-       char       *srcgrp = NULL;
-       char       *dstgrp = NULL;
-       void       *param = NULL;
-       int          ret = 0;
-       int          rc = -ENOMEM;
+       char            *batch_name;
+       char            *src_name = NULL;
+       char            *dst_name = NULL;
+       void            *param = NULL;
+       int             ret = 0;
+       int             rc = -ENOMEM;
 
        if (args->lstio_tes_resultp == NULL ||
            args->lstio_tes_retp == NULL ||
@@ -755,16 +755,16 @@ int lst_test_add_ioctl(lstio_test_args_t *args)
             args->lstio_tes_param_len > PAGE_CACHE_SIZE - sizeof(lstcon_test_t)))
                return -EINVAL;
 
-       LIBCFS_ALLOC(name, args->lstio_tes_bat_nmlen + 1);
-       if (name == NULL)
+       LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1);
+       if (batch_name == NULL)
                return rc;
 
-       LIBCFS_ALLOC(srcgrp, args->lstio_tes_sgrp_nmlen + 1);
-       if (srcgrp == NULL)
+       LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1);
+       if (src_name == NULL)
                goto out;
 
-       LIBCFS_ALLOC(dstgrp, args->lstio_tes_dgrp_nmlen + 1);
-        if (dstgrp == NULL)
+       LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1);
+        if (dst_name == NULL)
                goto out;
 
        if (args->lstio_tes_param != NULL) {
@@ -774,39 +774,37 @@ int lst_test_add_ioctl(lstio_test_args_t *args)
        }
 
        rc = -EFAULT;
-       if (copy_from_user(name,
-                             args->lstio_tes_bat_name,
-                             args->lstio_tes_bat_nmlen) ||
-           copy_from_user(srcgrp,
-                             args->lstio_tes_sgrp_name,
-                             args->lstio_tes_sgrp_nmlen) ||
-           copy_from_user(dstgrp,
-                             args->lstio_tes_dgrp_name,
-                             args->lstio_tes_dgrp_nmlen) ||
+       if (copy_from_user(batch_name, args->lstio_tes_bat_name,
+                          args->lstio_tes_bat_nmlen) ||
+           copy_from_user(src_name, args->lstio_tes_sgrp_name,
+                          args->lstio_tes_sgrp_nmlen) ||
+           copy_from_user(dst_name, args->lstio_tes_dgrp_name,
+                          args->lstio_tes_dgrp_nmlen) ||
            copy_from_user(param, args->lstio_tes_param,
                              args->lstio_tes_param_len))
                goto out;
 
-       rc = lstcon_test_add(name,
+       rc = lstcon_test_add(batch_name,
                            args->lstio_tes_type,
                            args->lstio_tes_loop,
                            args->lstio_tes_concur,
                            args->lstio_tes_dist, args->lstio_tes_span,
-                           srcgrp, dstgrp, param, args->lstio_tes_param_len,
+                           src_name, dst_name, param,
+                           args->lstio_tes_param_len,
                            &ret, args->lstio_tes_resultp);
 
        if (ret != 0)
                rc = (copy_to_user(args->lstio_tes_retp, &ret,
                                       sizeof(ret))) ? -EFAULT : 0;
 out:
-       if (name != NULL)
-               LIBCFS_FREE(name, args->lstio_tes_bat_nmlen + 1);
+       if (batch_name != NULL)
+               LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1);
 
-       if (srcgrp != NULL)
-               LIBCFS_FREE(srcgrp, args->lstio_tes_sgrp_nmlen + 1);
+       if (src_name != NULL)
+               LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1);
 
-       if (dstgrp != NULL)
-               LIBCFS_FREE(dstgrp, args->lstio_tes_dgrp_nmlen + 1);
+       if (dst_name != NULL)
+               LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1);
 
        if (param != NULL)
                LIBCFS_FREE(param, args->lstio_tes_param_len);
index 9a52f25b72e90931053c7bf642789797ca522325..53d58924737ba13b7bbc8de4ccbb614f0a7f2b1e 100644 (file)
@@ -311,7 +311,7 @@ lstcon_rpc_trans_abort(lstcon_rpc_trans_t *trans, int error)
 
                sfw_abort_rpc(rpc);
 
-               if  (error != ETIMEDOUT)
+               if (error != ETIMEDOUT)
                        continue;
 
                nd = crpc->crp_node;
index f1152e4fbcc41972fd115517348344d2122b9aa2..9556bc0412d617cdbc69e18ba25203a9aceebfe0 100644 (file)
@@ -265,7 +265,7 @@ lstcon_group_decref(lstcon_group_t *grp)
 }
 
 static int
-lstcon_group_find(char *name, lstcon_group_t **grpp)
+lstcon_group_find(const char *name, lstcon_group_t **grpp)
 {
        lstcon_group_t   *grp;
 
@@ -831,7 +831,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p,
 }
 
 int
-lstcon_batch_find(char *name, lstcon_batch_t **batpp)
+lstcon_batch_find(const char *name, lstcon_batch_t **batpp)
 {
        lstcon_batch_t   *bat;
 
@@ -1237,41 +1237,77 @@ again:
        goto again;
 }
 
-int
-lstcon_test_add(char *name, int type, int loop, int concur,
-               int dist, int span, char *src_name, char * dst_name,
-               void *param, int paramlen, int *retp,
-               struct list_head *result_up)
+static int
+lstcon_verify_batch(const char *name, lstcon_batch_t **batch)
 {
-       lstcon_group_t  *src_grp = NULL;
-       lstcon_group_t  *dst_grp = NULL;
-       lstcon_test_t   *test    = NULL;
-       lstcon_batch_t  *batch;
-       int           rc;
+       int rc;
 
-       rc = lstcon_batch_find(name, &batch);
+       rc = lstcon_batch_find(name, batch);
        if (rc != 0) {
                CDEBUG(D_NET, "Can't find batch %s\n", name);
                return rc;
        }
 
-       if (batch->bat_state != LST_BATCH_IDLE) {
+       if ((*batch)->bat_state != LST_BATCH_IDLE) {
                CDEBUG(D_NET, "Can't change running batch %s\n", name);
-               return rc;
+               return -EINVAL;
        }
 
-       rc = lstcon_group_find(src_name, &src_grp);
+       return 0;
+}
+
+static int
+lstcon_verify_group(const char *name, lstcon_group_t **grp)
+{
+       int                     rc;
+       lstcon_ndlink_t         *ndl;
+
+       rc = lstcon_group_find(name, grp);
        if (rc != 0) {
-               CDEBUG(D_NET, "Can't find group %s\n", src_name);
-               goto out;
+               CDEBUG(D_NET, "can't find group %s\n", name);
+               return rc;
        }
 
-       rc = lstcon_group_find(dst_name, &dst_grp);
-       if (rc != 0) {
-               CDEBUG(D_NET, "Can't find group %s\n", dst_name);
-               goto out;
+       list_for_each_entry(ndl, &(*grp)->grp_ndl_list, ndl_link) {
+               if (ndl->ndl_node->nd_state == LST_NODE_ACTIVE)
+                       return 0;
        }
 
+       CDEBUG(D_NET, "Group %s has no ACTIVE nodes\n", name);
+
+       return -EINVAL;
+}
+
+int
+lstcon_test_add(char *batch_name, int type, int loop,
+               int concur, int dist, int span,
+               char *src_name, char *dst_name,
+               void *param, int paramlen, int *retp,
+               struct list_head *result_up)
+{
+       lstcon_test_t    *test   = NULL;
+       int              rc;
+       lstcon_group_t   *src_grp = NULL;
+       lstcon_group_t   *dst_grp = NULL;
+       lstcon_batch_t   *batch = NULL;
+
+       /*
+        * verify that a batch of the given name exists, and the groups
+        * that will be part of the batch exist and have at least one
+        * active node
+        */
+       rc = lstcon_verify_batch(batch_name, &batch);
+       if (rc != 0)
+               goto out;
+
+       rc = lstcon_verify_group(src_name, &src_grp);
+       if (rc != 0)
+               goto out;
+
+       rc = lstcon_verify_group(dst_name, &dst_grp);
+       if (rc != 0)
+               goto out;
+
        if (dst_grp->grp_userland)
                *retp = 1;
 
@@ -1284,18 +1320,18 @@ lstcon_test_add(char *name, int type, int loop, int concur,
        }
 
        memset(test, 0, offsetof(lstcon_test_t, tes_param[paramlen]));
-       test->tes_hdr.tsb_id    = batch->bat_hdr.tsb_id;
-       test->tes_batch  = batch;
-       test->tes_type    = type;
-       test->tes_oneside       = 0; /* TODO */
-       test->tes_loop    = loop;
+       test->tes_hdr.tsb_id    = batch->bat_hdr.tsb_id;
+       test->tes_batch         = batch;
+       test->tes_type          = type;
+       test->tes_oneside       = 0; /* TODO */
+       test->tes_loop          = loop;
        test->tes_concur        = concur;
-       test->tes_stop_onerr    = 1; /* TODO */
-       test->tes_span    = span;
-       test->tes_dist    = dist;
+       test->tes_stop_onerr    = 1; /* TODO */
+       test->tes_span          = span;
+       test->tes_dist          = dist;
        test->tes_cliidx        = 0; /* just used for creating RPC */
-       test->tes_src_grp       = src_grp;
-       test->tes_dst_grp       = dst_grp;
+       test->tes_src_grp       = src_grp;
+       test->tes_dst_grp       = dst_grp;
        INIT_LIST_HEAD(&test->tes_trans_list);
 
        if (param != NULL) {
@@ -1310,7 +1346,8 @@ lstcon_test_add(char *name, int type, int loop, int concur,
 
        if (lstcon_trans_stat()->trs_rpc_errno != 0 ||
            lstcon_trans_stat()->trs_fwk_errno != 0)
-               CDEBUG(D_NET, "Failed to add test %d to batch %s\n", type, name);
+               CDEBUG(D_NET, "Failed to add test %d to batch %s\n", type,
+                      batch_name);
 
        /* add to test list anyway, so user can check what's going on */
        list_add_tail(&test->tes_link, &batch->bat_test_list);
index e61b26687dbb5793a42fea40f4b9fe106ffbf186..b57dbd80478a7a3e84cf70e67fb66607ba250506 100644 (file)
@@ -224,9 +224,9 @@ extern int lstcon_group_stat(char *grp_name, int timeout,
                             struct list_head *result_up);
 extern int lstcon_nodes_stat(int count, lnet_process_id_t *ids_up,
                             int timeout, struct list_head *result_up);
-extern int lstcon_test_add(char *name, int type, int loop, int concur,
-                          int dist, int span, char *src_name, char * dst_name,
+extern int lstcon_test_add(char *batch_name, int type, int loop,
+                          int concur, int dist, int span,
+                          char *src_name, char *dst_name,
                           void *param, int paramlen, int *retp,
                           struct list_head *result_up);
-
 #endif
index 483c78564daef82184a2c6a0a226e75123b81c7b..050723a0243a718ace7723134c3eb50634ca74a8 100644 (file)
 lst_sid_t LST_INVALID_SID = {LNET_NID_ANY, -1};
 
 static int session_timeout = 100;
-CFS_MODULE_PARM(session_timeout, "i", int, 0444,
-               "test session timeout in seconds (100 by default, 0 == never)");
+module_param(session_timeout, int, 0444);
+MODULE_PARM_DESC(session_timeout, "test session timeout in seconds (100 by default, 0 == never)");
 
 static int rpc_timeout = 64;
-CFS_MODULE_PARM(rpc_timeout, "i", int, 0644,
-               "rpc timeout in seconds (64 by default, 0 == never)");
+module_param(rpc_timeout, int, 0644);
+MODULE_PARM_DESC(rpc_timeout, "rpc timeout in seconds (64 by default, 0 == never)");
 
 #define sfw_unpack_id(id)             \
 do {                               \
index f0f919482b56e690578c6c50838bad54fdb425ad..a37c3ff032770f1c3e8c582b2c78be9bad582041 100644 (file)
@@ -45,7 +45,8 @@
 #define LST_PING_TEST_MAGIC     0xbabeface
 
 int ping_srv_workitems = SFW_TEST_WI_MAX;
-CFS_MODULE_PARM(ping_srv_workitems, "i", int, 0644, "# PING server workitems");
+module_param(ping_srv_workitems, int, 0644);
+MODULE_PARM_DESC(ping_srv_workitems, "# PING server workitems");
 
 typedef struct {
        spinlock_t      pnd_lock;       /* serialize */
index e47fd50b2a2ed53c1fa87226eb170e3a2d92c686..3191a398675d1d69bda59580ff85031e9cedd9a5 100644 (file)
@@ -504,10 +504,7 @@ static int __init fld_mod_init(void)
        fld_type_proc_dir = lprocfs_register(LUSTRE_FLD_NAME,
                                             proc_lustre_root,
                                             NULL, NULL);
-       if (IS_ERR(fld_type_proc_dir))
-               return PTR_ERR(fld_type_proc_dir);
-
-       return 0;
+       return PTR_ERR_OR_ZERO(fld_type_proc_dir);
 }
 
 static void __exit fld_mod_exit(void)
index c485206fc6c2207f1933a1cc4b19598c35a281bf..4d692dcd96cfb76b296e23c7c34f4f2f4c6b71c6 100644 (file)
@@ -2388,7 +2388,11 @@ struct cl_io {
         * Right now, only two opertaions need to verify layout: glimpse
         * and setattr.
         */
-                            ci_verify_layout:1;
+                            ci_verify_layout:1,
+       /**
+        * file is released, restore has to to be triggered by vvp layer
+        */
+                            ci_restore_needed:1;
        /**
         * Number of pages owned by this IO. For invariant checking.
         */
index b10ddfa7df29465cdb84613cf790d3b047623387..c491d52d86a238c0f7e0145f95728bc5893735d3 100644 (file)
@@ -52,8 +52,8 @@ struct lustre_intent_data {
 
 struct lookup_intent {
        int     it_op;
-       int     it_flags;
        int     it_create_mode;
+       __u64   it_flags;
        union {
                struct lustre_intent_data lustre;
        } d;
index d5b8225ef1a73d2d5d03a8a8d71ca3fe3a1871e1..6773bca1e0d834084d22f14e73db81672329a3f3 100644 (file)
@@ -397,17 +397,6 @@ static inline int lu_device_is_md(const struct lu_device *d)
        return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_MD);
 }
 
-/**
- * Flags for the object layers.
- */
-enum lu_object_flags {
-       /**
-        * this flags is set if lu_object_operations::loo_object_init() has
-        * been called for this layer. Used by lu_object_alloc().
-        */
-       LU_OBJECT_ALLOCATED = (1 << 0)
-};
-
 /**
  * Common object attributes.
  */
@@ -485,14 +474,6 @@ struct lu_object {
         * Linkage into list of all layers.
         */
        struct list_head                         lo_linkage;
-       /**
-        * Depth. Top level layer depth is 0.
-        */
-       int                             lo_depth;
-       /**
-        * Flags from enum lu_object_flags.
-        */
-       __u32                                   lo_flags;
        /**
         * Link to the device, for debugging.
         */
diff --git a/drivers/staging/lustre/lustre/include/lu_target.h b/drivers/staging/lustre/lustre/include/lu_target.h
deleted file mode 100644 (file)
index 8d48cf4..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef _LUSTRE_LU_TARGET_H
-#define _LUSTRE_LU_TARGET_H
-
-#include <dt_object.h>
-#include <lustre_disk.h>
-
-struct lu_target {
-       struct obd_device       *lut_obd;
-       struct dt_device        *lut_bottom;
-       /** last_rcvd file */
-       struct dt_object        *lut_last_rcvd;
-       /* transaction callbacks */
-       struct dt_txn_callback   lut_txn_cb;
-       /** server data in last_rcvd file */
-       struct lr_server_data    lut_lsd;
-       /** Server last transaction number */
-       __u64               lut_last_transno;
-       /** Lock protecting last transaction number */
-       spinlock_t               lut_translock;
-       /** Lock protecting client bitmap */
-       spinlock_t               lut_client_bitmap_lock;
-       /** Bitmap of known clients */
-       unsigned long      *lut_client_bitmap;
-};
-
-typedef void (*tgt_cb_t)(struct lu_target *lut, __u64 transno,
-                        void *data, int err);
-struct tgt_commit_cb {
-       tgt_cb_t  tgt_cb_func;
-       void     *tgt_cb_data;
-};
-
-void tgt_boot_epoch_update(struct lu_target *lut);
-int tgt_last_commit_cb_add(struct thandle *th, struct lu_target *lut,
-                          struct obd_export *exp, __u64 transno);
-int tgt_new_client_cb_add(struct thandle *th, struct obd_export *exp);
-int tgt_init(const struct lu_env *env, struct lu_target *lut,
-            struct obd_device *obd, struct dt_device *dt);
-void tgt_fini(const struct lu_env *env, struct lu_target *lut);
-int tgt_client_alloc(struct obd_export *exp);
-void tgt_client_free(struct obd_export *exp);
-int tgt_client_del(const struct lu_env *env, struct obd_export *exp);
-int tgt_client_add(const struct lu_env *env, struct obd_export *exp, int);
-int tgt_client_new(const struct lu_env *env, struct obd_export *exp);
-int tgt_client_data_read(const struct lu_env *env, struct lu_target *tg,
-                        struct lsd_client_data *lcd, loff_t *off, int index);
-int tgt_client_data_write(const struct lu_env *env, struct lu_target *tg,
-                         struct lsd_client_data *lcd, loff_t *off, struct thandle *th);
-int tgt_server_data_read(const struct lu_env *env, struct lu_target *tg);
-int tgt_server_data_write(const struct lu_env *env, struct lu_target *tg,
-                         struct thandle *th);
-int tgt_server_data_update(const struct lu_env *env, struct lu_target *tg, int sync);
-int tgt_truncate_last_rcvd(const struct lu_env *env, struct lu_target *tg, loff_t off);
-
-#endif /* __LUSTRE_LU_TARGET_H */
diff --git a/drivers/staging/lustre/lustre/include/lustre/liblustreapi.h b/drivers/staging/lustre/lustre/include/lustre/liblustreapi.h
deleted file mode 100644 (file)
index 707eb74..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-/*
- * NOTE: This file is DEPRECATED!  Please include lustreapi.h directly
- * instead of this file.  This file will be removed from a future version
- * of lustre!
- */
-
-#ifndef _LIBLUSTREAPI_H_
-#define _LIBLUSTREAPI_H_
-
-#include <lustre/lustreapi.h>
-#warning "Including liblustreapi.h is deprecated. Include lustreapi.h directly."
-
-#endif
index 5ca18d01601429e5452bee9b1a839d7ce1df4bd3..7dfb925a536b9d8b68f32fcfc681edc480b04106 100644 (file)
@@ -1025,6 +1025,18 @@ struct luda_type {
        __u16 lt_type;
 };
 
+#ifndef IFSHIFT
+#define IFSHIFT                 12
+#endif
+
+#ifndef IFTODT
+#define IFTODT(type)           (((type) & S_IFMT) >> IFSHIFT)
+#endif
+#ifndef DTTOIF
+#define DTTOIF(dirtype)                ((dirtype) << IFSHIFT)
+#endif
+
+
 struct lu_dirpage {
        __u64       ldp_hash_start;
        __u64       ldp_hash_end;
@@ -1725,10 +1737,7 @@ static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic)
 #define OBD_MD_MDS      (0x0000000100000000ULL) /* where an inode lives on */
 #define OBD_MD_REINT       (0x0000000200000000ULL) /* reintegrate oa */
 #define OBD_MD_MEA      (0x0000000400000000ULL) /* CMD split EA  */
-
-/* OBD_MD_MDTIDX is used to get MDT index, but it is never been used overwire,
- * and it is already obsolete since 2.3 */
-/* #define OBD_MD_MDTIDX      (0x0000000800000000ULL) */
+#define OBD_MD_TSTATE      (0x0000000800000000ULL) /* transient state field */
 
 #define OBD_MD_FLXATTR       (0x0000001000000000ULL) /* xattr */
 #define OBD_MD_FLXATTRLS     (0x0000002000000000ULL) /* xattr list */
@@ -2120,6 +2129,7 @@ extern void lustre_swab_generic_32s (__u32 *val);
 #define DISP_ENQ_OPEN_REF    0x00800000
 #define DISP_ENQ_CREATE_REF  0x01000000
 #define DISP_OPEN_LOCK       0x02000000
+#define DISP_OPEN_LEASE      0x04000000
 
 /* INODE LOCK PARTS */
 #define MDS_INODELOCK_LOOKUP 0x000001       /* dentry, mode, owner, group */
@@ -2207,6 +2217,11 @@ static inline int ll_inode_to_ext_flags(int iflags)
                ((iflags & S_IMMUTABLE) ? LUSTRE_IMMUTABLE_FL : 0));
 }
 
+/* 64 possible states */
+enum md_transient_state {
+       MS_RESTORE      = (1 << 0),     /* restore is running */
+};
+
 struct mdt_body {
        struct lu_fid  fid1;
        struct lu_fid  fid2;
@@ -2218,7 +2233,9 @@ struct mdt_body {
        obd_time        ctime;
        __u64     blocks; /* XID, in the case of MDS_READPAGE */
        __u64     ioepoch;
-       __u64          unused1; /* was "ino" until 2.4.0 */
+       __u64          t_state; /* transient file state defined in
+                                * enum md_transient_state
+                                * was "ino" until 2.4.0 */
        __u32     fsuid;
        __u32     fsgid;
        __u32     capability;
@@ -2373,6 +2390,10 @@ extern void lustre_swab_mdt_rec_setattr (struct mdt_rec_setattr *sa);
                                              * hsm restore) */
 #define MDS_OPEN_VOLATILE   0400000000000ULL /* File is volatile = created
                                                unlinked */
+#define MDS_OPEN_LEASE    01000000000000ULL /* Open the file and grant lease
+                                             * delegation, succeed if it's not
+                                             * being opened with conflict mode.
+                                             */
 
 /* permission for create non-directory file */
 #define MAY_CREATE      (1 << 7)
index c7bd4473a1d0fab2e38591d814cbb6e34dfaa6fe..9436166c6ef215b21bda78807196ac8d545b6089 100644 (file)
@@ -245,6 +245,9 @@ struct ost_id {
 #define LL_IOC_LMV_GETSTRIPE       _IOWR('f', 241, struct lmv_user_md)
 #define LL_IOC_REMOVE_ENTRY        _IOWR('f', 242, __u64)
 
+#define LL_IOC_SET_LEASE               _IOWR('f', 243, long)
+#define LL_IOC_GET_LEASE               _IO('f', 244)
+
 #define LL_STATFS_LMV     1
 #define LL_STATFS_LOV     2
 #define LL_STATFS_NODELAY      4
@@ -1118,11 +1121,10 @@ static inline int hal_size(struct hsm_action_list *hal)
 
        sz = sizeof(*hal) + cfs_size_round(strlen(hal->hal_fsname));
        hai = hai_zero(hal);
-       for (i = 0 ; i < hal->hal_count ; i++) {
+       for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai))
                sz += cfs_size_round(hai->hai_len);
-               hai = hai_next(hai);
-       }
-       return(sz);
+
+       return sz;
 }
 
 /* Copytool progress reporting */
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustreapi.h b/drivers/staging/lustre/lustre/include/lustre/lustreapi.h
deleted file mode 100644 (file)
index 63da665..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Whamcloud, Inc.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef _LUSTREAPI_H_
-#define _LUSTREAPI_H_
-
-/** \defgroup llapi llapi
- *
- * @{
- */
-
-#include <lustre/lustre_user.h>
-
-typedef void (*llapi_cb_t)(char *obd_type_name, char *obd_name, char *obd_uuid, void *args);
-
-/* lustreapi message severity level */
-enum llapi_message_level {
-       LLAPI_MSG_OFF    = 0,
-       LLAPI_MSG_FATAL  = 1,
-       LLAPI_MSG_ERROR  = 2,
-       LLAPI_MSG_WARN   = 3,
-       LLAPI_MSG_NORMAL = 4,
-       LLAPI_MSG_INFO   = 5,
-       LLAPI_MSG_DEBUG  = 6,
-       LLAPI_MSG_MAX
-};
-
-/* the bottom three bits reserved for llapi_message_level */
-#define LLAPI_MSG_MASK   0x00000007
-#define LLAPI_MSG_NO_ERRNO      0x00000010
-
-extern void llapi_msg_set_level(int level);
-extern void llapi_error(int level, int rc, char *fmt, ...);
-#define llapi_err_noerrno(level, fmt, a...)                         \
-       llapi_error((level) | LLAPI_MSG_NO_ERRNO, 0, fmt, ## a)
-extern void llapi_printf(int level, char *fmt, ...);
-extern int llapi_file_create(const char *name, unsigned long long stripe_size,
-                            int stripe_offset, int stripe_count,
-                            int stripe_pattern);
-extern int llapi_file_open(const char *name, int flags, int mode,
-                          unsigned long long stripe_size, int stripe_offset,
-                          int stripe_count, int stripe_pattern);
-extern int llapi_file_create_pool(const char *name,
-                                 unsigned long long stripe_size,
-                                 int stripe_offset, int stripe_count,
-                                 int stripe_pattern, char *pool_name);
-extern int llapi_file_open_pool(const char *name, int flags, int mode,
-                               unsigned long long stripe_size,
-                               int stripe_offset, int stripe_count,
-                               int stripe_pattern, char *pool_name);
-extern int llapi_poollist(const char *name);
-extern int llapi_get_poollist(const char *name, char **poollist, int list_size,
-                             char *buffer, int buffer_size);
-extern int llapi_get_poolmembers(const char *poolname, char **members,
-                                int list_size, char *buffer, int buffer_size);
-extern int llapi_file_get_stripe(const char *path, struct lov_user_md *lum);
-#define HAVE_LLAPI_FILE_LOOKUP
-extern int llapi_file_lookup(int dirfd, const char *name);
-
-#define VERBOSE_COUNT      0x1
-#define VERBOSE_SIZE       0x2
-#define VERBOSE_OFFSET     0x4
-#define VERBOSE_POOL       0x8
-#define VERBOSE_DETAIL     0x10
-#define VERBOSE_OBJID      0x20
-#define VERBOSE_GENERATION 0x40
-#define VERBOSE_MDTINDEX   0x80
-#define VERBOSE_ALL    (VERBOSE_COUNT | VERBOSE_SIZE | VERBOSE_OFFSET | \
-                           VERBOSE_POOL | VERBOSE_OBJID | VERBOSE_GENERATION)
-
-struct find_param {
-       unsigned int maxdepth;
-       time_t  atime;
-       time_t  mtime;
-       time_t  ctime;
-       int     asign;  /* cannot be bitfields due to using pointers to */
-       int     csign;  /* access them during argument parsing. */
-       int     msign;
-       int     type;
-       int          size_sign:2,       /* these need to be signed values */
-                       stripesize_sign:2,
-                       stripecount_sign:2;
-       unsigned long long size;
-       unsigned long long size_units;
-       uid_t uid;
-       gid_t gid;
-
-       unsigned long   zeroend:1,
-                       recursive:1,
-                       exclude_pattern:1,
-                       exclude_type:1,
-                       exclude_obd:1,
-                       exclude_mdt:1,
-                       exclude_gid:1,
-                       exclude_uid:1,
-                       check_gid:1,        /* group ID */
-                       check_uid:1,        /* user ID */
-                       check_pool:1,      /* LOV pool name */
-                       check_size:1,      /* file size */
-                       exclude_pool:1,
-                       exclude_size:1,
-                       exclude_atime:1,
-                       exclude_mtime:1,
-                       exclude_ctime:1,
-                       get_lmv:1,            /* get MDT list from LMV */
-                       raw:1,            /* do not fill in defaults */
-                       check_stripesize:1,     /* LOV stripe size */
-                       exclude_stripesize:1,
-                       check_stripecount:1,    /* LOV stripe count */
-                       exclude_stripecount:1;
-
-       int     verbose;
-       int     quiet;
-
-       /* regular expression */
-       char   *pattern;
-
-       char   *print_fmt;
-
-       struct  obd_uuid       *obduuid;
-       int                  num_obds;
-       int                  num_alloc_obds;
-       int                  obdindex;
-       int                 *obdindexes;
-
-       struct  obd_uuid       *mdtuuid;
-       int                  num_mdts;
-       int                  num_alloc_mdts;
-       int                  mdtindex;
-       int                 *mdtindexes;
-       int                  file_mdtindex;
-
-       int     lumlen;
-       struct  lov_user_mds_data *lmd;
-
-       char poolname[LOV_MAXPOOLNAME + 1];
-
-       int                     fp_lmv_count;
-       struct lmv_user_md      *fp_lmv_md;
-
-       unsigned long long stripesize;
-       unsigned long long stripesize_units;
-       unsigned long long stripecount;
-
-       /* In-process parameters. */
-       unsigned long   got_uuids:1,
-                       obds_printed:1,
-                       have_fileinfo:1;        /* file attrs and LOV xattr */
-       unsigned int    depth;
-       dev_t      st_dev;
-};
-
-extern int llapi_ostlist(char *path, struct find_param *param);
-extern int llapi_uuid_match(char *real_uuid, char *search_uuid);
-extern int llapi_getstripe(char *path, struct find_param *param);
-extern int llapi_find(char *path, struct find_param *param);
-
-extern int llapi_file_fget_mdtidx(int fd, int *mdtidx);
-extern int llapi_dir_create_pool(const char *name, int flags, int stripe_offset,
-                                int stripe_count, int stripe_pattern,
-                                char *poolname);
-int llapi_direntry_remove(char *dname);
-extern int llapi_obd_statfs(char *path, __u32 type, __u32 index,
-                    struct obd_statfs *stat_buf,
-                    struct obd_uuid *uuid_buf);
-extern int llapi_ping(char *obd_type, char *obd_name);
-extern int llapi_target_check(int num_types, char **obd_types, char *dir);
-extern int llapi_file_get_lov_uuid(const char *path, struct obd_uuid *lov_uuid);
-extern int llapi_file_get_lmv_uuid(const char *path, struct obd_uuid *lmv_uuid);
-extern int llapi_file_fget_lov_uuid(int fd, struct obd_uuid *lov_uuid);
-extern int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count);
-extern int llapi_lmv_get_uuids(int fd, struct obd_uuid *uuidp, int *mdt_count);
-extern int llapi_is_lustre_mnttype(const char *type);
-extern int llapi_search_ost(char *fsname, char *poolname, char *ostname);
-extern int llapi_get_obd_count(char *mnt, int *count, int is_mdt);
-extern int parse_size(char *optarg, unsigned long long *size,
-                     unsigned long long *size_units, int bytes_spec);
-extern int llapi_search_mounts(const char *pathname, int index,
-                              char *mntdir, char *fsname);
-extern int llapi_search_fsname(const char *pathname, char *fsname);
-extern int llapi_getname(const char *path, char *buf, size_t size);
-
-extern void llapi_ping_target(char *obd_type, char *obd_name,
-                             char *obd_uuid, void *args);
-
-extern int llapi_search_rootpath(char *pathname, const char *fsname);
-
-struct mntent;
-#define HAVE_LLAPI_IS_LUSTRE_MNT
-extern int llapi_is_lustre_mnt(struct mntent *mnt);
-extern int llapi_quotachown(char *path, int flag);
-extern int llapi_quotacheck(char *mnt, int check_type);
-extern int llapi_poll_quotacheck(char *mnt, struct if_quotacheck *qchk);
-extern int llapi_quotactl(char *mnt, struct if_quotactl *qctl);
-extern int llapi_target_iterate(int type_num, char **obd_type, void *args,
-                               llapi_cb_t cb);
-extern int llapi_get_connect_flags(const char *mnt, __u64 *flags);
-extern int llapi_lsetfacl(int argc, char *argv[]);
-extern int llapi_lgetfacl(int argc, char *argv[]);
-extern int llapi_rsetfacl(int argc, char *argv[]);
-extern int llapi_rgetfacl(int argc, char *argv[]);
-extern int llapi_cp(int argc, char *argv[]);
-extern int llapi_ls(int argc, char *argv[]);
-extern int llapi_fid2path(const char *device, const char *fidstr, char *path,
-                         int pathlen, long long *recno, int *linkno);
-extern int llapi_path2fid(const char *path, lustre_fid *fid);
-extern int llapi_fd2fid(const int fd, lustre_fid *fid);
-
-extern int llapi_get_version(char *buffer, int buffer_size, char **version);
-extern int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags);
-extern int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus);
-extern int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
-                              __u32 archive_id);
-
-extern int llapi_create_volatile_idx(char *directory, int idx, int mode);
-static inline int llapi_create_volatile(char *directory, int mode)
-{
-       return llapi_create_volatile_idx(directory, -1, mode);
-}
-
-
-extern int llapi_fswap_layouts(const int fd1, const int fd2,
-                              __u64 dv1, __u64 dv2, __u64 flags);
-extern int llapi_swap_layouts(const char *path1, const char *path2,
-                             __u64 dv1, __u64 dv2, __u64 flags);
-
-/* Changelog interface.  priv is private state, managed internally
-   by these functions */
-#define CHANGELOG_FLAG_FOLLOW 0x01   /* Not yet implemented */
-#define CHANGELOG_FLAG_BLOCK  0x02   /* Blocking IO makes sense in case of
-   slow user parsing of the records, but it also prevents us from cleaning
-   up if the records are not consumed. */
-
-/* Records received are in extentded format now, though most of them are still
- * written in disk in changelog_rec format (to save space and time), it's
- * converted to extented format in the lustre api to ease changelog analysis. */
-#define HAVE_CHANGELOG_EXTEND_REC 1
-
-extern int llapi_changelog_start(void **priv, int flags, const char *mdtname,
-                                long long startrec);
-extern int llapi_changelog_fini(void **priv);
-extern int llapi_changelog_recv(void *priv, struct changelog_ext_rec **rech);
-extern int llapi_changelog_free(struct changelog_ext_rec **rech);
-/* Allow records up to endrec to be destroyed; requires registered id. */
-extern int llapi_changelog_clear(const char *mdtname, const char *idstr,
-                                long long endrec);
-
-/* HSM copytool interface.
- * priv is private state, managed internally by these functions
- */
-struct hsm_copytool_private;
-extern int llapi_hsm_copytool_start(struct hsm_copytool_private **priv,
-                                   char *fsname, int flags,
-                                   int archive_count, int *archives);
-extern int llapi_hsm_copytool_fini(struct hsm_copytool_private **priv);
-extern int llapi_hsm_copytool_recv(struct hsm_copytool_private *priv,
-                                  struct hsm_action_list **hal, int *msgsize);
-extern int llapi_hsm_copytool_free(struct hsm_action_list **hal);
-extern int llapi_hsm_copy_start(char *mnt, struct hsm_copy *copy,
-                               const struct hsm_action_item *hai);
-extern int llapi_hsm_copy_end(char *mnt, struct hsm_copy *copy,
-                             const struct hsm_progress *hp);
-extern int llapi_hsm_progress(char *mnt, struct hsm_progress *hp);
-extern int llapi_hsm_import(const char *dst, int archive, struct stat *st,
-                           unsigned long long stripe_size, int stripe_offset,
-                           int stripe_count, int stripe_pattern,
-                           char *pool_name, lustre_fid *newfid);
-
-/* HSM user interface */
-extern struct hsm_user_request *llapi_hsm_user_request_alloc(int itemcount,
-                                                            int data_len);
-extern int llapi_hsm_request(char *mnt, struct hsm_user_request *request);
-extern int llapi_hsm_current_action(const char *path,
-                                   struct hsm_current_action *hca);
-/** @} llapi */
-
-#endif
index 9228b165b258d9c8bd08a67f380242b601cb9408..1de9a8bed497568fcce3a48a8d2a4edc5c43f2b7 100644 (file)
@@ -50,6 +50,7 @@
 
 #include <linux/libcfs/libcfs.h>
 #include <linux/lnet/types.h>
+#include <linux/backing-dev.h>
 
 /****************** on-disk files *********************/
 
index 8c34d9d4d2587b59d635c1f4bc7604f80f066b91..75716f17f64bedc927f80d6e5225924d58e6cc86 100644 (file)
@@ -35,7 +35,7 @@
 #ifndef LDLM_ALL_FLAGS_MASK
 
 /** l_flags bits marked as "all_flags" bits */
-#define LDLM_FL_ALL_FLAGS_MASK          0x007FFFFFC08F132FULL
+#define LDLM_FL_ALL_FLAGS_MASK          0x00FFFFFFC08F132FULL
 
 /** l_flags bits marked as "ast" bits */
 #define LDLM_FL_AST_MASK                0x0000000080000000ULL
@@ -53,7 +53,7 @@
 #define LDLM_FL_INHERIT_MASK            0x0000000000800000ULL
 
 /** l_flags bits marked as "local_only" bits */
-#define LDLM_FL_LOCAL_ONLY_MASK         0x007FFFFF00000000ULL
+#define LDLM_FL_LOCAL_ONLY_MASK         0x00FFFFFF00000000ULL
 
 /** l_flags bits marked as "on_wire" bits */
 #define LDLM_FL_ON_WIRE_MASK            0x00000000C08F132FULL
 #define ldlm_set_ns_srv(_l)             LDLM_SET_FLAG((  _l), 1ULL << 54)
 #define ldlm_clear_ns_srv(_l)           LDLM_CLEAR_FLAG((_l), 1ULL << 54)
 
+/** Flag whether this lock can be reused. Used by exclusive open. */
+#define LDLM_FL_EXCL                    0x0080000000000000ULL /* bit  55 */
+#define ldlm_is_excl(_l)                LDLM_TEST_FLAG((_l), 1ULL << 55)
+#define ldlm_set_excl(_l)               LDLM_SET_FLAG((_l), 1ULL << 55)
+#define ldlm_clear_excl(_l)             LDLM_CLEAR_FLAG((_l), 1ULL << 55)
+
 /** test for ldlm_lock flag bit set */
 #define LDLM_TEST_FLAG(_l, _b)        (((_l)->l_flags & (_b)) != 0)
 
@@ -414,47 +420,49 @@ static int hf_lustre_ldlm_fl_server_lock         = -1;
 static int hf_lustre_ldlm_fl_res_locked          = -1;
 static int hf_lustre_ldlm_fl_waited              = -1;
 static int hf_lustre_ldlm_fl_ns_srv              = -1;
+static int hf_lustre_ldlm_fl_excl                = -1;
 
 const value_string lustre_ldlm_flags_vals[] = {
-  {LDLM_FL_LOCK_CHANGED,        "LDLM_FL_LOCK_CHANGED"},
-  {LDLM_FL_BLOCK_GRANTED,       "LDLM_FL_BLOCK_GRANTED"},
-  {LDLM_FL_BLOCK_CONV,          "LDLM_FL_BLOCK_CONV"},
-  {LDLM_FL_BLOCK_WAIT,          "LDLM_FL_BLOCK_WAIT"},
-  {LDLM_FL_AST_SENT,            "LDLM_FL_AST_SENT"},
-  {LDLM_FL_REPLAY,              "LDLM_FL_REPLAY"},
-  {LDLM_FL_INTENT_ONLY,         "LDLM_FL_INTENT_ONLY"},
-  {LDLM_FL_HAS_INTENT,          "LDLM_FL_HAS_INTENT"},
-  {LDLM_FL_DISCARD_DATA,        "LDLM_FL_DISCARD_DATA"},
-  {LDLM_FL_NO_TIMEOUT,          "LDLM_FL_NO_TIMEOUT"},
-  {LDLM_FL_BLOCK_NOWAIT,        "LDLM_FL_BLOCK_NOWAIT"},
-  {LDLM_FL_TEST_LOCK,           "LDLM_FL_TEST_LOCK"},
-  {LDLM_FL_CANCEL_ON_BLOCK,     "LDLM_FL_CANCEL_ON_BLOCK"},
-  {LDLM_FL_DENY_ON_CONTENTION,  "LDLM_FL_DENY_ON_CONTENTION"},
-  {LDLM_FL_AST_DISCARD_DATA,    "LDLM_FL_AST_DISCARD_DATA"},
-  {LDLM_FL_FAIL_LOC,            "LDLM_FL_FAIL_LOC"},
-  {LDLM_FL_SKIPPED,             "LDLM_FL_SKIPPED"},
-  {LDLM_FL_CBPENDING,           "LDLM_FL_CBPENDING"},
-  {LDLM_FL_WAIT_NOREPROC,       "LDLM_FL_WAIT_NOREPROC"},
-  {LDLM_FL_CANCEL,              "LDLM_FL_CANCEL"},
-  {LDLM_FL_LOCAL_ONLY,          "LDLM_FL_LOCAL_ONLY"},
-  {LDLM_FL_FAILED,              "LDLM_FL_FAILED"},
-  {LDLM_FL_CANCELING,           "LDLM_FL_CANCELING"},
-  {LDLM_FL_LOCAL,               "LDLM_FL_LOCAL"},
-  {LDLM_FL_LVB_READY,           "LDLM_FL_LVB_READY"},
-  {LDLM_FL_KMS_IGNORE,          "LDLM_FL_KMS_IGNORE"},
-  {LDLM_FL_CP_REQD,             "LDLM_FL_CP_REQD"},
-  {LDLM_FL_CLEANED,             "LDLM_FL_CLEANED"},
-  {LDLM_FL_ATOMIC_CB,           "LDLM_FL_ATOMIC_CB"},
-  {LDLM_FL_BL_AST,              "LDLM_FL_BL_AST"},
-  {LDLM_FL_BL_DONE,             "LDLM_FL_BL_DONE"},
-  {LDLM_FL_NO_LRU,              "LDLM_FL_NO_LRU"},
-  {LDLM_FL_FAIL_NOTIFIED,       "LDLM_FL_FAIL_NOTIFIED"},
-  {LDLM_FL_DESTROYED,           "LDLM_FL_DESTROYED"},
-  {LDLM_FL_SERVER_LOCK,         "LDLM_FL_SERVER_LOCK"},
-  {LDLM_FL_RES_LOCKED,          "LDLM_FL_RES_LOCKED"},
-  {LDLM_FL_WAITED,              "LDLM_FL_WAITED"},
-  {LDLM_FL_NS_SRV,              "LDLM_FL_NS_SRV"},
-  { 0, NULL }
+       {LDLM_FL_LOCK_CHANGED,        "LDLM_FL_LOCK_CHANGED"},
+       {LDLM_FL_BLOCK_GRANTED,       "LDLM_FL_BLOCK_GRANTED"},
+       {LDLM_FL_BLOCK_CONV,          "LDLM_FL_BLOCK_CONV"},
+       {LDLM_FL_BLOCK_WAIT,          "LDLM_FL_BLOCK_WAIT"},
+       {LDLM_FL_AST_SENT,            "LDLM_FL_AST_SENT"},
+       {LDLM_FL_REPLAY,              "LDLM_FL_REPLAY"},
+       {LDLM_FL_INTENT_ONLY,         "LDLM_FL_INTENT_ONLY"},
+       {LDLM_FL_HAS_INTENT,          "LDLM_FL_HAS_INTENT"},
+       {LDLM_FL_DISCARD_DATA,        "LDLM_FL_DISCARD_DATA"},
+       {LDLM_FL_NO_TIMEOUT,          "LDLM_FL_NO_TIMEOUT"},
+       {LDLM_FL_BLOCK_NOWAIT,        "LDLM_FL_BLOCK_NOWAIT"},
+       {LDLM_FL_TEST_LOCK,           "LDLM_FL_TEST_LOCK"},
+       {LDLM_FL_CANCEL_ON_BLOCK,     "LDLM_FL_CANCEL_ON_BLOCK"},
+       {LDLM_FL_DENY_ON_CONTENTION,  "LDLM_FL_DENY_ON_CONTENTION"},
+       {LDLM_FL_AST_DISCARD_DATA,    "LDLM_FL_AST_DISCARD_DATA"},
+       {LDLM_FL_FAIL_LOC,            "LDLM_FL_FAIL_LOC"},
+       {LDLM_FL_SKIPPED,             "LDLM_FL_SKIPPED"},
+       {LDLM_FL_CBPENDING,           "LDLM_FL_CBPENDING"},
+       {LDLM_FL_WAIT_NOREPROC,       "LDLM_FL_WAIT_NOREPROC"},
+       {LDLM_FL_CANCEL,              "LDLM_FL_CANCEL"},
+       {LDLM_FL_LOCAL_ONLY,          "LDLM_FL_LOCAL_ONLY"},
+       {LDLM_FL_FAILED,              "LDLM_FL_FAILED"},
+       {LDLM_FL_CANCELING,           "LDLM_FL_CANCELING"},
+       {LDLM_FL_LOCAL,               "LDLM_FL_LOCAL"},
+       {LDLM_FL_LVB_READY,           "LDLM_FL_LVB_READY"},
+       {LDLM_FL_KMS_IGNORE,          "LDLM_FL_KMS_IGNORE"},
+       {LDLM_FL_CP_REQD,             "LDLM_FL_CP_REQD"},
+       {LDLM_FL_CLEANED,             "LDLM_FL_CLEANED"},
+       {LDLM_FL_ATOMIC_CB,           "LDLM_FL_ATOMIC_CB"},
+       {LDLM_FL_BL_AST,              "LDLM_FL_BL_AST"},
+       {LDLM_FL_BL_DONE,             "LDLM_FL_BL_DONE"},
+       {LDLM_FL_NO_LRU,              "LDLM_FL_NO_LRU"},
+       {LDLM_FL_FAIL_NOTIFIED,       "LDLM_FL_FAIL_NOTIFIED"},
+       {LDLM_FL_DESTROYED,           "LDLM_FL_DESTROYED"},
+       {LDLM_FL_SERVER_LOCK,         "LDLM_FL_SERVER_LOCK"},
+       {LDLM_FL_RES_LOCKED,          "LDLM_FL_RES_LOCKED"},
+       {LDLM_FL_WAITED,              "LDLM_FL_WAITED"},
+       {LDLM_FL_NS_SRV,              "LDLM_FL_NS_SRV"},
+       {LDLM_FL_EXCL,                "LDLM_FL_EXCL"},
+       { 0, NULL }
 };
 #endif /*  WIRESHARK_COMPILE */
 #endif /* LDLM_ALL_FLAGS_MASK */
index 5e11107d4c66d99816d39faef66b6ef94b105426..609a090484a65a9e9d0b39b90dd598111316e993 100644 (file)
@@ -81,11 +81,12 @@ struct client_obd *client_conn2cli(struct lustre_handle *conn);
 
 struct md_open_data;
 struct obd_client_handle {
-       struct lustre_handle  och_fh;
-       struct lu_fid    och_fid;
-       struct md_open_data  *och_mod;
-       __u32 och_magic;
-       int och_flags;
+       struct lustre_handle     och_fh;
+       struct lu_fid            och_fid;
+       struct md_open_data     *och_mod;
+       struct lustre_handle     och_lease_handle; /* open lock for lease */
+       __u32                    och_magic;
+       fmode_t                  och_flags;
 };
 #define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed
 
index 72edf01b58a21e3b0c36b99f8399d1ba1f7ca26d..91f28e363be2922399743b5758581d6b5f8dd26e 100644 (file)
@@ -3470,15 +3470,6 @@ static inline void ptlrpc_lprocfs_brw(struct ptlrpc_request *req, int bytes) {}
 #endif
 /** @} */
 
-/* ptlrpc/llog_server.c */
-int llog_origin_handle_open(struct ptlrpc_request *req);
-int llog_origin_handle_destroy(struct ptlrpc_request *req);
-int llog_origin_handle_prev_block(struct ptlrpc_request *req);
-int llog_origin_handle_next_block(struct ptlrpc_request *req);
-int llog_origin_handle_read_header(struct ptlrpc_request *req);
-int llog_origin_handle_close(struct ptlrpc_request *req);
-int llog_origin_handle_cancel(struct ptlrpc_request *req);
-
 /* ptlrpc/llog_client.c */
 extern struct llog_operations llog_client_ops;
 
index f4d3820865f125670827e57bc87eb66f3dbebc04..28325693fc11019e3e17e2d9bd0e25e744c6a0fd 100644 (file)
@@ -245,6 +245,8 @@ extern struct req_format RQF_LLOG_ORIGIN_HANDLE_PREV_BLOCK;
 extern struct req_format RQF_LLOG_ORIGIN_HANDLE_READ_HEADER;
 extern struct req_format RQF_LLOG_ORIGIN_CONNECT;
 
+extern struct req_format RQF_CONNECT;
+
 extern struct req_msg_field RMF_GENERIC_DATA;
 extern struct req_msg_field RMF_PTLRPC_BODY;
 extern struct req_msg_field RMF_MDT_BODY;
index 9697e7faff2fddbb62e484121e7186adcab4077c..825a0c95c585a25d8c421b0c5864e9745835330d 100644 (file)
@@ -416,6 +416,13 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type,
 #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
 #define OBD_FAIL_MGS_PAUSE_REQ    0x904
 #define OBD_FAIL_MGS_PAUSE_TARGET_REG    0x905
+#define OBD_FAIL_MGS_CONNECT_NET        0x906
+#define OBD_FAIL_MGS_DISCONNECT_NET     0x907
+#define OBD_FAIL_MGS_SET_INFO_NET       0x908
+#define OBD_FAIL_MGS_EXCEPTION_NET      0x909
+#define OBD_FAIL_MGS_TARGET_REG_NET     0x90a
+#define OBD_FAIL_MGS_TARGET_DEL_NET     0x90b
+#define OBD_FAIL_MGS_CONFIG_READ_NET    0x90c
 
 #define OBD_FAIL_QUOTA_DQACQ_NET                       0xA01
 #define OBD_FAIL_QUOTA_EDQUOT      0xA02
index e60c04d5393abaf6bf51ac3834adaf274d432d45..1c628e32575025c0c19f3a35c4a3be356628bc6a 100644 (file)
@@ -1006,6 +1006,12 @@ again:
        cl_io_fini(env, io);
        if (unlikely(io->ci_need_restart))
                goto again;
+       /* HSM import case: file is released, cannot be restored
+        * no need to fail except if restore registration failed
+        * with -ENODATA */
+       if (result == -ENODATA && io->ci_restore_needed &&
+           io->ci_result != -ENODATA)
+               result = 0;
        cl_env_put(env, &refcheck);
        return result;
 }
index 39fcdacc51ed2c5c9d9f3d40368ccc91c333f39a..c9aae132f98ae254bd213657a4304a940c9040fc 100644 (file)
@@ -95,20 +95,12 @@ ldlm_flocks_overlap(struct ldlm_lock *lock, struct ldlm_lock *new)
                lock->l_policy_data.l_flock.start));
 }
 
-static inline int ldlm_flock_blocking_link(struct ldlm_lock *req,
-                                          struct ldlm_lock *lock)
+static inline void ldlm_flock_blocking_link(struct ldlm_lock *req,
+                                           struct ldlm_lock *lock)
 {
-       int rc = 0;
-
        /* For server only */
        if (req->l_export == NULL)
-               return 0;
-
-       if (unlikely(req->l_export->exp_flock_hash == NULL)) {
-               rc = ldlm_init_flock_export(req->l_export);
-               if (rc)
-                       goto error;
-       }
+               return;
 
        LASSERT(hlist_unhashed(&req->l_exp_flock_hash));
 
@@ -121,8 +113,6 @@ static inline int ldlm_flock_blocking_link(struct ldlm_lock *req,
        cfs_hash_add(req->l_export->exp_flock_hash,
                     &req->l_policy_data.l_flock.owner,
                     &req->l_exp_flock_hash);
-error:
-       return rc;
 }
 
 static inline void ldlm_flock_blocking_unlink(struct ldlm_lock *req)
@@ -250,7 +240,6 @@ ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags, int first_enq,
        int overlaps = 0;
        int splitted = 0;
        const struct ldlm_callback_suite null_cbs = { NULL };
-       int rc;
 
        CDEBUG(D_DLMTRACE, "flags %#llx owner "LPU64" pid %u mode %u start "
               LPU64" end "LPU64"\n", *flags,
@@ -328,12 +317,8 @@ reprocess:
 
                        /* add lock to blocking list before deadlock
                         * check to prevent race */
-                       rc = ldlm_flock_blocking_link(req, lock);
-                       if (rc) {
-                               ldlm_flock_destroy(req, mode, *flags);
-                               *err = rc;
-                               return LDLM_ITER_STOP;
-                       }
+                       ldlm_flock_blocking_link(req, lock);
+
                        if (ldlm_flock_deadlock(req, lock)) {
                                ldlm_flock_blocking_unlink(req);
                                ldlm_flock_destroy(req, mode, *flags);
@@ -665,23 +650,20 @@ granted:
                /* fcntl(F_GETLK) request */
                /* The old mode was saved in getlk->fl_type so that if the mode
                 * in the lock changes we can decref the appropriate refcount.*/
-               ldlm_flock_destroy(lock, flock_type(getlk),
-                                  LDLM_FL_WAIT_NOREPROC);
+               ldlm_flock_destroy(lock, getlk->fl_type, LDLM_FL_WAIT_NOREPROC);
                switch (lock->l_granted_mode) {
                case LCK_PR:
-                       flock_set_type(getlk, F_RDLCK);
+                       getlk->fl_type = F_RDLCK;
                        break;
                case LCK_PW:
-                       flock_set_type(getlk, F_WRLCK);
+                       getlk->fl_type = F_WRLCK;
                        break;
                default:
-                       flock_set_type(getlk, F_UNLCK);
+                       getlk->fl_type = F_UNLCK;
                }
-               flock_set_pid(getlk, (pid_t)lock->l_policy_data.l_flock.pid);
-               flock_set_start(getlk,
-                               (loff_t)lock->l_policy_data.l_flock.start);
-               flock_set_end(getlk,
-                             (loff_t)lock->l_policy_data.l_flock.end);
+               getlk->fl_pid = (pid_t)lock->l_policy_data.l_flock.pid;
+               getlk->fl_start = (loff_t)lock->l_policy_data.l_flock.start;
+               getlk->fl_end = (loff_t)lock->l_policy_data.l_flock.end;
        } else {
                __u64 noreproc = LDLM_FL_WAIT_NOREPROC;
 
@@ -816,6 +798,9 @@ static cfs_hash_ops_t ldlm_export_flock_ops = {
 
 int ldlm_init_flock_export(struct obd_export *exp)
 {
+       if (strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_MDT_NAME) != 0)
+               return 0;
+
        exp->exp_flock_hash =
                cfs_hash_create(obd_uuid2str(&exp->exp_client_uuid),
                                HASH_EXP_LOCK_CUR_BITS,
index 3900a69742fc5bc84b4b1ba99949a88ac2c99cc3..ef826e90df03b6e0391e8bf4cb9366b7fba2c39c 100644 (file)
@@ -1129,6 +1129,11 @@ static struct ldlm_lock *search_queue(struct list_head *queue,
                if (lock == old_lock)
                        break;
 
+               /* Check if this lock can be matched.
+                * Used by LU-2919(exclusive open) for open lease lock */
+               if (ldlm_is_excl(lock))
+                       continue;
+
                /* llite sometimes wants to match locks that will be
                 * canceled when their users drop, but we allow it to match
                 * if it passes in CBPENDING and the lock still has users.
index fde9bcd1d48dfbe73c35cb1cfb21445412ea2c79..85f5e7e42486a5c415e0bef4313ac140ea622628 100644 (file)
 #include "ldlm_internal.h"
 
 static int ldlm_num_threads;
-CFS_MODULE_PARM(ldlm_num_threads, "i", int, 0444,
-               "number of DLM service threads to start");
+module_param(ldlm_num_threads, int, 0444);
+MODULE_PARM_DESC(ldlm_num_threads, "number of DLM service threads to start");
 
 static char *ldlm_cpts;
-CFS_MODULE_PARM(ldlm_cpts, "s", charp, 0444,
-               "CPU partitions ldlm threads should run on");
+module_param(ldlm_cpts, charp, 0444);
+MODULE_PARM_DESC(ldlm_cpts, "CPU partitions ldlm threads should run on");
 
 extern struct kmem_cache *ldlm_resource_slab;
 extern struct kmem_cache *ldlm_lock_slab;
@@ -597,45 +597,6 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
                rc = ldlm_handle_setinfo(req);
                ldlm_callback_reply(req, rc);
                return 0;
-       case OBD_LOG_CANCEL: /* remove this eventually - for 1.4.0 compat */
-               CERROR("shouldn't be handling OBD_LOG_CANCEL on DLM thread\n");
-               req_capsule_set(&req->rq_pill, &RQF_LOG_CANCEL);
-               if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOG_CANCEL_NET))
-                       return 0;
-               rc = llog_origin_handle_cancel(req);
-               if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOG_CANCEL_REP))
-                       return 0;
-               ldlm_callback_reply(req, rc);
-               return 0;
-       case LLOG_ORIGIN_HANDLE_CREATE:
-               req_capsule_set(&req->rq_pill, &RQF_LLOG_ORIGIN_HANDLE_CREATE);
-               if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET))
-                       return 0;
-               rc = llog_origin_handle_open(req);
-               ldlm_callback_reply(req, rc);
-               return 0;
-       case LLOG_ORIGIN_HANDLE_NEXT_BLOCK:
-               req_capsule_set(&req->rq_pill,
-                               &RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK);
-               if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET))
-                       return 0;
-               rc = llog_origin_handle_next_block(req);
-               ldlm_callback_reply(req, rc);
-               return 0;
-       case LLOG_ORIGIN_HANDLE_READ_HEADER:
-               req_capsule_set(&req->rq_pill,
-                               &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER);
-               if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET))
-                       return 0;
-               rc = llog_origin_handle_read_header(req);
-               ldlm_callback_reply(req, rc);
-               return 0;
-       case LLOG_ORIGIN_HANDLE_CLOSE:
-               if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET))
-                       return 0;
-               rc = llog_origin_handle_close(req);
-               ldlm_callback_reply(req, rc);
-               return 0;
        case OBD_QC_CALLBACK:
                req_capsule_set(&req->rq_pill, &RQF_QC_CALLBACK);
                if (OBD_FAIL_CHECK(OBD_FAIL_OBD_QC_CALLBACK_NET))
@@ -1003,6 +964,7 @@ static cfs_hash_ops_t ldlm_export_lock_ops = {
 
 int ldlm_init_export(struct obd_export *exp)
 {
+       int rc;
        exp->exp_lock_hash =
                cfs_hash_create(obd_uuid2str(&exp->exp_client_uuid),
                                HASH_EXP_LOCK_CUR_BITS,
@@ -1016,7 +978,14 @@ int ldlm_init_export(struct obd_export *exp)
        if (!exp->exp_lock_hash)
                return -ENOMEM;
 
+       rc = ldlm_init_flock_export(exp);
+       if (rc)
+               GOTO(err, rc);
+
        return 0;
+err:
+       ldlm_destroy_export(exp);
+       return rc;
 }
 EXPORT_SYMBOL(ldlm_init_export);
 
index dcc2784031367c0cd5187c2e3891f05be79957cd..4974becb3d9b83f81e7cea7828b706334a7f2514 100644 (file)
@@ -68,8 +68,8 @@
 #include "ldlm_internal.h"
 
 int ldlm_enqueue_min = OBD_TIMEOUT_DEFAULT;
-CFS_MODULE_PARM(ldlm_enqueue_min, "i", int, 0644,
-               "lock enqueue timeout minimum");
+module_param(ldlm_enqueue_min, int, 0644);
+MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
 
 /* in client side, whether the cached locks will be canceled before replay */
 unsigned int ldlm_cancel_unused_locks_before_replay = 1;
@@ -610,18 +610,12 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req,
                        lock->l_req_mode = newmode;
                }
 
-               if (memcmp(reply->lock_desc.l_resource.lr_name.name,
-                         lock->l_resource->lr_name.name,
-                         sizeof(struct ldlm_res_id))) {
-                       CDEBUG(D_INFO, "remote intent success, locking "
-                                       "(%ld,%ld,%ld) instead of "
-                                       "(%ld,%ld,%ld)\n",
-                             (long)reply->lock_desc.l_resource.lr_name.name[0],
-                             (long)reply->lock_desc.l_resource.lr_name.name[1],
-                             (long)reply->lock_desc.l_resource.lr_name.name[2],
-                             (long)lock->l_resource->lr_name.name[0],
-                             (long)lock->l_resource->lr_name.name[1],
-                             (long)lock->l_resource->lr_name.name[2]);
+               if (!ldlm_res_eq(&reply->lock_desc.l_resource.lr_name,
+                                &lock->l_resource->lr_name)) {
+                       CDEBUG(D_INFO, "remote intent success, locking "DLDLMRES
+                                      " instead of "DLDLMRES"\n",
+                              PLDLMRES(&reply->lock_desc.l_resource),
+                              PLDLMRES(lock->l_resource));
 
                        rc = ldlm_lock_change_resource(ns, lock,
                                        &reply->lock_desc.l_resource.lr_name);
@@ -910,7 +904,7 @@ int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp,
        lock->l_conn_export = exp;
        lock->l_export = NULL;
        lock->l_blocking_ast = einfo->ei_cb_bl;
-       lock->l_flags |= (*flags & LDLM_FL_NO_LRU);
+       lock->l_flags |= (*flags & (LDLM_FL_NO_LRU | LDLM_FL_EXCL));
 
        /* lock not sent to server yet */
 
@@ -1333,7 +1327,7 @@ int ldlm_cli_cancel(struct lustre_handle *lockh,
        }
 
        rc = ldlm_cli_cancel_local(lock);
-       if (rc == LDLM_FL_LOCAL_ONLY) {
+       if (rc == LDLM_FL_LOCAL_ONLY || cancel_flags & LCF_LOCAL) {
                LDLM_LOCK_RELEASE(lock);
                return 0;
        }
@@ -1912,7 +1906,8 @@ int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
                                           0, flags | LCF_BL_AST, opaque);
        rc = ldlm_cli_cancel_list(&cancels, count, NULL, flags);
        if (rc != ELDLM_OK)
-               CERROR("ldlm_cli_cancel_unused_resource: %d\n", rc);
+               CERROR("canceling unused lock "DLDLMRES": rc = %d\n",
+                      PLDLMRES(res), rc);
 
        LDLM_RESOURCE_DELREF(res);
        ldlm_resource_putref(res);
@@ -1930,15 +1925,10 @@ static int ldlm_cli_hash_cancel_unused(struct cfs_hash *hs, struct cfs_hash_bd *
 {
        struct ldlm_resource       *res = cfs_hash_object(hs, hnode);
        struct ldlm_cli_cancel_arg     *lc = arg;
-       int                          rc;
 
-       rc = ldlm_cli_cancel_unused_resource(ldlm_res_to_ns(res), &res->lr_name,
-                                            NULL, LCK_MINMODE,
-                                            lc->lc_flags, lc->lc_opaque);
-       if (rc != 0) {
-               CERROR("ldlm_cli_cancel_unused ("LPU64"): %d\n",
-                      res->lr_name.name[0], rc);
-       }
+       ldlm_cli_cancel_unused_resource(ldlm_res_to_ns(res), &res->lr_name,
+                                       NULL, LCK_MINMODE,
+                                       lc->lc_flags, lc->lc_opaque);
        /* must return 0 for hash iteration */
        return 0;
 }
index 77e022bf8bcc891d068ccf5518bc03b603c85073..25e14e1b3659b47dd5b7ba4bf718d05b6714e54d 100644 (file)
@@ -762,16 +762,9 @@ static int ldlm_resource_complain(struct cfs_hash *hs, struct cfs_hash_bd *bd,
        struct ldlm_resource  *res = cfs_hash_object(hs, hnode);
 
        lock_res(res);
-       CERROR("Namespace %s resource refcount nonzero "
-              "(%d) after lock cleanup; forcing "
-              "cleanup.\n",
-              ldlm_ns_name(ldlm_res_to_ns(res)),
-              atomic_read(&res->lr_refcount) - 1);
-
-       CERROR("Resource: %p ("LPU64"/"LPU64"/"LPU64"/"
-              LPU64") (rc: %d)\n", res,
-              res->lr_name.name[0], res->lr_name.name[1],
-              res->lr_name.name[2], res->lr_name.name[3],
+       CERROR("%s: namespace resource "DLDLMRES
+              " (%p) refcount nonzero (%d) after lock cleanup; forcing cleanup.\n",
+              ldlm_ns_name(ldlm_res_to_ns(res)), PLDLMRES(res), res,
               atomic_read(&res->lr_refcount) - 1);
 
        ldlm_resource_dump(D_ERROR, res);
@@ -1403,10 +1396,8 @@ void ldlm_resource_dump(int level, struct ldlm_resource *res)
        if (!((libcfs_debug | D_ERROR) & level))
                return;
 
-       CDEBUG(level, "--- Resource: %p ("LPU64"/"LPU64"/"LPU64"/"LPU64
-              ") (rc: %d)\n", res, res->lr_name.name[0], res->lr_name.name[1],
-              res->lr_name.name[2], res->lr_name.name[3],
-              atomic_read(&res->lr_refcount));
+       CDEBUG(level, "--- Resource: "DLDLMRES" (%p) refcount = %d\n",
+              PLDLMRES(res), res, atomic_read(&res->lr_refcount));
 
        if (!list_empty(&res->lr_granted)) {
                CDEBUG(level, "Granted locks (in reverse order):\n");
index 9b9c45116eee7bc26b08eee26eeca37bb1940fdd..f30c84f195aa12b9ff1a5e84c6dbc44e96716bad 100644 (file)
 static char debug_file_name[1024];
 
 unsigned int libcfs_subsystem_debug = ~0;
-CFS_MODULE_PARM(libcfs_subsystem_debug, "i", int, 0644,
-               "Lustre kernel debug subsystem mask");
+module_param(libcfs_subsystem_debug, int, 0644);
+MODULE_PARM_DESC(libcfs_subsystem_debug, "Lustre kernel debug subsystem mask");
 EXPORT_SYMBOL(libcfs_subsystem_debug);
 
 unsigned int libcfs_debug = (D_CANTMASK |
                             D_NETERROR | D_HA | D_CONFIG | D_IOCTL);
-CFS_MODULE_PARM(libcfs_debug, "i", int, 0644,
-               "Lustre kernel debug mask");
+module_param(libcfs_debug, int, 0644);
+MODULE_PARM_DESC(libcfs_debug, "Lustre kernel debug mask");
 EXPORT_SYMBOL(libcfs_debug);
 
 unsigned int libcfs_debug_mb = 0;
-CFS_MODULE_PARM(libcfs_debug_mb, "i", uint, 0644,
-               "Total debug buffer size.");
+module_param(libcfs_debug_mb, uint, 0644);
+MODULE_PARM_DESC(libcfs_debug_mb, "Total debug buffer size.");
 EXPORT_SYMBOL(libcfs_debug_mb);
 
 unsigned int libcfs_printk = D_CANTMASK;
-CFS_MODULE_PARM(libcfs_printk, "i", uint, 0644,
-               "Lustre kernel debug console mask");
+module_param(libcfs_printk, uint, 0644);
+MODULE_PARM_DESC(libcfs_printk, "Lustre kernel debug console mask");
 EXPORT_SYMBOL(libcfs_printk);
 
 unsigned int libcfs_console_ratelimit = 1;
-CFS_MODULE_PARM(libcfs_console_ratelimit, "i", uint, 0644,
-               "Lustre kernel debug console ratelimit (0 to disable)");
+module_param(libcfs_console_ratelimit, uint, 0644);
+MODULE_PARM_DESC(libcfs_console_ratelimit, "Lustre kernel debug console ratelimit (0 to disable)");
 EXPORT_SYMBOL(libcfs_console_ratelimit);
 
 unsigned int libcfs_console_max_delay;
-CFS_MODULE_PARM(libcfs_console_max_delay, "l", uint, 0644,
-               "Lustre kernel debug console max delay (jiffies)");
+module_param(libcfs_console_max_delay, uint, 0644);
+MODULE_PARM_DESC(libcfs_console_max_delay, "Lustre kernel debug console max delay (jiffies)");
 EXPORT_SYMBOL(libcfs_console_max_delay);
 
 unsigned int libcfs_console_min_delay;
-CFS_MODULE_PARM(libcfs_console_min_delay, "l", uint, 0644,
-               "Lustre kernel debug console min delay (jiffies)");
+module_param(libcfs_console_min_delay, uint, 0644);
+MODULE_PARM_DESC(libcfs_console_min_delay, "Lustre kernel debug console min delay (jiffies)");
 EXPORT_SYMBOL(libcfs_console_min_delay);
 
 unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF;
-CFS_MODULE_PARM(libcfs_console_backoff, "i", uint, 0644,
-               "Lustre kernel debug console backoff factor");
+module_param(libcfs_console_backoff, uint, 0644);
+MODULE_PARM_DESC(libcfs_console_backoff, "Lustre kernel debug console backoff factor");
 EXPORT_SYMBOL(libcfs_console_backoff);
 
 unsigned int libcfs_debug_binary = 1;
@@ -103,8 +103,8 @@ unsigned int libcfs_watchdog_ratelimit = 300;
 EXPORT_SYMBOL(libcfs_watchdog_ratelimit);
 
 unsigned int libcfs_panic_on_lbug = 1;
-CFS_MODULE_PARM(libcfs_panic_on_lbug, "i", uint, 0644,
-               "Lustre kernel panic on LBUG");
+module_param(libcfs_panic_on_lbug, uint, 0644);
+MODULE_PARM_DESC(libcfs_panic_on_lbug, "Lustre kernel panic on LBUG");
 EXPORT_SYMBOL(libcfs_panic_on_lbug);
 
 atomic_t libcfs_kmemory = ATOMIC_INIT(0);
@@ -116,9 +116,9 @@ char libcfs_debug_file_path_arr[PATH_MAX] = LIBCFS_DEBUG_FILE_PATH_DEFAULT;
 
 /* We need to pass a pointer here, but elsewhere this must be a const */
 char *libcfs_debug_file_path;
-CFS_MODULE_PARM(libcfs_debug_file_path, "s", charp, 0644,
-               "Path for dumping debug logs, "
-               "set 'NONE' to prevent log dumping");
+module_param(libcfs_debug_file_path, charp, 0644);
+MODULE_PARM_DESC(libcfs_debug_file_path,
+                "Path for dumping debug logs, set 'NONE' to prevent log dumping");
 
 int libcfs_panic_in_progress;
 
index e3e0578b27f91a80ef69914a142a370ee84abe54..85cbe91c29b91c2f9520bd9030076730e686375c 100644 (file)
 
 #if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1
 static unsigned int warn_on_depth = 8;
-CFS_MODULE_PARM(warn_on_depth, "i", uint, 0644,
-               "warning when hash depth is high.");
+module_param(warn_on_depth, uint, 0644);
+MODULE_PARM_DESC(warn_on_depth, "warning when hash depth is high.");
 #endif
 
 struct cfs_wi_sched *cfs_sched_rehash;
index 00ab8fdc1053ccfdda7dcb6441dff57c3ce1f8aa..58bb256ee04728fec585f14395009a3ac6bf63df 100644 (file)
@@ -47,7 +47,8 @@
  * >1 : specify number of partitions
  */
 static int     cpu_npartitions;
-CFS_MODULE_PARM(cpu_npartitions, "i", int, 0444, "# of CPU partitions");
+module_param(cpu_npartitions, int, 0444);
+MODULE_PARM_DESC(cpu_npartitions, "# of CPU partitions");
 
 /**
  * modparam for setting CPU partitions patterns:
@@ -61,7 +62,8 @@ CFS_MODULE_PARM(cpu_npartitions, "i", int, 0444, "# of CPU partitions");
  * NB: If user specified cpu_pattern, cpu_npartitions will be ignored
  */
 static char    *cpu_pattern = "";
-CFS_MODULE_PARM(cpu_pattern, "s", charp, 0444, "CPU partitions pattern");
+module_param(cpu_pattern, charp, 0444);
+MODULE_PARM_DESC(cpu_pattern, "CPU partitions pattern");
 
 struct cfs_cpt_data {
        /* serialize hotplug etc */
index 0bf8e5d87f1ad483035a3f0f93813530da56edc6..a2ef64c3403d90bee1833ad4e5ab955e07c12906 100644 (file)
@@ -140,18 +140,6 @@ int cfs_capable(cfs_cap_t cap)
        return capable(cfs_cap_unpack(cap));
 }
 
-/* Check if task is running in 32-bit API mode, for the purpose of
- * userspace binary interfaces.  On 32-bit Linux this is (unfortunately)
- * always true, even if the application is using LARGEFILE64 and 64-bit
- * APIs, because Linux provides no way for the filesystem to know if it
- * is called via 32-bit or 64-bit APIs.  Other clients may vary.  On
- * 64-bit systems, this will only be true if the binary is calling a
- * 32-bit system call. */
-int current_is_32bit(void)
-{
-       return is_compat_task();
-}
-
 static int cfs_access_process_vm(struct task_struct *tsk, unsigned long addr,
                                 void *buf, int len, int write)
 {
@@ -311,7 +299,6 @@ EXPORT_SYMBOL(cfs_cap_raised);
 EXPORT_SYMBOL(cfs_curproc_cap_pack);
 EXPORT_SYMBOL(cfs_curproc_cap_unpack);
 EXPORT_SYMBOL(cfs_capable);
-EXPORT_SYMBOL(current_is_32bit);
 
 /*
  * Local variables:
index fc6c9774948703bc55eef0e4f477303d8ee18eab..ef0ab106496f6e11e3195b58f5fb4d6796269989 100644 (file)
@@ -371,7 +371,6 @@ static ctl_table_t lnet_table[] = {
         * to go via /proc for portability.
         */
        {
-               INIT_CTL_NAME(PSDEV_DEBUG)
                .procname = "debug",
                .data     = &libcfs_debug,
                .maxlen   = sizeof(int),
@@ -379,7 +378,6 @@ static ctl_table_t lnet_table[] = {
                .proc_handler = &proc_dobitmasks,
        },
        {
-               INIT_CTL_NAME(PSDEV_SUBSYSTEM_DEBUG)
                .procname = "subsystem_debug",
                .data     = &libcfs_subsystem_debug,
                .maxlen   = sizeof(int),
@@ -387,7 +385,6 @@ static ctl_table_t lnet_table[] = {
                .proc_handler = &proc_dobitmasks,
        },
        {
-               INIT_CTL_NAME(PSDEV_PRINTK)
                .procname = "printk",
                .data     = &libcfs_printk,
                .maxlen   = sizeof(int),
@@ -395,7 +392,6 @@ static ctl_table_t lnet_table[] = {
                .proc_handler = &proc_dobitmasks,
        },
        {
-               INIT_CTL_NAME(PSDEV_CONSOLE_RATELIMIT)
                .procname = "console_ratelimit",
                .data     = &libcfs_console_ratelimit,
                .maxlen   = sizeof(int),
@@ -403,21 +399,18 @@ static ctl_table_t lnet_table[] = {
                .proc_handler = &proc_dointvec
        },
        {
-               INIT_CTL_NAME(PSDEV_CONSOLE_MAX_DELAY_CS)
                .procname = "console_max_delay_centisecs",
                .maxlen   = sizeof(int),
                .mode     = 0644,
                .proc_handler = &proc_console_max_delay_cs
        },
        {
-               INIT_CTL_NAME(PSDEV_CONSOLE_MIN_DELAY_CS)
                .procname = "console_min_delay_centisecs",
                .maxlen   = sizeof(int),
                .mode     = 0644,
                .proc_handler = &proc_console_min_delay_cs
        },
        {
-               INIT_CTL_NAME(PSDEV_CONSOLE_BACKOFF)
                .procname = "console_backoff",
                .maxlen   = sizeof(int),
                .mode     = 0644,
@@ -425,7 +418,6 @@ static ctl_table_t lnet_table[] = {
        },
 
        {
-               INIT_CTL_NAME(PSDEV_DEBUG_PATH)
                .procname = "debug_path",
                .data     = libcfs_debug_file_path_arr,
                .maxlen   = sizeof(libcfs_debug_file_path_arr),
@@ -434,7 +426,6 @@ static ctl_table_t lnet_table[] = {
        },
 
        {
-               INIT_CTL_NAME(PSDEV_CPT_TABLE)
                .procname = "cpu_partition_table",
                .maxlen   = 128,
                .mode     = 0444,
@@ -442,7 +433,6 @@ static ctl_table_t lnet_table[] = {
        },
 
        {
-               INIT_CTL_NAME(PSDEV_LNET_UPCALL)
                .procname = "upcall",
                .data     = lnet_upcall,
                .maxlen   = sizeof(lnet_upcall),
@@ -450,7 +440,6 @@ static ctl_table_t lnet_table[] = {
                .proc_handler = &proc_dostring,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_DEBUG_LOG_UPCALL)
                .procname = "debug_log_upcall",
                .data     = lnet_debug_log_upcall,
                .maxlen   = sizeof(lnet_debug_log_upcall),
@@ -458,54 +447,44 @@ static ctl_table_t lnet_table[] = {
                .proc_handler = &proc_dostring,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_MEMUSED)
                .procname = "lnet_memused",
                .data     = (int *)&libcfs_kmemory.counter,
                .maxlen   = sizeof(int),
                .mode     = 0444,
                .proc_handler = &proc_dointvec,
-               INIT_STRATEGY(&sysctl_intvec)
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_CATASTROPHE)
                .procname = "catastrophe",
                .data     = &libcfs_catastrophe,
                .maxlen   = sizeof(int),
                .mode     = 0444,
                .proc_handler = &proc_dointvec,
-               INIT_STRATEGY(&sysctl_intvec)
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_PANIC_ON_LBUG)
                .procname = "panic_on_lbug",
                .data     = &libcfs_panic_on_lbug,
                .maxlen   = sizeof(int),
                .mode     = 0644,
                .proc_handler = &proc_dointvec,
-               INIT_STRATEGY(&sysctl_intvec)
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_DUMP_KERNEL)
                .procname = "dump_kernel",
                .maxlen   = 256,
                .mode     = 0200,
                .proc_handler = &proc_dump_kernel,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_DAEMON_FILE)
                .procname = "daemon_file",
                .mode     = 0644,
                .maxlen   = 256,
                .proc_handler = &proc_daemon_file,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_DEBUG_MB)
                .procname = "debug_mb",
                .mode     = 0644,
                .proc_handler = &proc_debug_mb,
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_WATCHDOG_RATELIMIT)
                .procname = "watchdog_ratelimit",
                .data     = &libcfs_watchdog_ratelimit,
                .maxlen   = sizeof(int),
@@ -514,7 +493,7 @@ static ctl_table_t lnet_table[] = {
                .extra1   = &min_watchdog_ratelimit,
                .extra2   = &max_watchdog_ratelimit,
        },
-       {       INIT_CTL_NAME(PSDEV_LNET_FORCE_LBUG)
+       {
                .procname = "force_lbug",
                .data     = NULL,
                .maxlen   = 0,
@@ -522,7 +501,6 @@ static ctl_table_t lnet_table[] = {
                .proc_handler = &libcfs_force_lbug
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_FAIL_LOC)
                .procname = "fail_loc",
                .data     = &cfs_fail_loc,
                .maxlen   = sizeof(cfs_fail_loc),
@@ -530,7 +508,6 @@ static ctl_table_t lnet_table[] = {
                .proc_handler = &proc_fail_loc
        },
        {
-               INIT_CTL_NAME(PSDEV_LNET_FAIL_VAL)
                .procname = "fail_val",
                .data     = &cfs_fail_val,
                .maxlen   = sizeof(int),
@@ -538,14 +515,12 @@ static ctl_table_t lnet_table[] = {
                .proc_handler = &proc_dointvec
        },
        {
-               INIT_CTL_NAME(0)
        }
 };
 
 #ifdef CONFIG_SYSCTL
 static ctl_table_t top_table[] = {
        {
-               INIT_CTL_NAME(CTL_LNET)
                .procname = "lnet",
                .mode     = 0555,
                .data     = NULL,
@@ -553,7 +528,6 @@ static ctl_table_t top_table[] = {
                .child    = lnet_table,
        },
        {
-               INIT_CTL_NAME(0)
        }
 };
 #endif
diff --git a/drivers/staging/lustre/lustre/libcfs/lwt.c b/drivers/staging/lustre/lustre/libcfs/lwt.c
deleted file mode 100644 (file)
index b631f7d..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/libcfs/lwt.c
- *
- * Author: Eric Barton <eeb@clusterfs.com>
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-#include <linux/libcfs/libcfs.h>
-
-#if LWT_SUPPORT
-
-#if !KLWT_SUPPORT
-int     lwt_enabled;
-lwt_cpu_t   lwt_cpus[NR_CPUS];
-#endif
-
-int     lwt_pages_per_cpu;
-
-/* NB only root is allowed to retrieve LWT info; it's an open door into the
- * kernel... */
-
-int
-lwt_lookup_string (int *size, char *knl_ptr,
-                  char *user_ptr, int user_size)
-{
-       int   maxsize = 128;
-
-       /* knl_ptr was retrieved from an LWT snapshot and the caller wants to
-        * turn it into a string.  NB we can crash with an access violation
-        * trying to determine the string length, so we're trusting our
-        * caller... */
-
-       if (!cfs_capable(CFS_CAP_SYS_ADMIN))
-               return (-EPERM);
-
-       if (user_size > 0 &&
-           maxsize > user_size)
-               maxsize = user_size;
-
-       *size = strnlen (knl_ptr, maxsize - 1) + 1;
-
-       if (user_ptr != NULL) {
-               if (user_size < 4)
-                       return (-EINVAL);
-
-               if (copy_to_user (user_ptr, knl_ptr, *size))
-                       return (-EFAULT);
-
-               /* Did I truncate the string?  */
-               if (knl_ptr[*size - 1] != 0)
-                       copy_to_user (user_ptr + *size - 4, "...", 4);
-       }
-
-       return (0);
-}
-
-int
-lwt_control (int enable, int clear)
-{
-       lwt_page_t  *p;
-       int       i;
-       int       j;
-
-       if (!cfs_capable(CFS_CAP_SYS_ADMIN))
-               return (-EPERM);
-
-       if (!enable) {
-               LWT_EVENT(0,0,0,0);
-               lwt_enabled = 0;
-               mb();
-               /* give people some time to stop adding traces */
-               schedule_timeout(10);
-       }
-
-       for (i = 0; i < num_online_cpus(); i++) {
-               p = lwt_cpus[i].lwtc_current_page;
-
-               if (p == NULL)
-                       return (-ENODATA);
-
-               if (!clear)
-                       continue;
-
-               for (j = 0; j < lwt_pages_per_cpu; j++) {
-                       memset (p->lwtp_events, 0, PAGE_CACHE_SIZE);
-
-                       p = list_entry (p->lwtp_list.next,
-                                           lwt_page_t, lwtp_list);
-               }
-       }
-
-       if (enable) {
-               lwt_enabled = 1;
-               mb();
-               LWT_EVENT(0,0,0,0);
-       }
-
-       return (0);
-}
-
-int
-lwt_snapshot (cfs_cycles_t *now, int *ncpu, int *total_size,
-             void *user_ptr, int user_size)
-{
-       const int    events_per_page = PAGE_CACHE_SIZE / sizeof(lwt_event_t);
-       const int    bytes_per_page = events_per_page * sizeof(lwt_event_t);
-       lwt_page_t  *p;
-       int       i;
-       int       j;
-
-       if (!cfs_capable(CFS_CAP_SYS_ADMIN))
-               return (-EPERM);
-
-       *ncpu = num_online_cpus();
-       *total_size = num_online_cpus() * lwt_pages_per_cpu *
-               bytes_per_page;
-       *now = get_cycles();
-
-       if (user_ptr == NULL)
-               return (0);
-
-       for (i = 0; i < num_online_cpus(); i++) {
-               p = lwt_cpus[i].lwtc_current_page;
-
-               if (p == NULL)
-                       return (-ENODATA);
-
-               for (j = 0; j < lwt_pages_per_cpu; j++) {
-                       if (copy_to_user(user_ptr, p->lwtp_events,
-                                            bytes_per_page))
-                               return (-EFAULT);
-
-                       user_ptr = ((char *)user_ptr) + bytes_per_page;
-                       p = list_entry(p->lwtp_list.next,
-                                          lwt_page_t, lwtp_list);
-               }
-       }
-
-       return (0);
-}
-
-int
-lwt_init ()
-{
-       int     i;
-       int     j;
-
-       for (i = 0; i < num_online_cpus(); i++)
-               if (lwt_cpus[i].lwtc_current_page != NULL)
-                       return (-EALREADY);
-
-       LASSERT (!lwt_enabled);
-
-       /* NULL pointers, zero scalars */
-       memset (lwt_cpus, 0, sizeof (lwt_cpus));
-       lwt_pages_per_cpu =
-               LWT_MEMORY / (num_online_cpus() * PAGE_CACHE_SIZE);
-
-       for (i = 0; i < num_online_cpus(); i++)
-               for (j = 0; j < lwt_pages_per_cpu; j++) {
-                       struct page *page = alloc_page (GFP_KERNEL);
-                       lwt_page_t  *lwtp;
-
-                       if (page == NULL) {
-                               CERROR ("Can't allocate page\n");
-                               lwt_fini ();
-                               return (-ENOMEM);
-                       }
-
-                       LIBCFS_ALLOC(lwtp, sizeof (*lwtp));
-                       if (lwtp == NULL) {
-                               CERROR ("Can't allocate lwtp\n");
-                               __free_page(page);
-                               lwt_fini ();
-                               return (-ENOMEM);
-                       }
-
-                       lwtp->lwtp_page = page;
-                       lwtp->lwtp_events = page_address(page);
-                       memset (lwtp->lwtp_events, 0, PAGE_CACHE_SIZE);
-
-                       if (j == 0) {
-                               INIT_LIST_HEAD (&lwtp->lwtp_list);
-                               lwt_cpus[i].lwtc_current_page = lwtp;
-                       } else {
-                               list_add (&lwtp->lwtp_list,
-                                   &lwt_cpus[i].lwtc_current_page->lwtp_list);
-                       }
-               }
-
-       lwt_enabled = 1;
-       mb();
-
-       LWT_EVENT(0,0,0,0);
-
-       return (0);
-}
-
-void
-lwt_fini ()
-{
-       int    i;
-
-       lwt_control(0, 0);
-
-       for (i = 0; i < num_online_cpus(); i++)
-               while (lwt_cpus[i].lwtc_current_page != NULL) {
-                       lwt_page_t *lwtp = lwt_cpus[i].lwtc_current_page;
-
-                       if (list_empty (&lwtp->lwtp_list)) {
-                               lwt_cpus[i].lwtc_current_page = NULL;
-                       } else {
-                               lwt_cpus[i].lwtc_current_page =
-                                       list_entry (lwtp->lwtp_list.next,
-                                                       lwt_page_t, lwtp_list);
-
-                               list_del (&lwtp->lwtp_list);
-                       }
-
-                       __free_page (lwtp->lwtp_page);
-                       LIBCFS_FREE (lwtp, sizeof (*lwtp));
-               }
-}
-
-EXPORT_SYMBOL(lwt_enabled);
-EXPORT_SYMBOL(lwt_cpus);
-
-EXPORT_SYMBOL(lwt_init);
-EXPORT_SYMBOL(lwt_fini);
-EXPORT_SYMBOL(lwt_lookup_string);
-EXPORT_SYMBOL(lwt_control);
-EXPORT_SYMBOL(lwt_snapshot);
-#endif
index f3108c7f818e93c209d1096fc6f8a789cac349a4..463b3e17e282e4f88735e9d389d43ccbf76c33fa 100644 (file)
@@ -235,41 +235,6 @@ static int libcfs_ioctl_int(struct cfs_psdev_file *pfile,unsigned long cmd,
                        return -EINVAL;
                libcfs_debug_mark_buffer(data->ioc_inlbuf1);
                return 0;
-#if LWT_SUPPORT
-       case IOC_LIBCFS_LWT_CONTROL:
-               err = lwt_control ((data->ioc_flags & 1) != 0,
-                                  (data->ioc_flags & 2) != 0);
-               break;
-
-       case IOC_LIBCFS_LWT_SNAPSHOT: {
-               cfs_cycles_t   now;
-               int         ncpu;
-               int         total_size;
-
-               err = lwt_snapshot (&now, &ncpu, &total_size,
-                                   data->ioc_pbuf1, data->ioc_plen1);
-               data->ioc_u64[0] = now;
-               data->ioc_u32[0] = ncpu;
-               data->ioc_u32[1] = total_size;
-
-               /* Hedge against broken user/kernel typedefs (e.g. cycles_t) */
-               data->ioc_u32[2] = sizeof(lwt_event_t);
-               data->ioc_u32[3] = offsetof(lwt_event_t, lwte_where);
-
-               if (err == 0 &&
-                   libcfs_ioctl_popdata(arg, data, sizeof (*data)))
-                       err = -EFAULT;
-               break;
-       }
-
-       case IOC_LIBCFS_LWT_LOOKUP_STRING:
-               err = lwt_lookup_string (&data->ioc_count, data->ioc_pbuf1,
-                                        data->ioc_pbuf2, data->ioc_plen2);
-               if (err == 0 &&
-                   libcfs_ioctl_popdata(arg, data, sizeof (*data)))
-                       err = -EFAULT;
-               break;
-#endif
        case IOC_LIBCFS_MEMHOG:
                if (pfile->private_data == NULL) {
                        err = -EINVAL;
@@ -392,17 +357,10 @@ static int init_libcfs_module(void)
        if (rc != 0)
                goto cleanup_debug;
 
-#if LWT_SUPPORT
-       rc = lwt_init();
-       if (rc != 0) {
-               CERROR("lwt_init: error %d\n", rc);
-               goto cleanup_debug;
-       }
-#endif
        rc = misc_register(&libcfs_dev);
        if (rc) {
                CERROR("misc_register: error %d\n", rc);
-               goto cleanup_lwt;
+               goto cleanup_cpu;
        }
 
        rc = cfs_wi_startup();
@@ -441,10 +399,8 @@ static int init_libcfs_module(void)
        cfs_wi_shutdown();
  cleanup_deregister:
        misc_deregister(&libcfs_dev);
- cleanup_lwt:
-#if LWT_SUPPORT
-       lwt_fini();
-#endif
+cleanup_cpu:
+       cfs_cpu_fini();
  cleanup_debug:
        libcfs_debug_cleanup();
        return rc;
@@ -471,9 +427,6 @@ static void exit_libcfs_module(void)
        if (rc)
                CERROR("misc_deregister error %d\n", rc);
 
-#if LWT_SUPPORT
-       lwt_fini();
-#endif
        cfs_cpu_fini();
 
        if (atomic_read(&libcfs_kmemory) != 0)
index 99c9e9d2493ffbc67cbbb8d4e13c310487c191a0..732ae5540bf4e163df67c32e0fe1b3d78d45eeeb 100644 (file)
  */
 
 static char      libcfs_nidstrings[LNET_NIDSTR_COUNT][LNET_NIDSTR_SIZE];
-static int       libcfs_nidstring_idx = 0;
+static int       libcfs_nidstring_idx;
 
 static spinlock_t libcfs_nidstring_lock;
 
-void libcfs_init_nidstrings (void)
+void libcfs_init_nidstrings(void)
 {
        spin_lock_init(&libcfs_nidstring_lock);
 }
@@ -69,7 +69,7 @@ void libcfs_init_nidstrings (void)
 # define NIDSTR_UNLOCK(f) spin_unlock_irqrestore(&libcfs_nidstring_lock, f)
 
 static char *
-libcfs_next_nidstring (void)
+libcfs_next_nidstring(void)
 {
        char      *str;
        unsigned long  flags;
@@ -326,6 +326,7 @@ libcfs_isknown_lnd(int type)
 {
        return libcfs_lnd2netstrfns(type) != NULL;
 }
+EXPORT_SYMBOL(libcfs_isknown_lnd);
 
 char *
 libcfs_lnd2modname(int lnd)
@@ -334,6 +335,7 @@ libcfs_lnd2modname(int lnd)
 
        return (nf == NULL) ? NULL : nf->nf_modname;
 }
+EXPORT_SYMBOL(libcfs_lnd2modname);
 
 char *
 libcfs_lnd2str(int lnd)
@@ -348,6 +350,7 @@ libcfs_lnd2str(int lnd)
        snprintf(str, LNET_NIDSTR_SIZE, "?%u?", lnd);
        return str;
 }
+EXPORT_SYMBOL(libcfs_lnd2str);
 
 int
 libcfs_str2lnd(const char *str)
@@ -359,6 +362,7 @@ libcfs_str2lnd(const char *str)
 
        return -1;
 }
+EXPORT_SYMBOL(libcfs_str2lnd);
 
 char *
 libcfs_net2str(__u32 net)
@@ -377,6 +381,7 @@ libcfs_net2str(__u32 net)
 
        return str;
 }
+EXPORT_SYMBOL(libcfs_net2str);
 
 char *
 libcfs_nid2str(lnet_nid_t nid)
@@ -410,6 +415,7 @@ libcfs_nid2str(lnet_nid_t nid)
 
        return str;
 }
+EXPORT_SYMBOL(libcfs_nid2str);
 
 static struct netstrfns *
 libcfs_str2net_internal(const char *str, __u32 *net)
@@ -458,6 +464,7 @@ libcfs_str2net(const char *str)
 
        return LNET_NIDNET(LNET_NID_ANY);
 }
+EXPORT_SYMBOL(libcfs_str2net);
 
 lnet_nid_t
 libcfs_str2nid(const char *str)
@@ -475,7 +482,7 @@ libcfs_str2nid(const char *str)
                sep = str + strlen(str);
                net = LNET_MKNET(SOCKLND, 0);
                nf = libcfs_lnd2netstrfns(SOCKLND);
-               LASSERT (nf != NULL);
+               LASSERT(nf != NULL);
        }
 
        if (!nf->nf_str2addr(str, (int)(sep - str), &addr))
@@ -483,6 +490,7 @@ libcfs_str2nid(const char *str)
 
        return LNET_MKNID(net, addr);
 }
+EXPORT_SYMBOL(libcfs_str2nid);
 
 char *
 libcfs_id2str(lnet_process_id_t id)
@@ -500,6 +508,7 @@ libcfs_id2str(lnet_process_id_t id)
                 (id.pid & ~LNET_PID_USERFLAG), libcfs_nid2str(id.nid));
        return str;
 }
+EXPORT_SYMBOL(libcfs_id2str);
 
 int
 libcfs_str2anynid(lnet_nid_t *nidp, const char *str)
@@ -512,6 +521,7 @@ libcfs_str2anynid(lnet_nid_t *nidp, const char *str)
        *nidp = libcfs_str2nid(str);
        return *nidp != LNET_NID_ANY;
 }
+EXPORT_SYMBOL(libcfs_str2anynid);
 
 /**
  * Nid range list syntax.
@@ -765,6 +775,7 @@ cfs_free_nidlist(struct list_head *list)
                LIBCFS_FREE(nr, sizeof(struct nidrange));
        }
 }
+EXPORT_SYMBOL(cfs_free_nidlist);
 
 /**
  * Parses nid range list.
@@ -803,6 +814,7 @@ cfs_parse_nidlist(char *str, int len, struct list_head *nidlist)
        }
        return 1;
 }
+EXPORT_SYMBOL(cfs_parse_nidlist);
 
 /*
  * Nf_match_addr method for networks using numeric addresses
@@ -848,18 +860,4 @@ int cfs_match_nid(lnet_nid_t nid, struct list_head *nidlist)
        }
        return 0;
 }
-
-
-EXPORT_SYMBOL(libcfs_isknown_lnd);
-EXPORT_SYMBOL(libcfs_lnd2modname);
-EXPORT_SYMBOL(libcfs_lnd2str);
-EXPORT_SYMBOL(libcfs_str2lnd);
-EXPORT_SYMBOL(libcfs_net2str);
-EXPORT_SYMBOL(libcfs_nid2str);
-EXPORT_SYMBOL(libcfs_str2net);
-EXPORT_SYMBOL(libcfs_str2nid);
-EXPORT_SYMBOL(libcfs_id2str);
-EXPORT_SYMBOL(libcfs_str2anynid);
-EXPORT_SYMBOL(cfs_free_nidlist);
-EXPORT_SYMBOL(cfs_parse_nidlist);
 EXPORT_SYMBOL(cfs_match_nid);
index f71a3cc63ad85032226e37630be781d25088bd9d..54290ce6bb438c2257eea9abcdd60410b410651e 100644 (file)
@@ -678,6 +678,7 @@ int cfs_tracefile_dump_all_pages(char *filename)
        struct file             *filp;
        struct cfs_trace_page   *tage;
        struct cfs_trace_page   *tmp;
+       char                    *buf;
        int rc;
 
        DECL_MMSPACE;
@@ -708,8 +709,11 @@ int cfs_tracefile_dump_all_pages(char *filename)
 
                __LASSERT_TAGE_INVARIANT(tage);
 
-               rc = filp_write(filp, page_address(tage->page),
-                               tage->used, filp_poff(filp));
+               buf = kmap(tage->page);
+               rc = vfs_write(filp, (__force const char __user *)buf,
+                              tage->used, &filp->f_pos);
+               kunmap(tage->page);
+
                if (rc != (int)tage->used) {
                        printk(KERN_WARNING "wanted to write %u but wrote "
                               "%d\n", tage->used, rc);
@@ -721,7 +725,7 @@ int cfs_tracefile_dump_all_pages(char *filename)
                cfs_tage_free(tage);
        }
        MMSPACE_CLOSE;
-       rc = filp_fsync(filp);
+       rc = vfs_fsync(filp, 1);
        if (rc)
                printk(KERN_ERR "sync returns %d\n", rc);
 close:
@@ -971,6 +975,7 @@ static int tracefiled(void *arg)
        struct cfs_trace_page *tage;
        struct cfs_trace_page *tmp;
        struct file *filp;
+       char *buf;
        int last_loop = 0;
        int rc;
 
@@ -1020,11 +1025,14 @@ static int tracefiled(void *arg)
 
                        if (f_pos >= (off_t)cfs_tracefile_size)
                                f_pos = 0;
-                       else if (f_pos > (off_t)filp_size(filp))
-                               f_pos = filp_size(filp);
+                       else if (f_pos > i_size_read(filp->f_dentry->d_inode))
+                               f_pos = i_size_read(filp->f_dentry->d_inode);
+
+                       buf = kmap(tage->page);
+                       rc = vfs_write(filp, (__force const char __user *)buf,
+                                      tage->used, &f_pos);
+                       kunmap(tage->page);
 
-                       rc = filp_write(filp, page_address(tage->page),
-                                       tage->used, &f_pos);
                        if (rc != (int)tage->used) {
                                printk(KERN_WARNING "wanted to write %u "
                                       "but wrote %d\n", tage->used, rc);
index fb85a58db058ec3f34cf80065e4b9cdb5e35c05f..f36c5d8dbae0e71796ad2d5dca0e78540d86175c 100644 (file)
@@ -241,6 +241,24 @@ int ll_md_close(struct obd_export *md_exp, struct inode *inode,
        if (unlikely(fd->fd_flags & LL_FILE_GROUP_LOCKED))
                ll_put_grouplock(inode, file, fd->fd_grouplock.cg_gid);
 
+       if (fd->fd_lease_och != NULL) {
+               bool lease_broken;
+
+               /* Usually the lease is not released when the
+                * application crashed, we need to release here. */
+               rc = ll_lease_close(fd->fd_lease_och, inode, &lease_broken);
+               CDEBUG(rc ? D_ERROR : D_INODE, "Clean up lease "DFID" %d/%d\n",
+                       PFID(&lli->lli_fid), rc, lease_broken);
+
+               fd->fd_lease_och = NULL;
+       }
+
+       if (fd->fd_och != NULL) {
+               rc = ll_close_inode_openhandle(md_exp, inode, fd->fd_och);
+               fd->fd_och = NULL;
+               GOTO(out, rc);
+       }
+
        /* Let's see if we have good enough OPEN lock on the file and if
           we can skip talking to MDS */
        if (file->f_dentry->d_inode) { /* Can this ever be false? */
@@ -277,6 +295,7 @@ int ll_md_close(struct obd_export *md_exp, struct inode *inode,
                       file, file->f_dentry, file->f_dentry->d_name.name);
        }
 
+out:
        LUSTRE_FPRIVATE(file) = NULL;
        ll_file_data_put(fd);
        ll_capa_close(inode);
@@ -349,8 +368,6 @@ static int ll_intent_file_open(struct file *file, void *lmm,
 {
        struct ll_sb_info *sbi = ll_i2sbi(file->f_dentry->d_inode);
        struct dentry *parent = file->f_dentry->d_parent;
-       const char *name = file->f_dentry->d_name.name;
-       const int len = file->f_dentry->d_name.len;
        struct md_op_data *op_data;
        struct ptlrpc_request *req;
        __u32 opc = LUSTRE_OPC_ANY;
@@ -375,8 +392,9 @@ static int ll_intent_file_open(struct file *file, void *lmm,
        }
 
        op_data  = ll_prep_md_op_data(NULL, parent->d_inode,
-                                     file->f_dentry->d_inode, name, len,
+                                     file->f_dentry->d_inode, NULL, 0,
                                      O_RDWR, opc, NULL);
+
        if (IS_ERR(op_data))
                return PTR_ERR(op_data);
 
@@ -431,22 +449,18 @@ void ll_ioepoch_open(struct ll_inode_info *lli, __u64 ioepoch)
        }
 }
 
-static int ll_och_fill(struct obd_export *md_exp, struct ll_inode_info *lli,
-                      struct lookup_intent *it, struct obd_client_handle *och)
+static int ll_och_fill(struct obd_export *md_exp, struct lookup_intent *it,
+                      struct obd_client_handle *och)
 {
        struct ptlrpc_request *req = it->d.lustre.it_data;
        struct mdt_body *body;
 
-       LASSERT(och);
-
        body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
-       LASSERT(body != NULL);                /* reply already checked out */
-
-       memcpy(&och->och_fh, &body->handle, sizeof(body->handle));
+       och->och_fh = body->handle;
+       och->och_fid = body->fid1;
+       och->och_lease_handle.cookie = it->d.lustre.it_lock_handle;
        och->och_magic = OBD_CLIENT_HANDLE_MAGIC;
-       och->och_fid = lli->lli_fid;
        och->och_flags = it->it_flags;
-       ll_ioepoch_open(lli, body->ioepoch);
 
        return md_set_open_replay_data(md_exp, och, req);
 }
@@ -466,20 +480,17 @@ int ll_local_open(struct file *file, struct lookup_intent *it,
                struct mdt_body *body;
                int rc;
 
-               rc = ll_och_fill(ll_i2sbi(inode)->ll_md_exp, lli, it, och);
-               if (rc)
+               rc = ll_och_fill(ll_i2sbi(inode)->ll_md_exp, it, och);
+               if (rc != 0)
                        return rc;
 
                body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
-               if ((it->it_flags & FMODE_WRITE) &&
-                   (body->valid & OBD_MD_FLSIZE))
-                       CDEBUG(D_INODE, "Epoch "LPU64" opened on "DFID"\n",
-                              lli->lli_ioepoch, PFID(&lli->lli_fid));
+               ll_ioepoch_open(lli, body->ioepoch);
        }
 
        LUSTRE_FPRIVATE(file) = fd;
        ll_readahead_init(inode, &fd->fd_ras);
-       fd->fd_omode = it->it_flags;
+       fd->fd_omode = it->it_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
        return 0;
 }
 
@@ -681,6 +692,196 @@ out_openerr:
        return rc;
 }
 
+static int ll_md_blocking_lease_ast(struct ldlm_lock *lock,
+                       struct ldlm_lock_desc *desc, void *data, int flag)
+{
+       int rc;
+       struct lustre_handle lockh;
+
+       switch (flag) {
+       case LDLM_CB_BLOCKING:
+               ldlm_lock2handle(lock, &lockh);
+               rc = ldlm_cli_cancel(&lockh, LCF_ASYNC);
+               if (rc < 0) {
+                       CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc);
+                       return rc;
+               }
+               break;
+       case LDLM_CB_CANCELING:
+               /* do nothing */
+               break;
+       }
+       return 0;
+}
+
+/**
+ * Acquire a lease and open the file.
+ */
+struct obd_client_handle *ll_lease_open(struct inode *inode, struct file *file,
+                                       fmode_t fmode)
+{
+       struct lookup_intent it = { .it_op = IT_OPEN };
+       struct ll_sb_info *sbi = ll_i2sbi(inode);
+       struct md_op_data *op_data;
+       struct ptlrpc_request *req;
+       struct lustre_handle old_handle = { 0 };
+       struct obd_client_handle *och = NULL;
+       int rc;
+       int rc2;
+
+       if (fmode != FMODE_WRITE && fmode != FMODE_READ)
+               return ERR_PTR(-EINVAL);
+
+       if (file != NULL) {
+               struct ll_inode_info *lli = ll_i2info(inode);
+               struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+               struct obd_client_handle **och_p;
+               __u64 *och_usecount;
+
+               if (!(fmode & file->f_mode) || (file->f_mode & FMODE_EXEC))
+                       return ERR_PTR(-EPERM);
+
+               /* Get the openhandle of the file */
+               rc = -EBUSY;
+               mutex_lock(&lli->lli_och_mutex);
+               if (fd->fd_lease_och != NULL) {
+                       mutex_unlock(&lli->lli_och_mutex);
+                       return ERR_PTR(rc);
+               }
+
+               if (fd->fd_och == NULL) {
+                       if (file->f_mode & FMODE_WRITE) {
+                               LASSERT(lli->lli_mds_write_och != NULL);
+                               och_p = &lli->lli_mds_write_och;
+                               och_usecount = &lli->lli_open_fd_write_count;
+                       } else {
+                               LASSERT(lli->lli_mds_read_och != NULL);
+                               och_p = &lli->lli_mds_read_och;
+                               och_usecount = &lli->lli_open_fd_read_count;
+                       }
+                       if (*och_usecount == 1) {
+                               fd->fd_och = *och_p;
+                               *och_p = NULL;
+                               *och_usecount = 0;
+                               rc = 0;
+                       }
+               }
+               mutex_unlock(&lli->lli_och_mutex);
+               if (rc < 0) /* more than 1 opener */
+                       return ERR_PTR(rc);
+
+               LASSERT(fd->fd_och != NULL);
+               old_handle = fd->fd_och->och_fh;
+       }
+
+       OBD_ALLOC_PTR(och);
+       if (och == NULL)
+               return ERR_PTR(-ENOMEM);
+
+       op_data = ll_prep_md_op_data(NULL, inode, inode, NULL, 0, 0,
+                                       LUSTRE_OPC_ANY, NULL);
+       if (IS_ERR(op_data))
+               GOTO(out, rc = PTR_ERR(op_data));
+
+       /* To tell the MDT this openhandle is from the same owner */
+       op_data->op_handle = old_handle;
+
+       it.it_flags = fmode | MDS_OPEN_LOCK | MDS_OPEN_BY_FID | MDS_OPEN_LEASE;
+       rc = md_intent_lock(sbi->ll_md_exp, op_data, NULL, 0, &it, 0, &req,
+                               ll_md_blocking_lease_ast,
+       /* LDLM_FL_NO_LRU: To not put the lease lock into LRU list, otherwise
+        * it can be cancelled which may mislead applications that the lease is
+        * broken;
+        * LDLM_FL_EXCL: Set this flag so that it won't be matched by normal
+        * open in ll_md_blocking_ast(). Otherwise as ll_md_blocking_lease_ast
+        * doesn't deal with openhandle, so normal openhandle will be leaked. */
+                               LDLM_FL_NO_LRU | LDLM_FL_EXCL);
+       ll_finish_md_op_data(op_data);
+       if (req != NULL) {
+               ptlrpc_req_finished(req);
+               it_clear_disposition(&it, DISP_ENQ_COMPLETE);
+       }
+       if (rc < 0)
+               GOTO(out_release_it, rc);
+
+       if (it_disposition(&it, DISP_LOOKUP_NEG))
+               GOTO(out_release_it, rc = -ENOENT);
+
+       rc = it_open_error(DISP_OPEN_OPEN, &it);
+       if (rc)
+               GOTO(out_release_it, rc);
+
+       LASSERT(it_disposition(&it, DISP_ENQ_OPEN_REF));
+       ll_och_fill(sbi->ll_md_exp, &it, och);
+
+       if (!it_disposition(&it, DISP_OPEN_LEASE)) /* old server? */
+               GOTO(out_close, rc = -EOPNOTSUPP);
+
+       /* already get lease, handle lease lock */
+       ll_set_lock_data(sbi->ll_md_exp, inode, &it, NULL);
+       if (it.d.lustre.it_lock_mode == 0 ||
+           it.d.lustre.it_lock_bits != MDS_INODELOCK_OPEN) {
+               /* open lock must return for lease */
+               CERROR(DFID "lease granted but no open lock, %d/%llu.\n",
+                       PFID(ll_inode2fid(inode)), it.d.lustre.it_lock_mode,
+                       it.d.lustre.it_lock_bits);
+               GOTO(out_close, rc = -EPROTO);
+       }
+
+       ll_intent_release(&it);
+       return och;
+
+out_close:
+       rc2 = ll_close_inode_openhandle(sbi->ll_md_exp, inode, och);
+       if (rc2)
+               CERROR("Close openhandle returned %d\n", rc2);
+
+       /* cancel open lock */
+       if (it.d.lustre.it_lock_mode != 0) {
+               ldlm_lock_decref_and_cancel(&och->och_lease_handle,
+                                               it.d.lustre.it_lock_mode);
+               it.d.lustre.it_lock_mode = 0;
+       }
+out_release_it:
+       ll_intent_release(&it);
+out:
+       OBD_FREE_PTR(och);
+       return ERR_PTR(rc);
+}
+EXPORT_SYMBOL(ll_lease_open);
+
+/**
+ * Release lease and close the file.
+ * It will check if the lease has ever broken.
+ */
+int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
+                       bool *lease_broken)
+{
+       struct ldlm_lock *lock;
+       bool cancelled = true;
+       int rc;
+
+       lock = ldlm_handle2lock(&och->och_lease_handle);
+       if (lock != NULL) {
+               lock_res_and_lock(lock);
+               cancelled = ldlm_is_cancel(lock);
+               unlock_res_and_lock(lock);
+               ldlm_lock_put(lock);
+       }
+
+       CDEBUG(D_INODE, "lease for "DFID" broken? %d\n",
+               PFID(&ll_i2info(inode)->lli_fid), cancelled);
+
+       if (!cancelled)
+               ldlm_cli_cancel(&och->och_lease_handle, 0);
+       if (lease_broken != NULL)
+               *lease_broken = cancelled;
+
+       rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp, inode, och);
+       return rc;
+}
+EXPORT_SYMBOL(ll_lease_close);
+
 /* Fills the obdo with the attributes for the lsm */
 static int ll_lsm_getattr(struct lov_stripe_md *lsm, struct obd_export *exp,
                          struct obd_capa *capa, struct obdo *obdo,
@@ -905,7 +1106,7 @@ out:
        cl_io_fini(env, io);
        /* If any bit been read/written (result != 0), we just return
         * short read/write instead of restart io. */
-       if (result == 0 && io->ci_need_restart) {
+       if ((result == 0 || result == -ENODATA) && io->ci_need_restart) {
                CDEBUG(D_VFSTRACE, "Restart %s on %s from %lld, count:%zd\n",
                       iot == CIT_READ ? "read" : "write",
                       file->f_dentry->d_name.name, *ppos, count);
@@ -1482,8 +1683,7 @@ int ll_release_openhandle(struct dentry *dentry, struct lookup_intent *it)
        if (!och)
                GOTO(out, rc = -ENOMEM);
 
-       ll_och_fill(ll_i2sbi(inode)->ll_md_exp,
-                   ll_i2info(inode), it, och);
+       ll_och_fill(ll_i2sbi(inode)->ll_md_exp, it, och);
 
        rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp,
                                       inode, och);
@@ -2075,6 +2275,91 @@ long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                OBD_FREE_PTR(hca);
                return rc;
        }
+       case LL_IOC_SET_LEASE: {
+               struct ll_inode_info *lli = ll_i2info(inode);
+               struct obd_client_handle *och = NULL;
+               bool lease_broken;
+               fmode_t mode = 0;
+
+               switch (arg) {
+               case F_WRLCK:
+                       if (!(file->f_mode & FMODE_WRITE))
+                               return -EPERM;
+                       mode = FMODE_WRITE;
+                       break;
+               case F_RDLCK:
+                       if (!(file->f_mode & FMODE_READ))
+                               return -EPERM;
+                       mode = FMODE_READ;
+                       break;
+               case F_UNLCK:
+                       mutex_lock(&lli->lli_och_mutex);
+                       if (fd->fd_lease_och != NULL) {
+                               och = fd->fd_lease_och;
+                               fd->fd_lease_och = NULL;
+                       }
+                       mutex_unlock(&lli->lli_och_mutex);
+
+                       if (och != NULL) {
+                               mode = och->och_flags &
+                                      (FMODE_READ|FMODE_WRITE);
+                               rc = ll_lease_close(och, inode, &lease_broken);
+                               if (rc == 0 && lease_broken)
+                                       mode = 0;
+                       } else {
+                               rc = -ENOLCK;
+                       }
+
+                       /* return the type of lease or error */
+                       return rc < 0 ? rc : (int)mode;
+               default:
+                       return -EINVAL;
+               }
+
+               CDEBUG(D_INODE, "Set lease with mode %d\n", mode);
+
+               /* apply for lease */
+               och = ll_lease_open(inode, file, mode);
+               if (IS_ERR(och))
+                       return PTR_ERR(och);
+
+               rc = 0;
+               mutex_lock(&lli->lli_och_mutex);
+               if (fd->fd_lease_och == NULL) {
+                       fd->fd_lease_och = och;
+                       och = NULL;
+               }
+               mutex_unlock(&lli->lli_och_mutex);
+               if (och != NULL) {
+                       /* impossible now that only excl is supported for now */
+                       ll_lease_close(och, inode, &lease_broken);
+                       rc = -EBUSY;
+               }
+               return rc;
+       }
+       case LL_IOC_GET_LEASE: {
+               struct ll_inode_info *lli = ll_i2info(inode);
+               struct ldlm_lock *lock = NULL;
+
+               rc = 0;
+               mutex_lock(&lli->lli_och_mutex);
+               if (fd->fd_lease_och != NULL) {
+                       struct obd_client_handle *och = fd->fd_lease_och;
+
+                       lock = ldlm_handle2lock(&och->och_lease_handle);
+                       if (lock != NULL) {
+                               lock_res_and_lock(lock);
+                               if (!ldlm_is_cancel(lock))
+                                       rc = och->och_flags &
+                                               (FMODE_READ | FMODE_WRITE);
+                               unlock_res_and_lock(lock);
+                               ldlm_lock_put(lock);
+                       }
+               }
+               mutex_unlock(&lli->lli_och_mutex);
+
+               return rc;
+       }
        default: {
                int err;
 
@@ -2581,7 +2866,15 @@ int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
                LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_lvb.lvb_mtime;
                LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_lvb.lvb_ctime;
        } else {
-               rc = ll_glimpse_size(inode);
+               /* In case of restore, the MDT has the right size and has
+                * already send it back without granting the layout lock,
+                * inode is up-to-date so glimpse is useless.
+                * Also to glimpse we need the layout, in case of a running
+                * restore the MDT holds the layout lock so the glimpse will
+                * block up to the end of restore (getattr will block)
+                */
+               if (!(ll_i2info(inode)->lli_flags & LLIF_FILE_RESTORING))
+                       rc = ll_glimpse_size(inode);
        }
        return rc;
 }
@@ -2628,6 +2921,38 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
        return ll_getattr_it(mnt, de, &it, stat);
 }
 
+int ll_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+               __u64 start, __u64 len)
+{
+       int rc;
+       size_t num_bytes;
+       struct ll_user_fiemap *fiemap;
+       unsigned int extent_count = fieinfo->fi_extents_max;
+
+       num_bytes = sizeof(*fiemap) + (extent_count *
+                                      sizeof(struct ll_fiemap_extent));
+       OBD_ALLOC_LARGE(fiemap, num_bytes);
+
+       if (fiemap == NULL)
+               return -ENOMEM;
+
+       fiemap->fm_flags = fieinfo->fi_flags;
+       fiemap->fm_extent_count = fieinfo->fi_extents_max;
+       fiemap->fm_start = start;
+       fiemap->fm_length = len;
+       memcpy(&fiemap->fm_extents[0], fieinfo->fi_extents_start,
+              sizeof(struct ll_fiemap_extent));
+
+       rc = ll_do_fiemap(inode, fiemap, num_bytes);
+
+       fieinfo->fi_flags = fiemap->fm_flags;
+       fieinfo->fi_extents_mapped = fiemap->fm_mapped_extents;
+       memcpy(fieinfo->fi_extents_start, &fiemap->fm_extents[0],
+              fiemap->fm_mapped_extents * sizeof(struct ll_fiemap_extent));
+
+       OBD_FREE_LARGE(fiemap, num_bytes);
+       return rc;
+}
 
 struct posix_acl * ll_get_acl(struct inode *inode, int type)
 {
@@ -2676,17 +3001,12 @@ int ll_inode_permission(struct inode *inode, int mask)
        return rc;
 }
 
-#define READ_METHOD aio_read
-#define READ_FUNCTION ll_file_aio_read
-#define WRITE_METHOD aio_write
-#define WRITE_FUNCTION ll_file_aio_write
-
 /* -o localflock - only provides locally consistent flock locks */
 struct file_operations ll_file_operations = {
        .read      = ll_file_read,
-       .READ_METHOD    = READ_FUNCTION,
+       .aio_read = ll_file_aio_read,
        .write    = ll_file_write,
-       .WRITE_METHOD   = WRITE_FUNCTION,
+       .aio_write = ll_file_aio_write,
        .unlocked_ioctl = ll_file_ioctl,
        .open      = ll_file_open,
        .release        = ll_file_release,
@@ -2699,9 +3019,9 @@ struct file_operations ll_file_operations = {
 
 struct file_operations ll_file_operations_flock = {
        .read      = ll_file_read,
-       .READ_METHOD    = READ_FUNCTION,
+       .aio_read    = ll_file_aio_read,
        .write    = ll_file_write,
-       .WRITE_METHOD   = WRITE_FUNCTION,
+       .aio_write   = ll_file_aio_write,
        .unlocked_ioctl = ll_file_ioctl,
        .open      = ll_file_open,
        .release        = ll_file_release,
@@ -2717,9 +3037,9 @@ struct file_operations ll_file_operations_flock = {
 /* These are for -o noflock - to return ENOSYS on flock calls */
 struct file_operations ll_file_operations_noflock = {
        .read      = ll_file_read,
-       .READ_METHOD    = READ_FUNCTION,
+       .aio_read    = ll_file_aio_read,
        .write    = ll_file_write,
-       .WRITE_METHOD   = WRITE_FUNCTION,
+       .aio_write   = ll_file_aio_write,
        .unlocked_ioctl = ll_file_ioctl,
        .open      = ll_file_open,
        .release        = ll_file_release,
@@ -2740,6 +3060,7 @@ struct inode_operations ll_file_inode_operations = {
        .getxattr       = ll_getxattr,
        .listxattr      = ll_listxattr,
        .removexattr    = ll_removexattr,
+       .fiemap         = ll_fiemap,
        .get_acl        = ll_get_acl,
 };
 
@@ -3150,3 +3471,30 @@ again:
 
        return rc;
 }
+
+/**
+ *  This function send a restore request to the MDT
+ */
+int ll_layout_restore(struct inode *inode)
+{
+       struct hsm_user_request *hur;
+       int                      len, rc;
+
+       len = sizeof(struct hsm_user_request) +
+             sizeof(struct hsm_user_item);
+       OBD_ALLOC(hur, len);
+       if (hur == NULL)
+               return -ENOMEM;
+
+       hur->hur_request.hr_action = HUA_RESTORE;
+       hur->hur_request.hr_archive_id = 0;
+       hur->hur_request.hr_flags = 0;
+       memcpy(&hur->hur_user_item[0].hui_fid, &ll_i2info(inode)->lli_fid,
+              sizeof(hur->hur_user_item[0].hui_fid));
+       hur->hur_user_item[0].hui_extent.length = -1;
+       hur->hur_request.hr_itemcount = 1;
+       rc = obd_iocontrol(LL_IOC_HSM_REQUEST, cl_i2sbi(inode)->ll_md_exp,
+                          len, hur, NULL);
+       OBD_FREE(hur, len);
+       return rc;
+}
index 47e443d90fe1a56cc955b40e4341a9453e2e6f56..c326ff24410cfe79d9cc1b09d74d6c0789c95846 100644 (file)
@@ -46,6 +46,7 @@
 #include <lclient.h>
 #include <lustre_mdc.h>
 #include <linux/lustre_intent.h>
+#include <linux/compat.h>
 
 #ifndef FMODE_EXEC
 #define FMODE_EXEC 0
@@ -124,6 +125,8 @@ enum lli_flags {
        LLIF_SRVLOCK        = (1 << 5),
        /* File data is modified. */
        LLIF_DATA_MODIFIED      = (1 << 6),
+       /* File is being restored */
+       LLIF_FILE_RESTORING     = (1 << 7),
 };
 
 struct ll_inode_info {
@@ -458,7 +461,7 @@ struct ll_sb_info {
        struct lu_fid        ll_root_fid; /* root object fid */
 
        int                    ll_flags;
-       int                       ll_umounting:1;
+       unsigned int                      ll_umounting:1;
        struct list_head                ll_conn_chain; /* per-conn chain of SBs */
        struct lustre_client_ocd  ll_lco;
 
@@ -607,10 +610,14 @@ extern struct kmem_cache *ll_file_data_slab;
 struct lustre_handle;
 struct ll_file_data {
        struct ll_readahead_state fd_ras;
-       int fd_omode;
        struct ccc_grouplock fd_grouplock;
        __u64 lfd_pos;
        __u32 fd_flags;
+       fmode_t fd_omode;
+       /* openhandle if lease exists for this file.
+        * Borrow lli->lli_och_mutex to protect assignment */
+       struct obd_client_handle *fd_lease_och;
+       struct obd_client_handle *fd_och;
        struct file *fd_file;
        /* Indicate whether need to report failure when close.
         * true: failure is known, not report again.
@@ -643,7 +650,7 @@ static inline int ll_need_32bit_api(struct ll_sb_info *sbi)
 #if BITS_PER_LONG == 32
        return 1;
 #else
-       return unlikely(current_is_32bit() || (sbi->ll_flags & LL_SBI_32BIT_API));
+       return unlikely(is_compat_task() || (sbi->ll_flags & LL_SBI_32BIT_API));
 #endif
 }
 
@@ -776,6 +783,11 @@ int ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg);
 int ll_fid2path(struct inode *inode, void *arg);
 int ll_data_version(struct inode *inode, __u64 *data_version, int extent_lock);
 
+struct obd_client_handle *ll_lease_open(struct inode *inode, struct file *file,
+                                       fmode_t mode);
+int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
+                  bool *lease_broken);
+
 /* llite/dcache.c */
 
 int ll_dops_init(struct dentry *de, int block, int init_sa);
@@ -1578,5 +1590,6 @@ enum {
 
 int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf);
 int ll_layout_refresh(struct inode *inode, __u32 *gen);
+int ll_layout_restore(struct inode *inode);
 
 #endif /* LLITE_INTERNAL_H */
index fd584ff7e2df0e22602347199a1ccfe02544ca41..facc391584475adf007fc72ae2aedd1de522938d 100644 (file)
@@ -1353,6 +1353,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
        struct ll_inode_info *lli = ll_i2info(inode);
        struct md_op_data *op_data = NULL;
        struct md_open_data *mod = NULL;
+       bool file_is_released = false;
        int rc = 0, rc1 = 0;
 
        CDEBUG(D_VFSTRACE, "%s: setattr inode %p/fid:"DFID" from %llu to %llu, "
@@ -1436,10 +1437,40 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
            (attr->ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MTIME_SET)))
                op_data->op_flags = MF_EPOCH_OPEN;
 
+       /* truncate on a released file must failed with -ENODATA,
+        * so size must not be set on MDS for released file
+        * but other attributes must be set
+        */
+       if (S_ISREG(inode->i_mode)) {
+               struct lov_stripe_md *lsm;
+               __u32 gen;
+
+               ll_layout_refresh(inode, &gen);
+               lsm = ccc_inode_lsm_get(inode);
+               if (lsm && lsm->lsm_pattern & LOV_PATTERN_F_RELEASED)
+                       file_is_released = true;
+               ccc_inode_lsm_put(inode, lsm);
+       }
+
+       /* clear size attr for released file
+        * we clear the attribute send to MDT in op_data, not the original
+        * received from caller in attr which is used later to
+        * decide return code */
+       if (file_is_released && (attr->ia_valid & ATTR_SIZE))
+               op_data->op_attr.ia_valid &= ~ATTR_SIZE;
+
        rc = ll_md_setattr(dentry, op_data, &mod);
        if (rc)
                GOTO(out, rc);
 
+       /* truncate failed, others succeed */
+       if (file_is_released) {
+               if (attr->ia_valid & ATTR_SIZE)
+                       GOTO(out, rc = -ENODATA);
+               else
+                       GOTO(out, rc = 0);
+       }
+
        /* RPC to MDT is sent, cancel data modification flag */
        if (rc == 0 && (op_data->op_bias & MDS_DATA_MODIFIED)) {
                spin_lock(&lli->lli_lock);
@@ -1761,6 +1792,11 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
                LASSERT(md->oss_capa);
                ll_add_capa(inode, md->oss_capa);
        }
+
+       if (body->valid & OBD_MD_TSTATE) {
+               if (body->t_state & MS_RESTORE)
+                       lli->lli_flags |= LLIF_FILE_RESTORING;
+       }
 }
 
 void ll_read_inode2(struct inode *inode, void *opaque)
index e2421ea6135292aa37af132259356602770dcb67..0718905adeb256cb2a2dd12336f3dbb7db365d23 100644 (file)
@@ -194,10 +194,10 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head)
        struct cl_object     *obj = ll_i2info(inode)->lli_clob;
        pgoff_t        offset;
        int                ret;
-       int                i;
        int                rw;
        obd_count            page_count = 0;
-       struct bio_vec       *bvec;
+       struct bio_vec       bvec;
+       struct bvec_iter   iter;
        struct bio         *bio;
        ssize_t        bytes;
 
@@ -220,15 +220,15 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head)
        for (bio = head; bio != NULL; bio = bio->bi_next) {
                LASSERT(rw == bio->bi_rw);
 
-               offset = (pgoff_t)(bio->bi_sector << 9) + lo->lo_offset;
-               bio_for_each_segment(bvec, bio, i) {
-                       BUG_ON(bvec->bv_offset != 0);
-                       BUG_ON(bvec->bv_len != PAGE_CACHE_SIZE);
+               offset = (pgoff_t)(bio->bi_iter.bi_sector << 9) + lo->lo_offset;
+               bio_for_each_segment(bvec, bio, iter) {
+                       BUG_ON(bvec.bv_offset != 0);
+                       BUG_ON(bvec.bv_len != PAGE_CACHE_SIZE);
 
-                       pages[page_count] = bvec->bv_page;
+                       pages[page_count] = bvec.bv_page;
                        offsets[page_count] = offset;
                        page_count++;
-                       offset += bvec->bv_len;
+                       offset += bvec.bv_len;
                }
                LASSERT(page_count <= LLOOP_MAX_SEGMENTS);
        }
@@ -313,7 +313,8 @@ static unsigned int loop_get_bio(struct lloop_device *lo, struct bio **req)
        bio = &lo->lo_bio;
        while (*bio && (*bio)->bi_rw == rw) {
                CDEBUG(D_INFO, "bio sector %llu size %u count %u vcnt%u \n",
-                      (unsigned long long)(*bio)->bi_sector, (*bio)->bi_size,
+                      (unsigned long long)(*bio)->bi_iter.bi_sector,
+                      (*bio)->bi_iter.bi_size,
                       page_count, (*bio)->bi_vcnt);
                if (page_count + (*bio)->bi_vcnt > LLOOP_MAX_SEGMENTS)
                        break;
@@ -347,7 +348,8 @@ static void loop_make_request(struct request_queue *q, struct bio *old_bio)
                goto err;
 
        CDEBUG(D_INFO, "submit bio sector %llu size %u\n",
-              (unsigned long long)old_bio->bi_sector, old_bio->bi_size);
+              (unsigned long long)old_bio->bi_iter.bi_sector,
+              old_bio->bi_iter.bi_size);
 
        spin_lock_irq(&lo->lo_lock);
        inactive = (lo->lo_state != LLOOP_BOUND);
@@ -367,7 +369,7 @@ static void loop_make_request(struct request_queue *q, struct bio *old_bio)
        loop_add_bio(lo, old_bio);
        return;
 err:
-       cfs_bio_io_error(old_bio, old_bio->bi_size);
+       cfs_bio_io_error(old_bio, old_bio->bi_iter.bi_size);
 }
 
 
@@ -378,7 +380,7 @@ static inline void loop_handle_bio(struct lloop_device *lo, struct bio *bio)
        while (bio) {
                struct bio *tmp = bio->bi_next;
                bio->bi_next = NULL;
-               cfs_bio_endio(bio, bio->bi_size, ret);
+               cfs_bio_endio(bio, bio->bi_iter.bi_size, ret);
                bio = tmp;
        }
 }
@@ -856,7 +858,8 @@ static void lloop_exit(void)
 module_init(lloop_init);
 module_exit(lloop_exit);
 
-CFS_MODULE_PARM(max_loop, "i", int, 0444, "maximum of lloop_device");
+module_param(max_loop, int, 0444);
+MODULE_PARM_DESC(max_loop, "maximum of lloop_device");
 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
 MODULE_DESCRIPTION("Lustre virtual block device");
 MODULE_LICENSE("GPL");
index 90bbdae824ac522064d89515acbbc89ef6be4300..804451fabfbf39dce069b3159973b9b47274edae 100644 (file)
@@ -233,12 +233,9 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
                        ll_have_md_lock(inode, &bits, mode);
 
                fid = ll_inode2fid(inode);
-               if (lock->l_resource->lr_name.name[0] != fid_seq(fid) ||
-                   lock->l_resource->lr_name.name[1] != fid_oid(fid) ||
-                   lock->l_resource->lr_name.name[2] != fid_ver(fid)) {
+               if (!fid_res_name_eq(fid, &lock->l_resource->lr_name))
                        LDLM_ERROR(lock, "data mismatch with object "
                                   DFID" (%p)", PFID(fid), inode);
-               }
 
                if (bits & MDS_INODELOCK_OPEN) {
                        int flags = 0;
index 3ff664ce7503b62d22b1094d34178125b4075d26..f69e3aa98022645c7527a69e32acd11a1bb6e6c4 100644 (file)
@@ -121,8 +121,38 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
 
        CLOBINVRNT(env, obj, ccc_object_invariant(obj));
 
-       CDEBUG(D_VFSTRACE, "ignore/verify layout %d/%d, layout version %d.\n",
-               io->ci_ignore_layout, io->ci_verify_layout, cio->cui_layout_gen);
+       CDEBUG(D_VFSTRACE, DFID
+              " ignore/verify layout %d/%d, layout version %d restore needed %d\n",
+              PFID(lu_object_fid(&obj->co_lu)),
+              io->ci_ignore_layout, io->ci_verify_layout,
+              cio->cui_layout_gen, io->ci_restore_needed);
+
+       if (io->ci_restore_needed == 1) {
+               int     rc;
+
+               /* file was detected release, we need to restore it
+                * before finishing the io
+                */
+               rc = ll_layout_restore(ccc_object_inode(obj));
+               /* if restore registration failed, no restart,
+                * we will return -ENODATA */
+               /* The layout will change after restore, so we need to
+                * block on layout lock hold by the MDT
+                * as MDT will not send new layout in lvb (see LU-3124)
+                * we have to explicitly fetch it, all this will be done
+                * by ll_layout_refresh()
+                */
+               if (rc == 0) {
+                       io->ci_restore_needed = 0;
+                       io->ci_need_restart = 1;
+                       io->ci_verify_layout = 1;
+               } else {
+                       io->ci_restore_needed = 1;
+                       io->ci_need_restart = 0;
+                       io->ci_verify_layout = 0;
+                       io->ci_result = rc;
+               }
+       }
 
        if (!io->ci_ignore_layout && io->ci_verify_layout) {
                __u32 gen = 0;
@@ -130,9 +160,17 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
                /* check layout version */
                ll_layout_refresh(ccc_object_inode(obj), &gen);
                io->ci_need_restart = cio->cui_layout_gen != gen;
-               if (io->ci_need_restart)
-                       CDEBUG(D_VFSTRACE, "layout changed from %d to %d.\n",
-                               cio->cui_layout_gen, gen);
+               if (io->ci_need_restart) {
+                       CDEBUG(D_VFSTRACE,
+                              DFID" layout changed from %d to %d.\n",
+                              PFID(lu_object_fid(&obj->co_lu)),
+                              cio->cui_layout_gen, gen);
+                       /* today successful restore is the only possible
+                        * case */
+                       /* restore was done, clear restoring state */
+                       ll_i2info(ccc_object_inode(obj))->lli_flags &=
+                               ~LLIF_FILE_RESTORING;
+               }
        }
 }
 
@@ -1111,6 +1149,12 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj,
 
        CLOBINVRNT(env, obj, ccc_object_invariant(obj));
 
+       CDEBUG(D_VFSTRACE, DFID
+              " ignore/verify layout %d/%d, layout version %d restore needed %d\n",
+              PFID(lu_object_fid(&obj->co_lu)),
+              io->ci_ignore_layout, io->ci_verify_layout,
+              cio->cui_layout_gen, io->ci_restore_needed);
+
        CL_IO_SLICE_CLEAN(cio, cui_cl);
        cl_io_slice_add(io, &cio->cui_cl, obj, &vvp_io_ops);
        vio->cui_ra_window_set = 0;
index 2792fa5c4be2fb38dff7fc9b3d2082dbb1476a02..5a6ab70ed0a1a3a4126e836a3b144e4d880bf5d2 100644 (file)
@@ -947,14 +947,23 @@ int lov_io_init_released(const struct lu_env *env, struct cl_object *obj,
                LASSERTF(0, "invalid type %d\n", io->ci_type);
        case CIT_MISC:
        case CIT_FSYNC:
-               result = +1;
+               result = 1;
                break;
        case CIT_SETATTR:
+               /* the truncate to 0 is managed by MDT:
+                * - in open, for open O_TRUNC
+                * - in setattr, for truncate
+                */
+               /* the truncate is for size > 0 so triggers a restore */
+               if (cl_io_is_trunc(io))
+                       io->ci_restore_needed = 1;
+               result = -ENODATA;
+               break;
        case CIT_READ:
        case CIT_WRITE:
        case CIT_FAULT:
-               /* TODO: need to restore the file. */
-               result = -EBADF;
+               io->ci_restore_needed = 1;
+               result = -ENODATA;
                break;
        }
        if (result == 0) {
index ec6f6e0572ae906fd43ce7f3530449cd0e1eee62..27ed27e6fa6a1d9eefbf6a6b2e90af1edaea026b 100644 (file)
@@ -105,24 +105,22 @@ void lov_dump_lmm(int level, void *lmm)
 {
        int magic;
 
-       magic = ((struct lov_mds_md_v1 *)(lmm))->lmm_magic;
+       magic = le32_to_cpu(((struct lov_mds_md *)lmm)->lmm_magic);
        switch (magic) {
        case LOV_MAGIC_V1:
-               return lov_dump_lmm_v1(level, (struct lov_mds_md_v1 *)(lmm));
+               lov_dump_lmm_v1(level, (struct lov_mds_md_v1 *)lmm);
+               break;
        case LOV_MAGIC_V3:
-               return lov_dump_lmm_v3(level, (struct lov_mds_md_v3 *)(lmm));
+               lov_dump_lmm_v3(level, (struct lov_mds_md_v3 *)lmm);
+               break;
        default:
-               CERROR("Cannot recognize lmm_magic %x", magic);
+               CDEBUG(level, "unrecognized lmm_magic %x, assuming %x\n",
+                      magic, LOV_MAGIC_V1);
+               lov_dump_lmm_common(level, lmm);
+               break;
        }
-       return;
 }
 
-#define LMM_ASSERT(test)                                               \
-do {                                                               \
-       if (!(test)) lov_dump_lmm(D_ERROR, lmm);                        \
-       LASSERT(test); /* so we know what assertion failed */      \
-} while (0)
-
 /* Pack LOV object metadata for disk storage.  It is packed in LE byte
  * order and is opaque to the networking layer.
  *
index 15744e13a3f2d34e12edaba88c7491c46b2bde86..e6f22e3a3a388ad9501ed4aadfcd7434cb0f13f2 100644 (file)
@@ -260,29 +260,29 @@ LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesfree);
 LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesavail);
 
 struct lprocfs_vars lprocfs_lov_obd_vars[] = {
-       { "uuid",         &lov_uuid_fops,         0, 0 },
-       { "stripesize",   &lov_stripesize_fops,   0 },
-       { "stripeoffset", &lov_stripeoffset_fops, 0 },
-       { "stripecount",  &lov_stripecount_fops,  0 },
-       { "stripetype",   &lov_stripetype_fops,   0 },
-       { "numobd",       &lov_numobd_fops,       0, 0 },
-       { "activeobd",    &lov_activeobd_fops,    0, 0 },
-       { "filestotal",   &lov_filestotal_fops,   0, 0 },
-       { "filesfree",    &lov_filesfree_fops,    0, 0 },
-       /*{ "filegroups", lprocfs_rd_filegroups,  0, 0 },*/
-       { "blocksize",    &lov_blksize_fops,      0, 0 },
-       { "kbytestotal",  &lov_kbytestotal_fops,  0, 0 },
-       { "kbytesfree",   &lov_kbytesfree_fops,   0, 0 },
-       { "kbytesavail",  &lov_kbytesavail_fops,  0, 0 },
-       { "desc_uuid",    &lov_desc_uuid_fops,    0, 0 },
-       { 0 }
+       { "uuid",         &lov_uuid_fops,         NULL, 0 },
+       { "stripesize",   &lov_stripesize_fops,   NULL },
+       { "stripeoffset", &lov_stripeoffset_fops, NULL },
+       { "stripecount",  &lov_stripecount_fops,  NULL },
+       { "stripetype",   &lov_stripetype_fops,   NULL },
+       { "numobd",       &lov_numobd_fops,       NULL, 0 },
+       { "activeobd",    &lov_activeobd_fops,    NULL, 0 },
+       { "filestotal",   &lov_filestotal_fops,   NULL, 0 },
+       { "filesfree",    &lov_filesfree_fops,    NULL, 0 },
+       /*{ "filegroups", lprocfs_rd_filegroups,  NULL, 0 },*/
+       { "blocksize",    &lov_blksize_fops,      NULL, 0 },
+       { "kbytestotal",  &lov_kbytestotal_fops,  NULL, 0 },
+       { "kbytesfree",   &lov_kbytesfree_fops,   NULL, 0 },
+       { "kbytesavail",  &lov_kbytesavail_fops,  NULL, 0 },
+       { "desc_uuid",    &lov_desc_uuid_fops,    NULL, 0 },
+       { NULL }
 };
 
 LPROC_SEQ_FOPS_RO_TYPE(lov, numrefs);
 
 static struct lprocfs_vars lprocfs_lov_module_vars[] = {
-       { "num_refs",     &lov_numrefs_fops,     0, 0 },
-       { 0 }
+       { "num_refs",     &lov_numrefs_fops,     NULL, 0 },
+       { NULL }
 };
 
 void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars)
diff --git a/drivers/staging/lustre/lustre/lvfs/fsfilt_ext3.c b/drivers/staging/lustre/lustre/lvfs/fsfilt_ext3.c
deleted file mode 100644 (file)
index ee75994..0000000
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lustre/lvfs/fsfilt_ext3.c
- *
- * Author: Andreas Dilger <adilger@clusterfs.com>
- */
-
-#define DEBUG_SUBSYSTEM S_FILTER
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <ldiskfs/ldiskfs_config.h>
-#include <ext4/ext4.h>
-#include <ext4/ext4_jbd2.h>
-#include <linux/bitops.h>
-#include <linux/quota.h>
-
-#include <linux/libcfs/libcfs.h>
-#include <lustre_fsfilt.h>
-#include <obd.h>
-#include <linux/lustre_compat25.h>
-#include <linux/lprocfs_status.h>
-
-#include <ext4/ext4_extents.h>
-
-#ifdef HAVE_EXT_PBLOCK /* Name changed to ext4_ext_pblock for kernel 2.6.35 */
-#define ext3_ext_pblock(ex) ext_pblock((ex))
-#endif
-
-/* for kernels 2.6.18 and later */
-#define FSFILT_SINGLEDATA_TRANS_BLOCKS(sb) EXT3_SINGLEDATA_TRANS_BLOCKS(sb)
-
-#define fsfilt_ext3_ext_insert_extent(handle, inode, path, newext, flag) \
-              ext3_ext_insert_extent(handle, inode, path, newext, flag)
-
-#define ext3_mb_discard_inode_preallocations(inode) \
-                ext3_discard_preallocations(inode)
-
-#define fsfilt_log_start_commit(journal, tid) jbd2_log_start_commit(journal, tid)
-#define fsfilt_log_wait_commit(journal, tid) jbd2_log_wait_commit(journal, tid)
-
-static struct kmem_cache *fcb_cache;
-
-struct fsfilt_cb_data {
-       struct ext4_journal_cb_entry cb_jcb; /* private data - MUST BE FIRST */
-       fsfilt_cb_t cb_func;        /* MDS/OBD completion function */
-       struct obd_device *cb_obd;      /* MDS/OBD completion device */
-       __u64 cb_last_rcvd;          /* MDS/OST last committed operation */
-       void *cb_data;            /* MDS/OST completion function data */
-};
-
-static char *fsfilt_ext3_get_label(struct super_block *sb)
-{
-       return EXT3_SB(sb)->s_es->s_volume_name;
-}
-
-/* kernel has ext4_blocks_for_truncate since linux-3.1.1 */
-# include <ext4/truncate.h>
-
-/*
- * We don't currently need any additional blocks for rmdir and
- * unlink transactions because we are storing the OST oa_id inside
- * the inode (which we will be changing anyways as part of this
- * transaction).
- */
-static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private,
-                              int logs)
-{
-       /* For updates to the last received file */
-       int nblocks = FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb);
-       journal_t *journal;
-       void *handle;
-
-       if (current->journal_info) {
-               CDEBUG(D_INODE, "increasing refcount on %p\n",
-                      current->journal_info);
-               goto journal_start;
-       }
-
-       switch(op) {
-       case FSFILT_OP_UNLINK:
-               /* delete one file + create/update logs for each stripe */
-               nblocks += EXT3_DELETE_TRANS_BLOCKS(inode->i_sb);
-               nblocks += (EXT3_INDEX_EXTRA_TRANS_BLOCKS +
-                           FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb)) * logs;
-               break;
-       case FSFILT_OP_CANCEL_UNLINK:
-               LASSERT(logs == 1);
-
-               /* blocks for log header bitmap update OR
-                * blocks for catalog header bitmap update + unlink of logs +
-                * blocks for delete the inode (include blocks truncating). */
-               nblocks = (LLOG_CHUNK_SIZE >> inode->i_blkbits) +
-                         EXT3_DELETE_TRANS_BLOCKS(inode->i_sb) +
-                         ext4_blocks_for_truncate(inode) + 3;
-               break;
-       default: CERROR("unknown transaction start op %d\n", op);
-               LBUG();
-       }
-
-       LASSERT(current->journal_info == desc_private);
-       journal = EXT3_SB(inode->i_sb)->s_journal;
-       if (nblocks > journal->j_max_transaction_buffers) {
-               CWARN("too many credits %d for op %ux%u using %d instead\n",
-                      nblocks, op, logs, journal->j_max_transaction_buffers);
-               nblocks = journal->j_max_transaction_buffers;
-       }
-
- journal_start:
-       LASSERTF(nblocks > 0, "can't start %d credit transaction\n", nblocks);
-       handle = ext3_journal_start(inode, nblocks);
-
-       if (!IS_ERR(handle))
-               LASSERT(current->journal_info == handle);
-       else
-               CERROR("error starting handle for op %u (%u credits): rc %ld\n",
-                      op, nblocks, PTR_ERR(handle));
-       return handle;
-}
-
-static int fsfilt_ext3_commit(struct inode *inode, void *h, int force_sync)
-{
-       int rc;
-       handle_t *handle = h;
-
-       LASSERT(current->journal_info == handle);
-       if (force_sync)
-               handle->h_sync = 1; /* recovery likes this */
-
-       rc = ext3_journal_stop(handle);
-
-       return rc;
-}
-
-#ifndef EXT3_EXTENTS_FL
-#define EXT3_EXTENTS_FL                 0x00080000 /* Inode uses extents */
-#endif
-
-#ifndef EXT_ASSERT
-#define EXT_ASSERT(cond)  BUG_ON(!(cond))
-#endif
-
-#define EXT_GENERATION(inode)     (EXT4_I(inode)->i_ext_generation)
-#define ext3_ext_base             inode
-#define ext3_ext_base2inode(inode)      (inode)
-#define EXT_DEPTH(inode)               ext_depth(inode)
-#define fsfilt_ext3_ext_walk_space(inode, block, num, cb, cbdata) \
-                       ext3_ext_walk_space(inode, block, num, cb, cbdata);
-
-struct bpointers {
-       unsigned long *blocks;
-       unsigned long start;
-       int num;
-       int init_num;
-       int create;
-};
-
-static long ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path,
-                              unsigned long block, int *aflags)
-{
-       struct ext3_inode_info *ei = EXT3_I(inode);
-       unsigned long bg_start;
-       unsigned long colour;
-       int depth;
-
-       if (path) {
-               struct ext3_extent *ex;
-               depth = path->p_depth;
-
-               /* try to predict block placement */
-               if ((ex = path[depth].p_ext))
-                       return ext4_ext_pblock(ex) + (block - le32_to_cpu(ex->ee_block));
-
-               /* it looks index is empty
-                * try to find starting from index itself */
-               if (path[depth].p_bh)
-                       return path[depth].p_bh->b_blocknr;
-       }
-
-       /* OK. use inode's group */
-       bg_start = (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) +
-               le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block);
-       colour = (current->pid % 16) *
-               (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16);
-       return bg_start + colour + block;
-}
-
-#define ll_unmap_underlying_metadata(sb, blocknr) \
-       unmap_underlying_metadata((sb)->s_bdev, blocknr)
-
-#ifndef EXT3_MB_HINT_GROUP_ALLOC
-static unsigned long new_blocks(handle_t *handle, struct ext3_ext_base *base,
-                               struct ext3_ext_path *path, unsigned long block,
-                               unsigned long *count, int *err)
-{
-       unsigned long pblock, goal;
-       int aflags = 0;
-       struct inode *inode = ext3_ext_base2inode(base);
-
-       goal = ext3_ext_find_goal(inode, path, block, &aflags);
-       aflags |= 2; /* block have been already reserved */
-       pblock = ext3_mb_new_blocks(handle, inode, goal, count, aflags, err);
-       return pblock;
-
-}
-#else
-static unsigned long new_blocks(handle_t *handle, struct ext3_ext_base *base,
-                               struct ext3_ext_path *path, unsigned long block,
-                               unsigned long *count, int *err)
-{
-       struct inode *inode = ext3_ext_base2inode(base);
-       struct ext3_allocation_request ar;
-       unsigned long pblock;
-       int aflags;
-
-       /* find neighbour allocated blocks */
-       ar.lleft = block;
-       *err = ext3_ext_search_left(base, path, &ar.lleft, &ar.pleft);
-       if (*err)
-               return 0;
-       ar.lright = block;
-       *err = ext3_ext_search_right(base, path, &ar.lright, &ar.pright);
-       if (*err)
-               return 0;
-
-       /* allocate new block */
-       ar.goal = ext3_ext_find_goal(inode, path, block, &aflags);
-       ar.inode = inode;
-       ar.logical = block;
-       ar.len = *count;
-       ar.flags = EXT3_MB_HINT_DATA;
-       pblock = ext3_mb_new_blocks(handle, &ar, err);
-       *count = ar.len;
-       return pblock;
-}
-#endif
-
-static int ext3_ext_new_extent_cb(struct ext3_ext_base *base,
-                                 struct ext3_ext_path *path,
-                                 struct ext3_ext_cache *cex,
-#ifdef HAVE_EXT_PREPARE_CB_EXTENT
-                                  struct ext3_extent *ex,
-#endif
-                                 void *cbdata)
-{
-       struct bpointers *bp = cbdata;
-       struct inode *inode = ext3_ext_base2inode(base);
-       struct ext3_extent nex;
-       unsigned long pblock;
-       unsigned long tgen;
-       int err, i;
-       unsigned long count;
-       handle_t *handle;
-
-#ifdef EXT3_EXT_CACHE_EXTENT
-       if (cex->ec_type == EXT3_EXT_CACHE_EXTENT)
-#else
-       if ((cex->ec_len != 0) && (cex->ec_start != 0))
-#endif
-                                                  {
-               err = EXT_CONTINUE;
-               goto map;
-       }
-
-       if (bp->create == 0) {
-               i = 0;
-               if (cex->ec_block < bp->start)
-                       i = bp->start - cex->ec_block;
-               if (i >= cex->ec_len)
-                       CERROR("nothing to do?! i = %d, e_num = %u\n",
-                                       i, cex->ec_len);
-               for (; i < cex->ec_len && bp->num; i++) {
-                       *(bp->blocks) = 0;
-                       bp->blocks++;
-                       bp->num--;
-                       bp->start++;
-               }
-
-               return EXT_CONTINUE;
-       }
-
-       tgen = EXT_GENERATION(base);
-       count = ext3_ext_calc_credits_for_insert(base, path);
-
-       handle = ext3_journal_start(inode, count+EXT3_ALLOC_NEEDED+1);
-       if (IS_ERR(handle)) {
-               return PTR_ERR(handle);
-       }
-
-       if (tgen != EXT_GENERATION(base)) {
-               /* the tree has changed. so path can be invalid at moment */
-               ext3_journal_stop(handle);
-               return EXT_REPEAT;
-       }
-
-       /* In 2.6.32 kernel, ext4_ext_walk_space()'s callback func is not
-        * protected by i_data_sem as whole. so we patch it to store
-        * generation to path and now verify the tree hasn't changed */
-       down_write((&EXT4_I(inode)->i_data_sem));
-
-       /* validate extent, make sure the extent tree does not changed */
-       if (EXT_GENERATION(base) != path[0].p_generation) {
-               /* cex is invalid, try again */
-               up_write(&EXT4_I(inode)->i_data_sem);
-               ext3_journal_stop(handle);
-               return EXT_REPEAT;
-       }
-
-       count = cex->ec_len;
-       pblock = new_blocks(handle, base, path, cex->ec_block, &count, &err);
-       if (!pblock)
-               goto out;
-       EXT_ASSERT(count <= cex->ec_len);
-
-       /* insert new extent */
-       nex.ee_block = cpu_to_le32(cex->ec_block);
-       ext3_ext_store_pblock(&nex, pblock);
-       nex.ee_len = cpu_to_le16(count);
-       err = fsfilt_ext3_ext_insert_extent(handle, base, path, &nex, 0);
-       if (err) {
-               /* free data blocks we just allocated */
-               /* not a good idea to call discard here directly,
-                * but otherwise we'd need to call it every free() */
-#ifdef EXT3_MB_HINT_GROUP_ALLOC
-               ext3_mb_discard_inode_preallocations(inode);
-#endif
-#ifdef HAVE_EXT_FREE_BLOCK_WITH_BUFFER_HEAD /* Introduced in 2.6.32-rc7 */
-               ext3_free_blocks(handle, inode, NULL, ext4_ext_pblock(&nex),
-                                cpu_to_le16(nex.ee_len), 0);
-#else
-               ext3_free_blocks(handle, inode, ext4_ext_pblock(&nex),
-                                cpu_to_le16(nex.ee_len), 0);
-#endif
-               goto out;
-       }
-
-       /*
-        * Putting len of the actual extent we just inserted,
-        * we are asking ext3_ext_walk_space() to continue
-        * scaning after that block
-        */
-       cex->ec_len = le16_to_cpu(nex.ee_len);
-       cex->ec_start = ext4_ext_pblock(&nex);
-       BUG_ON(le16_to_cpu(nex.ee_len) == 0);
-       BUG_ON(le32_to_cpu(nex.ee_block) != cex->ec_block);
-
-out:
-       up_write((&EXT4_I(inode)->i_data_sem));
-       ext3_journal_stop(handle);
-map:
-       if (err >= 0) {
-               /* map blocks */
-               if (bp->num == 0) {
-                       CERROR("hmm. why do we find this extent?\n");
-                       CERROR("initial space: %lu:%u\n",
-                               bp->start, bp->init_num);
-#ifdef EXT3_EXT_CACHE_EXTENT
-                       CERROR("current extent: %u/%u/%llu %d\n",
-                               cex->ec_block, cex->ec_len,
-                               (unsigned long long)cex->ec_start,
-                               cex->ec_type);
-#else
-                       CERROR("current extent: %u/%u/%llu\n",
-                               cex->ec_block, cex->ec_len,
-                               (unsigned long long)cex->ec_start);
-#endif
-               }
-               i = 0;
-               if (cex->ec_block < bp->start)
-                       i = bp->start - cex->ec_block;
-               if (i >= cex->ec_len)
-                       CERROR("nothing to do?! i = %d, e_num = %u\n",
-                                       i, cex->ec_len);
-               for (; i < cex->ec_len && bp->num; i++) {
-                       *(bp->blocks) = cex->ec_start + i;
-#ifdef EXT3_EXT_CACHE_EXTENT
-                       if (cex->ec_type != EXT3_EXT_CACHE_EXTENT)
-#else
-                       if ((cex->ec_len == 0) || (cex->ec_start == 0))
-#endif
-                                                                       {
-                               /* unmap any possible underlying metadata from
-                                * the block device mapping.  bug 6998. */
-                               ll_unmap_underlying_metadata(inode->i_sb,
-                                                            *(bp->blocks));
-                       }
-                       bp->blocks++;
-                       bp->num--;
-                       bp->start++;
-               }
-       }
-       return err;
-}
-
-int fsfilt_map_nblocks(struct inode *inode, unsigned long block,
-                      unsigned long num, unsigned long *blocks,
-                      int create)
-{
-       struct ext3_ext_base *base = inode;
-       struct bpointers bp;
-       int err;
-
-       CDEBUG(D_OTHER, "blocks %lu-%lu requested for inode %u\n",
-              block, block + num - 1, (unsigned) inode->i_ino);
-
-       bp.blocks = blocks;
-       bp.start = block;
-       bp.init_num = bp.num = num;
-       bp.create = create;
-
-       err = fsfilt_ext3_ext_walk_space(base, block, num,
-                                        ext3_ext_new_extent_cb, &bp);
-       ext3_ext_invalidate_cache(base);
-
-       return err;
-}
-
-int fsfilt_ext3_map_ext_inode_pages(struct inode *inode, struct page **page,
-                                   int pages, unsigned long *blocks,
-                                   int create)
-{
-       int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits;
-       int rc = 0, i = 0;
-       struct page *fp = NULL;
-       int clen = 0;
-
-       CDEBUG(D_OTHER, "inode %lu: map %d pages from %lu\n",
-               inode->i_ino, pages, (*page)->index);
-
-       /* pages are sorted already. so, we just have to find
-        * contig. space and process them properly */
-       while (i < pages) {
-               if (fp == NULL) {
-                       /* start new extent */
-                       fp = *page++;
-                       clen = 1;
-                       i++;
-                       continue;
-               } else if (fp->index + clen == (*page)->index) {
-                       /* continue the extent */
-                       page++;
-                       clen++;
-                       i++;
-                       continue;
-               }
-
-               /* process found extent */
-               rc = fsfilt_map_nblocks(inode, fp->index * blocks_per_page,
-                                       clen * blocks_per_page, blocks,
-                                       create);
-               if (rc)
-                       GOTO(cleanup, rc);
-
-               /* look for next extent */
-               fp = NULL;
-               blocks += blocks_per_page * clen;
-       }
-
-       if (fp)
-               rc = fsfilt_map_nblocks(inode, fp->index * blocks_per_page,
-                                       clen * blocks_per_page, blocks,
-                                       create);
-cleanup:
-       return rc;
-}
-
-int fsfilt_ext3_map_bm_inode_pages(struct inode *inode, struct page **page,
-                                  int pages, unsigned long *blocks,
-                                  int create)
-{
-       int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits;
-       unsigned long *b;
-       int rc = 0, i;
-
-       for (i = 0, b = blocks; i < pages; i++, page++) {
-               rc = ext3_map_inode_page(inode, *page, b, create);
-               if (rc) {
-                       CERROR("ino %lu, blk %lu create %d: rc %d\n",
-                              inode->i_ino, *b, create, rc);
-                       break;
-               }
-
-               b += blocks_per_page;
-       }
-       return rc;
-}
-
-int fsfilt_ext3_map_inode_pages(struct inode *inode, struct page **page,
-                               int pages, unsigned long *blocks,
-                               int create, struct mutex *optional_mutex)
-{
-       int rc;
-
-       if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) {
-               rc = fsfilt_ext3_map_ext_inode_pages(inode, page, pages,
-                                                    blocks, create);
-               return rc;
-       }
-       if (optional_mutex != NULL)
-               mutex_lock(optional_mutex);
-       rc = fsfilt_ext3_map_bm_inode_pages(inode, page, pages, blocks, create);
-       if (optional_mutex != NULL)
-               mutex_unlock(optional_mutex);
-
-       return rc;
-}
-
-int fsfilt_ext3_read(struct inode *inode, void *buf, int size, loff_t *offs)
-{
-       unsigned long block;
-       struct buffer_head *bh;
-       int err, blocksize, csize, boffs, osize = size;
-
-       /* prevent reading after eof */
-       spin_lock(&inode->i_lock);
-       if (i_size_read(inode) < *offs + size) {
-               size = i_size_read(inode) - *offs;
-               spin_unlock(&inode->i_lock);
-               if (size < 0) {
-                       CDEBUG(D_EXT2, "size %llu is too short for read @%llu\n",
-                              i_size_read(inode), *offs);
-                       return -EBADR;
-               } else if (size == 0) {
-                       return 0;
-               }
-       } else {
-               spin_unlock(&inode->i_lock);
-       }
-
-       blocksize = 1 << inode->i_blkbits;
-
-       while (size > 0) {
-               block = *offs >> inode->i_blkbits;
-               boffs = *offs & (blocksize - 1);
-               csize = min(blocksize - boffs, size);
-               bh = ext3_bread(NULL, inode, block, 0, &err);
-               if (!bh) {
-                       CERROR("can't read block: %d\n", err);
-                       return err;
-               }
-
-               memcpy(buf, bh->b_data + boffs, csize);
-               brelse(bh);
-
-               *offs += csize;
-               buf += csize;
-               size -= csize;
-       }
-       return osize;
-}
-EXPORT_SYMBOL(fsfilt_ext3_read);
-
-static int fsfilt_ext3_read_record(struct file * file, void *buf,
-                                  int size, loff_t *offs)
-{
-       int rc;
-       rc = fsfilt_ext3_read(file->f_dentry->d_inode, buf, size, offs);
-       if (rc > 0)
-               rc = 0;
-       return rc;
-}
-
-int fsfilt_ext3_write_handle(struct inode *inode, void *buf, int bufsize,
-                               loff_t *offs, handle_t *handle)
-{
-       struct buffer_head *bh = NULL;
-       loff_t old_size = i_size_read(inode), offset = *offs;
-       loff_t new_size = i_size_read(inode);
-       unsigned long block;
-       int err = 0, blocksize = 1 << inode->i_blkbits, size, boffs;
-
-       while (bufsize > 0) {
-               if (bh != NULL)
-                       brelse(bh);
-
-               block = offset >> inode->i_blkbits;
-               boffs = offset & (blocksize - 1);
-               size = min(blocksize - boffs, bufsize);
-               bh = ext3_bread(handle, inode, block, 1, &err);
-               if (!bh) {
-                       CERROR("can't read/create block: %d\n", err);
-                       break;
-               }
-
-               err = ext3_journal_get_write_access(handle, bh);
-               if (err) {
-                       CERROR("journal_get_write_access() returned error %d\n",
-                              err);
-                       break;
-               }
-               LASSERT(bh->b_data + boffs + size <= bh->b_data + bh->b_size);
-               memcpy(bh->b_data + boffs, buf, size);
-               err = ext3_journal_dirty_metadata(handle, bh);
-               if (err) {
-                       CERROR("journal_dirty_metadata() returned error %d\n",
-                              err);
-                       break;
-               }
-               if (offset + size > new_size)
-                       new_size = offset + size;
-               offset += size;
-               bufsize -= size;
-               buf += size;
-       }
-       if (bh)
-               brelse(bh);
-
-       /* correct in-core and on-disk sizes */
-       if (new_size > i_size_read(inode)) {
-               spin_lock(&inode->i_lock);
-               if (new_size > i_size_read(inode))
-                       i_size_write(inode, new_size);
-               if (i_size_read(inode) > EXT3_I(inode)->i_disksize)
-                       EXT3_I(inode)->i_disksize = i_size_read(inode);
-               if (i_size_read(inode) > old_size) {
-                       spin_unlock(&inode->i_lock);
-                       mark_inode_dirty(inode);
-               } else {
-                       spin_unlock(&inode->i_lock);
-               }
-       }
-
-       if (err == 0)
-               *offs = offset;
-       return err;
-}
-EXPORT_SYMBOL(fsfilt_ext3_write_handle);
-
-static int fsfilt_ext3_write_record(struct file *file, void *buf, int bufsize,
-                                   loff_t *offs, int force_sync)
-{
-       struct inode *inode = file->f_dentry->d_inode;
-       handle_t *handle;
-       int err, block_count = 0, blocksize;
-
-       /* Determine how many transaction credits are needed */
-       blocksize = 1 << inode->i_blkbits;
-       block_count = (*offs & (blocksize - 1)) + bufsize;
-       block_count = (block_count + blocksize - 1) >> inode->i_blkbits;
-
-       handle = ext3_journal_start(inode,
-                       block_count * EXT3_DATA_TRANS_BLOCKS(inode->i_sb) + 2);
-       if (IS_ERR(handle)) {
-               CERROR("can't start transaction for %d blocks (%d bytes)\n",
-                      block_count * EXT3_DATA_TRANS_BLOCKS(inode->i_sb) + 2,
-                      bufsize);
-               return PTR_ERR(handle);
-       }
-
-       err = fsfilt_ext3_write_handle(inode, buf, bufsize, offs, handle);
-
-       if (!err && force_sync)
-               handle->h_sync = 1; /* recovery likes this */
-
-       ext3_journal_stop(handle);
-
-       return err;
-}
-
-static int fsfilt_ext3_setup(struct super_block *sb)
-{
-       if (!EXT3_HAS_COMPAT_FEATURE(sb,
-                               EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
-               CERROR("ext3 mounted without journal\n");
-               return -EINVAL;
-       }
-
-#ifdef S_PDIROPS
-       CWARN("Enabling PDIROPS\n");
-       set_opt(EXT3_SB(sb)->s_mount_opt, PDIROPS);
-       sb->s_flags |= S_PDIROPS;
-#endif
-       if (!EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
-               CWARN("filesystem doesn't have dir_index feature enabled\n");
-       return 0;
-}
-static struct fsfilt_operations fsfilt_ext3_ops = {
-       .fs_type                = "ext3",
-       .fs_owner              = THIS_MODULE,
-       .fs_getlabel        = fsfilt_ext3_get_label,
-       .fs_start              = fsfilt_ext3_start,
-       .fs_commit            = fsfilt_ext3_commit,
-       .fs_map_inode_pages     = fsfilt_ext3_map_inode_pages,
-       .fs_write_record        = fsfilt_ext3_write_record,
-       .fs_read_record  = fsfilt_ext3_read_record,
-       .fs_setup              = fsfilt_ext3_setup,
-};
-
-static int __init fsfilt_ext3_init(void)
-{
-       int rc;
-
-       fcb_cache = kmem_cache_create("fsfilt_ext3_fcb",
-                                        sizeof(struct fsfilt_cb_data), 0, 0);
-       if (!fcb_cache) {
-               CERROR("error allocating fsfilt journal callback cache\n");
-               GOTO(out, rc = -ENOMEM);
-       }
-
-       rc = fsfilt_register_ops(&fsfilt_ext3_ops);
-
-       if (rc) {
-               int err = kmem_cache_destroy(fcb_cache);
-               LASSERTF(err == 0, "error destroying new cache: rc %d\n", err);
-       }
-out:
-       return rc;
-}
-
-static void __exit fsfilt_ext3_exit(void)
-{
-       int rc;
-
-       fsfilt_unregister_ops(&fsfilt_ext3_ops);
-       rc = kmem_cache_destroy(fcb_cache);
-       LASSERTF(rc == 0, "couldn't destroy fcb_cache slab\n");
-}
-
-module_init(fsfilt_ext3_init);
-module_exit(fsfilt_ext3_exit);
-
-MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
-MODULE_DESCRIPTION("Lustre ext3 Filesystem Helper v0.1");
-MODULE_LICENSE("GPL");
index 2aeff0ecec34d662146a842dbf1986da5083f155..b995af6a2782cb4343e042e7ef59e93a07ae502a 100644 (file)
@@ -69,7 +69,7 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
                     const void *data, int datalen, __u32 mode, __u32 uid,
                     __u32 gid, cfs_cap_t capability, __u64 rdev);
 void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
-                  __u32 mode, __u64 rdev, __u32 flags, const void *data,
+                  __u32 mode, __u64 rdev, __u64 flags, const void *data,
                   int datalen);
 void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data);
 void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data);
index b2de478036795a2b4c3607b474ab5ff397726218..3e7702075bf9a75b5664e5ffeffa78e1eaca90ee 100644 (file)
@@ -174,12 +174,12 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
        }
 }
 
-static __u64 mds_pack_open_flags(__u32 flags, __u32 mode)
+static __u64 mds_pack_open_flags(__u64 flags, __u32 mode)
 {
        __u64 cr_flags = (flags & (FMODE_READ | FMODE_WRITE |
                                   MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS |
                                   MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK |
-                                  MDS_OPEN_BY_FID));
+                                  MDS_OPEN_BY_FID | MDS_OPEN_LEASE));
        if (flags & O_CREAT)
                cr_flags |= MDS_OPEN_CREAT;
        if (flags & O_EXCL)
@@ -207,7 +207,7 @@ static __u64 mds_pack_open_flags(__u32 flags, __u32 mode)
 
 /* packing of MDS records */
 void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
-                  __u32 mode, __u64 rdev, __u32 flags, const void *lmm,
+                  __u32 mode, __u64 rdev, __u64 flags, const void *lmm,
                   int lmmlen)
 {
        struct mdt_rec_create *rec;
@@ -234,6 +234,7 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
        rec->cr_suppgid2 = op_data->op_suppgids[1];
        rec->cr_bias     = op_data->op_bias;
        rec->cr_umask    = current_umask();
+       rec->cr_old_handle = op_data->op_handle;
 
        mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
        /* the next buffer is child capa, which is used for replay,
index fb5a9959bf7ac652880a6d16448310cbeef22cd7..09dee1120ed24d6f5bd03df9c923127f935fae3a 100644 (file)
@@ -75,6 +75,12 @@ EXPORT_SYMBOL(it_clear_disposition);
 
 int it_open_error(int phase, struct lookup_intent *it)
 {
+       if (it_disposition(it, DISP_OPEN_LEASE)) {
+               if (phase >= DISP_OPEN_LEASE)
+                       return it->d.lustre.it_status;
+               else
+                       return 0;
+       }
        if (it_disposition(it, DISP_OPEN_OPEN)) {
                if (phase >= DISP_OPEN_OPEN)
                        return it->d.lustre.it_status;
@@ -281,14 +287,21 @@ static struct ptlrpc_request *mdc_intent_open_pack(struct obd_export *exp,
        /* XXX: openlock is not cancelled for cross-refs. */
        /* If inode is known, cancel conflicting OPEN locks. */
        if (fid_is_sane(&op_data->op_fid2)) {
-               if (it->it_flags & (FMODE_WRITE|MDS_OPEN_TRUNC))
-                       mode = LCK_CW;
+               if (it->it_flags & MDS_OPEN_LEASE) { /* try to get lease */
+                       if (it->it_flags & FMODE_WRITE)
+                               mode = LCK_EX;
+                       else
+                               mode = LCK_PR;
+               } else {
+                       if (it->it_flags & (FMODE_WRITE|MDS_OPEN_TRUNC))
+                               mode = LCK_CW;
 #ifdef FMODE_EXEC
-               else if (it->it_flags & FMODE_EXEC)
-                       mode = LCK_PR;
+                       else if (it->it_flags & FMODE_EXEC)
+                               mode = LCK_PR;
 #endif
-               else
-                       mode = LCK_CR;
+                       else
+                               mode = LCK_CR;
+               }
                count = mdc_resource_get_unused(exp, &op_data->op_fid2,
                                                &cancels, mode,
                                                MDS_INODELOCK_OPEN);
@@ -958,13 +971,8 @@ static int mdc_finish_intent_lock(struct obd_export *exp,
 
                LASSERTF(fid_res_name_eq(&mdt_body->fid1,
                                         &lock->l_resource->lr_name),
-                        "Lock res_id: %lu/%lu/%lu, fid: %lu/%lu/%lu.\n",
-                        (unsigned long)lock->l_resource->lr_name.name[0],
-                        (unsigned long)lock->l_resource->lr_name.name[1],
-                        (unsigned long)lock->l_resource->lr_name.name[2],
-                        (unsigned long)fid_seq(&mdt_body->fid1),
-                        (unsigned long)fid_oid(&mdt_body->fid1),
-                        (unsigned long)fid_ver(&mdt_body->fid1));
+                        "Lock res_id: "DLDLMRES", fid: "DFID"\n",
+                        PLDLMRES(lock->l_resource), PFID(&mdt_body->fid1));
                LDLM_LOCK_PUT(lock);
 
                memcpy(&old_lock, lockh, sizeof(*lockh));
@@ -1065,10 +1073,10 @@ int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
        LASSERT(it);
 
        CDEBUG(D_DLMTRACE, "(name: %.*s,"DFID") in obj "DFID
-              ", intent: %s flags %#o\n", op_data->op_namelen,
-              op_data->op_name, PFID(&op_data->op_fid2),
-              PFID(&op_data->op_fid1), ldlm_it2str(it->it_op),
-              it->it_flags);
+               ", intent: %s flags %#Lo\n", op_data->op_namelen,
+               op_data->op_name, PFID(&op_data->op_fid2),
+               PFID(&op_data->op_fid1), ldlm_it2str(it->it_op),
+               it->it_flags);
 
        lockh.cookie = 0;
        if (fid_is_sane(&op_data->op_fid2) &&
@@ -1194,9 +1202,10 @@ int mdc_intent_getattr_async(struct obd_export *exp,
        int                   rc = 0;
        __u64               flags = LDLM_FL_HAS_INTENT;
 
-       CDEBUG(D_DLMTRACE,"name: %.*s in inode "DFID", intent: %s flags %#o\n",
-              op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1),
-              ldlm_it2str(it->it_op), it->it_flags);
+       CDEBUG(D_DLMTRACE,
+               "name: %.*s in inode "DFID", intent: %s flags %#Lo\n",
+               op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1),
+               ldlm_it2str(it->it_op), it->it_flags);
 
        fid_build_reg_res_name(&op_data->op_fid1, &res_id);
        req = mdc_intent_getattr_pack(exp, it, op_data);
index ed3a7a05557f31c877b4d4f5baa99f835121097d..8373778c2e780fbb914fc450b80f3aab594ee5de 100644 (file)
@@ -1743,6 +1743,7 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                GOTO(out, rc);
        case LL_IOC_HSM_STATE_SET:
                rc = mdc_ioc_hsm_state_set(exp, karg);
+               GOTO(out, rc);
        case LL_IOC_HSM_ACTION:
                rc = mdc_ioc_hsm_current_action(exp, karg);
                GOTO(out, rc);
@@ -1814,8 +1815,8 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                struct obd_quotactl *oqctl;
 
                OBD_ALLOC_PTR(oqctl);
-               if (!oqctl)
-                       return -ENOMEM;
+               if (oqctl == NULL)
+                       GOTO(out, rc = -ENOMEM);
 
                QCTL_COPY(oqctl, qctl);
                rc = obd_quotactl(exp, oqctl);
@@ -1824,23 +1825,21 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                        qctl->qc_valid = QC_MDTIDX;
                        qctl->obd_uuid = obd->u.cli.cl_target_uuid;
                }
+
                OBD_FREE_PTR(oqctl);
-               break;
+               GOTO(out, rc);
        }
-       case LL_IOC_GET_CONNECT_FLAGS: {
-               if (copy_to_user(uarg,
-                                    exp_connect_flags_ptr(exp),
-                                    sizeof(__u64)))
+       case LL_IOC_GET_CONNECT_FLAGS:
+               if (copy_to_user(uarg, exp_connect_flags_ptr(exp),
+                                sizeof(*exp_connect_flags_ptr(exp))))
                        GOTO(out, rc = -EFAULT);
-               else
-                       GOTO(out, rc = 0);
-       }
-       case LL_IOC_LOV_SWAP_LAYOUTS: {
+
+               GOTO(out, rc = 0);
+       case LL_IOC_LOV_SWAP_LAYOUTS:
                rc = mdc_ioc_swap_layouts(exp, karg);
-               break;
-       }
+               GOTO(out, rc);
        default:
-               CERROR("mdc_ioctl(): unrecognised ioctl %#x\n", cmd);
+               CERROR("unrecognised ioctl: cmd = %#x\n", cmd);
                GOTO(out, rc = -ENOTTY);
        }
 out:
@@ -1920,10 +1919,8 @@ static void lustre_swab_hal(struct hsm_action_list *h)
        __swab32s(&h->hal_archive_id);
        __swab64s(&h->hal_flags);
        hai = hai_zero(h);
-       for (i = 0; i < h->hal_count; i++) {
+       for (i = 0; i < h->hal_count; i++, hai = hai_next(hai))
                lustre_swab_hai(hai);
-               hai = hai_next(hai);
-       }
 }
 
 static void lustre_swab_kuch(struct kuc_hdr *l)
index 12a9ede21a8565a77e4e5f07c43041f35d4025f0..93b601d1ff38f6218a933274b944fe421d1486c0 100644 (file)
@@ -788,8 +788,8 @@ static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
                /* We've given up the lock, prepare ourselves to update. */
                LDLM_DEBUG(lock, "MGC cancel CB");
 
-               CDEBUG(D_MGC, "Lock res "LPX64" (%.8s)\n",
-                      lock->l_resource->lr_name.name[0],
+               CDEBUG(D_MGC, "Lock res "DLDLMRES" (%.8s)\n",
+                      PLDLMRES(lock->l_resource),
                       (char *)&lock->l_resource->lr_name.name[0]);
 
                if (!cld) {
index acd2619227dfcf905c861500037f1b110aa61caa..c1ef0c9b5a1aae9af7c0901b8ad537fcec93c865 100644 (file)
@@ -282,7 +282,6 @@ int LL_PROC_PROTO(proc_at_history)
 #ifdef CONFIG_SYSCTL
 static ctl_table_t obd_table[] = {
        {
-               INIT_CTL_NAME(OBD_TIMEOUT)
                .procname = "timeout",
                .data     = &obd_timeout,
                .maxlen   = sizeof(int),
@@ -290,7 +289,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_set_timeout
        },
        {
-               INIT_CTL_NAME(OBD_DEBUG_PEER_ON_TIMEOUT)
                .procname = "debug_peer_on_timeout",
                .data     = &obd_debug_peer_on_timeout,
                .maxlen   = sizeof(int),
@@ -298,7 +296,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_dointvec
        },
        {
-               INIT_CTL_NAME(OBD_DUMP_ON_TIMEOUT)
                .procname = "dump_on_timeout",
                .data     = &obd_dump_on_timeout,
                .maxlen   = sizeof(int),
@@ -306,7 +303,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_dointvec
        },
        {
-               INIT_CTL_NAME(OBD_DUMP_ON_EVICTION)
                .procname = "dump_on_eviction",
                .data     = &obd_dump_on_eviction,
                .maxlen   = sizeof(int),
@@ -314,7 +310,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_dointvec
        },
        {
-               INIT_CTL_NAME(OBD_MEMUSED)
                .procname = "memused",
                .data     = NULL,
                .maxlen   = 0,
@@ -322,7 +317,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_memory_alloc
        },
        {
-               INIT_CTL_NAME(OBD_PAGESUSED)
                .procname = "pagesused",
                .data     = NULL,
                .maxlen   = 0,
@@ -330,7 +324,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_pages_alloc
        },
        {
-               INIT_CTL_NAME(OBD_MAXMEMUSED)
                .procname = "memused_max",
                .data     = NULL,
                .maxlen   = 0,
@@ -338,7 +331,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_mem_max
        },
        {
-               INIT_CTL_NAME(OBD_MAXPAGESUSED)
                .procname = "pagesused_max",
                .data     = NULL,
                .maxlen   = 0,
@@ -346,7 +338,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_pages_max
        },
        {
-               INIT_CTL_NAME(OBD_LDLM_TIMEOUT)
                .procname = "ldlm_timeout",
                .data     = &ldlm_timeout,
                .maxlen   = sizeof(int),
@@ -354,7 +345,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_set_timeout
        },
        {
-               INIT_CTL_NAME(OBD_ALLOC_FAIL_RATE)
                .procname = "alloc_fail_rate",
                .data     = &obd_alloc_fail_rate,
                .maxlen   = sizeof(int),
@@ -362,7 +352,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_alloc_fail_rate
        },
        {
-               INIT_CTL_NAME(OBD_MAX_DIRTY_PAGES)
                .procname = "max_dirty_mb",
                .data     = &obd_max_dirty_pages,
                .maxlen   = sizeof(int),
@@ -370,7 +359,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_max_dirty_pages_in_mb
        },
        {
-               INIT_CTL_NAME(OBD_AT_MIN)
                .procname = "at_min",
                .data     = &at_min,
                .maxlen   = sizeof(int),
@@ -378,7 +366,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_at_min
        },
        {
-               INIT_CTL_NAME(OBD_AT_MAX)
                .procname = "at_max",
                .data     = &at_max,
                .maxlen   = sizeof(int),
@@ -386,7 +373,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_at_max
        },
        {
-               INIT_CTL_NAME(OBD_AT_EXTRA)
                .procname = "at_extra",
                .data     = &at_extra,
                .maxlen   = sizeof(int),
@@ -394,7 +380,6 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_at_extra
        },
        {
-               INIT_CTL_NAME(OBD_AT_EARLY_MARGIN)
                .procname = "at_early_margin",
                .data     = &at_early_margin,
                .maxlen   = sizeof(int),
@@ -402,26 +387,24 @@ static ctl_table_t obd_table[] = {
                .proc_handler = &proc_at_early_margin
        },
        {
-               INIT_CTL_NAME(OBD_AT_HISTORY)
                .procname = "at_history",
                .data     = &at_history,
                .maxlen   = sizeof(int),
                .mode     = 0644,
                .proc_handler = &proc_at_history
        },
-       {       INIT_CTL_NAME(0)    }
+       {}
 };
 
 static ctl_table_t parent_table[] = {
        {
-               INIT_CTL_NAME(OBD_SYSCTL)
                .procname = "lustre",
                .data     = NULL,
                .maxlen   = 0,
                .mode     = 0555,
                .child    = obd_table
        },
-       {       INIT_CTL_NAME(0)   }
+       {}
 };
 #endif
 
index 0cb44287502b712ebe6ab6a9258790408deb4b3d..b4dad344b72a857a21ceda8efdfe673a854ad9c6 100644 (file)
@@ -62,7 +62,7 @@ struct llog_handle *llog_alloc_handle(void)
 
        OBD_ALLOC_PTR(loghandle);
        if (loghandle == NULL)
-               return ERR_PTR(-ENOMEM);
+               return NULL;
 
        init_rwsem(&loghandle->lgh_lock);
        spin_lock_init(&loghandle->lgh_hdr_lock);
index cc19fbab0207cb3070f6a33e6766894050218586..51ab7f4130041d378747c49713362d07517474c5 100644 (file)
@@ -246,7 +246,7 @@ int local_object_create(const struct lu_env *env,
                        struct dt_object_format *dof, struct thandle *th)
 {
        struct dt_thread_info   *dti = dt_info(env);
-       obd_id                   lastid;
+       __le64                   lastid;
        int                      rc;
 
        rc = dt_create(env, o, attr, NULL, dof, th);
index 02d76f8dbcb9b58da43d253433c69099d3b073b4..0f0750beab3b168bb21dd17151848b6fbdb1c9fb 100644 (file)
@@ -49,8 +49,8 @@
 #if defined(LPROCFS)
 
 static int lprocfs_no_percpu_stats = 0;
-CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
-               "Do not alloc percpu data for lprocfs stats");
+module_param(lprocfs_no_percpu_stats, int, 0644);
+MODULE_PARM_DESC(lprocfs_no_percpu_stats, "Do not alloc percpu data for lprocfs stats");
 
 #define MAX_STRING_SIZE 128
 
index 212823ab937b759f6dbe7537e4e4a45d100d00e5..1d6754bbace71a41ddd4bca8250c2fb7ac308a25 100644 (file)
@@ -200,6 +200,8 @@ static struct lu_object *lu_object_alloc(const struct lu_env *env,
        struct lu_object *scan;
        struct lu_object *top;
        struct list_head *layers;
+       unsigned int init_mask = 0;
+       unsigned int init_flag;
        int clean;
        int result;
 
@@ -218,15 +220,17 @@ static struct lu_object *lu_object_alloc(const struct lu_env *env,
         */
        top->lo_header->loh_fid = *f;
        layers = &top->lo_header->loh_layers;
+
        do {
                /*
                 * Call ->loo_object_init() repeatedly, until no more new
                 * object slices are created.
                 */
                clean = 1;
+               init_flag = 1;
                list_for_each_entry(scan, layers, lo_linkage) {
-                       if (scan->lo_flags & LU_OBJECT_ALLOCATED)
-                               continue;
+                       if (init_mask & init_flag)
+                               goto next;
                        clean = 0;
                        scan->lo_header = top->lo_header;
                        result = scan->lo_ops->loo_object_init(env, scan, conf);
@@ -234,7 +238,9 @@ static struct lu_object *lu_object_alloc(const struct lu_env *env,
                                lu_object_free(env, top);
                                return ERR_PTR(result);
                        }
-                       scan->lo_flags |= LU_OBJECT_ALLOCATED;
+                       init_mask |= init_flag;
+next:
+                       init_flag <<= 1;
                }
        } while (!clean);
 
@@ -487,23 +493,25 @@ void lu_object_print(const struct lu_env *env, void *cookie,
 {
        static const char ruler[] = "........................................";
        struct lu_object_header *top;
-       int depth;
+       int depth = 4;
 
        top = o->lo_header;
        lu_object_header_print(env, cookie, printer, top);
-       (*printer)(env, cookie, "{ \n");
-       list_for_each_entry(o, &top->loh_layers, lo_linkage) {
-               depth = o->lo_depth + 4;
+       (*printer)(env, cookie, "{\n");
 
+       list_for_each_entry(o, &top->loh_layers, lo_linkage) {
                /*
                 * print `.' \a depth times followed by type name and address
                 */
                (*printer)(env, cookie, "%*.*s%s@%p", depth, depth, ruler,
                           o->lo_dev->ld_type->ldt_name, o);
+
                if (o->lo_ops->loo_object_print != NULL)
-                       o->lo_ops->loo_object_print(env, cookie, printer, o);
+                       (*o->lo_ops->loo_object_print)(env, cookie, printer, o);
+
                (*printer)(env, cookie, "\n");
        }
+
        (*printer)(env, cookie, "} header@%p\n", top);
 }
 EXPORT_SYMBOL(lu_object_print);
@@ -830,8 +838,8 @@ enum {
 };
 
 static unsigned int lu_cache_percent = LU_CACHE_PERCENT_DEFAULT;
-CFS_MODULE_PARM(lu_cache_percent, "i", int, 0644,
-               "Percentage of memory to be used as lu_object cache");
+module_param(lu_cache_percent, int, 0644);
+MODULE_PARM_DESC(lu_cache_percent, "Percentage of memory to be used as lu_object cache");
 
 /**
  * Return desired hash table order.
index 1fb0ac4e920d58136163b7bd244fe782ecdc493a..9b2dea29236380ed8796cff1ffb1e8a2568cbfe4 100644 (file)
@@ -1106,7 +1106,7 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d,
        /* coverity[overrun-buffer-val] */
        obj = cl_object_find(env, echo_dev2cl(d), fid, &conf->eoc_cl);
        if (IS_ERR(obj))
-               GOTO(out, eco = (void*)obj);
+               GOTO(out, eco = (void *)obj);
 
        eco = cl2echo_obj(obj);
        if (eco->eo_deleted) {
index cb197782d9a3378c0060a21614a8a5fda06be166..c837a0d71e0f2bc5b193c2a4fa4902f0429ae742 100644 (file)
 #include <obd_ost.h>
 #include <obd_lov.h>
 
-#ifdef  __CYGWIN__
-# include <ctype.h>
-#endif
-
 #include <lustre_ha.h>
 #include <lprocfs_status.h>
 #include <lustre_log.h>
index 6d78b80487f2be1a37dad00f13c6f1e9ac60d38c..2ec0c24ff38b52b9b206c8af61a41de6305bdeb8 100644 (file)
@@ -10,7 +10,7 @@ ldlm_objs += $(LDLM)ldlm_pool.o
 ldlm_objs += $(LDLM)interval_tree.o
 ptlrpc_objs := client.o recover.o connection.o niobuf.o pack_generic.o
 ptlrpc_objs += events.o ptlrpc_module.o service.o pinger.o
-ptlrpc_objs += llog_net.o llog_client.o llog_server.o import.o ptlrpcd.o
+ptlrpc_objs += llog_net.o llog_client.o import.o ptlrpcd.o
 ptlrpc_objs += pers.o lproc_ptlrpc.o wiretest.o layout.o
 ptlrpc_objs += sec.o sec_bulk.o sec_gc.o sec_config.o sec_lproc.o
 ptlrpc_objs += sec_null.o sec_plain.o nrs.o nrs_fifo.o
index c2ab0c8c4d42520b16be642385636240f7cb8a9e..d90efe4084147d77d035b7d72350ce4fae147f62 100644 (file)
@@ -200,7 +200,7 @@ void __ptlrpc_free_bulk(struct ptlrpc_bulk_desc *desc, int unpin)
                class_import_put(desc->bd_import);
 
        if (unpin) {
-               for (i = 0; i < desc->bd_iov_count ; i++)
+               for (i = 0; i < desc->bd_iov_count; i++)
                        page_cache_release(desc->bd_iov[i].kiov_page);
        }
 
@@ -459,7 +459,7 @@ ptlrpc_init_rq_pool(int num_rq, int msgsize,
 {
        struct ptlrpc_request_pool *pool;
 
-       OBD_ALLOC(pool, sizeof (struct ptlrpc_request_pool));
+       OBD_ALLOC(pool, sizeof(struct ptlrpc_request_pool));
        if (!pool)
                return NULL;
 
@@ -475,7 +475,7 @@ ptlrpc_init_rq_pool(int num_rq, int msgsize,
 
        if (list_empty(&pool->prp_req_list)) {
                /* have not allocated a single request for the pool */
-               OBD_FREE(pool, sizeof (struct ptlrpc_request_pool));
+               OBD_FREE(pool, sizeof(struct ptlrpc_request_pool));
                pool = NULL;
        }
        return pool;
@@ -881,7 +881,7 @@ void ptlrpc_set_destroy(struct ptlrpc_request_set *set)
        /* Requests on the set should either all be completed, or all be new */
        expected_phase = (atomic_read(&set->set_remaining) == 0) ?
                         RQ_PHASE_COMPLETE : RQ_PHASE_NEW;
-       list_for_each (tmp, &set->set_requests) {
+       list_for_each(tmp, &set->set_requests) {
                struct ptlrpc_request *req =
                        list_entry(tmp, struct ptlrpc_request,
                                       rq_set_chain);
@@ -912,7 +912,7 @@ void ptlrpc_set_destroy(struct ptlrpc_request_set *set)
                req->rq_invalid_rqset = 0;
                spin_unlock(&req->rq_lock);
 
-               ptlrpc_req_finished (req);
+               ptlrpc_req_finished(req);
        }
 
        LASSERT(atomic_read(&set->set_remaining) == 0);
@@ -1020,7 +1020,7 @@ static int ptlrpc_import_delay_req(struct obd_import *imp,
 {
        int delay = 0;
 
-       LASSERT (status != NULL);
+       LASSERT(status != NULL);
        *status = 0;
 
        if (req->rq_ctx_init || req->rq_ctx_fini) {
@@ -1039,7 +1039,7 @@ static int ptlrpc_import_delay_req(struct obd_import *imp,
                *status = -EIO;
        } else if (req->rq_send_state == LUSTRE_IMP_CONNECTING &&
                   imp->imp_state == LUSTRE_IMP_CONNECTING) {
-               /* allow CONNECT even if import is invalid */ ;
+               /* allow CONNECT even if import is invalid */
                if (atomic_read(&imp->imp_inval_count) != 0) {
                        DEBUG_REQ(D_ERROR, req, "invalidate in flight");
                        *status = -EIO;
@@ -1596,7 +1596,8 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
                                        continue;
 
                                spin_lock(&imp->imp_lock);
-                               if (ptlrpc_import_delay_req(imp, req, &status)){
+                               if (ptlrpc_import_delay_req(imp, req,
+                                                           &status)) {
                                        /* put on delay list - only if we wait
                                         * recovery finished - before send */
                                        list_del_init(&req->rq_list);
@@ -1752,7 +1753,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
 
                ptlrpc_rqphase_move(req, RQ_PHASE_INTERPRET);
 
-       interpret:
+interpret:
                LASSERT(req->rq_phase == RQ_PHASE_INTERPRET);
 
                /* This moves to "unregistering" phase we need to wait for
@@ -1907,7 +1908,7 @@ int ptlrpc_expired_set(void *data)
        /*
         * A timeout expired. See which reqs it applies to...
         */
-       list_for_each (tmp, &set->set_requests) {
+       list_for_each(tmp, &set->set_requests) {
                struct ptlrpc_request *req =
                        list_entry(tmp, struct ptlrpc_request,
                                       rq_set_chain);
@@ -2688,7 +2689,7 @@ int ptlrpc_replay_req(struct ptlrpc_request *req)
 
        LASSERT(req->rq_import->imp_state == LUSTRE_IMP_REPLAY);
 
-       LASSERT (sizeof (*aa) <= sizeof (req->rq_async_args));
+       LASSERT(sizeof(*aa) <= sizeof(req->rq_async_args));
        aa = ptlrpc_req_async_args(req);
        memset(aa, 0, sizeof(*aa));
 
@@ -2962,7 +2963,7 @@ void *ptlrpcd_alloc_work(struct obd_import *imp,
        init_waitqueue_head(&req->rq_set_waitq);
        atomic_set(&req->rq_refcount, 1);
 
-       CLASSERT (sizeof(*args) <= sizeof(req->rq_async_args));
+       CLASSERT(sizeof(*args) <= sizeof(req->rq_async_args));
        args = ptlrpc_req_async_args(req);
        args->magic  = PTLRPC_WORK_MAGIC;
        args->cb     = cb;
index 58d089c3fef4905fe1ff1a8f7adc6e1c3b62a4aa..f66cfea87acfccb666f36ef0431141ee6aa25dbc 100644 (file)
@@ -56,9 +56,9 @@ void request_out_callback(lnet_event_t *ev)
        struct ptlrpc_cb_id   *cbid = ev->md.user_ptr;
        struct ptlrpc_request *req = cbid->cbid_arg;
 
-       LASSERT (ev->type == LNET_EVENT_SEND ||
-                ev->type == LNET_EVENT_UNLINK);
-       LASSERT (ev->unlinked);
+       LASSERT(ev->type == LNET_EVENT_SEND ||
+               ev->type == LNET_EVENT_UNLINK);
+       LASSERT(ev->unlinked);
 
        DEBUG_REQ(D_NET, req, "type %d, status %d", ev->type, ev->status);
 
@@ -90,9 +90,9 @@ void reply_in_callback(lnet_event_t *ev)
 
        DEBUG_REQ(D_NET, req, "type %d, status %d", ev->type, ev->status);
 
-       LASSERT (ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_UNLINK);
-       LASSERT (ev->md.start == req->rq_repbuf);
-       LASSERT (ev->offset + ev->mlength <= req->rq_repbuf_len);
+       LASSERT(ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_UNLINK);
+       LASSERT(ev->md.start == req->rq_repbuf);
+       LASSERT(ev->offset + ev->mlength <= req->rq_repbuf_len);
        /* We've set LNET_MD_MANAGE_REMOTE for all outgoing requests
           for adaptive timeouts' early reply. */
        LASSERT((ev->md.options & LNET_MD_MANAGE_REMOTE) != 0);
@@ -113,7 +113,7 @@ void reply_in_callback(lnet_event_t *ev)
                goto out_wake;
        }
 
-       if (ev->mlength < ev->rlength ) {
+       if (ev->mlength < ev->rlength) {
                CDEBUG(D_RPCTRACE, "truncate req %p rpc %d - %d+%d\n", req,
                       req->rq_replen, ev->rlength, ev->offset);
                req->rq_reply_truncate = 1;
@@ -167,18 +167,18 @@ out_wake:
 /*
  * Client's bulk has been written/read
  */
-void client_bulk_callback (lnet_event_t *ev)
+void client_bulk_callback(lnet_event_t *ev)
 {
        struct ptlrpc_cb_id     *cbid = ev->md.user_ptr;
        struct ptlrpc_bulk_desc *desc = cbid->cbid_arg;
        struct ptlrpc_request   *req;
 
-       LASSERT ((desc->bd_type == BULK_PUT_SINK &&
-                 ev->type == LNET_EVENT_PUT) ||
-                (desc->bd_type == BULK_GET_SOURCE &&
-                 ev->type == LNET_EVENT_GET) ||
-                ev->type == LNET_EVENT_UNLINK);
-       LASSERT (ev->unlinked);
+       LASSERT((desc->bd_type == BULK_PUT_SINK &&
+                ev->type == LNET_EVENT_PUT) ||
+               (desc->bd_type == BULK_GET_SOURCE &&
+                ev->type == LNET_EVENT_GET) ||
+               ev->type == LNET_EVENT_UNLINK);
+       LASSERT(ev->unlinked);
 
        if (CFS_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_CLIENT_BULK_CB, CFS_FAIL_ONCE))
                ev->status = -EIO;
@@ -283,11 +283,11 @@ void request_in_callback(lnet_event_t *ev)
        struct ptlrpc_service        *service = svcpt->scp_service;
        struct ptlrpc_request        *req;
 
-       LASSERT (ev->type == LNET_EVENT_PUT ||
-                ev->type == LNET_EVENT_UNLINK);
-       LASSERT ((char *)ev->md.start >= rqbd->rqbd_buffer);
-       LASSERT ((char *)ev->md.start + ev->offset + ev->mlength <=
-                rqbd->rqbd_buffer + service->srv_buf_size);
+       LASSERT(ev->type == LNET_EVENT_PUT ||
+               ev->type == LNET_EVENT_UNLINK);
+       LASSERT((char *)ev->md.start >= rqbd->rqbd_buffer);
+       LASSERT((char *)ev->md.start + ev->offset + ev->mlength <=
+               rqbd->rqbd_buffer + service->srv_buf_size);
 
        CDEBUG((ev->status == 0) ? D_NET : D_ERROR,
               "event type %d, status %d, service %s\n",
@@ -300,9 +300,9 @@ void request_in_callback(lnet_event_t *ev)
                 * we'd have to re-post the rqbd, which we can't do in this
                 * context. */
                req = &rqbd->rqbd_req;
-               memset(req, 0, sizeof (*req));
+               memset(req, 0, sizeof(*req));
        } else {
-               LASSERT (ev->type == LNET_EVENT_PUT);
+               LASSERT(ev->type == LNET_EVENT_PUT);
                if (ev->status != 0) {
                        /* We moaned above already... */
                        return;
@@ -381,19 +381,19 @@ void reply_out_callback(lnet_event_t *ev)
        struct ptlrpc_reply_state *rs = cbid->cbid_arg;
        struct ptlrpc_service_part *svcpt = rs->rs_svcpt;
 
-       LASSERT (ev->type == LNET_EVENT_SEND ||
-                ev->type == LNET_EVENT_ACK ||
-                ev->type == LNET_EVENT_UNLINK);
+       LASSERT(ev->type == LNET_EVENT_SEND ||
+               ev->type == LNET_EVENT_ACK ||
+               ev->type == LNET_EVENT_UNLINK);
 
        if (!rs->rs_difficult) {
                /* 'Easy' replies have no further processing so I drop the
                 * net's ref on 'rs' */
-               LASSERT (ev->unlinked);
+               LASSERT(ev->unlinked);
                ptlrpc_rs_decref(rs);
                return;
        }
 
-       LASSERT (rs->rs_on_net);
+       LASSERT(rs->rs_on_net);
 
        if (ev->unlinked) {
                /* Last network callback. The net's ref on 'rs' stays put
@@ -419,18 +419,17 @@ static void ptlrpc_master_callback(lnet_event_t *ev)
        void (*callback)(lnet_event_t *ev) = cbid->cbid_fn;
 
        /* Honestly, it's best to find out early. */
-       LASSERT (cbid->cbid_arg != LP_POISON);
-       LASSERT (callback == request_out_callback ||
-                callback == reply_in_callback ||
-                callback == client_bulk_callback ||
-                callback == request_in_callback ||
-                callback == reply_out_callback
-                );
-
-       callback (ev);
+       LASSERT(cbid->cbid_arg != LP_POISON);
+       LASSERT(callback == request_out_callback ||
+               callback == reply_in_callback ||
+               callback == client_bulk_callback ||
+               callback == request_in_callback ||
+               callback == reply_out_callback);
+
+       callback(ev);
 }
 
-int ptlrpc_uuid_to_peer (struct obd_uuid *uuid,
+int ptlrpc_uuid_to_peer(struct obd_uuid *uuid,
                         lnet_process_id_t *peer, lnet_nid_t *self)
 {
        int            best_dist = 0;
@@ -538,7 +537,7 @@ int ptlrpc_ni_init(void)
        /* We're not passing any limits yet... */
        rc = LNetNIInit(pid);
        if (rc < 0) {
-               CDEBUG (D_NET, "Can't init network interface: %d\n", rc);
+               CDEBUG(D_NET, "Can't init network interface: %d\n", rc);
                return (-ENOENT);
        }
 
@@ -552,7 +551,7 @@ int ptlrpc_ni_init(void)
        if (rc == 0)
                return 0;
 
-       CERROR ("Failed to allocate event queue: %d\n", rc);
+       CERROR("Failed to allocate event queue: %d\n", rc);
        LNetNIFini();
 
        return (-ENOMEM);
index c70eb00796f986e52eb7bb483e41163629cb98e8..bdfd83880422251d119951cfdab888ec5cb9ad0c 100644 (file)
@@ -64,9 +64,9 @@
 #define G_REFLECT                              (-2045022961L)
 #define G_WRONG_TOKID                      (-2045022960L)
 
-#define g_OID_equal(o1,o2) \
-   (((o1)->len == (o2)->len) && \
-    (memcmp((o1)->data,(o2)->data,(int) (o1)->len) == 0))
+#define g_OID_equal(o1, o2) \
+       (((o1)->len == (o2)->len) && \
+        (memcmp((o1)->data, (o2)->data, (int) (o1)->len) == 0))
 
 __u32 g_verify_token_header(rawobj_t *mech,
                            int *body_size,
index 13425796fa33000c3f89c71ce3eb982039622065..37ec101e14e50b8757ebb2dbb54cadae7e5b99fa 100644 (file)
@@ -106,14 +106,14 @@ typedef unsigned int OM_uint32;
  * evaluates its argument only once.
  */
 #define GSS_CALLING_ERROR(x) \
-  ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+       ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
 #define GSS_ROUTINE_ERROR(x) \
-  ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+       ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
 #define GSS_SUPPLEMENTARY_INFO(x) \
-  ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+       ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
 #define GSS_ERROR(x) \
-  ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
-         (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+       ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+               (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
 
 /*
  * Now the actual status code definitions
index 188dbbfbd2f495c3aeee906f71ae51900abfef71..d43a13c696695f51b2f28575467cd2a18daa778e 100644 (file)
@@ -165,7 +165,7 @@ void ctx_start_timer_kr(struct ptlrpc_cli_ctx *ctx, long timeout)
 
        init_timer(timer);
        timer->expires = timeout;
-       timer->data = (unsigned long ) ctx;
+       timer->data = (unsigned long) ctx;
        timer->function = ctx_upcall_timeout_kr;
 
        add_timer(timer);
index c106a9e049a7516412253fd6e1e3139901fad500..b9fa3b4a40dbad20ecf6f01f2e0a6257b84ddcff 100644 (file)
@@ -1276,7 +1276,7 @@ arc4_out_tfm:
 arc4_out_key:
                rawobj_free(&arc4_keye);
 arc4_out:
-               do {} while(0); /* just to avoid compile warning */
+               do {} while (0); /* just to avoid compile warning */
        } else {
                rc = krb5_encrypt_rawobjs(kctx->kc_keye.kb_tfm, 0,
                                          3, data_desc, &cipher, 1);
index b42ddda9ee25e70ee428f4fa1b5dbe5fd8e62a77..8ce6271a5daa53320355364c106e5dc86ffd81ef 100644 (file)
@@ -483,7 +483,7 @@ int gss_do_check_seq(unsigned long *window, __u32 win_size, __u32 *max_seq,
                        memset(window, 0, win_size / 8);
                        *max_seq = seq_num;
                } else {
-                       while(*max_seq < seq_num) {
+                       while (*max_seq < seq_num) {
                                (*max_seq)++;
                                __clear_bit((*max_seq) % win_size, window);
                        }
@@ -804,7 +804,8 @@ int gss_cli_ctx_verify(struct ptlrpc_cli_ctx *ctx,
        case PTLRPC_GSS_PROC_DATA:
                pack_bulk = ghdr->gh_flags & LUSTRE_GSS_PACK_BULK;
 
-               if (!req->rq_early && !equi(req->rq_pack_bulk == 1, pack_bulk)){
+               if (!req->rq_early &&
+                   !equi(req->rq_pack_bulk == 1, pack_bulk)) {
                        CERROR("%s bulk flag in reply\n",
                               req->rq_pack_bulk ? "missing" : "unexpected");
                        return -EPROTO;
@@ -1009,7 +1010,8 @@ int gss_cli_ctx_unseal(struct ptlrpc_cli_ctx *ctx,
        case PTLRPC_GSS_PROC_DATA:
                pack_bulk = ghdr->gh_flags & LUSTRE_GSS_PACK_BULK;
 
-               if (!req->rq_early && !equi(req->rq_pack_bulk == 1, pack_bulk)){
+               if (!req->rq_early &&
+                   !equi(req->rq_pack_bulk == 1, pack_bulk)) {
                        CERROR("%s bulk flag in reply\n",
                               req->rq_pack_bulk ? "missing" : "unexpected");
                        return -EPROTO;
@@ -1979,7 +1981,7 @@ int gss_svc_handle_init(struct ptlrpc_request *req,
                return SECSVC_DROP;
        }
 
-       if (reqbuf->lm_bufcount < 3 || reqbuf->lm_bufcount > 4){
+       if (reqbuf->lm_bufcount < 3 || reqbuf->lm_bufcount > 4) {
                CERROR("Invalid bufcount %d\n", reqbuf->lm_bufcount);
                return SECSVC_DROP;
        }
@@ -2369,7 +2371,7 @@ int gss_svc_accept(struct ptlrpc_sec_policy *policy, struct ptlrpc_request *req)
        if (swabbed)
                gss_header_swabber(ghdr);
 
-       switch(ghdr->gh_proc) {
+       switch (ghdr->gh_proc) {
        case PTLRPC_GSS_PROC_INIT:
        case PTLRPC_GSS_PROC_CONTINUE_INIT:
                rc = gss_svc_handle_init(req, gw);
@@ -2388,7 +2390,7 @@ int gss_svc_accept(struct ptlrpc_sec_policy *policy, struct ptlrpc_request *req)
 
        switch (rc) {
        case SECSVC_OK:
-               LASSERT (grctx->src_ctx);
+               LASSERT(grctx->src_ctx);
 
                req->rq_auth_gss = 1;
                req->rq_auth_remote = grctx->src_ctx->gsc_remote;
index 7b96a0e88cdbb5cd1f63d0096c2d7d81d737ea05..283173a2fe2334fcf44165e0d7fc9d31bea59f71 100644 (file)
@@ -72,23 +72,23 @@ static void __import_set_state(struct obd_import *imp,
 }
 
 /* A CLOSED import should remain so. */
-#define IMPORT_SET_STATE_NOLOCK(imp, state)                                \
-do {                                                                      \
-       if (imp->imp_state != LUSTRE_IMP_CLOSED) {                           \
-              CDEBUG(D_HA, "%p %s: changing import state from %s to %s\n",    \
-                     imp, obd2cli_tgt(imp->imp_obd),                     \
-                     ptlrpc_import_state_name(imp->imp_state),         \
-                     ptlrpc_import_state_name(state));                 \
-              __import_set_state(imp, state);                           \
-       }                                                                     \
-} while(0)
+#define IMPORT_SET_STATE_NOLOCK(imp, state)                                   \
+do {                                                                          \
+       if (imp->imp_state != LUSTRE_IMP_CLOSED) {                             \
+               CDEBUG(D_HA, "%p %s: changing import state from %s to %s\n",   \
+                      imp, obd2cli_tgt(imp->imp_obd),                         \
+                      ptlrpc_import_state_name(imp->imp_state),               \
+                      ptlrpc_import_state_name(state));                       \
+               __import_set_state(imp, state);                                \
+       }                                                                      \
+} while (0)
 
 #define IMPORT_SET_STATE(imp, state)                                   \
 do {                                                                   \
        spin_lock(&imp->imp_lock);                                      \
        IMPORT_SET_STATE_NOLOCK(imp, state);                            \
        spin_unlock(&imp->imp_lock);                                    \
-} while(0)
+} while (0)
 
 
 static int ptlrpc_connect_interpret(const struct lu_env *env,
@@ -680,7 +680,7 @@ int ptlrpc_connect_import(struct obd_import *imp)
        ptlrpc_request_set_replen(request);
        request->rq_interpret_reply = ptlrpc_connect_interpret;
 
-       CLASSERT(sizeof (*aa) <= sizeof (request->rq_async_args));
+       CLASSERT(sizeof(*aa) <= sizeof(request->rq_async_args));
        aa = ptlrpc_req_async_args(request);
        memset(aa, 0, sizeof(*aa));
 
@@ -859,7 +859,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
        if (MSG_CONNECT_RECONNECT & msg_flags) {
                memset(&old_hdl, 0, sizeof(old_hdl));
                if (!memcmp(&old_hdl, lustre_msg_get_handle(request->rq_repmsg),
-                           sizeof (old_hdl))) {
+                           sizeof(old_hdl))) {
                        LCONSOLE_WARN("Reconnect to %s (at @%s) failed due "
                                      "bad handle "LPX64"\n",
                                      obd2cli_tgt(imp->imp_obd),
@@ -1135,9 +1135,11 @@ out:
                        if (ocd &&
                            (ocd->ocd_connect_flags & OBD_CONNECT_VERSION) &&
                            (ocd->ocd_version != LUSTRE_VERSION_CODE)) {
-                          /* Actually servers are only supposed to refuse
-                             connection from liblustre clients, so we should
-                             never see this from VFS context */
+                               /*
+                                * Actually servers are only supposed to refuse
+                                * connection from liblustre clients, so we
+                                * should never see this from VFS context
+                                */
                                LCONSOLE_ERROR_MSG(0x16a, "Server %s version "
                                        "(%d.%d.%d.%d)"
                                        " refused connection from this client "
@@ -1507,7 +1509,7 @@ int at_measured(struct adaptive_timeout *at, unsigned int val)
                at->at_worst_time = now;
                at->at_hist[0] = val;
                at->at_binstart = now;
-       } else if (now - at->at_binstart < binlimit ) {
+       } else if (now - at->at_binstart < binlimit) {
                /* in bin 0 */
                at->at_hist[0] = max(val, at->at_hist[0]);
                at->at_current = max(val, at->at_current);
@@ -1517,7 +1519,7 @@ int at_measured(struct adaptive_timeout *at, unsigned int val)
                /* move bins over */
                shift = (now - at->at_binstart) / binlimit;
                LASSERT(shift > 0);
-               for(i = AT_BINS - 1; i >= 0; i--) {
+               for (i = AT_BINS - 1; i >= 0; i--) {
                        if (i >= shift) {
                                at->at_hist[i] = at->at_hist[i - shift];
                                maxv = max(maxv, at->at_hist[i]);
index d0a6e56892271c2bc00072e207f74248f84209a1..4d6ac68676e055cd174cd66c30177a241caa5fd3 100644 (file)
@@ -738,7 +738,8 @@ static struct req_format *req_formats[] = {
        &RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK,
        &RQF_LLOG_ORIGIN_HANDLE_PREV_BLOCK,
        &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER,
-       &RQF_LLOG_ORIGIN_CONNECT
+       &RQF_LLOG_ORIGIN_CONNECT,
+       &RQF_CONNECT,
 };
 
 struct req_msg_field {
@@ -1504,6 +1505,10 @@ struct req_format RQF_LLOG_ORIGIN_CONNECT =
        DEFINE_REQ_FMT0("LLOG_ORIGIN_CONNECT", llogd_conn_body_only, empty);
 EXPORT_SYMBOL(RQF_LLOG_ORIGIN_CONNECT);
 
+struct req_format RQF_CONNECT =
+       DEFINE_REQ_FMT0("CONNECT", obd_connect_client, obd_connect_server);
+EXPORT_SYMBOL(RQF_CONNECT);
+
 struct req_format RQF_OST_CONNECT =
        DEFINE_REQ_FMT0("OST_CONNECT",
                        obd_connect_client, obd_connect_server);
@@ -1808,7 +1813,7 @@ swabber_dumper_helper(struct req_capsule *pill,
                      const struct req_msg_field *field,
                      enum req_location loc,
                      int offset,
-                     void *value, int len, int dump, void (*swabber)( void *))
+                     void *value, int len, int dump, void (*swabber)(void *))
 {
        void    *p;
        int     i;
@@ -1883,7 +1888,7 @@ swabber_dumper_helper(struct req_capsule *pill,
 static void *__req_capsule_get(struct req_capsule *pill,
                               const struct req_msg_field *field,
                               enum req_location loc,
-                              void (*swabber)( void *),
+                              void (*swabber)(void *),
                               int dump)
 {
        const struct req_format *fmt;
index 379e59477ea2df00b7476e5be03dee06d6e6f34d..ab084541fddb00e453507b0ea0f8aeda31149e4e 100644 (file)
@@ -63,7 +63,7 @@
                return (-EINVAL);                                    \
        }                                                            \
        mutex_unlock(&ctxt->loc_mutex);                    \
-} while(0)
+} while (0)
 
 #define LLOG_CLIENT_EXIT(ctxt, imp) do {                             \
        mutex_lock(&ctxt->loc_mutex);                        \
@@ -72,7 +72,7 @@
                       ctxt->loc_imp, imp);                        \
        class_import_put(imp);                                  \
        mutex_unlock(&ctxt->loc_mutex);                    \
-} while(0)
+} while (0)
 
 /* This is a callback from the llog_* functions.
  * Assumes caller has already pushed us into the kernel context. */
@@ -302,7 +302,7 @@ static int llog_client_read_header(const struct lu_env *env,
        if (hdr == NULL)
                GOTO(out, rc =-EFAULT);
 
-       memcpy(handle->lgh_hdr, hdr, sizeof (*hdr));
+       memcpy(handle->lgh_hdr, hdr, sizeof(*hdr));
        handle->lgh_last_idx = handle->lgh_hdr->llh_tail.lrt_index;
 
        /* sanity checks */
diff --git a/drivers/staging/lustre/lustre/ptlrpc/llog_server.c b/drivers/staging/lustre/lustre/ptlrpc/llog_server.c
deleted file mode 100644 (file)
index af9d2ac..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lustre/ptlrpc/llog_server.c
- *
- * remote api for llog - server side
- *
- * Author: Andreas Dilger <adilger@clusterfs.com>
- */
-
-#define DEBUG_SUBSYSTEM S_LOG
-
-
-#include <obd_class.h>
-#include <lustre_log.h>
-#include <lustre_net.h>
-#include <lustre_fsfilt.h>
-
-#if  defined(LUSTRE_LOG_SERVER)
-static int llog_origin_close(const struct lu_env *env, struct llog_handle *lgh)
-{
-       if (lgh->lgh_hdr != NULL && lgh->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
-               return llog_cat_close(env, lgh);
-       else
-               return llog_close(env, lgh);
-}
-
-/* Only open is supported, no new llog can be created remotely */
-int llog_origin_handle_open(struct ptlrpc_request *req)
-{
-       struct obd_export       *exp = req->rq_export;
-       struct obd_device       *obd = exp->exp_obd;
-       struct obd_device       *disk_obd;
-       struct lvfs_run_ctxt     saved;
-       struct llog_handle      *loghandle;
-       struct llogd_body       *body;
-       struct llog_logid       *logid = NULL;
-       struct llog_ctxt        *ctxt;
-       char                    *name = NULL;
-       int                      rc;
-
-       body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
-       if (body == NULL)
-               return -EFAULT;
-
-       if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
-               logid = &body->lgd_logid;
-
-       if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) {
-               name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
-               if (name == NULL)
-                       return -EFAULT;
-               CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name);
-       }
-
-       ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
-       if (ctxt == NULL) {
-               CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n",
-                      obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name);
-               return -ENODEV;
-       }
-       disk_obd = ctxt->loc_exp->exp_obd;
-       push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-
-       rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, logid,
-                      name, LLOG_OPEN_EXISTS);
-       if (rc)
-               GOTO(out_pop, rc);
-
-       rc = req_capsule_server_pack(&req->rq_pill);
-       if (rc)
-               GOTO(out_close, rc = -ENOMEM);
-
-       body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
-       body->lgd_logid = loghandle->lgh_id;
-
-out_close:
-       llog_origin_close(req->rq_svc_thread->t_env, loghandle);
-out_pop:
-       pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-       llog_ctxt_put(ctxt);
-       return rc;
-}
-EXPORT_SYMBOL(llog_origin_handle_open);
-
-int llog_origin_handle_destroy(struct ptlrpc_request *req)
-{
-       struct obd_device       *disk_obd;
-       struct lvfs_run_ctxt     saved;
-       struct llogd_body       *body;
-       struct llog_logid       *logid = NULL;
-       struct llog_ctxt        *ctxt;
-       int                      rc;
-
-       body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
-       if (body == NULL)
-               return -EFAULT;
-
-       if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
-               logid = &body->lgd_logid;
-
-       if (!(body->lgd_llh_flags & LLOG_F_IS_PLAIN))
-               CERROR("%s: wrong llog flags %x\n",
-                      req->rq_export->exp_obd->obd_name, body->lgd_llh_flags);
-
-       ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
-       if (ctxt == NULL)
-               return -ENODEV;
-
-       disk_obd = ctxt->loc_exp->exp_obd;
-       push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-
-       rc = req_capsule_server_pack(&req->rq_pill);
-       /* erase only if no error and logid is valid */
-       if (rc == 0)
-               rc = llog_erase(req->rq_svc_thread->t_env, ctxt, logid, NULL);
-       pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-       llog_ctxt_put(ctxt);
-       return rc;
-}
-EXPORT_SYMBOL(llog_origin_handle_destroy);
-
-int llog_origin_handle_next_block(struct ptlrpc_request *req)
-{
-       struct obd_device   *disk_obd;
-       struct llog_handle  *loghandle;
-       struct llogd_body   *body;
-       struct llogd_body   *repbody;
-       struct lvfs_run_ctxt saved;
-       struct llog_ctxt    *ctxt;
-       __u32           flags;
-       void            *ptr;
-       int               rc;
-
-       body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
-       if (body == NULL)
-               return -EFAULT;
-
-       ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
-       if (ctxt == NULL)
-               return -ENODEV;
-
-       disk_obd = ctxt->loc_exp->exp_obd;
-       push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-
-       rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
-                      &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
-       if (rc)
-               GOTO(out_pop, rc);
-
-       flags = body->lgd_llh_flags;
-       rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
-                             NULL);
-       if (rc)
-               GOTO(out_close, rc);
-
-       req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
-                            LLOG_CHUNK_SIZE);
-       rc = req_capsule_server_pack(&req->rq_pill);
-       if (rc)
-               GOTO(out_close, rc = -ENOMEM);
-
-       repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
-       *repbody = *body;
-
-       ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
-       rc = llog_next_block(req->rq_svc_thread->t_env, loghandle,
-                            &repbody->lgd_saved_index, repbody->lgd_index,
-                            &repbody->lgd_cur_offset, ptr, LLOG_CHUNK_SIZE);
-       if (rc)
-               GOTO(out_close, rc);
-out_close:
-       llog_origin_close(req->rq_svc_thread->t_env, loghandle);
-out_pop:
-       pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-       llog_ctxt_put(ctxt);
-       return rc;
-}
-EXPORT_SYMBOL(llog_origin_handle_next_block);
-
-int llog_origin_handle_prev_block(struct ptlrpc_request *req)
-{
-       struct llog_handle   *loghandle;
-       struct llogd_body    *body;
-       struct llogd_body    *repbody;
-       struct obd_device    *disk_obd;
-       struct lvfs_run_ctxt  saved;
-       struct llog_ctxt     *ctxt;
-       __u32            flags;
-       void             *ptr;
-       int                rc;
-
-       body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
-       if (body == NULL)
-               return -EFAULT;
-
-       ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
-       if (ctxt == NULL)
-               return -ENODEV;
-
-       disk_obd = ctxt->loc_exp->exp_obd;
-       push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-
-       rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
-                        &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
-       if (rc)
-               GOTO(out_pop, rc);
-
-       flags = body->lgd_llh_flags;
-       rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
-                             NULL);
-       if (rc)
-               GOTO(out_close, rc);
-
-       req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
-                            LLOG_CHUNK_SIZE);
-       rc = req_capsule_server_pack(&req->rq_pill);
-       if (rc)
-               GOTO(out_close, rc = -ENOMEM);
-
-       repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
-       *repbody = *body;
-
-       ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
-       rc = llog_prev_block(req->rq_svc_thread->t_env, loghandle,
-                            body->lgd_index, ptr, LLOG_CHUNK_SIZE);
-       if (rc)
-               GOTO(out_close, rc);
-
-out_close:
-       llog_origin_close(req->rq_svc_thread->t_env, loghandle);
-out_pop:
-       pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-       llog_ctxt_put(ctxt);
-       return rc;
-}
-EXPORT_SYMBOL(llog_origin_handle_prev_block);
-
-int llog_origin_handle_read_header(struct ptlrpc_request *req)
-{
-       struct obd_device    *disk_obd;
-       struct llog_handle   *loghandle;
-       struct llogd_body    *body;
-       struct llog_log_hdr  *hdr;
-       struct lvfs_run_ctxt  saved;
-       struct llog_ctxt     *ctxt;
-       __u32            flags;
-       int                rc;
-
-       body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
-       if (body == NULL)
-               return -EFAULT;
-
-       ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
-       if (ctxt == NULL)
-               return -ENODEV;
-
-       disk_obd = ctxt->loc_exp->exp_obd;
-       push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-
-       rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
-                      &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
-       if (rc)
-               GOTO(out_pop, rc);
-
-       /*
-        * llog_init_handle() reads the llog header
-        */
-       flags = body->lgd_llh_flags;
-       rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
-                             NULL);
-       if (rc)
-               GOTO(out_close, rc);
-       flags = loghandle->lgh_hdr->llh_flags;
-
-       rc = req_capsule_server_pack(&req->rq_pill);
-       if (rc)
-               GOTO(out_close, rc = -ENOMEM);
-
-       hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR);
-       *hdr = *loghandle->lgh_hdr;
-out_close:
-       llog_origin_close(req->rq_svc_thread->t_env, loghandle);
-out_pop:
-       pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-       llog_ctxt_put(ctxt);
-       return rc;
-}
-EXPORT_SYMBOL(llog_origin_handle_read_header);
-
-int llog_origin_handle_close(struct ptlrpc_request *req)
-{
-       /* Nothing to do */
-       return 0;
-}
-EXPORT_SYMBOL(llog_origin_handle_close);
-
-int llog_origin_handle_cancel(struct ptlrpc_request *req)
-{
-       int num_cookies, rc = 0, err, i, failed = 0;
-       struct obd_device *disk_obd;
-       struct llog_cookie *logcookies;
-       struct llog_ctxt *ctxt = NULL;
-       struct lvfs_run_ctxt saved;
-       struct llog_handle *cathandle;
-       struct inode *inode;
-       void *handle;
-
-       logcookies = req_capsule_client_get(&req->rq_pill, &RMF_LOGCOOKIES);
-       num_cookies = req_capsule_get_size(&req->rq_pill, &RMF_LOGCOOKIES,
-                                          RCL_CLIENT) / sizeof(*logcookies);
-       if (logcookies == NULL || num_cookies == 0) {
-               DEBUG_REQ(D_HA, req, "No llog cookies sent");
-               return -EFAULT;
-       }
-
-       ctxt = llog_get_context(req->rq_export->exp_obd,
-                               logcookies->lgc_subsys);
-       if (ctxt == NULL)
-               return -ENODEV;
-
-       disk_obd = ctxt->loc_exp->exp_obd;
-       push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-       for (i = 0; i < num_cookies; i++, logcookies++) {
-               cathandle = ctxt->loc_handle;
-               LASSERT(cathandle != NULL);
-               inode = cathandle->lgh_file->f_dentry->d_inode;
-
-               handle = fsfilt_start_log(disk_obd, inode,
-                                         FSFILT_OP_CANCEL_UNLINK, NULL, 1);
-               if (IS_ERR(handle)) {
-                       CERROR("fsfilt_start_log() failed: %ld\n",
-                              PTR_ERR(handle));
-                       GOTO(pop_ctxt, rc = PTR_ERR(handle));
-               }
-
-               rc = llog_cat_cancel_records(req->rq_svc_thread->t_env,
-                                            cathandle, 1, logcookies);
-
-               /*
-                * Do not raise -ENOENT errors for resent rpcs. This rec already
-                * might be killed.
-                */
-               if (rc == -ENOENT &&
-                   (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT)) {
-                       /*
-                        * Do not change this message, reply-single.sh test_59b
-                        * expects to find this in log.
-                        */
-                       CDEBUG(D_RPCTRACE, "RESENT cancel req %p - ignored\n",
-                              req);
-                       rc = 0;
-               } else if (rc == 0) {
-                       CDEBUG(D_RPCTRACE, "Canceled %d llog-records\n",
-                              num_cookies);
-               }
-
-               err = fsfilt_commit(disk_obd, inode, handle, 0);
-               if (err) {
-                       CERROR("Error committing transaction: %d\n", err);
-                       if (!rc)
-                               rc = err;
-                       failed++;
-                       GOTO(pop_ctxt, rc);
-               } else if (rc)
-                       failed++;
-       }
-       GOTO(pop_ctxt, rc);
-pop_ctxt:
-       pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
-       if (rc)
-               CERROR("Cancel %d of %d llog-records failed: %d\n",
-                      failed, num_cookies, rc);
-
-       llog_ctxt_put(ctxt);
-       return rc;
-}
-EXPORT_SYMBOL(llog_origin_handle_cancel);
-
-#else /* !__KERNEL__ */
-int llog_origin_handle_open(struct ptlrpc_request *req)
-{
-       LBUG();
-       return 0;
-}
-
-int llog_origin_handle_destroy(struct ptlrpc_request *req)
-{
-       LBUG();
-       return 0;
-}
-
-int llog_origin_handle_next_block(struct ptlrpc_request *req)
-{
-       LBUG();
-       return 0;
-}
-int llog_origin_handle_prev_block(struct ptlrpc_request *req)
-{
-       LBUG();
-       return 0;
-}
-int llog_origin_handle_read_header(struct ptlrpc_request *req)
-{
-       LBUG();
-       return 0;
-}
-int llog_origin_handle_close(struct ptlrpc_request *req)
-{
-       LBUG();
-       return 0;
-}
-int llog_origin_handle_cancel(struct ptlrpc_request *req)
-{
-       LBUG();
-       return 0;
-}
-#endif
index bea44a3d4a2f387d171ab153515b05c52c0e02c4..1be978609c593d412ec201361c93be8815a7fb2c 100644 (file)
@@ -46,8 +46,8 @@
 
 
 struct ll_rpc_opcode {
-     __u32       opcode;
-     const char *opname;
+       __u32       opcode;
+       const char *opname;
 } ll_rpc_opcode_table[LUSTRE_MAX_OPCODES] = {
        { OST_REPLY,    "ost_reply" },
        { OST_GETATTR,      "ost_getattr" },
@@ -114,10 +114,10 @@ struct ll_rpc_opcode {
        { MGS_SET_INFO,     "mgs_set_info" },
        { MGS_CONFIG_READ,  "mgs_config_read" },
        { OBD_PING,      "obd_ping" },
-       { OBD_LOG_CANCEL,   "llog_origin_handle_cancel" },
+       { OBD_LOG_CANCEL,       "llog_cancel" },
        { OBD_QC_CALLBACK,  "obd_quota_callback" },
        { OBD_IDX_READ,     "dt_index_read" },
-       { LLOG_ORIGIN_HANDLE_CREATE,     "llog_origin_handle_create" },
+       { LLOG_ORIGIN_HANDLE_CREATE,     "llog_origin_handle_open" },
        { LLOG_ORIGIN_HANDLE_NEXT_BLOCK, "llog_origin_handle_next_block" },
        { LLOG_ORIGIN_HANDLE_READ_HEADER,"llog_origin_handle_read_header" },
        { LLOG_ORIGIN_HANDLE_WRITE_REC,  "llog_origin_handle_write_rec" },
@@ -137,8 +137,8 @@ struct ll_rpc_opcode {
 };
 
 struct ll_eopcode {
-     __u32       opcode;
-     const char *opname;
+       __u32       opcode;
+       const char *opname;
 } ll_eopcode_table[EXTRA_LAST_OPC] = {
        { LDLM_GLIMPSE_ENQUEUE, "ldlm_glimpse_enqueue" },
        { LDLM_PLAIN_ENQUEUE,   "ldlm_plain_enqueue" },
@@ -221,7 +221,7 @@ void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir,
        for (i = 0; i < EXTRA_LAST_OPC; i++) {
                char *units;
 
-               switch(i) {
+               switch (i) {
                case BRW_WRITE_BYTES:
                case BRW_READ_BYTES:
                        units = "bytes";
index a0e009717a5ad825b9d9627977ad49deb864f7bd..5f2aa7aa17ea7a7738aab307c851ef3a3d1465b0 100644 (file)
  * over \a conn connection to portal \a portal.
  * Returns 0 on success or error code.
  */
-static int ptl_send_buf (lnet_handle_md_t *mdh, void *base, int len,
-                        lnet_ack_req_t ack, struct ptlrpc_cb_id *cbid,
-                        struct ptlrpc_connection *conn, int portal, __u64 xid,
-                        unsigned int offset)
+static int ptl_send_buf(lnet_handle_md_t *mdh, void *base, int len,
+                       lnet_ack_req_t ack, struct ptlrpc_cb_id *cbid,
+                       struct ptlrpc_connection *conn, int portal, __u64 xid,
+                       unsigned int offset)
 {
        int           rc;
        lnet_md_t        md;
 
-       LASSERT (portal != 0);
-       LASSERT (conn != NULL);
-       CDEBUG (D_INFO, "conn=%p id %s\n", conn, libcfs_id2str(conn->c_peer));
+       LASSERT(portal != 0);
+       LASSERT(conn != NULL);
+       CDEBUG(D_INFO, "conn=%p id %s\n", conn, libcfs_id2str(conn->c_peer));
        md.start     = base;
        md.length    = len;
        md.threshold = (ack == LNET_ACK_REQ) ? 2 : 1;
@@ -66,23 +66,24 @@ static int ptl_send_buf (lnet_handle_md_t *mdh, void *base, int len,
        md.eq_handle = ptlrpc_eq_h;
 
        if (unlikely(ack == LNET_ACK_REQ &&
-                    OBD_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_ACK, OBD_FAIL_ONCE))){
+                    OBD_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_ACK,
+                                         OBD_FAIL_ONCE))) {
                /* don't ask for the ack to simulate failing client */
                ack = LNET_NOACK_REQ;
        }
 
-       rc = LNetMDBind (md, LNET_UNLINK, mdh);
+       rc = LNetMDBind(md, LNET_UNLINK, mdh);
        if (unlikely(rc != 0)) {
-               CERROR ("LNetMDBind failed: %d\n", rc);
-               LASSERT (rc == -ENOMEM);
+               CERROR("LNetMDBind failed: %d\n", rc);
+               LASSERT(rc == -ENOMEM);
                return -ENOMEM;
        }
 
        CDEBUG(D_NET, "Sending %d bytes to portal %d, xid "LPD64", offset %u\n",
               len, portal, xid, offset);
 
-       rc = LNetPut (conn->c_self, *mdh, ack,
-                     conn->c_peer, portal, xid, offset, 0);
+       rc = LNetPut(conn->c_self, *mdh, ack,
+                    conn->c_peer, portal, xid, offset, 0);
        if (unlikely(rc != 0)) {
                int rc2;
                /* We're going to get an UNLINK event when I unlink below,
@@ -363,14 +364,14 @@ int ptlrpc_send_reply(struct ptlrpc_request *req, int flags)
         * request, or a saved copy if this is a req saved in
         * target_queue_final_reply().
         */
-       LASSERT (req->rq_no_reply == 0);
-       LASSERT (req->rq_reqbuf != NULL);
-       LASSERT (rs != NULL);
-       LASSERT ((flags & PTLRPC_REPLY_MAYBE_DIFFICULT) || !rs->rs_difficult);
-       LASSERT (req->rq_repmsg != NULL);
-       LASSERT (req->rq_repmsg == rs->rs_msg);
-       LASSERT (rs->rs_cb_id.cbid_fn == reply_out_callback);
-       LASSERT (rs->rs_cb_id.cbid_arg == rs);
+       LASSERT(req->rq_no_reply == 0);
+       LASSERT(req->rq_reqbuf != NULL);
+       LASSERT(rs != NULL);
+       LASSERT((flags & PTLRPC_REPLY_MAYBE_DIFFICULT) || !rs->rs_difficult);
+       LASSERT(req->rq_repmsg != NULL);
+       LASSERT(req->rq_repmsg == rs->rs_msg);
+       LASSERT(rs->rs_cb_id.cbid_fn == reply_out_callback);
+       LASSERT(rs->rs_cb_id.cbid_arg == rs);
 
        /* There may be no rq_export during failover */
 
@@ -423,12 +424,12 @@ int ptlrpc_send_reply(struct ptlrpc_request *req, int flags)
 
        req->rq_sent = cfs_time_current_sec();
 
-       rc = ptl_send_buf (&rs->rs_md_h, rs->rs_repbuf, rs->rs_repdata_len,
-                          (rs->rs_difficult && !rs->rs_no_ack) ?
-                          LNET_ACK_REQ : LNET_NOACK_REQ,
-                          &rs->rs_cb_id, conn,
-                          ptlrpc_req2svc(req)->srv_rep_portal,
-                          req->rq_xid, req->rq_reply_off);
+       rc = ptl_send_buf(&rs->rs_md_h, rs->rs_repbuf, rs->rs_repdata_len,
+                         (rs->rs_difficult && !rs->rs_no_ack) ?
+                         LNET_ACK_REQ : LNET_NOACK_REQ,
+                         &rs->rs_cb_id, conn,
+                         ptlrpc_req2svc(req)->srv_rep_portal,
+                         req->rq_xid, req->rq_reply_off);
 out:
        if (unlikely(rc != 0))
                ptlrpc_req_drop_rs(req);
@@ -437,7 +438,7 @@ out:
 }
 EXPORT_SYMBOL(ptlrpc_send_reply);
 
-int ptlrpc_reply (struct ptlrpc_request *req)
+int ptlrpc_reply(struct ptlrpc_request *req)
 {
        if (req->rq_no_reply)
                return 0;
@@ -537,13 +538,13 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
 
        /* bulk register should be done after wrap_request() */
        if (request->rq_bulk != NULL) {
-               rc = ptlrpc_register_bulk (request);
+               rc = ptlrpc_register_bulk(request);
                if (rc != 0)
                        GOTO(out, rc);
        }
 
        if (!noreply) {
-               LASSERT (request->rq_replen != 0);
+               LASSERT(request->rq_replen != 0);
                if (request->rq_repbuf == NULL) {
                        LASSERT(request->rq_repdata == NULL);
                        LASSERT(request->rq_repmsg == NULL);
@@ -566,7 +567,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
                                  LNET_UNLINK, LNET_INS_AFTER, &reply_me_h);
                if (rc != 0) {
                        CERROR("LNetMEAttach failed: %d\n", rc);
-                       LASSERT (rc == -ENOMEM);
+                       LASSERT(rc == -ENOMEM);
                        GOTO(cleanup_bulk, rc = -ENOMEM);
                }
        }
@@ -604,7 +605,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
                                  &request->rq_reply_md_h);
                if (rc != 0) {
                        CERROR("LNetMDAttach failed: %d\n", rc);
-                       LASSERT (rc == -ENOMEM);
+                       LASSERT(rc == -ENOMEM);
                        spin_lock(&request->rq_lock);
                        /* ...but the MD attach didn't succeed... */
                        request->rq_receiving_reply = 0;
@@ -655,7 +656,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
         * nobody apart from the PUT's target has the right nid+XID to
         * access the reply buffer. */
        rc2 = LNetMEUnlink(reply_me_h);
-       LASSERT (rc2 == 0);
+       LASSERT(rc2 == 0);
        /* UNLINKED callback called synchronously */
        LASSERT(!request->rq_receiving_reply);
 
@@ -714,10 +715,10 @@ int ptlrpc_register_rqbd(struct ptlrpc_request_buffer_desc *rqbd)
        if (rc == 0)
                return (0);
 
-       CERROR("LNetMDAttach failed: %d; \n", rc);
-       LASSERT (rc == -ENOMEM);
-       rc = LNetMEUnlink (me_h);
-       LASSERT (rc == 0);
+       CERROR("LNetMDAttach failed: %d;\n", rc);
+       LASSERT(rc == -ENOMEM);
+       rc = LNetMEUnlink(me_h);
+       LASSERT(rc == 0);
        rqbd->rqbd_refcount = 0;
 
        return (-ENOMEM);
index cd2611a3b53d1823b6249c417e771a584fb6ec3e..d831bd7e8e089d1c90c5715320a65f05a202c297 100644 (file)
@@ -274,8 +274,8 @@ do {                                                                        \
        spin_unlock(&ptlrpc_rs_debug_lock);                             \
 } while (0)
 #else
-# define PTLRPC_RS_DEBUG_LRU_ADD(rs) do {} while(0)
-# define PTLRPC_RS_DEBUG_LRU_DEL(rs) do {} while(0)
+# define PTLRPC_RS_DEBUG_LRU_ADD(rs) do {} while (0)
+# define PTLRPC_RS_DEBUG_LRU_DEL(rs) do {} while (0)
 #endif
 
 struct ptlrpc_reply_state *
@@ -507,14 +507,14 @@ void lustre_free_reply_state(struct ptlrpc_reply_state *rs)
 {
        PTLRPC_RS_DEBUG_LRU_DEL(rs);
 
-       LASSERT (atomic_read(&rs->rs_refcount) == 0);
-       LASSERT (!rs->rs_difficult || rs->rs_handled);
-       LASSERT (!rs->rs_on_net);
-       LASSERT (!rs->rs_scheduled);
-       LASSERT (rs->rs_export == NULL);
-       LASSERT (rs->rs_nlocks == 0);
-       LASSERT (list_empty(&rs->rs_exp_list));
-       LASSERT (list_empty(&rs->rs_obd_list));
+       LASSERT(atomic_read(&rs->rs_refcount) == 0);
+       LASSERT(!rs->rs_difficult || rs->rs_handled);
+       LASSERT(!rs->rs_on_net);
+       LASSERT(!rs->rs_scheduled);
+       LASSERT(rs->rs_export == NULL);
+       LASSERT(rs->rs_nlocks == 0);
+       LASSERT(list_empty(&rs->rs_exp_list));
+       LASSERT(list_empty(&rs->rs_obd_list));
 
        sptlrpc_svc_free_rs(rs);
 }
@@ -548,8 +548,8 @@ static int lustre_unpack_msg_v2(struct lustre_msg_v2 *m, int len)
        required_len = lustre_msg_hdr_size_v2(m->lm_bufcount);
        if (len < required_len) {
                /* didn't receive all the buffer lengths */
-               CERROR ("message length %d too small for %d buflens\n",
-                       len, m->lm_bufcount);
+               CERROR("message length %d too small for %d buflens\n",
+                      len, m->lm_bufcount);
                return -EINVAL;
        }
 
@@ -636,8 +636,8 @@ static inline int lustre_unpack_ptlrpc_body_v2(struct ptlrpc_request *req,
        }
 
        if ((pb->pb_version & ~LUSTRE_VERSION_MASK) != PTLRPC_MSG_VERSION) {
-                CERROR("wrong lustre_msg version %08x\n", pb->pb_version);
-                return -EINVAL;
+               CERROR("wrong lustre_msg version %08x\n", pb->pb_version);
+               return -EINVAL;
        }
 
        if (!inout)
@@ -749,7 +749,7 @@ char *lustre_msg_string(struct lustre_msg *m, int index, int max_len)
        }
 
        if (str == NULL) {
-               CERROR ("can't unpack string in msg %p buffer[%d]\n", m, index);
+               CERROR("can't unpack string in msg %p buffer[%d]\n", m, index);
                return NULL;
        }
 
@@ -1653,25 +1653,25 @@ EXPORT_SYMBOL(do_set_info_async);
  */
 void lustre_swab_ptlrpc_body(struct ptlrpc_body *b)
 {
-       __swab32s (&b->pb_type);
-       __swab32s (&b->pb_version);
-       __swab32s (&b->pb_opc);
-       __swab32s (&b->pb_status);
-       __swab64s (&b->pb_last_xid);
-       __swab64s (&b->pb_last_seen);
-       __swab64s (&b->pb_last_committed);
-       __swab64s (&b->pb_transno);
-       __swab32s (&b->pb_flags);
-       __swab32s (&b->pb_op_flags);
-       __swab32s (&b->pb_conn_cnt);
-       __swab32s (&b->pb_timeout);
-       __swab32s (&b->pb_service_time);
-       __swab32s (&b->pb_limit);
-       __swab64s (&b->pb_slv);
-       __swab64s (&b->pb_pre_versions[0]);
-       __swab64s (&b->pb_pre_versions[1]);
-       __swab64s (&b->pb_pre_versions[2]);
-       __swab64s (&b->pb_pre_versions[3]);
+       __swab32s(&b->pb_type);
+       __swab32s(&b->pb_version);
+       __swab32s(&b->pb_opc);
+       __swab32s(&b->pb_status);
+       __swab64s(&b->pb_last_xid);
+       __swab64s(&b->pb_last_seen);
+       __swab64s(&b->pb_last_committed);
+       __swab64s(&b->pb_transno);
+       __swab32s(&b->pb_flags);
+       __swab32s(&b->pb_op_flags);
+       __swab32s(&b->pb_conn_cnt);
+       __swab32s(&b->pb_timeout);
+       __swab32s(&b->pb_service_time);
+       __swab32s(&b->pb_limit);
+       __swab64s(&b->pb_slv);
+       __swab64s(&b->pb_pre_versions[0]);
+       __swab64s(&b->pb_pre_versions[1]);
+       __swab64s(&b->pb_pre_versions[2]);
+       __swab64s(&b->pb_pre_versions[3]);
        CLASSERT(offsetof(typeof(*b), pb_padding) != 0);
        /* While we need to maintain compatibility between
         * clients and servers without ptlrpc_body_v2 (< 2.3)
@@ -1723,33 +1723,33 @@ void lustre_swab_connect(struct obd_connect_data *ocd)
        CLASSERT(offsetof(typeof(*ocd), paddingF) != 0);
 }
 
-void lustre_swab_obdo (struct obdo  *o)
+void lustre_swab_obdo(struct obdo  *o)
 {
-       __swab64s (&o->o_valid);
+       __swab64s(&o->o_valid);
        lustre_swab_ost_id(&o->o_oi);
-       __swab64s (&o->o_parent_seq);
-       __swab64s (&o->o_size);
-       __swab64s (&o->o_mtime);
-       __swab64s (&o->o_atime);
-       __swab64s (&o->o_ctime);
-       __swab64s (&o->o_blocks);
-       __swab64s (&o->o_grant);
-       __swab32s (&o->o_blksize);
-       __swab32s (&o->o_mode);
-       __swab32s (&o->o_uid);
-       __swab32s (&o->o_gid);
-       __swab32s (&o->o_flags);
-       __swab32s (&o->o_nlink);
-       __swab32s (&o->o_parent_oid);
-       __swab32s (&o->o_misc);
-       __swab64s (&o->o_ioepoch);
-       __swab32s (&o->o_stripe_idx);
-       __swab32s (&o->o_parent_ver);
+       __swab64s(&o->o_parent_seq);
+       __swab64s(&o->o_size);
+       __swab64s(&o->o_mtime);
+       __swab64s(&o->o_atime);
+       __swab64s(&o->o_ctime);
+       __swab64s(&o->o_blocks);
+       __swab64s(&o->o_grant);
+       __swab32s(&o->o_blksize);
+       __swab32s(&o->o_mode);
+       __swab32s(&o->o_uid);
+       __swab32s(&o->o_gid);
+       __swab32s(&o->o_flags);
+       __swab32s(&o->o_nlink);
+       __swab32s(&o->o_parent_oid);
+       __swab32s(&o->o_misc);
+       __swab64s(&o->o_ioepoch);
+       __swab32s(&o->o_stripe_idx);
+       __swab32s(&o->o_parent_ver);
        /* o_handle is opaque */
        /* o_lcookie is swabbed elsewhere */
-       __swab32s (&o->o_uid_h);
-       __swab32s (&o->o_gid_h);
-       __swab64s (&o->o_data_version);
+       __swab32s(&o->o_uid_h);
+       __swab32s(&o->o_gid_h);
+       __swab64s(&o->o_data_version);
        CLASSERT(offsetof(typeof(*o), o_padding_4) != 0);
        CLASSERT(offsetof(typeof(*o), o_padding_5) != 0);
        CLASSERT(offsetof(typeof(*o), o_padding_6) != 0);
@@ -1757,19 +1757,19 @@ void lustre_swab_obdo (struct obdo  *o)
 }
 EXPORT_SYMBOL(lustre_swab_obdo);
 
-void lustre_swab_obd_statfs (struct obd_statfs *os)
+void lustre_swab_obd_statfs(struct obd_statfs *os)
 {
-       __swab64s (&os->os_type);
-       __swab64s (&os->os_blocks);
-       __swab64s (&os->os_bfree);
-       __swab64s (&os->os_bavail);
-       __swab64s (&os->os_files);
-       __swab64s (&os->os_ffree);
+       __swab64s(&os->os_type);
+       __swab64s(&os->os_blocks);
+       __swab64s(&os->os_bfree);
+       __swab64s(&os->os_bavail);
+       __swab64s(&os->os_files);
+       __swab64s(&os->os_ffree);
        /* no need to swab os_fsid */
-       __swab32s (&os->os_bsize);
-       __swab32s (&os->os_namelen);
-       __swab64s (&os->os_maxbytes);
-       __swab32s (&os->os_state);
+       __swab32s(&os->os_bsize);
+       __swab32s(&os->os_namelen);
+       __swab64s(&os->os_maxbytes);
+       __swab32s(&os->os_state);
        CLASSERT(offsetof(typeof(*os), os_fprecreated) != 0);
        CLASSERT(offsetof(typeof(*os), os_spare2) != 0);
        CLASSERT(offsetof(typeof(*os), os_spare3) != 0);
@@ -1790,17 +1790,17 @@ void lustre_swab_obd_ioobj(struct obd_ioobj *ioo)
 }
 EXPORT_SYMBOL(lustre_swab_obd_ioobj);
 
-void lustre_swab_niobuf_remote (struct niobuf_remote *nbr)
+void lustre_swab_niobuf_remote(struct niobuf_remote *nbr)
 {
-       __swab64s (&nbr->offset);
-       __swab32s (&nbr->len);
-       __swab32s (&nbr->flags);
+       __swab64s(&nbr->offset);
+       __swab32s(&nbr->len);
+       __swab32s(&nbr->flags);
 }
 EXPORT_SYMBOL(lustre_swab_niobuf_remote);
 
-void lustre_swab_ost_body (struct ost_body *b)
+void lustre_swab_ost_body(struct ost_body *b)
 {
-       lustre_swab_obdo (&b->oa);
+       lustre_swab_obdo(&b->oa);
 }
 EXPORT_SYMBOL(lustre_swab_ost_body);
 
@@ -1861,45 +1861,45 @@ void lustre_swab_lquota_lvb(struct lquota_lvb *lvb)
 }
 EXPORT_SYMBOL(lustre_swab_lquota_lvb);
 
-void lustre_swab_mdt_body (struct mdt_body *b)
+void lustre_swab_mdt_body(struct mdt_body *b)
 {
-       lustre_swab_lu_fid (&b->fid1);
-       lustre_swab_lu_fid (&b->fid2);
+       lustre_swab_lu_fid(&b->fid1);
+       lustre_swab_lu_fid(&b->fid2);
        /* handle is opaque */
-       __swab64s (&b->valid);
-       __swab64s (&b->size);
-       __swab64s (&b->mtime);
-       __swab64s (&b->atime);
-       __swab64s (&b->ctime);
-       __swab64s (&b->blocks);
-       __swab64s (&b->ioepoch);
-       CLASSERT(offsetof(typeof(*b), unused1) != 0);
-       __swab32s (&b->fsuid);
-       __swab32s (&b->fsgid);
-       __swab32s (&b->capability);
-       __swab32s (&b->mode);
-       __swab32s (&b->uid);
-       __swab32s (&b->gid);
-       __swab32s (&b->flags);
-       __swab32s (&b->rdev);
-       __swab32s (&b->nlink);
+       __swab64s(&b->valid);
+       __swab64s(&b->size);
+       __swab64s(&b->mtime);
+       __swab64s(&b->atime);
+       __swab64s(&b->ctime);
+       __swab64s(&b->blocks);
+       __swab64s(&b->ioepoch);
+       __swab64s(&b->t_state);
+       __swab32s(&b->fsuid);
+       __swab32s(&b->fsgid);
+       __swab32s(&b->capability);
+       __swab32s(&b->mode);
+       __swab32s(&b->uid);
+       __swab32s(&b->gid);
+       __swab32s(&b->flags);
+       __swab32s(&b->rdev);
+       __swab32s(&b->nlink);
        CLASSERT(offsetof(typeof(*b), unused2) != 0);
-       __swab32s (&b->suppgid);
-       __swab32s (&b->eadatasize);
-       __swab32s (&b->aclsize);
-       __swab32s (&b->max_mdsize);
-       __swab32s (&b->max_cookiesize);
-       __swab32s (&b->uid_h);
-       __swab32s (&b->gid_h);
+       __swab32s(&b->suppgid);
+       __swab32s(&b->eadatasize);
+       __swab32s(&b->aclsize);
+       __swab32s(&b->max_mdsize);
+       __swab32s(&b->max_cookiesize);
+       __swab32s(&b->uid_h);
+       __swab32s(&b->gid_h);
        CLASSERT(offsetof(typeof(*b), padding_5) != 0);
 }
 EXPORT_SYMBOL(lustre_swab_mdt_body);
 
-void lustre_swab_mdt_ioepoch (struct mdt_ioepoch *b)
+void lustre_swab_mdt_ioepoch(struct mdt_ioepoch *b)
 {
        /* handle is opaque */
-        __swab64s (&b->ioepoch);
-        __swab32s (&b->flags);
+        __swab64s(&b->ioepoch);
+        __swab32s(&b->flags);
         CLASSERT(offsetof(typeof(*b), padding) != 0);
 }
 EXPORT_SYMBOL(lustre_swab_mdt_ioepoch);
@@ -1957,49 +1957,49 @@ void lustre_swab_mgs_config_res(struct mgs_config_res *body)
 }
 EXPORT_SYMBOL(lustre_swab_mgs_config_res);
 
-static void lustre_swab_obd_dqinfo (struct obd_dqinfo *i)
+static void lustre_swab_obd_dqinfo(struct obd_dqinfo *i)
 {
-       __swab64s (&i->dqi_bgrace);
-       __swab64s (&i->dqi_igrace);
-       __swab32s (&i->dqi_flags);
-       __swab32s (&i->dqi_valid);
+       __swab64s(&i->dqi_bgrace);
+       __swab64s(&i->dqi_igrace);
+       __swab32s(&i->dqi_flags);
+       __swab32s(&i->dqi_valid);
 }
 
-static void lustre_swab_obd_dqblk (struct obd_dqblk *b)
+static void lustre_swab_obd_dqblk(struct obd_dqblk *b)
 {
-       __swab64s (&b->dqb_ihardlimit);
-       __swab64s (&b->dqb_isoftlimit);
-       __swab64s (&b->dqb_curinodes);
-       __swab64s (&b->dqb_bhardlimit);
-       __swab64s (&b->dqb_bsoftlimit);
-       __swab64s (&b->dqb_curspace);
-       __swab64s (&b->dqb_btime);
-       __swab64s (&b->dqb_itime);
-       __swab32s (&b->dqb_valid);
+       __swab64s(&b->dqb_ihardlimit);
+       __swab64s(&b->dqb_isoftlimit);
+       __swab64s(&b->dqb_curinodes);
+       __swab64s(&b->dqb_bhardlimit);
+       __swab64s(&b->dqb_bsoftlimit);
+       __swab64s(&b->dqb_curspace);
+       __swab64s(&b->dqb_btime);
+       __swab64s(&b->dqb_itime);
+       __swab32s(&b->dqb_valid);
        CLASSERT(offsetof(typeof(*b), dqb_padding) != 0);
 }
 
-void lustre_swab_obd_quotactl (struct obd_quotactl *q)
+void lustre_swab_obd_quotactl(struct obd_quotactl *q)
 {
-       __swab32s (&q->qc_cmd);
-       __swab32s (&q->qc_type);
-       __swab32s (&q->qc_id);
-       __swab32s (&q->qc_stat);
-       lustre_swab_obd_dqinfo (&q->qc_dqinfo);
-       lustre_swab_obd_dqblk (&q->qc_dqblk);
+       __swab32s(&q->qc_cmd);
+       __swab32s(&q->qc_type);
+       __swab32s(&q->qc_id);
+       __swab32s(&q->qc_stat);
+       lustre_swab_obd_dqinfo(&q->qc_dqinfo);
+       lustre_swab_obd_dqblk(&q->qc_dqblk);
 }
 EXPORT_SYMBOL(lustre_swab_obd_quotactl);
 
-void lustre_swab_mdt_remote_perm (struct mdt_remote_perm *p)
+void lustre_swab_mdt_remote_perm(struct mdt_remote_perm *p)
 {
-       __swab32s (&p->rp_uid);
-       __swab32s (&p->rp_gid);
-       __swab32s (&p->rp_fsuid);
-       __swab32s (&p->rp_fsuid_h);
-       __swab32s (&p->rp_fsgid);
-       __swab32s (&p->rp_fsgid_h);
-       __swab32s (&p->rp_access_perm);
-       __swab32s (&p->rp_padding);
+       __swab32s(&p->rp_uid);
+       __swab32s(&p->rp_gid);
+       __swab32s(&p->rp_fsuid);
+       __swab32s(&p->rp_fsuid_h);
+       __swab32s(&p->rp_fsgid);
+       __swab32s(&p->rp_fsgid_h);
+       __swab32s(&p->rp_access_perm);
+       __swab32s(&p->rp_padding);
 };
 EXPORT_SYMBOL(lustre_swab_mdt_remote_perm);
 
@@ -2089,31 +2089,31 @@ void lustre_swab_mdt_rec_reint (struct mdt_rec_reint *rr)
 };
 EXPORT_SYMBOL(lustre_swab_mdt_rec_reint);
 
-void lustre_swab_lov_desc (struct lov_desc *ld)
+void lustre_swab_lov_desc(struct lov_desc *ld)
 {
-       __swab32s (&ld->ld_tgt_count);
-       __swab32s (&ld->ld_active_tgt_count);
-       __swab32s (&ld->ld_default_stripe_count);
-       __swab32s (&ld->ld_pattern);
-       __swab64s (&ld->ld_default_stripe_size);
-       __swab64s (&ld->ld_default_stripe_offset);
-       __swab32s (&ld->ld_qos_maxage);
+       __swab32s(&ld->ld_tgt_count);
+       __swab32s(&ld->ld_active_tgt_count);
+       __swab32s(&ld->ld_default_stripe_count);
+       __swab32s(&ld->ld_pattern);
+       __swab64s(&ld->ld_default_stripe_size);
+       __swab64s(&ld->ld_default_stripe_offset);
+       __swab32s(&ld->ld_qos_maxage);
        /* uuid endian insensitive */
 }
 EXPORT_SYMBOL(lustre_swab_lov_desc);
 
-void lustre_swab_lmv_desc (struct lmv_desc *ld)
+void lustre_swab_lmv_desc(struct lmv_desc *ld)
 {
-       __swab32s (&ld->ld_tgt_count);
-       __swab32s (&ld->ld_active_tgt_count);
-       __swab32s (&ld->ld_default_stripe_count);
-       __swab32s (&ld->ld_pattern);
-       __swab64s (&ld->ld_default_hash_size);
-       __swab32s (&ld->ld_qos_maxage);
+       __swab32s(&ld->ld_tgt_count);
+       __swab32s(&ld->ld_active_tgt_count);
+       __swab32s(&ld->ld_default_stripe_count);
+       __swab32s(&ld->ld_pattern);
+       __swab64s(&ld->ld_default_hash_size);
+       __swab32s(&ld->ld_qos_maxage);
        /* uuid endian insensitive */
 }
 
-void lustre_swab_lmv_stripe_md (struct lmv_stripe_md *mea)
+void lustre_swab_lmv_stripe_md(struct lmv_stripe_md *mea)
 {
        __swab32s(&mea->mea_magic);
        __swab32s(&mea->mea_count);
@@ -2142,7 +2142,7 @@ void lustre_swab_lmv_user_md(struct lmv_user_md *lum)
 }
 EXPORT_SYMBOL(lustre_swab_lmv_user_md);
 
-static void print_lum (struct lov_user_md *lum)
+static void print_lum(struct lov_user_md *lum)
 {
        CDEBUG(D_OTHER, "lov_user_md %p:\n", lum);
        CDEBUG(D_OTHER, "\tlmm_magic: %#x\n", lum->lmm_magic);
@@ -2212,16 +2212,16 @@ void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod,
 }
 EXPORT_SYMBOL(lustre_swab_lov_user_md_objects);
 
-void lustre_swab_ldlm_res_id (struct ldlm_res_id *id)
+void lustre_swab_ldlm_res_id(struct ldlm_res_id *id)
 {
        int  i;
 
        for (i = 0; i < RES_NAME_SIZE; i++)
-               __swab64s (&id->name[i]);
+               __swab64s(&id->name[i]);
 }
 EXPORT_SYMBOL(lustre_swab_ldlm_res_id);
 
-void lustre_swab_ldlm_policy_data (ldlm_wire_policy_data_t *d)
+void lustre_swab_ldlm_policy_data(ldlm_wire_policy_data_t *d)
 {
        /* the lock data is a union and the first two fields are always an
         * extent so it's ok to process an LDLM_EXTENT and LDLM_FLOCK lock
@@ -2234,46 +2234,46 @@ void lustre_swab_ldlm_policy_data (ldlm_wire_policy_data_t *d)
 }
 EXPORT_SYMBOL(lustre_swab_ldlm_policy_data);
 
-void lustre_swab_ldlm_intent (struct ldlm_intent *i)
+void lustre_swab_ldlm_intent(struct ldlm_intent *i)
 {
-       __swab64s (&i->opc);
+       __swab64s(&i->opc);
 }
 EXPORT_SYMBOL(lustre_swab_ldlm_intent);
 
-void lustre_swab_ldlm_resource_desc (struct ldlm_resource_desc *r)
+void lustre_swab_ldlm_resource_desc(struct ldlm_resource_desc *r)
 {
-       __swab32s (&r->lr_type);
+       __swab32s(&r->lr_type);
        CLASSERT(offsetof(typeof(*r), lr_padding) != 0);
-       lustre_swab_ldlm_res_id (&r->lr_name);
+       lustre_swab_ldlm_res_id(&r->lr_name);
 }
 EXPORT_SYMBOL(lustre_swab_ldlm_resource_desc);
 
-void lustre_swab_ldlm_lock_desc (struct ldlm_lock_desc *l)
+void lustre_swab_ldlm_lock_desc(struct ldlm_lock_desc *l)
 {
-       lustre_swab_ldlm_resource_desc (&l->l_resource);
-       __swab32s (&l->l_req_mode);
-       __swab32s (&l->l_granted_mode);
-       lustre_swab_ldlm_policy_data (&l->l_policy_data);
+       lustre_swab_ldlm_resource_desc(&l->l_resource);
+       __swab32s(&l->l_req_mode);
+       __swab32s(&l->l_granted_mode);
+       lustre_swab_ldlm_policy_data(&l->l_policy_data);
 }
 EXPORT_SYMBOL(lustre_swab_ldlm_lock_desc);
 
-void lustre_swab_ldlm_request (struct ldlm_request *rq)
+void lustre_swab_ldlm_request(struct ldlm_request *rq)
 {
-       __swab32s (&rq->lock_flags);
-       lustre_swab_ldlm_lock_desc (&rq->lock_desc);
-       __swab32s (&rq->lock_count);
+       __swab32s(&rq->lock_flags);
+       lustre_swab_ldlm_lock_desc(&rq->lock_desc);
+       __swab32s(&rq->lock_count);
        /* lock_handle[] opaque */
 }
 EXPORT_SYMBOL(lustre_swab_ldlm_request);
 
-void lustre_swab_ldlm_reply (struct ldlm_reply *r)
+void lustre_swab_ldlm_reply(struct ldlm_reply *r)
 {
-       __swab32s (&r->lock_flags);
+       __swab32s(&r->lock_flags);
        CLASSERT(offsetof(typeof(*r), lock_padding) != 0);
-       lustre_swab_ldlm_lock_desc (&r->lock_desc);
+       lustre_swab_ldlm_lock_desc(&r->lock_desc);
        /* lock_handle opaque */
-       __swab64s (&r->lock_policy_res1);
-       __swab64s (&r->lock_policy_res2);
+       __swab64s(&r->lock_policy_res1);
+       __swab64s(&r->lock_policy_res2);
 }
 EXPORT_SYMBOL(lustre_swab_ldlm_reply);
 
@@ -2409,7 +2409,7 @@ static inline int rep_ptlrpc_body_swabbed(struct ptlrpc_request *req)
 
 void _debug_req(struct ptlrpc_request *req,
                struct libcfs_debug_msg_data *msgdata,
-               const char *fmt, ... )
+               const char *fmt, ...)
 {
        int req_ok = req->rq_reqmsg != NULL;
        int rep_ok = req->rq_repmsg != NULL;
@@ -2457,20 +2457,20 @@ EXPORT_SYMBOL(_debug_req);
 void lustre_swab_lustre_capa(struct lustre_capa *c)
 {
        lustre_swab_lu_fid(&c->lc_fid);
-       __swab64s (&c->lc_opc);
-       __swab64s (&c->lc_uid);
-       __swab64s (&c->lc_gid);
-       __swab32s (&c->lc_flags);
-       __swab32s (&c->lc_keyid);
-       __swab32s (&c->lc_timeout);
-       __swab32s (&c->lc_expiry);
+       __swab64s(&c->lc_opc);
+       __swab64s(&c->lc_uid);
+       __swab64s(&c->lc_gid);
+       __swab32s(&c->lc_flags);
+       __swab32s(&c->lc_keyid);
+       __swab32s(&c->lc_timeout);
+       __swab32s(&c->lc_expiry);
 }
 EXPORT_SYMBOL(lustre_swab_lustre_capa);
 
 void lustre_swab_lustre_capa_key(struct lustre_capa_key *k)
 {
-       __swab64s (&k->lk_seq);
-       __swab32s (&k->lk_keyid);
+       __swab64s(&k->lk_seq);
+       __swab32s(&k->lk_keyid);
        CLASSERT(offsetof(typeof(*k), lk_padding) != 0);
 }
 EXPORT_SYMBOL(lustre_swab_lustre_capa_key);
index 5dec771d70eee8c08a6bc0b787f7f116ddd6906d..4684b03c4a5f8bbc6bb43957f920bdfbd3f54868 100644 (file)
@@ -45,7 +45,8 @@
 #include "ptlrpc_internal.h"
 
 static int suppress_pings;
-CFS_MODULE_PARM(suppress_pings, "i", int, 0644, "Suppress pings");
+module_param(suppress_pings, int, 0644);
+MODULE_PARM_DESC(suppress_pings, "Suppress pings");
 
 struct mutex pinger_mutex;
 static LIST_HEAD(pinger_imports);
@@ -409,8 +410,8 @@ int ptlrpc_stop_pinger(void)
        struct l_wait_info lwi = { 0 };
        int rc = 0;
 
-       if (!thread_is_init(&pinger_thread) &&
-           !thread_is_stopped(&pinger_thread))
+       if (thread_is_init(&pinger_thread) ||
+           thread_is_stopped(&pinger_thread))
                return -EALREADY;
 
        ptlrpc_pinger_remove_timeouts();
@@ -576,7 +577,7 @@ int ptlrpc_del_timeout_client(struct list_head *obd_list,
                        break;
                }
        }
-       LASSERTF(ti != NULL, "ti is NULL ! \n");
+       LASSERTF(ti != NULL, "ti is NULL !\n");
        if (list_empty(&ti->ti_obd_list)) {
                list_del(&ti->ti_chain);
                OBD_FREE_PTR(ti);
index ab363477151d081eae9a0bb5f4c8b6d88072aa96..5d0749cc4b0f7223481ab281f427c1a398ec7bf2 100644 (file)
@@ -77,13 +77,13 @@ void ptlrpc_lprocfs_register_service(struct proc_dir_entry *proc_entry,
                                     struct ptlrpc_service *svc);
 void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc);
 void ptlrpc_lprocfs_rpc_sent(struct ptlrpc_request *req, long amount);
-void ptlrpc_lprocfs_do_request_stat (struct ptlrpc_request *req,
+void ptlrpc_lprocfs_do_request_stat(struct ptlrpc_request *req,
                                     long q_usec, long work_usec);
 #else
-#define ptlrpc_lprocfs_register_service(params...) do{}while(0)
-#define ptlrpc_lprocfs_unregister_service(params...) do{}while(0)
-#define ptlrpc_lprocfs_rpc_sent(params...) do{}while(0)
-#define ptlrpc_lprocfs_do_request_stat(params...) do{}while(0)
+#define ptlrpc_lprocfs_register_service(params...) do {} while (0)
+#define ptlrpc_lprocfs_unregister_service(params...) do {} while (0)
+#define ptlrpc_lprocfs_rpc_sent(params...) do {} while (0)
+#define ptlrpc_lprocfs_do_request_stat(params...) do {} while (0)
 #endif /* LPROCFS */
 
 /* NRS */
index 419e634854df0c32e2344e2434ed8eeee63b3a9d..0efd35887a15994efe20e6d842ee12bac2a6edf5 100644 (file)
@@ -112,7 +112,7 @@ __init int ptlrpc_init(void)
        return 0;
 
 cleanup:
-       switch(cleanup_phase) {
+       switch (cleanup_phase) {
        case 8:
                ptlrpc_nrs_fini();
        case 7:
index 89c9be96f454a57c4dd0839cf92f378883dce91e..2ebdb1b06dde3d945634b8a2521c68f81eb6958f 100644 (file)
@@ -77,12 +77,12 @@ struct ptlrpcd {
 };
 
 static int max_ptlrpcds;
-CFS_MODULE_PARM(max_ptlrpcds, "i", int, 0644,
-               "Max ptlrpcd thread count to be started.");
+module_param(max_ptlrpcds, int, 0644);
+MODULE_PARM_DESC(max_ptlrpcds, "Max ptlrpcd thread count to be started.");
 
 static int ptlrpcd_bind_policy = PDB_POLICY_PAIR;
-CFS_MODULE_PARM(ptlrpcd_bind_policy, "i", int, 0644,
-               "Ptlrpcd threads binding mode.");
+module_param(ptlrpcd_bind_policy, int, 0644);
+MODULE_PARM_DESC(ptlrpcd_bind_policy, "Ptlrpcd threads binding mode.");
 static struct ptlrpcd *ptlrpcds;
 
 struct mutex ptlrpcd_mutex;
index 21de868da522ae813d798d588132f74c5d819f7b..590fa8df8b7f827f31258126c41b2f2fa8cf5211 100644 (file)
 
 /* The following are visible and mutable through /sys/module/ptlrpc */
 int test_req_buffer_pressure = 0;
-CFS_MODULE_PARM(test_req_buffer_pressure, "i", int, 0444,
-               "set non-zero to put pressure on request buffer pools");
-CFS_MODULE_PARM(at_min, "i", int, 0644,
-               "Adaptive timeout minimum (sec)");
-CFS_MODULE_PARM(at_max, "i", int, 0644,
-               "Adaptive timeout maximum (sec)");
-CFS_MODULE_PARM(at_history, "i", int, 0644,
-               "Adaptive timeouts remember the slowest event that took place "
-               "within this period (sec)");
-CFS_MODULE_PARM(at_early_margin, "i", int, 0644,
-               "How soon before an RPC deadline to send an early reply");
-CFS_MODULE_PARM(at_extra, "i", int, 0644,
-               "How much extra time to give with each early reply");
+module_param(test_req_buffer_pressure, int, 0444);
+MODULE_PARM_DESC(test_req_buffer_pressure, "set non-zero to put pressure on request buffer pools");
+module_param(at_min, int, 0644);
+MODULE_PARM_DESC(at_min, "Adaptive timeout minimum (sec)");
+module_param(at_max, int, 0644);
+MODULE_PARM_DESC(at_max, "Adaptive timeout maximum (sec)");
+module_param(at_history, int, 0644);
+MODULE_PARM_DESC(at_history,
+                "Adaptive timeouts remember the slowest event that took place within this period (sec)");
+module_param(at_early_margin, int, 0644);
+MODULE_PARM_DESC(at_early_margin, "How soon before an RPC deadline to send an early reply");
+module_param(at_extra, int, 0644);
+MODULE_PARM_DESC(at_extra, "How much extra time to give with each early reply");
 
 
 /* forward ref */
@@ -386,7 +386,7 @@ ptlrpc_schedule_difficult_reply(struct ptlrpc_reply_state *rs)
 {
        LASSERT(spin_is_locked(&rs->rs_svcpt->scp_rep_lock));
        LASSERT(spin_is_locked(&rs->rs_lock));
-       LASSERT (rs->rs_difficult);
+       LASSERT(rs->rs_difficult);
        rs->rs_scheduled_ever = 1;  /* flag any notification attempt */
 
        if (rs->rs_scheduled) {     /* being set up or already notified */
@@ -412,7 +412,7 @@ void ptlrpc_commit_replies(struct obd_export *exp)
        spin_lock(&exp->exp_uncommitted_replies_lock);
        list_for_each_entry_safe(rs, nxt, &exp->exp_uncommitted_replies,
                                     rs_obd_list) {
-               LASSERT (rs->rs_difficult);
+               LASSERT(rs->rs_difficult);
                /* VBR: per-export last_committed */
                LASSERT(rs->rs_export);
                if (rs->rs_transno <= exp->exp_last_committed) {
@@ -796,7 +796,7 @@ ptlrpc_register_service(struct ptlrpc_service_conf *conf,
        LASSERT(rc == 0);
 
        mutex_lock(&ptlrpc_all_services_mutex);
-       list_add (&service->srv_list, &ptlrpc_all_services);
+       list_add(&service->srv_list, &ptlrpc_all_services);
        mutex_unlock(&ptlrpc_all_services_mutex);
 
        if (proc_entry != NULL)
@@ -1115,8 +1115,10 @@ static int ptlrpc_check_req(struct ptlrpc_request *req)
        }
        if (unlikely(req->rq_export->exp_obd &&
                     req->rq_export->exp_obd->obd_fail)) {
-            /* Failing over, don't handle any more reqs, send
-               error response instead. */
+               /*
+                * Failing over, don't handle any more reqs, send
+                * error response instead.
+                */
                CDEBUG(D_RPCTRACE, "Dropping req %p for failed obd %s\n",
                       req, req->rq_export->exp_obd->obd_name);
                rc = -ENODEV;
@@ -1268,7 +1270,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
                return -ETIMEDOUT;
        }
 
-       if ((lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT) == 0){
+       if (!(lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) {
                DEBUG_REQ(D_INFO, req, "Wanted to ask client for more time, "
                          "but no AT support");
                return -ENOSYS;
@@ -1777,9 +1779,9 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
 
        rc = lustre_unpack_req_ptlrpc_body(req, MSG_PTLRPC_BODY_OFF);
        if (rc) {
-               CERROR ("error unpacking ptlrpc body: ptl %d from %s x"
-                       LPU64"\n", svc->srv_req_portal,
-                       libcfs_id2str(req->rq_peer), req->rq_xid);
+               CERROR("error unpacking ptlrpc body: ptl %d from %s x"
+                      LPU64"\n", svc->srv_req_portal,
+                      libcfs_id2str(req->rq_peer), req->rq_xid);
                goto err_req;
        }
 
@@ -1798,7 +1800,7 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
                goto err_req;
        }
 
-       switch(lustre_msg_get_opc(req->rq_reqmsg)) {
+       switch (lustre_msg_get_opc(req->rq_reqmsg)) {
        case MDS_WRITEPAGE:
        case OST_WRITE:
                req->rq_bulk_write = 1;
@@ -1895,7 +1897,7 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt,
 
        ptlrpc_rqphase_move(request, RQ_PHASE_INTERPRET);
 
-       if(OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_DUMP_LOG))
+       if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_DUMP_LOG))
                libcfs_debug_dumplog();
 
        do_gettimeofday(&work_start);
@@ -1967,13 +1969,14 @@ put_conn:
        lu_context_fini(&request->rq_session);
 
        if (unlikely(cfs_time_current_sec() > request->rq_deadline)) {
-                    DEBUG_REQ(D_WARNING, request, "Request took longer "
-                              "than estimated ("CFS_DURATION_T":"CFS_DURATION_T"s);"
-                              " client may timeout.",
-                              cfs_time_sub(request->rq_deadline,
-                                           request->rq_arrival_time.tv_sec),
-                              cfs_time_sub(cfs_time_current_sec(),
-                                           request->rq_deadline));
+               DEBUG_REQ(D_WARNING, request,
+                         "Request took longer than estimated ("
+                               CFS_DURATION_T":"CFS_DURATION_T
+                               "s); client may timeout.",
+                         cfs_time_sub(request->rq_deadline,
+                                      request->rq_arrival_time.tv_sec),
+                         cfs_time_sub(cfs_time_current_sec(),
+                                      request->rq_deadline));
        }
 
        do_gettimeofday(&work_end);
@@ -2037,13 +2040,13 @@ ptlrpc_handle_rs(struct ptlrpc_reply_state *rs)
 
        exp = rs->rs_export;
 
-       LASSERT (rs->rs_difficult);
-       LASSERT (rs->rs_scheduled);
-       LASSERT (list_empty(&rs->rs_list));
+       LASSERT(rs->rs_difficult);
+       LASSERT(rs->rs_scheduled);
+       LASSERT(list_empty(&rs->rs_list));
 
        spin_lock(&exp->exp_lock);
        /* Noop if removed already */
-       list_del_init (&rs->rs_exp_list);
+       list_del_init(&rs->rs_exp_list);
        spin_unlock(&exp->exp_lock);
 
        /* The disk commit callback holds exp_uncommitted_replies_lock while it
@@ -2113,9 +2116,9 @@ ptlrpc_handle_rs(struct ptlrpc_reply_state *rs)
                /* Off the net */
                spin_unlock(&rs->rs_lock);
 
-               class_export_put (exp);
+               class_export_put(exp);
                rs->rs_export = NULL;
-               ptlrpc_rs_decref (rs);
+               ptlrpc_rs_decref(rs);
                if (atomic_dec_and_test(&svcpt->scp_nreps_difficult) &&
                    svc->srv_is_stopping)
                        wake_up_all(&svcpt->scp_waitq);
index 9890bd9cfb93ae7f150da6ad6f90e414b9c72e56..e3f02c77f3b9c98b04858e1140db906f5a2cff0e 100644 (file)
@@ -49,9 +49,10 @@ void lustre_assert_wire_constants(void)
 {
         /* Wire protocol assertions generated by 'wirecheck'
          * (make -C lustre/utils newwiretest)
-         * running on Linux deva 2.6.32.279.lustre #5 SMP Tue Apr 9 22:52:17 CST 2013 x86_64 x86_64 x
-         * with gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC)  */
-
+         * running on Linux centos6-bis 2.6.32-358.0.1.el6-head
+         * #3 SMP Wed Apr 17 17:37:43 CEST 2013
+         * with gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC)
+         */
 
        /* Constants... */
        LASSERTF(PTL_RPC_MSG_REQUEST == 4711, "found %lld\n",
@@ -1335,6 +1336,8 @@ void lustre_assert_wire_constants(void)
                 OBD_MD_REINT);
        LASSERTF(OBD_MD_MEA == (0x0000000400000000ULL), "found 0x%.16llxULL\n",
                 OBD_MD_MEA);
+       LASSERTF(OBD_MD_TSTATE == (0x0000000800000000ULL),
+                "found 0x%.16llxULL\n", OBD_MD_TSTATE);
        LASSERTF(OBD_MD_FLXATTR == (0x0000001000000000ULL), "found 0x%.16llxULL\n",
                 OBD_MD_FLXATTR);
        LASSERTF(OBD_MD_FLXATTRLS == (0x0000002000000000ULL), "found 0x%.16llxULL\n",
@@ -1918,10 +1921,11 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct mdt_body, blocks));
        LASSERTF((int)sizeof(((struct mdt_body *)0)->blocks) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct mdt_body *)0)->blocks));
-       LASSERTF((int)offsetof(struct mdt_body, unused1) == 96, "found %lld\n",
-                (long long)(int)offsetof(struct mdt_body, unused1));
-       LASSERTF((int)sizeof(((struct mdt_body *)0)->unused1) == 8, "found %lld\n",
-                (long long)(int)sizeof(((struct mdt_body *)0)->unused1));
+       LASSERTF((int)offsetof(struct mdt_body, t_state) == 96, "found %lld\n",
+                (long long)(int)offsetof(struct mdt_body, t_state));
+       LASSERTF((int)sizeof(((struct mdt_body *)0)->t_state) == 8,
+                "found %lld\n",
+                (long long)(int)sizeof(((struct mdt_body *)0)->t_state));
        LASSERTF((int)offsetof(struct mdt_body, fsuid) == 104, "found %lld\n",
                 (long long)(int)offsetof(struct mdt_body, fsuid));
        LASSERTF((int)sizeof(((struct mdt_body *)0)->fsuid) == 4, "found %lld\n",
index 766a071b0a224a4b7c6ad5b0a8c4139341981f5f..b7044a380fe316fcb2cb37657f61377bfd9ef688 100644 (file)
@@ -1009,7 +1009,7 @@ static int ipipe_validate_yee_params(struct vpfe_ipipe_yee *yee)
            yee->es_ofst_grad > YEE_THR_MASK)
                return -EINVAL;
 
-       for (i = 0; i < VPFE_IPIPE_MAX_SIZE_YEE_LUT ; i++)
+       for (i = 0; i < VPFE_IPIPE_MAX_SIZE_YEE_LUT; i++)
                if (yee->table[i] > YEE_ENTRY_MASK)
                        return -EINVAL;
 
index e027b92b54ef197720ca12cedd2c28aae3c1d6bc..2d36b60bdbf166e369049e82ef2ce3f15de26f45 100644 (file)
@@ -791,7 +791,7 @@ ipipe_set_3d_lut_regs(void *__iomem base_addr, void *__iomem isp5_base_addr,
 
        /* valied table */
        tbl = lut_3d->table;
-       for (i = 0 ; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++) {
+       for (i = 0; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++) {
                /* Each entry has 0-9 (B), 10-19 (G) and
                20-29 R values */
                val = tbl[i].b & D3_LUT_ENTRY_MASK;
@@ -899,7 +899,7 @@ ipipe_set_gbce_regs(void *__iomem base_addr, void *__iomem isp5_base_addr,
        if (!gbce->table)
                return;
 
-       for (count = 0; count < VPFE_IPIPE_MAX_SIZE_GBCE_LUT ; count += 2)
+       for (count = 0; count < VPFE_IPIPE_MAX_SIZE_GBCE_LUT; count += 2)
                w_ip_table(isp5_base_addr, ((gbce->table[count + 1] & mask) <<
                GBCE_ENTRY_SHIFT) | (gbce->table[count] & mask),
                ((count/2) << 2) + GBCE_TB_START_ADDR);
index c2d0e58afc340f4cecf62b392d67aa269c9cfb22..479953b2d983f9da207ebec75da16b190ec3229c 100644 (file)
@@ -722,7 +722,8 @@ static int vti_bitlen(struct go7007 *go)
 {
        unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
 
-       for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i);
+       for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i)
+               ;
        return i + 1;
 }
 
index 58684da45e6c2927cb042ceb0dc4a364b3037a5c..b658c2316df340b4480ed72ca90d457d913e3691 100644 (file)
@@ -15,6 +15,8 @@
  * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -661,7 +663,7 @@ static int go7007_usb_interface_reset(struct go7007 *go)
 
        if (usb->board->flags & GO7007_USB_EZUSB) {
                /* Reset buffer in EZ-USB */
-               dev_dbg(go->dev, "resetting EZ-USB buffers\n");
+               pr_debug("resetting EZ-USB buffers\n");
                if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
                    go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
                        return -1;
@@ -689,7 +691,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
        u16 status_reg = 0;
        int timeout = 500;
 
-       dev_dbg(go->dev, "WriteInterrupt: %04x %04x\n", addr, data);
+       pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
 
        for (i = 0; i < 100; ++i) {
                r = usb_control_msg(usb->usbdev,
@@ -734,7 +736,7 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
        int r;
        int timeout = 500;
 
-       dev_dbg(go->dev, "WriteInterrupt: %04x %04x\n", addr, data);
+       pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
 
        go->usb_buf[0] = data & 0xff;
        go->usb_buf[1] = data >> 8;
@@ -771,7 +773,7 @@ static void go7007_usb_readinterrupt_complete(struct urb *urb)
                go->interrupt_available = 1;
                go->interrupt_data = __le16_to_cpu(regs[0]);
                go->interrupt_value = __le16_to_cpu(regs[1]);
-               dev_dbg(go->dev, "ReadInterrupt: %04x %04x\n",
+               pr_debug("ReadInterrupt: %04x %04x\n",
                                go->interrupt_value, go->interrupt_data);
        }
 
@@ -891,7 +893,7 @@ static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
        int transferred, pipe;
        int timeout = 500;
 
-       dev_dbg(go->dev, "DownloadBuffer sending %d bytes\n", len);
+       pr_debug("DownloadBuffer sending %d bytes\n", len);
 
        if (usb->board->flags & GO7007_USB_EZUSB)
                pipe = usb_sndbulkpipe(usb->usbdev, 2);
@@ -977,7 +979,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
                                !(msgs[i].flags & I2C_M_RD) &&
                                (msgs[i + 1].flags & I2C_M_RD)) {
 #ifdef GO7007_I2C_DEBUG
-                       dev_dbg(go->dev, "i2c write/read %d/%d bytes on %02x\n",
+                       pr_debug("i2c write/read %d/%d bytes on %02x\n",
                                msgs[i].len, msgs[i + 1].len, msgs[i].addr);
 #endif
                        buf[0] = 0x01;
@@ -988,7 +990,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
                        buf[buf_len++] = msgs[++i].len;
                } else if (msgs[i].flags & I2C_M_RD) {
 #ifdef GO7007_I2C_DEBUG
-                       dev_dbg(go->dev, "i2c read %d bytes on %02x\n",
+                       pr_debug("i2c read %d bytes on %02x\n",
                                        msgs[i].len, msgs[i].addr);
 #endif
                        buf[0] = 0x01;
@@ -998,7 +1000,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
                        buf_len = 4;
                } else {
 #ifdef GO7007_I2C_DEBUG
-                       dev_dbg(go->dev, "i2c write %d bytes on %02x\n",
+                       pr_debug("i2c write %d bytes on %02x\n",
                                        msgs[i].len, msgs[i].addr);
 #endif
                        buf[0] = 0x00;
@@ -1057,7 +1059,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
        char *name;
        int video_pipe, i, v_urb_len;
 
-       dev_dbg(go->dev, "probing new GO7007 USB board\n");
+       pr_debug("probing new GO7007 USB board\n");
 
        switch (id->driver_info) {
        case GO7007_BOARDID_MATRIX_II:
@@ -1097,13 +1099,13 @@ static int go7007_usb_probe(struct usb_interface *intf,
                board = &board_px_tv402u;
                break;
        case GO7007_BOARDID_LIFEVIEW_LR192:
-               dev_err(go->dev, "The Lifeview TV Walker Ultra is not supported. Sorry!\n");
+               dev_err(&intf->dev, "The Lifeview TV Walker Ultra is not supported. Sorry!\n");
                return -ENODEV;
                name = "Lifeview TV Walker Ultra";
                board = &board_lifeview_lr192;
                break;
        case GO7007_BOARDID_SENSORAY_2250:
-               dev_info(go->dev, "Sensoray 2250 found\n");
+               dev_info(&intf->dev, "Sensoray 2250 found\n");
                name = "Sensoray 2250/2251";
                board = &board_sensoray_2250;
                break;
@@ -1112,7 +1114,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
                board = &board_ads_usbav_709;
                break;
        default:
-               dev_err(go->dev, "unknown board ID %d!\n",
+               dev_err(&intf->dev, "unknown board ID %d!\n",
                                (unsigned int)id->driver_info);
                return -ENODEV;
        }
@@ -1247,7 +1249,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
                                        sizeof(go->name));
                        break;
                default:
-                       dev_dbg(go->dev, "unable to detect tuner type!\n");
+                       pr_debug("unable to detect tuner type!\n");
                        break;
                }
                /* Configure tuner mode selection inputs connected
index d80b235d72ee62c1d072139db004643b44a58859..6e2ca338cdd9917d9f2216fbc67680f84261400b 100644 (file)
@@ -86,7 +86,7 @@ static const struct go7007_board_info board_voyager = {
        .audio_main_div  = 2,
        .hpi_buffer_cap  = 7,
        .num_inputs      = 1,
-       .inputs          = {
+       .inputs          = {
                {
                        .name           = "SAA7134",
                },
index 28c8b0bcf5b2a2da86f3987389831670ccf574b6..f2dcc4a292da838cb0998d031120f2a39b93a0ac 100644 (file)
@@ -363,8 +363,8 @@ static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf)
                      /*dummy*/ir->buf_in, /*dummy*/ir->len_in,
                      /*timeout*/HZ * USB_CTRL_GET_TIMEOUT);
                if (ret < 0)
-                       printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: "
-                              "error %d\n", ir->devnum, ret);
+                       printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n",
+                              ir->devnum, ret);
                return 0;
        } else if (ret < 0)
                printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n",
index ab2ae115b524eac74a54759bc471d1c6dff2c2aa..c7d6667e7d140fbe28a10c92b688fde3e3f04275 100644 (file)
@@ -808,7 +808,8 @@ static int imon_probe(struct usb_interface *interface,
 
        /* Input endpoint is mandatory */
        if (!ir_ep_found) {
-               dev_err(dev, "%s: no valid input (IR) endpoint found.\n", __func__);
+               dev_err(dev, "%s: no valid input (IR) endpoint found.\n",
+                       __func__);
                retval = -ENODEV;
                alloc_status = 2;
                goto alloc_status_switch;
@@ -878,8 +879,8 @@ static int imon_probe(struct usb_interface *interface,
                alloc_status = 7;
                goto unlock;
        } else
-               dev_info(dev, "Registered iMON driver "
-                        "(lirc minor: %d)\n", lirc_minor);
+               dev_info(dev, "Registered iMON driver (lirc minor: %d)\n",
+                        lirc_minor);
 
        /* Needed while unregistering! */
        driver->minor = lirc_minor;
@@ -923,8 +924,8 @@ static int imon_probe(struct usb_interface *interface,
 
                if (usb_register_dev(interface, &imon_class)) {
                        /* Not a fatal error, so ignore */
-                       dev_info(dev, "%s: could not get a minor number for "
-                                "display\n", __func__);
+                       dev_info(dev, "%s: could not get a minor number for display\n",
+                                __func__);
                }
        }
 
index 2e3a98575d47f9fbdddebecdd2a17d9741ffd09e..abe0d5caa20b2e8836d2f02159647e1f0d44bdf4 100644 (file)
@@ -428,8 +428,8 @@ static int init_timing_params(unsigned int new_duty_cycle,
        period = 256 * 1000000L / freq;
        pulse_width = period * duty_cycle / 100;
        space_width = period - pulse_width;
-       dprintk("in init_timing_params, freq=%d pulse=%ld, "
-               "space=%ld\n", freq, pulse_width, space_width);
+       dprintk("in init_timing_params, freq=%d pulse=%ld, space=%ld\n",
+               freq, pulse_width, space_width);
        return 0;
 }
 #endif /* USE_RDTSC */
@@ -974,7 +974,7 @@ static void set_use_dec(void *data)
        spin_unlock_irqrestore(&hardware[type].lock, flags);
 }
 
-static ssize_t lirc_write(struct file *file, const char *buf,
+static ssize_t lirc_write(struct file *file, const char __user *buf,
                         size_t n, loff_t *ppos)
 {
        int i, count;
index 0feeaadf29dc12c47eee290c7616cfaf915e6ace..e1feb6164593484cb4eb9f286d021a9bcb2c09f3 100644 (file)
@@ -767,8 +767,8 @@ static int fw_load(struct IR_tx *tx)
        /* Request codeset data file */
        ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->l.dev);
        if (ret != 0) {
-               zilog_error("firmware haup-ir-blaster.bin not available "
-                           "(%d)\n", ret);
+               zilog_error("firmware haup-ir-blaster.bin not available (%d)\n",
+                           ret);
                ret = ret < 0 ? ret : -EFAULT;
                goto out;
        }
index 3066ee2e753be3ed887d11b9615b41b78261b6bb..bb152201e93d2292835571c838c01ebf58805ed1 100644 (file)
@@ -83,7 +83,7 @@ enum nvec_sleep_subcmds {
 
 static struct nvec_chip *nvec_power_handle;
 
-static struct mfd_cell nvec_devices[] = {
+static const struct mfd_cell nvec_devices[] = {
        {
                .name = "nvec-kbd",
                .id = 1,
@@ -681,7 +681,8 @@ static irqreturn_t nvec_interrupt(int irq, void *dev)
                        dev_err(nvec->dev,
                                "RX buffer overflow on %p: "
                                "Trying to write byte %u of %u\n",
-                               nvec->rx, nvec->rx->pos, NVEC_MSG_SIZE);
+                               nvec->rx, nvec->rx ? nvec->rx->pos : 0,
+                               NVEC_MSG_SIZE);
                break;
        default:
                nvec->state = 0;
index 92b02891704d04738365011cd28f6f93b7055dd8..26b4ec56fd30738b69a2a18ecf0d93d365e7ef08 100644 (file)
@@ -255,17 +255,19 @@ static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank)
 {
        int err;
 
+       console_lock();
        if (!lock_fb_info(dcon->fbinfo)) {
+               console_unlock();
                dev_err(&dcon->client->dev, "unable to lock framebuffer\n");
                return false;
        }
-       console_lock();
+
        dcon->ignore_fb_events = true;
        err = fb_blank(dcon->fbinfo,
                        blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
        dcon->ignore_fb_events = false;
-       console_unlock();
        unlock_fb_info(dcon->fbinfo);
+       console_unlock();
 
        if (err) {
                dev_err(&dcon->client->dev, "couldn't %sblank framebuffer\n",
index 9b86486c6b114b57fbd3792800b473fb47f445b8..02d5412478191f7e2fd552841a7a8ad0987f7fb2 100644 (file)
@@ -138,7 +138,7 @@ int oz_elt_stream_create(struct oz_elt_buf *buf, u8 id, int max_buf_count)
 
        oz_dbg(ON, "%s: (0x%x)\n", __func__, id);
 
-       st = kzalloc(sizeof(struct oz_elt_stream), GFP_ATOMIC | __GFP_ZERO);
+       st = kzalloc(sizeof(struct oz_elt_stream), GFP_ATOMIC);
        if (st == NULL)
                return -ENOMEM;
        atomic_set(&st->ref_count, 1);
index 88714ec85705f3a771edb4ecc740d06a1a8bc452..9f2dffe6e131cedca3030dc53287a59bdf49e709 100644 (file)
@@ -337,7 +337,7 @@ static void oz_rx_frame(struct sk_buff *skb)
        oz_dbg(RX_FRAMES, "RX frame PN=0x%x LPN=0x%x control=0x%x\n",
               oz_hdr->pkt_num, oz_hdr->last_pkt_num, oz_hdr->control);
        mac_hdr = skb_mac_header(skb);
-       src_addr = &mac_hdr[ETH_ALEN] ;
+       src_addr = &mac_hdr[ETH_ALEN];
        length = skb->len;
 
        /* Check the version field */
index 9f6ebdb23740596f530e9ab5d52194ca3c9c438e..a85c3d68c462b1a14b8a517445521a6df61bf64e 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
 
index 9d2d5c58add2bfbe079466e501c6b01ef1d26aa9..4483c2c0307c9a481e485d17bcecf0fd428d6d70 100644 (file)
@@ -1,16 +1,6 @@
-//-----------------------------------------------------------------------------
-//     File:
-//             Dot11d.c
-//
-//     Description:
-//             Implement 802.11d.
-//
-//-----------------------------------------------------------------------------
-
 #include "dot11d.h"
 
-void
-Dot11d_Init(struct ieee80211_device *ieee)
+void Dot11d_Init(struct ieee80211_device *ieee)
 {
        PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
 
@@ -22,23 +12,19 @@ Dot11d_Init(struct ieee80211_device *ieee)
        memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
        RESET_CIE_WATCHDOG(ieee);
 
-       printk("Dot11d_Init()\n");
+       netdev_info(ieee->dev, "Dot11d_Init()\n");
 }
 
-//
-//     Description:
-//             Reset to the state as we are just entering a regulatory domain.
-//
-void
-Dot11d_Reset(struct ieee80211_device *ieee)
+/* Reset to the state as we are just entering a regulatory domain. */
+void Dot11d_Reset(struct ieee80211_device *ieee)
 {
        u32 i;
        PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
 
-       // Clear old channel map
+       /* Clear old channel map */
        memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
        memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
-       // Set new channel map
+       /* Set new channel map */
        for (i = 1; i <= 11; i++)
                (pDot11dInfo->channel_map)[i] = 1;
 
@@ -48,36 +34,30 @@ Dot11d_Reset(struct ieee80211_device *ieee)
        pDot11dInfo->State = DOT11D_STATE_NONE;
        pDot11dInfo->CountryIeLen = 0;
        RESET_CIE_WATCHDOG(ieee);
-
-       //printk("Dot11d_Reset()\n");
 }
 
-//
-//     Description:
-//             Update country IE from Beacon or Probe Response
-//             and configure PHY for operation in the regulatory domain.
-//
-//     TODO:
-//             Configure Tx power.
-//
-//     Assumption:
-//             1. IS_DOT11D_ENABLE() is TRUE.
-//             2. Input IE is an valid one.
-//
-void
-Dot11d_UpdateCountryIe(
-       struct ieee80211_device *dev,
-       u8 *pTaddr,
-       u16     CoutryIeLen,
-       u8 *pCoutryIe
-       )
+/*
+ * Description:
+ *     Update country IE from Beacon or Probe Response and configure PHY for
+ *     operation in the regulatory domain.
+ *
+ * TODO:
+ *     Configure Tx power.
+ *
+ * Assumption:
+ *     1. IS_DOT11D_ENABLE() is TRUE.
+ *     2. Input IE is an valid one.
+ */
+void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
+                           u16 CoutryIeLen, u8 *pCoutryIe)
 {
        PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
        u8 i, j, NumTriples, MaxChnlNum;
+       u8 index, MaxTxPowerInDbm;
        PCHNL_TXPOWER_TRIPLE pTriple;
 
        if ((CoutryIeLen - 3)%3 != 0) {
-               printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+               netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
                Dot11d_Reset(dev);
                return;
        }
@@ -85,37 +65,47 @@ Dot11d_UpdateCountryIe(
        memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
        memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
        MaxChnlNum = 0;
-       NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
+       NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */
        pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
        for (i = 0; i < NumTriples; i++) {
                if (MaxChnlNum >= pTriple->FirstChnl) {
-               // It is not in a monotonically increasing order, so stop processing.
-                       printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+                       /*
+                        * It is not in a monotonically increasing order,
+                        * so stop processing.
+                        */
+                       netdev_info(dev->dev,
+                                   "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
                        Dot11d_Reset(dev);
                        return;
                }
-               if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls)) {
-               // It is not a valid set of channel id, so stop processing.
-                       printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
+               if (MAX_CHANNEL_NUMBER <
+                   (pTriple->FirstChnl + pTriple->NumChnls)) {
+                       /*
+                        * It is not a valid set of channel id,
+                        * so stop processing
+                        */
+                       netdev_info(dev->dev,
+                                   "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
                        Dot11d_Reset(dev);
                        return;
                }
 
-               for (j = 0 ; j < pTriple->NumChnls; j++) {
-                       pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
-                       pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
+               for (j = 0; j < pTriple->NumChnls; j++) {
+                       index = pTriple->FirstChnl + j;
+                       pDot11dInfo->channel_map[index] = 1;
+                       MaxTxPowerInDbm = pTriple->MaxTxPowerInDbm;
+                       pDot11dInfo->MaxTxPwrDbmList[index] = MaxTxPowerInDbm;
                        MaxChnlNum = pTriple->FirstChnl + j;
                }
 
                pTriple = (PCHNL_TXPOWER_TRIPLE)((u8 *)pTriple + 3);
        }
 #if 1
-       //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
-       printk("Channel List:");
+       netdev_info(dev->dev, "Channel List:");
        for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
                if (pDot11dInfo->channel_map[i] > 0)
-                       printk(" %d", i);
-       printk("\n");
+                       netdev_info(dev->dev, " %d", i);
+       netdev_info(dev->dev, "\n");
 #endif
 
        UPDATE_CIE_SRC(dev, pTaddr);
@@ -125,31 +115,23 @@ Dot11d_UpdateCountryIe(
        pDot11dInfo->State = DOT11D_STATE_LEARNED;
 }
 
-u8
-DOT11D_GetMaxTxPwrInDbm(
-       struct ieee80211_device *dev,
-       u8 Channel
-       )
+u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel)
 {
        PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
        u8 MaxTxPwrInDbm = 255;
 
        if (MAX_CHANNEL_NUMBER < Channel) {
-               printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
+               netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
                return MaxTxPwrInDbm;
        }
-       if (pDot11dInfo->channel_map[Channel]) {
+       if (pDot11dInfo->channel_map[Channel])
                MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
-       }
 
        return MaxTxPwrInDbm;
 }
 
 
-void
-DOT11D_ScanComplete(
-       struct ieee80211_device *dev
-       )
+void DOT11D_ScanComplete(struct ieee80211_device *dev)
 {
        PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
 
@@ -160,7 +142,7 @@ DOT11D_ScanComplete(
 
        case DOT11D_STATE_DONE:
                if (GET_CIE_WATCHDOG(dev) == 0) {
-               // Reset country IE if previous one is gone.
+                       /* Reset country IE if previous one is gone. */
                        Dot11d_Reset(dev);
                }
                break;
@@ -169,15 +151,12 @@ DOT11D_ScanComplete(
        }
 }
 
-int IsLegalChannel(
-       struct ieee80211_device *dev,
-       u8 channel
-)
+int IsLegalChannel(struct ieee80211_device *dev, u8 channel)
 {
        PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
 
        if (MAX_CHANNEL_NUMBER < channel) {
-               printk("IsLegalChannel(): Invalid Channel\n");
+               netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
                return 0;
        }
        if (pDot11dInfo->channel_map[channel] > 0)
@@ -185,10 +164,7 @@ int IsLegalChannel(
        return 0;
 }
 
-int ToLegalChannel(
-       struct ieee80211_device *dev,
-       u8 channel
-)
+int ToLegalChannel(struct ieee80211_device *dev, u8 channel)
 {
        PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
        u8 default_chn = 0;
@@ -202,7 +178,7 @@ int ToLegalChannel(
        }
 
        if (MAX_CHANNEL_NUMBER < channel) {
-               printk("IsLegalChannel(): Invalid Channel\n");
+               netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
                return default_chn;
        }
 
index 029c2cab1e0093d6779027a72870babcc958f7d8..63f4f3c72f109da9c05bc9343defb663f1b06647 100644 (file)
@@ -3,9 +3,9 @@
 
 #include "ieee80211.h"
 
-//#define ENABLE_DOT11D
+/* #define ENABLE_DOT11D */
 
-//#define DOT11D_MAX_CHNL_NUM 83
+/* #define DOT11D_MAX_CHNL_NUM 83 */
 
 typedef struct _CHNL_TXPOWER_TRIPLE {
        u8 FirstChnl;
@@ -20,18 +20,18 @@ typedef enum _DOT11D_STATE {
 }DOT11D_STATE;
 
 typedef struct _RT_DOT11D_INFO {
-       //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+       /* DECLARE_RT_OBJECT(RT_DOT12D_INFO); */
 
-       bool bEnabled; // dot11MultiDomainCapabilityEnabled
+       bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
 
-       u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
+       u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */
        u8  CountryIeBuf[MAX_IE_LEN];
-       u8  CountryIeSrcAddr[6]; // Source AP of the country IE.
+       u8  CountryIeSrcAddr[6]; /* Source AP of the country IE. */
        u8  CountryIeWatchdog;
 
-       u8  channel_map[MAX_CHANNEL_NUMBER+1];  //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
-       //u8  ChnlListLen; // #Bytes valid in ChnlList[].
-       //u8  ChnlList[DOT11D_MAX_CHNL_NUM];
+       u8  channel_map[MAX_CHANNEL_NUMBER+1];  /* !!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
+       /* u8  ChnlListLen; // #Bytes valid in ChnlList[]. */
+       /* u8  ChnlList[DOT11D_MAX_CHNL_NUM]; */
        u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
 
        DOT11D_STATE State;
@@ -58,43 +58,13 @@ typedef struct _RT_DOT11D_INFO {
 
 #define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
 
+void Dot11d_Init(struct ieee80211_device *dev);
+void Dot11d_Reset(struct ieee80211_device *dev);
+void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
+                           u16 CoutryIeLen, u8 *pCoutryIe);
+u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel);
+void DOT11D_ScanComplete(struct ieee80211_device *dev);
+int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
+int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
 
-void
-Dot11d_Init(
-       struct ieee80211_device *dev
-       );
-
-void
-Dot11d_Reset(
-       struct ieee80211_device *dev
-       );
-
-void
-Dot11d_UpdateCountryIe(
-       struct ieee80211_device *dev,
-       u8 *            pTaddr,
-       u16     CoutryIeLen,
-       u8 * pCoutryIe
-       );
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
-       struct ieee80211_device *dev,
-       u8 Channel
-       );
-
-void
-DOT11D_ScanComplete(
-       struct ieee80211_device * dev
-       );
-
-int IsLegalChannel(
-       struct ieee80211_device * dev,
-       u8 channel
-);
-
-int ToLegalChannel(
-       struct ieee80211_device * dev,
-       u8 channel
-);
-#endif // #ifndef __INC_DOT11D_H
+#endif /*  #ifndef __INC_DOT11D_H */
index 7f015499cfae98ffadb41ba9ac516f3165326fe2..09ffd9bc89918240d33947c795f347610193be97 100644 (file)
@@ -90,6 +90,9 @@
 
 #define        IEEE_CRYPT_ALG_NAME_LEN                 16
 
+extern int ieee80211_crypto_tkip_init(void);
+extern void ieee80211_crypto_tkip_exit(void);
+
 //by amy for ps
 typedef struct ieee_param {
        u32 cmd;
@@ -1237,7 +1240,8 @@ static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
        return 1;
 }
 
-static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
+                                         int mode)
 {
        /*
         * It is possible for both access points and our device to support
@@ -1300,19 +1304,16 @@ extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
 
 /* ieee80211_tx.c */
 
-extern int ieee80211_encrypt_fragment(
-       struct ieee80211_device *ieee,
-       struct sk_buff *frag,
-       int hdr_len);
+extern int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
+                                     struct sk_buff *frag, int hdr_len);
 
-extern int ieee80211_rtl_xmit(struct sk_buff *skb,
-                         struct net_device *dev);
+extern int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev);
 extern void ieee80211_txb_free(struct ieee80211_txb *);
 
 
 /* ieee80211_rx.c */
 extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
-                       struct ieee80211_rx_stats *rx_stats);
+                           struct ieee80211_rx_stats *rx_stats);
 extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
                             struct ieee80211_hdr_4addr *header,
                             struct ieee80211_rx_stats *stats);
@@ -1328,25 +1329,28 @@ extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
                                   struct iw_request_info *info,
                                   union iwreq_data *wrqu, char *key);
 extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data* wrqu, char *extra);
+                                      struct iw_request_info *info,
+                                      union iwreq_data *wrqu, char *extra);
 int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
-                               struct iw_request_info *info,
-                               struct iw_param *data, char *extra);
+                         struct iw_request_info *info,
+                         struct iw_param *data, char *extra);
 int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra);
+                         struct iw_request_info *info,
+                         union iwreq_data *wrqu, char *extra);
 
 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
 /* ieee80211_softmac.c */
 extern short ieee80211_is_54g(const struct ieee80211_network *net);
 extern short ieee80211_is_shortslot(const struct ieee80211_network *net);
-extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
-                       struct ieee80211_rx_stats *rx_stats, u16 type,
-                       u16 stype);
-extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
-
-extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
+extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee,
+                                     struct sk_buff *skb,
+                                     struct ieee80211_rx_stats *rx_stats,
+                                     u16 type, u16 stype);
+extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee,
+                                     struct ieee80211_network *net);
+
+extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb,
+                                  struct ieee80211_device *ieee);
 extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
 extern void ieee80211_start_bss(struct ieee80211_device *ieee);
 extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
@@ -1368,16 +1372,17 @@ extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
 extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
 extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
 extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
+extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee,
+                                         struct iw_point *p);
 extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
 extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
-extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn);
+extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta,
+                              u8 asRsn);
 extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee);
 
 //Add for RF power on power off by lizhaoming 080512
-extern void SendDisassociation(struct ieee80211_device *ieee,
-                                u8*                     asSta,
-                        u8                      asRsn);
+extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta,
+                              u8 asRsn);
 
 /* ieee80211_crypt_ccmp&tkip&wep.c */
 extern void ieee80211_tkip_null(void);
@@ -1386,64 +1391,72 @@ extern void ieee80211_ccmp_null(void);
 /* ieee80211_softmac_wx.c */
 
 extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *ext);
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *ext);
 
 extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
-                        struct iw_request_info *info,
-                        union iwreq_data *awrq,
-                        char *extra);
+                               struct iw_request_info *info,
+                               union iwreq_data *awrq,
+                               char *extra);
 
-extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
+extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee,
+                                 struct iw_request_info *a,
+                                 union iwreq_data *wrqu, char *b);
 
 extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra);
+                                struct iw_request_info *info,
+                                union iwreq_data *wrqu, char *extra);
 
 extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra);
+                                struct iw_request_info *info,
+                                union iwreq_data *wrqu, char *extra);
 
-extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
+extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee,
+                                struct iw_request_info *a,
+                                union iwreq_data *wrqu, char *b);
 
-extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
+extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee,
+                                struct iw_request_info *a,
+                                union iwreq_data *wrqu, char *b);
 
 extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
-                             struct iw_request_info *a,
-                             union iwreq_data *wrqu, char *extra);
+                                 struct iw_request_info *a,
+                                 union iwreq_data *wrqu, char *extra);
 
-extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
+extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee,
+                                struct iw_request_info *a,
+                                union iwreq_data *wrqu, char *b);
 
-extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
+extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee,
+                                struct iw_request_info *a,
+                                union iwreq_data *wrqu, char *b);
 
-extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b);
+extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
+                                struct iw_request_info *a,
+                                union iwreq_data *wrqu, char *b);
 
 extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
 
 extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra);
+                                 struct iw_request_info *info,
+                                 union iwreq_data *wrqu, char *extra);
 
 extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
                                 struct iw_request_info *info,
                                 union iwreq_data *wrqu, char *extra);
 
+extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
+                                 struct iw_request_info *info,
+                                 union iwreq_data *wrqu, char *extra);
+
 extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
-                                struct iw_request_info *info,
-                                union iwreq_data *wrqu, char *extra);
+                                 struct iw_request_info *info,
+                                 union iwreq_data *wrqu, char *extra);
 
 extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
 
-extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
+extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
+                                            short pwr);
 
 extern const long ieee80211_wlan_frequencies[];
 
index 694eae3d4fdaffb279811650bed898b69b6c4c82..a0340ee9d8b780fe2327007a9b7f68405129e429 100644 (file)
@@ -39,8 +39,7 @@ struct ieee80211_crypto {
 
 static struct ieee80211_crypto *hcrypt;
 
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
-                                          int force)
+void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
 {
        struct list_head *ptr, *n;
        struct ieee80211_crypt_data *entry;
index f5949e89e5c233b898f31fbc1e8daade9d826e01..0e8392acdeacb6836c38a232566faf400d4db980 100644 (file)
@@ -11,7 +11,6 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-//#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -61,7 +60,7 @@ struct ieee80211_ccmp_data {
 };
 
 void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
-                            const u8 pt[16], u8 ct[16])
+                               const u8 pt[16], u8 ct[16])
 {
        crypto_cipher_encrypt_one((void *)tfm, ct, pt);
 }
@@ -130,7 +129,6 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
        qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
                       (WLAN_FC_GET_STYPE(fc) & 0x08));
        */
-       // fixed by David :2006.9.6
        qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
                       (WLAN_FC_GET_STYPE(fc) & 0x80));
        aad_len = 22;
@@ -212,7 +210,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        pos = skb_push(skb, CCMP_HDR_LEN);
        memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
        pos += hdr_len;
-//     mic = skb_put(skb, CCMP_MIC_LEN);
 
        i = CCMP_PN_LEN - 1;
        while (i >= 0) {
@@ -232,7 +229,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        *pos++ = key->tx_pn[0];
 
        hdr = (struct ieee80211_hdr_4addr *)skb->data;
-       //mic is moved to here by john
        mic = skb_put(skb, CCMP_MIC_LEN);
 
        ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
@@ -416,9 +412,8 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
 static char *ieee80211_ccmp_print_stats(char *p, void *priv)
 {
        struct ieee80211_ccmp_data *ccmp = priv;
-       p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
-                    "tx_pn=%pm rx_pn=%pm "
-                    "format_errors=%d replays=%d decrypt_errors=%d\n",
+       p += sprintf(p,
+                    "key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n",
                     ccmp->key_idx, ccmp->key_set,
                     ccmp->tx_pn, ccmp->rx_pn,
                     ccmp->dot11RSNAStatsCCMPFormatErrors,
@@ -430,7 +425,6 @@ static char *ieee80211_ccmp_print_stats(char *p, void *priv)
 
 void ieee80211_ccmp_null(void)
 {
-//    printk("============>%s()\n", __func__);
        return;
 }
 static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
index da24e430ca1322a913fd9d2a02452c28cffab6d0..34a10d1868b4ed5c81dc9b2b96cac455a6a44dd6 100644 (file)
@@ -9,7 +9,6 @@
  * more details.
  */
 
-//#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -65,7 +64,7 @@ struct ieee80211_tkip_data {
        u8 rx_hdr[16], tx_hdr[16];
 };
 
-static void * ieee80211_tkip_init(int key_idx)
+static void *ieee80211_tkip_init(int key_idx)
 {
        struct ieee80211_tkip_data *priv;
 
@@ -304,8 +303,8 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
 
 static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
-        struct ieee80211_tkip_data *tkey = priv;
-        struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
+       struct ieee80211_tkip_data *tkey = priv;
+       struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
        int len;
        u8  *pos;
        struct ieee80211_hdr_4addr *hdr;
@@ -467,27 +466,27 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        return keyidx;
 }
 
-static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
-                       u8 * data, size_t data_len, u8 * mic)
+static int michael_mic(struct crypto_hash *tfm_michael, u8 *key, u8 *hdr,
+                       u8 *data, size_t data_len, u8 *mic)
 {
-        struct hash_desc desc;
-        struct scatterlist sg[2];
+       struct hash_desc desc;
+       struct scatterlist sg[2];
 
-        if (tfm_michael == NULL) {
-                printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
-                return -1;
-        }
+       if (tfm_michael == NULL) {
+               printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
+               return -1;
+       }
 
        sg_init_table(sg, 2);
        sg_set_buf(&sg[0], hdr, 16);
        sg_set_buf(&sg[1], data, data_len);
 
-        if (crypto_hash_setkey(tfm_michael, key, 8))
-                return -1;
+       if (crypto_hash_setkey(tfm_michael, key, 8))
+               return -1;
 
-        desc.tfm = tfm_michael;
-        desc.flags = 0;
-        return crypto_hash_digest(&desc, sg, data_len + 16, mic);
+       desc.tfm = tfm_michael;
+       desc.flags = 0;
+       return crypto_hash_digest(&desc, sg, data_len + 16, mic);
 }
 
 static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
@@ -521,7 +520,8 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
 }
 
 
-static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
+static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
+                                    void *priv)
 {
        struct ieee80211_tkip_data *tkey = priv;
        u8 *pos;
@@ -538,12 +538,9 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
 
        michael_mic_hdr(skb, tkey->tx_hdr);
 
-       // { david, 2006.9.1
-       // fix the wpa process with wmm enabled.
        if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
                tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
        }
-       // }
        pos = skb_put(skb, 8);
 
        if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
@@ -554,8 +551,8 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
 }
 
 static void ieee80211_michael_mic_failure(struct net_device *dev,
-                                      struct ieee80211_hdr_4addr *hdr,
-                                      int keyidx)
+                                         struct ieee80211_hdr_4addr *hdr,
+                                         int keyidx)
 {
        union iwreq_data wrqu;
        struct iw_michaelmicfailure ev;
@@ -575,7 +572,7 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
 }
 
 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
-                                    int hdr_len, void *priv)
+                                       int hdr_len, void *priv)
 {
        struct ieee80211_tkip_data *tkey = priv;
        u8 mic[8];
@@ -587,12 +584,9 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
                return -1;
 
        michael_mic_hdr(skb, tkey->rx_hdr);
-       // { david, 2006.9.1
-       // fix the wpa process with wmm enabled.
        if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
                tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
        }
-       // }
 
        if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
                        skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
@@ -688,7 +682,7 @@ static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
 }
 
 
-static char * ieee80211_tkip_print_stats(char *p, void *priv)
+static char *ieee80211_tkip_print_stats(char *p, void *priv)
 {
        struct ieee80211_tkip_data *tkip = priv;
        p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
@@ -746,6 +740,4 @@ void ieee80211_crypto_tkip_exit(void)
 
 void ieee80211_tkip_null(void)
 {
-//    printk("============>%s()\n", __func__);
-        return;
 }
index 304579096562aa0011f0159e0b26665aeb4815ea..b522b57a26916ad1d7e96c334f42bb087fcddded 100644 (file)
@@ -337,8 +337,9 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 /* Called only as a tasklet (software IRQ), by ieee80211_rx */
 static inline int
-ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *skb,
-                            int keyidx, struct ieee80211_crypt_data *crypt)
+ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
+                               struct sk_buff *skb, int keyidx,
+                               struct ieee80211_crypt_data *crypt)
 {
        struct ieee80211_hdr_4addr *hdr;
        int res, hdrlen;
@@ -366,7 +367,7 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *s
 /* this function is stolen from ipw2200 driver*/
 #define IEEE_PACKET_RETRY_TIME (5*HZ)
 static int is_duplicate_packet(struct ieee80211_device *ieee,
-                                     struct ieee80211_hdr_4addr *header)
+                              struct ieee80211_hdr_4addr *header)
 {
        u16 fc = le16_to_cpu(header->frame_ctl);
        u16 sc = le16_to_cpu(header->seq_ctl);
@@ -467,7 +468,7 @@ drop:
  * IEEE 802.11 format, i.e., in the format it was sent over air.
  * This function is called only as a tasklet (software IRQ). */
 int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
-                struct ieee80211_rx_stats *rx_stats)
+                    struct ieee80211_rx_stats *rx_stats)
 {
        struct net_device *dev = ieee->dev;
        //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
@@ -794,9 +795,7 @@ static inline int ieee80211_is_ofdm_rate(u8 rate)
        return 0;
 }
 
-static inline int ieee80211_SignalStrengthTranslate(
-       int  CurrSS
-       )
+static inline int ieee80211_SignalStrengthTranslate(int CurrSS)
 {
        int RetSS;
 
@@ -831,12 +830,10 @@ static inline int ieee80211_SignalStrengthTranslate(
        return RetSS;
 }
 
-static inline void ieee80211_extract_country_ie(
-       struct ieee80211_device *ieee,
-       struct ieee80211_info_element *info_element,
-       struct ieee80211_network *network,
-       u8 *addr2
-)
+static inline void
+ieee80211_extract_country_ie(struct ieee80211_device *ieee,
+                            struct ieee80211_info_element *info_element,
+                            struct ieee80211_network *network, u8 *addr2)
 {
        if (IS_DOT11D_ENABLE(ieee)) {
                if (info_element->len != 0) {
@@ -858,10 +855,8 @@ static inline void ieee80211_extract_country_ie(
 
 }
 
-static int
-ieee80211_TranslateToDbm(
-       unsigned char SignalStrengthIndex       // 0-100 index.
-       )
+/* SignalStrengthIndex is 0-100 */
+static int ieee80211_TranslateToDbm(unsigned char SignalStrengthIndex)
 {
        unsigned char SignalPower; // in dBm.
 
@@ -1197,7 +1192,7 @@ static inline int is_same_network(struct ieee80211_network *src,
 }
 
 inline void update_network(struct ieee80211_network *dst,
-                                 struct ieee80211_network *src)
+                          struct ieee80211_network *src)
 {
        unsigned char quality = src->stats.signalstrength;
        unsigned char signal = 0;
@@ -1281,10 +1276,10 @@ inline void update_network(struct ieee80211_network *dst,
 }
 
 
-inline void ieee80211_process_probe_response(
-       struct ieee80211_device *ieee,
-       struct ieee80211_probe_response *beacon,
-       struct ieee80211_rx_stats *stats)
+inline void
+ieee80211_process_probe_response(struct ieee80211_device *ieee,
+                                struct ieee80211_probe_response *beacon,
+                                struct ieee80211_rx_stats *stats)
 {
        struct ieee80211_network network;
        struct ieee80211_network *target;
index 029070603f661861d9081b374b47ffb6873fd0b8..3af1bf965981896f18b0dce9a4dfc643492c3a91 100644 (file)
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/etherdevice.h>
 
 #include "dot11d.h"
 u8 rsn_authen_cipher_suite[16][4] = {
-       {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
-       {0x00,0x0F,0xAC,0x01}, //WEP-40         //RSNA default
-       {0x00,0x0F,0xAC,0x02}, //TKIP           //NONE          //{used just as default}
-       {0x00,0x0F,0xAC,0x03}, //WRAP-historical
-       {0x00,0x0F,0xAC,0x04}, //CCMP
-       {0x00,0x0F,0xAC,0x05}, //WEP-104
+       {0x00, 0x0F, 0xAC, 0x00}, //Use group key, //Reserved
+       {0x00, 0x0F, 0xAC, 0x01}, //WEP-40         //RSNA default
+       {0x00, 0x0F, 0xAC, 0x02}, //TKIP           //NONE               //{used just as default}
+       {0x00, 0x0F, 0xAC, 0x03}, //WRAP-historical
+       {0x00, 0x0F, 0xAC, 0x04}, //CCMP
+       {0x00, 0x0F, 0xAC, 0x05}, //WEP-104
 };
 
 short ieee80211_is_54g(const struct ieee80211_network *net)
@@ -106,7 +106,8 @@ void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
 }
 
 
-void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
+void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p)
+{
        u8 *tag = *tag_p;
 
        *tag++ = MFIE_TYPE_GENERIC; //0
@@ -118,30 +119,28 @@ void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
        *tag++ = 0x00;
        *tag++ = 0x01;
 #ifdef SUPPORT_USPD
-       if(ieee->current_network.wmm_info & 0x80) {
+       if (ieee->current_network.wmm_info & 0x80)
                *tag++ = 0x0f|MAX_SP_Len;
-       } else {
+       else
                *tag++ = MAX_SP_Len;
-       }
 #else
        *tag++ = MAX_SP_Len;
 #endif
        *tag_p = tag;
 }
 
-void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
+void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p)
+{
        u8 *tag = *tag_p;
-
-        *tag++ = MFIE_TYPE_GENERIC; //0
-        *tag++ = 7;
-        *tag++ = 0x00;
-        *tag++ = 0xe0;
-        *tag++ = 0x4c;
-        *tag++ = 0x01;//5
-        *tag++ = 0x02;
-        *tag++ = 0x11;
+       *tag++ = MFIE_TYPE_GENERIC; /* 0 */
+       *tag++ = 7;
+       *tag++ = 0x00;
+       *tag++ = 0xe0;
+       *tag++ = 0x4c;
+       *tag++ = 0x01; /* 5 */
+       *tag++ = 0x02;
+       *tag++ = 0x11;
        *tag++ = 0x00;
-
        *tag_p = tag;
        printk(KERN_ALERT "This is enable turbo mode IE process\n");
 }
@@ -187,7 +186,8 @@ void init_mgmt_queue(struct ieee80211_device *ieee)
 
 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
 
-inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
+inline void softmac_mgmt_xmit(struct sk_buff *skb,
+                             struct ieee80211_device *ieee)
 {
        unsigned long flags;
        short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
@@ -238,7 +238,8 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee
 }
 
 
-inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
+inline void softmac_ps_mgmt_xmit(struct sk_buff *skb,
+                                struct ieee80211_device *ieee)
 {
 
        short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
@@ -276,10 +277,9 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i
 //     dev_kfree_skb_any(skb);//edit by thomas
 }
 //by amy for power save
-inline struct sk_buff *ieee80211_disassociate_skb(
-                                                       struct ieee80211_network *beacon,
-                                                       struct ieee80211_device *ieee,
-                                                       u8      asRsn)
+inline struct sk_buff *
+ieee80211_disassociate_skb(struct ieee80211_network *beacon,
+                          struct ieee80211_device *ieee, u8 asRsn)
 {
        struct sk_buff *skb;
        struct ieee80211_disassoc_frame *disass;
@@ -299,12 +299,7 @@ inline struct sk_buff *ieee80211_disassociate_skb(
        disass->reasoncode = asRsn;
        return skb;
 }
-void
-SendDisassociation(
-        struct ieee80211_device *ieee,
-        u8*                     asSta,
-        u8                      asRsn
-)
+void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, u8 asRsn)
 {
         struct ieee80211_network *beacon = &ieee->current_network;
         struct sk_buff *skb;
@@ -735,8 +730,9 @@ void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
 
 }
 
-inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
-       struct ieee80211_device *ieee, int challengelen)
+inline struct sk_buff *
+ieee80211_authentication_req(struct ieee80211_network *beacon,
+                            struct ieee80211_device *ieee, int challengelen)
 {
        struct sk_buff *skb;
        struct ieee80211_authentication *auth;
@@ -768,7 +764,8 @@ inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *be
 
 }
 
-static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
+static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee,
+                                           u8 *dest)
 {
        u8 *tag;
        int beacon_size;
@@ -969,7 +966,7 @@ static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
 
 }
 
-struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
+struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee, short pwr)
 {
        struct sk_buff *skb;
        struct ieee80211_hdr_3addr* hdr;
@@ -995,7 +992,7 @@ struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
 }
 
 
-void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8dest)
+void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
 {
        struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
 
@@ -1006,7 +1003,7 @@ void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
 }
 
 
-void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8dest)
+void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8 *dest)
 {
        struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
 
@@ -1029,7 +1026,9 @@ void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
 }
 
 
-inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
+inline struct sk_buff *
+ieee80211_association_req(struct ieee80211_network *beacon,
+                         struct ieee80211_device *ieee)
 {
        struct sk_buff *skb;
        //unsigned long flags;
@@ -1200,7 +1199,8 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee)
        }
 }
 
-void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
+void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge,
+                                 int chlen)
 {
        u8 *c;
        struct sk_buff *skb;
@@ -1310,7 +1310,8 @@ void ieee80211_associate_procedure_wq(struct work_struct *work)
        up(&ieee->wx_sem);
 }
 
-inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
+inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee,
+                                     struct ieee80211_network *net)
 {
        u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
        int tmp_ssid_len = 0;
@@ -1423,7 +1424,7 @@ void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
 }
 
 
-static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
+static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
 {
        struct ieee80211_authentication *a;
        u8 *t;
@@ -1449,7 +1450,7 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
 }
 
 
-int auth_rq_parse(struct sk_buff *skb,u8* dest)
+int auth_rq_parse(struct sk_buff *skb, u8 *dest)
 {
        struct ieee80211_authentication *a;
 
@@ -1467,7 +1468,8 @@ int auth_rq_parse(struct sk_buff *skb,u8* dest)
        return WLAN_STATUS_SUCCESS;
 }
 
-static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
+static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb,
+                           u8 *src)
 {
        u8 *tag;
        u8 *skbend;
@@ -1505,7 +1507,7 @@ static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 }
 
-int assoc_rq_parse(struct sk_buff *skb,u8* dest)
+int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
 {
        struct ieee80211_assoc_request_frame *a;
 
@@ -1536,8 +1538,8 @@ static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
        return le16_to_cpu(a->status);
 }
 
-static inline void
-ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
+static inline void ieee80211_rx_probe_rq(struct ieee80211_device *ieee,
+                                        struct sk_buff *skb)
 {
        u8 dest[ETH_ALEN];
 
@@ -1551,8 +1553,8 @@ ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
        }
 }
 
-inline void
-ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
+inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee,
+                                struct sk_buff *skb)
 {
        u8 dest[ETH_ALEN];
        int status;
@@ -1595,7 +1597,8 @@ void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
 }
 
 
-short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
+short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
+                            u32 *time_l)
 {
         int timeout = 0;
 
@@ -1770,10 +1773,10 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
        spin_unlock_irqrestore(&ieee->lock, flags);
 }
 
-inline int
-ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
-                       struct ieee80211_rx_stats *rx_stats, u16 type,
-                       u16 stype)
+inline int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee,
+                                     struct sk_buff *skb,
+                                     struct ieee80211_rx_stats *rx_stats,
+                                     u16 type, u16 stype)
 {
        struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
        u16 errcode;
@@ -1976,7 +1979,8 @@ associate_complete:
  * to the driver later, when it wakes the queue.
  */
 
-void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
+void ieee80211_softmac_xmit(struct ieee80211_txb *txb,
+                           struct ieee80211_device *ieee)
 {
 
 
@@ -2619,7 +2623,8 @@ static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
 }
 
 
-void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
+void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie,
+                              int wpa_ie_len)
 {
        /* make sure WPA is enabled */
        ieee80211_wpa_enable(ieee, 1);
@@ -2628,7 +2633,8 @@ void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int
 }
 
 
-static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
+static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command,
+                             int reason)
 {
 
        int ret = 0;
@@ -2652,7 +2658,7 @@ static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int re
 
 
 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
-                             struct ieee_param *param, int plen)
+                                   struct ieee_param *param, int plen)
 {
        u8 *buf;
 
@@ -2706,7 +2712,8 @@ static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
        return ret;
 }
 
-static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
+static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name,
+                                  u32 value)
 {
        int ret=0;
        unsigned long flags;
@@ -2784,7 +2791,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v
 /* implementation borrowed from hostap driver */
 
 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
-                                 struct ieee_param *param, int param_len)
+                                       struct ieee_param *param, int param_len)
 {
        int ret = 0;
 
@@ -2931,7 +2938,8 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
        return ret;
 }
 
-int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
+int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee,
+                                  struct iw_point *p)
 {
        struct ieee_param *param;
        int ret=0;
index e5282068e3dee22dfeb10b665fa716212d040a29..46f35644126c3aebc7538a520daa68ddc046f248 100644 (file)
@@ -28,8 +28,9 @@ const long ieee80211_wlan_frequencies[] = {
 };
 
 
-int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b)
+int ieee80211_wx_set_freq(struct ieee80211_device *ieee,
+                         struct iw_request_info *a, union iwreq_data *wrqu,
+                         char *b)
 {
        int ret;
        struct iw_freq *fwrq = &wrqu->freq;
@@ -82,8 +83,8 @@ out:
 
 
 int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
-                            struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b)
+                         struct iw_request_info *a, union iwreq_data *wrqu,
+                         char *b)
 {
        struct iw_freq *fwrq = &wrqu->freq;
 
@@ -97,8 +98,8 @@ int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
 }
 
 int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *extra)
+                        struct iw_request_info *info, union iwreq_data *wrqu,
+                        char *extra)
 {
        unsigned long flags;
 
@@ -126,8 +127,7 @@ int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
 
 
 int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
-                        struct iw_request_info *info,
-                        union iwreq_data *awrq,
+                        struct iw_request_info *info, union iwreq_data *awrq,
                         char *extra)
 {
 
@@ -174,8 +174,9 @@ out:
        return ret;
 }
 
-int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,
-                           union iwreq_data *wrqu, char *b)
+int ieee80211_wx_get_essid(struct ieee80211_device *ieee,
+                          struct iw_request_info *a, union iwreq_data *wrqu,
+                          char *b)
 {
        int len, ret = 0;
        unsigned long flags;
@@ -211,8 +212,8 @@ out:
 }
 
 int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                         struct iw_request_info *info, union iwreq_data *wrqu,
+                         char *extra)
 {
 
        u32 target_rate = wrqu->bitrate.value;
@@ -230,8 +231,8 @@ int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
 
 
 int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                         struct iw_request_info *info, union iwreq_data *wrqu,
+                         char *extra)
 {
 
        wrqu->bitrate.value = ieee->rate * 100000;
@@ -239,8 +240,9 @@ int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
        return 0;
 }
 
-int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b)
+int ieee80211_wx_set_mode(struct ieee80211_device *ieee,
+                         struct iw_request_info *a, union iwreq_data *wrqu,
+                         char *b)
 {
 
        ieee->sync_scan_hurryup = 1;
@@ -305,8 +307,9 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work)
 
 }
 
-int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b)
+int ieee80211_wx_set_scan(struct ieee80211_device *ieee,
+                         struct iw_request_info *a, union iwreq_data *wrqu,
+                         char *b)
 {
        int ret = 0;
 
@@ -333,8 +336,8 @@ out:
 }
 
 int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
-                             struct iw_request_info *a,
-                             union iwreq_data *wrqu, char *extra)
+                          struct iw_request_info *a, union iwreq_data *wrqu,
+                          char *extra)
 {
 
        int ret = 0, len;
@@ -395,8 +398,9 @@ out:
        return ret;
 }
 
-int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-                            union iwreq_data *wrqu, char *b)
+int ieee80211_wx_get_mode(struct ieee80211_device *ieee,
+                         struct iw_request_info *a, union iwreq_data *wrqu,
+                         char *b)
 {
 
        wrqu->mode = ieee->iw_mode;
@@ -404,8 +408,8 @@ int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info
 }
 
 int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
+                          struct iw_request_info *info, union iwreq_data *wrqu,
+                          char *extra)
 {
 
        int *parms = (int *)extra;
@@ -440,8 +444,8 @@ int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
 }
 
 int ieee80211_wx_get_name(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                         struct iw_request_info *info, union iwreq_data *wrqu,
+                         char *extra)
 {
        strlcpy(wrqu->name, "802.11", IFNAMSIZ);
        if (ieee->modulation & IEEE80211_CCK_MODULATION) {
@@ -464,8 +468,8 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee,
 
 /* this is mostly stolen from hostap */
 int ieee80211_wx_set_power(struct ieee80211_device *ieee,
-                                struct iw_request_info *info,
-                                union iwreq_data *wrqu, char *extra)
+                          struct iw_request_info *info, union iwreq_data *wrqu,
+                          char *extra)
 {
        int ret = 0;
 
@@ -525,8 +529,8 @@ exit:
 
 /* this is stolen from hostap */
 int ieee80211_wx_get_power(struct ieee80211_device *ieee,
-                                struct iw_request_info *info,
-                                union iwreq_data *wrqu, char *extra)
+                          struct iw_request_info *info, union iwreq_data *wrqu,
+                          char *extra)
 {
        int ret = 0;
 
index f5a5219fe14de4accc234d4f22f12dfd343a2463..0dc5ae414270de5e7a6aa6d7572ec78dcd4972bc 100644 (file)
@@ -177,10 +177,8 @@ static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
        return SNAP_SIZE + sizeof(u16);
 }
 
-int ieee80211_encrypt_fragment(
-       struct ieee80211_device *ieee,
-       struct sk_buff *frag,
-       int hdr_len)
+int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
+                              struct sk_buff *frag, int hdr_len)
 {
        struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
        int res;
@@ -279,8 +277,8 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
  * Classify the to-be send data packet
  * Need to acquire the sent queue index.
  */
-static int
-ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
+static int ieee80211_classify(struct sk_buff *skb,
+                             struct ieee80211_network *network)
 {
        struct ether_header *eh = (struct ether_header *)skb->data;
        unsigned int wme_UP = 0;
@@ -310,8 +308,7 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
 }
 
 /* SKBs are added to the ieee->tx_queue. */
-int ieee80211_rtl_xmit(struct sk_buff *skb,
-                      struct net_device *dev)
+int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ieee80211_device *ieee = netdev_priv(dev);
        struct ieee80211_txb *txb = NULL;
index 24d39ccc13378e4f16d6c380e9c6b8d754276400..3b7955f0ff987a96c6a077bf8e5d5504f5f9f0e6 100644 (file)
@@ -633,8 +633,8 @@ done:
        return ret;
 }
 int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
+                         struct iw_request_info *info,
+                         union iwreq_data *wrqu, char *extra)
 {
        struct iw_mlme *mlme = (struct iw_mlme *) extra;
 //     printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __func__, mlme->cmd);
@@ -653,8 +653,8 @@ int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
 }
 
 int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
-                              struct iw_request_info *info,
-                              struct iw_param *data, char *extra)
+                         struct iw_request_info *info,
+                         struct iw_param *data, char *extra)
 {
 /*
         struct ieee80211_security sec = {
index d052f4a9a839ed6f95234d695ba7a12e00b6108d..e9602f67cac883698abf5d7007410f643c30fb01 100644 (file)
@@ -639,20 +639,20 @@ typedef struct r8180_priv
                ((_ac) == WME_AC_BK) ? BK_PRIORITY : \
                BE_PRIORITY)
 
-short rtl8180_tx(struct net_device *dev,u8* skbuf, int len,int priority,
-       short morefrag,short fragdesc,int rate);
+short rtl8180_tx(struct net_device *dev, u8 *skbuf, int len, int priority,
+                short morefrag, short fragdesc, int rate);
 
 u8 read_nic_byte(struct net_device *dev, int x);
 u32 read_nic_dword(struct net_device *dev, int x);
 u16 read_nic_word(struct net_device *dev, int x) ;
-void write_nic_byte(struct net_device *dev, int x,u8 y);
-void write_nic_word(struct net_device *dev, int x,u16 y);
-void write_nic_dword(struct net_device *dev, int x,u32 y);
+void write_nic_byte(struct net_device *dev, int x, u8 y);
+void write_nic_word(struct net_device *dev, int x, u16 y);
+void write_nic_dword(struct net_device *dev, int x, u32 y);
 void force_pci_posting(struct net_device *dev);
 
 void rtl8180_rtx_disable(struct net_device *);
-void rtl8180_set_anaparam(struct net_device *dev,u32 a);
-void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
+void rtl8180_set_anaparam(struct net_device *dev, u32 a);
+void rtl8185_set_anaparam2(struct net_device *dev, u32 a);
 void rtl8180_set_hw_wep(struct net_device *dev);
 void rtl8180_no_hw_wep(struct net_device *dev);
 void rtl8180_update_msr(struct net_device *dev);
@@ -661,7 +661,7 @@ void rtl8180_beacon_rx_disable(struct net_device *dev);
 int rtl8180_down(struct net_device *dev);
 int rtl8180_up(struct net_device *dev);
 void rtl8180_commit(struct net_device *dev);
-void rtl8180_set_chan(struct net_device *dev,short ch);
+void rtl8180_set_chan(struct net_device *dev, short ch);
 void write_phy(struct net_device *dev, u8 adr, u8 data);
 void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
 void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
@@ -671,7 +671,8 @@ void IPSEnter(struct net_device *dev);
 void IPSLeave(struct net_device *dev);
 int get_curr_tx_free_desc(struct net_device *dev, int priority);
 void UpdateInitialGain(struct net_device *dev);
-bool SetAntennaConfig87SE(struct net_device *dev, u8  DefaultAnt, bool bAntDiversity);
+bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt,
+                         bool bAntDiversity);
 
 //#ifdef CONFIG_RTL8185B
 void rtl8185b_adapter_start(struct net_device *dev);
@@ -684,6 +685,17 @@ void fix_tx_fifo(struct net_device *dev);
 void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
 void rtl8180_rate_adapter(struct work_struct * work);
 //#endif
-bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource);
+bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet,
+                        u32 ChangeSource);
 
 #endif
+
+/* fun with the built-in ieee80211 stack... */
+extern int ieee80211_crypto_init(void);
+extern void ieee80211_crypto_deinit(void);
+extern int ieee80211_crypto_tkip_init(void);
+extern void ieee80211_crypto_tkip_exit(void);
+extern int ieee80211_crypto_ccmp_init(void);
+extern void ieee80211_crypto_ccmp_exit(void);
+extern int ieee80211_crypto_wep_init(void);
+extern void ieee80211_crypto_wep_exit(void);
index 76a67386b927326e99c793059ce3093d07e52b63..297136b3c57d4728aa7759a00625257d23b37ea8 100644 (file)
@@ -79,7 +79,7 @@ module_param(hwwep, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards");
 
 static int rtl8180_pci_probe(struct pci_dev *pdev,
-                                      const struct pci_device_id *id);
+                            const struct pci_device_id *id);
 
 static void rtl8180_pci_remove(struct pci_dev *pdev);
 
@@ -387,7 +387,8 @@ static short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
        return 0;
 }
 
-void buffer_free(struct net_device *dev, struct buffer **buffer, int len, short consistent)
+void buffer_free(struct net_device *dev, struct buffer **buffer, int len,
+                short consistent)
 {
 
        struct buffer *tmp, *next;
@@ -1855,7 +1856,7 @@ short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority,
 
                if (remain == len && !descfrag) {
                        ownbit_flag = false;
-                       *tail = *tail | (1<<29) ; /* fist segment of the packet */
+                       *tail = *tail | (1<<29); /* fist segment of the packet */
                        *tail = *tail | (len);
                } else {
                        ownbit_flag = true;
@@ -2238,7 +2239,8 @@ static CHANNEL_LIST ChannelPlan[] = {
        {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} /* world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 080826 */
 };
 
-static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee)
+static void rtl8180_set_channel_map(u8 channel_plan,
+                                   struct ieee80211_device *ieee)
 {
        int i;
 
@@ -2830,11 +2832,8 @@ static struct net_device_stats *rtl8180_stats(struct net_device *dev)
 /*
  * Change current and default preamble mode.
  */
-bool
-MgntActSet_802_11_PowerSaveMode(
-       struct r8180_priv *priv,
-       RT_PS_MODE              rtPsMode
-)
+bool MgntActSet_802_11_PowerSaveMode(struct r8180_priv *priv,
+                                    RT_PS_MODE rtPsMode)
 {
        /* Currently, we do not change power save mode on IBSS mode. */
        if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
@@ -3161,7 +3160,7 @@ static const struct net_device_ops rtl8180_netdev_ops = {
 };
 
 static int rtl8180_pci_probe(struct pci_dev *pdev,
-                                      const struct pci_device_id *id)
+                            const struct pci_device_id *id)
 {
        unsigned long ioaddr = 0;
        struct net_device *dev = NULL;
@@ -3310,16 +3309,6 @@ static void rtl8180_pci_remove(struct pci_dev *pdev)
        DMESG("wlan driver removed\n");
 }
 
-/* fun with the built-in ieee80211 stack... */
-extern int ieee80211_crypto_init(void);
-extern void ieee80211_crypto_deinit(void);
-extern int ieee80211_crypto_tkip_init(void);
-extern void ieee80211_crypto_tkip_exit(void);
-extern int ieee80211_crypto_ccmp_init(void);
-extern void ieee80211_crypto_ccmp_exit(void);
-extern int ieee80211_crypto_wep_init(void);
-extern void ieee80211_crypto_wep_exit(void);
-
 static int __init rtl8180_pci_module_init(void)
 {
        int ret;
index 732c06ac1026ad16075b301d6fc44f29487c37e9..cb4046f346efedbd552f9fe944f0ad32bcc215b6 100644 (file)
@@ -5,7 +5,7 @@
 /* #include "r8180_hw.h"       */
 /* #include "r8180_93cx6.h"    */
 void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
-bool SetAntenna8185(struct net_device *dev,    u8 u1bAntennaIndex);
+bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
 bool SwitchAntenna(struct net_device *dev);
 void SwAntennaDiversity(struct net_device *dev);
 void SwAntennaDiversityTimerCallback(struct net_device *dev);
index c94ca0794a5d522d781db2aa8d2082e13c2370da..de084f07a071bbd4e814be2ed6f51e9b0bc075c3 100644 (file)
@@ -28,7 +28,8 @@ u16 RF_ReadReg(struct net_device *dev, u8 offset);
 
 void rtl8180_set_mode(struct net_device *dev, int mode);
 void rtl8180_set_mode(struct net_device *dev, int mode);
-bool SetZebraRFPowerState8185(struct net_device *dev, RT_RF_POWER_STATE  eRFPowerState);
+bool SetZebraRFPowerState8185(struct net_device *dev,
+                             RT_RF_POWER_STATE eRFPowerState);
 void rtl8225z4_rf_sleep(struct net_device *dev);
 void rtl8225z4_rf_wakeup(struct net_device *dev);
 
index 4e01653e098a3b782e6844fd23430ced355ee2f2..bae68759bd6aff454a3b117babea275bac250b5b 100644 (file)
@@ -21,6 +21,7 @@
 #include "r8180.h"
 #include "r8180_hw.h"
 
+#include <net/iw_handler.h>
 #include "ieee80211/dot11d.h"
 
 u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
@@ -74,8 +75,9 @@ static int r8180_wx_set_key(struct net_device *dev,
 }
 
 
-static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
-                         union iwreq_data *wrqu, char *b)
+static int r8180_wx_set_beaconinterval(struct net_device *dev,
+                                      struct iw_request_info *aa,
+                                      union iwreq_data *wrqu, char *b)
 {
        int *parms = (int *)b;
        int bi = parms[0];
@@ -473,9 +475,8 @@ static int r8180_wx_get_frag(struct net_device *dev,
 
 
 static int r8180_wx_set_wap(struct net_device *dev,
-                        struct iw_request_info *info,
-                        union iwreq_data *awrq,
-                        char *extra)
+                           struct iw_request_info *info,
+                           union iwreq_data *awrq, char *extra)
 {
        int ret;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -537,8 +538,10 @@ static int r8180_wx_get_enc(struct net_device *dev,
 }
 
 
-static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
-       iwreq_data *wrqu, char *p)      {
+static int r8180_wx_set_scan_type(struct net_device *dev,
+                                 struct iw_request_info *aa,
+                                 union iwreq_data *wrqu, char *p)
+{
 
        struct r8180_priv *priv = ieee80211_priv(dev);
        int *parms = (int*)p;
@@ -553,8 +556,8 @@ static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info
 }
 
 static int r8180_wx_set_retry(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
+                             struct iw_request_info *info,
+                             union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int err = 0;
@@ -601,8 +604,8 @@ exit:
 }
 
 static int r8180_wx_get_retry(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
+                             struct iw_request_info *info,
+                             union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -625,8 +628,8 @@ static int r8180_wx_get_retry(struct net_device *dev,
 }
 
 static int r8180_wx_get_sens(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
+                            struct iw_request_info *info,
+                            union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        if (priv->rf_set_sens == NULL)
@@ -637,8 +640,8 @@ static int r8180_wx_get_sens(struct net_device *dev,
 
 
 static int r8180_wx_set_sens(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
+                            struct iw_request_info *info,
+                            union iwreq_data *wrqu, char *extra)
 {
 
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -666,8 +669,8 @@ exit:
 
 
 static int r8180_wx_set_rawtx(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
+                             struct iw_request_info *info,
+                             union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int ret;
@@ -686,8 +689,8 @@ static int r8180_wx_set_rawtx(struct net_device *dev,
 }
 
 static int r8180_wx_get_power(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
+                             struct iw_request_info *info,
+                             union iwreq_data *wrqu, char *extra)
 {
        int ret;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -702,8 +705,8 @@ static int r8180_wx_get_power(struct net_device *dev,
 }
 
 static int r8180_wx_set_power(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
+                             struct iw_request_info *info,
+                             union iwreq_data *wrqu, char *extra)
 {
        int ret;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -728,8 +731,8 @@ static int r8180_wx_set_power(struct net_device *dev,
 }
 
 static int r8180_wx_set_rts(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                           struct iw_request_info *info,
+                           union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -750,8 +753,8 @@ static int r8180_wx_set_rts(struct net_device *dev,
        return 0;
 }
 static int r8180_wx_get_rts(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                           struct iw_request_info *info,
+                           union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -841,8 +844,8 @@ static int r8180_wx_set_iwmode(struct net_device *dev,
        return ret;
 }
 static int r8180_wx_get_preamble(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                                struct iw_request_info *info,
+                                union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -858,8 +861,8 @@ static int r8180_wx_get_preamble(struct net_device *dev,
        return 0;
 }
 static int r8180_wx_set_preamble(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                                struct iw_request_info *info,
+                                union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int ret = 0;
@@ -881,8 +884,8 @@ static int r8180_wx_set_preamble(struct net_device *dev,
        return ret;
 }
 static int r8180_wx_get_siglevel(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
+                                struct iw_request_info *info,
+                                union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int ret = 0;
@@ -900,8 +903,8 @@ static int r8180_wx_get_siglevel(struct net_device *dev,
        return ret;
 }
 static int r8180_wx_get_sigqual(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int ret = 0;
@@ -959,8 +962,8 @@ static int r8180_wx_reset_stats(struct net_device *dev,
 
 }
 static int r8180_wx_radio_on(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
+                            struct iw_request_info *info,
+                            union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -978,8 +981,8 @@ static int r8180_wx_radio_on(struct net_device *dev,
 }
 
 static int r8180_wx_radio_off(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
+                             struct iw_request_info *info,
+                             union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -996,8 +999,8 @@ static int r8180_wx_radio_off(struct net_device *dev,
 
 }
 static int r8180_wx_get_channelplan(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                                   struct iw_request_info *info,
+                                   union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -1013,8 +1016,8 @@ static int r8180_wx_get_channelplan(struct net_device *dev,
        return 0;
 }
 static int r8180_wx_set_channelplan(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                                   struct iw_request_info *info,
+                                   union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int *val = (int *)extra;
@@ -1043,8 +1046,8 @@ static int r8180_wx_set_channelplan(struct net_device *dev,
 }
 
 static int r8180_wx_get_version(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        /* struct ieee80211_device *ieee; */
@@ -1059,8 +1062,8 @@ static int r8180_wx_get_version(struct net_device *dev,
 /* added by amy 080818 */
 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
 static int r8180_wx_set_forcerate(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu, char *extra)
+                                 struct iw_request_info *info,
+                                 union iwreq_data *wrqu, char *extra)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u8 forcerate = *extra;
@@ -1084,8 +1087,8 @@ static int r8180_wx_set_forcerate(struct net_device *dev,
 }
 
 static int r8180_wx_set_enc_ext(struct net_device *dev,
-                                                                               struct iw_request_info *info,
-                                                                               union iwreq_data *wrqu, char *extra)
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
 {
 
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -1118,8 +1121,8 @@ static int r8180_wx_set_auth(struct net_device *dev,
 }
 
 static int r8180_wx_set_mlme(struct net_device *dev,
-                                                                               struct iw_request_info *info,
-                                                                               union iwreq_data *wrqu, char *extra)
+                            struct iw_request_info *info,
+                            union iwreq_data *wrqu, char *extra)
 {
        int ret = 0;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -1156,65 +1159,48 @@ static int r8180_wx_set_gen_ie(struct net_device *dev,
 
 
 }
-static iw_handler r8180_wx_handlers[] =        {
-               NULL,                                   /* SIOCSIWCOMMIT */
-               r8180_wx_get_name,                      /* SIOCGIWNAME */
-               dummy,                                  /* SIOCSIWNWID */
-               dummy,                                  /* SIOCGIWNWID */
-               r8180_wx_set_freq,                      /* SIOCSIWFREQ */
-               r8180_wx_get_freq,                      /* SIOCGIWFREQ */
-               r8180_wx_set_mode,                      /* SIOCSIWMODE */
-               r8180_wx_get_mode,                      /* SIOCGIWMODE */
-               r8180_wx_set_sens,                      /* SIOCSIWSENS */
-               r8180_wx_get_sens,                      /* SIOCGIWSENS */
-               NULL,                                   /* SIOCSIWRANGE */
-               rtl8180_wx_get_range,                   /* SIOCGIWRANGE */
-               NULL,                                   /* SIOCSIWPRIV */
-               NULL,                                   /* SIOCGIWPRIV */
-               NULL,                                   /* SIOCSIWSTATS */
-               NULL,                                   /* SIOCGIWSTATS */
-               dummy,                                  /* SIOCSIWSPY */
-               dummy,                                  /* SIOCGIWSPY */
-               NULL,                                   /* SIOCGIWTHRSPY */
-               NULL,                                   /* SIOCWIWTHRSPY */
-               r8180_wx_set_wap,                       /* SIOCSIWAP */
-               r8180_wx_get_wap,                       /* SIOCGIWAP */
-               r8180_wx_set_mlme,                      /* SIOCSIWMLME*/
-               dummy,                                  /* SIOCGIWAPLIST -- deprecated */
-               r8180_wx_set_scan,                      /* SIOCSIWSCAN */
-               r8180_wx_get_scan,                      /* SIOCGIWSCAN */
-               r8180_wx_set_essid,                     /* SIOCSIWESSID */
-               r8180_wx_get_essid,                     /* SIOCGIWESSID */
-               dummy,                                  /* SIOCSIWNICKN */
-               dummy,                                  /* SIOCGIWNICKN */
-               NULL,                                   /* -- hole -- */
-               NULL,                                   /* -- hole -- */
-               r8180_wx_set_rate,                      /* SIOCSIWRATE */
-               r8180_wx_get_rate,                      /* SIOCGIWRATE */
-               r8180_wx_set_rts,                       /* SIOCSIWRTS */
-               r8180_wx_get_rts,                       /* SIOCGIWRTS */
-               r8180_wx_set_frag,                      /* SIOCSIWFRAG */
-               r8180_wx_get_frag,                      /* SIOCGIWFRAG */
-               dummy,                                  /* SIOCSIWTXPOW */
-               dummy,                                  /* SIOCGIWTXPOW */
-               r8180_wx_set_retry,                     /* SIOCSIWRETRY */
-               r8180_wx_get_retry,                     /* SIOCGIWRETRY */
-               r8180_wx_set_enc,                       /* SIOCSIWENCODE */
-               r8180_wx_get_enc,                       /* SIOCGIWENCODE */
-               r8180_wx_set_power,                     /* SIOCSIWPOWER */
-               r8180_wx_get_power,                     /* SIOCGIWPOWER */
-               NULL,                                   /*---hole---*/
-               NULL,                                   /*---hole---*/
-               r8180_wx_set_gen_ie,                    /* SIOCSIWGENIE */
-               NULL,                                   /* SIOCSIWGENIE */
-               r8180_wx_set_auth,                      /* SIOCSIWAUTH */
-               NULL,                                   /* SIOCSIWAUTH */
-               r8180_wx_set_enc_ext,                   /* SIOCSIWENCODEEXT */
-               NULL,                                   /* SIOCSIWENCODEEXT */
-               NULL,                                   /* SIOCSIWPMKSA */
-               NULL,                                   /*---hole---*/
-};
 
+static const iw_handler r8180_wx_handlers[] =  {
+       IW_HANDLER(SIOCGIWNAME,         r8180_wx_get_name),
+       IW_HANDLER(SIOCSIWNWID,         dummy),
+       IW_HANDLER(SIOCGIWNWID,         dummy),
+       IW_HANDLER(SIOCSIWFREQ,         r8180_wx_set_freq),
+       IW_HANDLER(SIOCGIWFREQ,         r8180_wx_get_freq),
+       IW_HANDLER(SIOCSIWMODE,         r8180_wx_set_mode),
+       IW_HANDLER(SIOCGIWMODE,         r8180_wx_get_mode),
+       IW_HANDLER(SIOCSIWSENS,         r8180_wx_set_sens),
+       IW_HANDLER(SIOCGIWSENS,         r8180_wx_get_sens),
+       IW_HANDLER(SIOCGIWRANGE,        rtl8180_wx_get_range),
+       IW_HANDLER(SIOCSIWSPY,          dummy),
+       IW_HANDLER(SIOCGIWSPY,          dummy),
+       IW_HANDLER(SIOCSIWAP,           r8180_wx_set_wap),
+       IW_HANDLER(SIOCGIWAP,           r8180_wx_get_wap),
+       IW_HANDLER(SIOCSIWMLME,         r8180_wx_set_mlme),
+       IW_HANDLER(SIOCGIWAPLIST,       dummy),         /* deprecated */
+       IW_HANDLER(SIOCSIWSCAN,         r8180_wx_set_scan),
+       IW_HANDLER(SIOCGIWSCAN,         r8180_wx_get_scan),
+       IW_HANDLER(SIOCSIWESSID,        r8180_wx_set_essid),
+       IW_HANDLER(SIOCGIWESSID,        r8180_wx_get_essid),
+       IW_HANDLER(SIOCSIWNICKN,        dummy),
+       IW_HANDLER(SIOCGIWNICKN,        dummy),
+       IW_HANDLER(SIOCSIWRATE,         r8180_wx_set_rate),
+       IW_HANDLER(SIOCGIWRATE,         r8180_wx_get_rate),
+       IW_HANDLER(SIOCSIWRTS,          r8180_wx_set_rts),
+       IW_HANDLER(SIOCGIWRTS,          r8180_wx_get_rts),
+       IW_HANDLER(SIOCSIWFRAG,         r8180_wx_set_frag),
+       IW_HANDLER(SIOCGIWFRAG,         r8180_wx_get_frag),
+       IW_HANDLER(SIOCSIWTXPOW,        dummy),
+       IW_HANDLER(SIOCGIWTXPOW,        dummy),
+       IW_HANDLER(SIOCSIWRETRY,        r8180_wx_set_retry),
+       IW_HANDLER(SIOCGIWRETRY,        r8180_wx_get_retry),
+       IW_HANDLER(SIOCSIWENCODE,       r8180_wx_set_enc),
+       IW_HANDLER(SIOCGIWENCODE,       r8180_wx_get_enc),
+       IW_HANDLER(SIOCSIWPOWER,        r8180_wx_set_power),
+       IW_HANDLER(SIOCGIWPOWER,        r8180_wx_get_power),
+       IW_HANDLER(SIOCSIWGENIE,        r8180_wx_set_gen_ie),
+       IW_HANDLER(SIOCSIWAUTH,         r8180_wx_set_auth),
+       IW_HANDLER(SIOCSIWENCODEEXT,    r8180_wx_set_enc_ext),
+};
 
 static const struct iw_priv_args r8180_private_args[] = {
        {
@@ -1350,7 +1336,7 @@ static iw_handler r8180_private_handler[] = {
 };
 
 static inline int is_same_network(struct ieee80211_network *src,
-                                                                       struct ieee80211_network *dst,
+                                 struct ieee80211_network *dst,
                                  struct ieee80211_device *ieee)
 {
                /* A network is only a duplicate if the channel, BSSID, ESSID
index dc52a3e584d838a7fca7a64e5d551df729c0a2d7..c8b9baff1dbce491adff7db3aed358bf48464c28 100644 (file)
@@ -497,7 +497,7 @@ static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
          */
                RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) |
                            (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1);
-               printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
+               netdev_info(dev, "ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
                      (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) |
                       BIT11 | BIT9);
        } else {
@@ -870,9 +870,10 @@ static u8 GetSupportedWirelessMode8185(struct net_device *dev)
        return WIRELESS_MODE_B | WIRELESS_MODE_G;
 }
 
-static void ActUpdateChannelAccessSetting(struct net_device *dev,
-                                  WIRELESS_MODE WirelessMode,
-                                  PCHANNEL_ACCESS_SETTING ChnlAccessSetting)
+static void
+ActUpdateChannelAccessSetting(struct net_device *dev,
+                             WIRELESS_MODE WirelessMode,
+                             PCHANNEL_ACCESS_SETTING ChnlAccessSetting)
 {
        AC_CODING       eACI;
 
@@ -1084,7 +1085,7 @@ static bool MgntDisconnect(struct net_device *dev, u8 asRsn)
  *             PASSIVE LEVEL.
  */
 static bool SetRFPowerState(struct net_device *dev,
-               RT_RF_POWER_STATE eRFPowerState)
+                           RT_RF_POWER_STATE eRFPowerState)
 {
        struct  r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        bool    bResult = false;
@@ -1097,8 +1098,8 @@ static bool SetRFPowerState(struct net_device *dev,
        return bResult;
 }
 
-bool MgntActSet_RF_State(struct net_device *dev,
-               RT_RF_POWER_STATE StateToSet, u32 ChangeSource)
+bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet,
+                        u32 ChangeSource)
 {
        struct  r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        bool    bActionAllowed = false;
@@ -1125,7 +1126,7 @@ bool MgntActSet_RF_State(struct net_device *dev,
                                 *      to be stuck here.
                                 */
                                if (RFWaitCounter > 1000) { /* 1sec */
-                                       printk("MgntActSet_RF_State(): Wait too long to set RF\n");
+                                       netdev_info(dev, "MgntActSet_RF_State(): Wait too long to set RF\n");
                                        /* TODO: Reset RF state? */
                                        return false;
                                }
index 2c678f4095734698b2fcfcdf6318691b7b8c4855..2f548ebada59286fbc8290bd3ce8724d2641aae0 100644 (file)
@@ -1115,6 +1115,9 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
                        return _FAIL;
        }
 
+       /* fix bug of flush_cam_entry at STOP AP mode */
+       psta->state |= WIFI_AP_STATE;
+       rtw_indicate_connect(padapter);
        pmlmepriv->cur_network.join_res = true;/* for check if already set beacon */
        return ret;
 }
index 10c9c6560b20207226575a184c4ed04a5b555442..c47990a62b7ce1c38b20ddd40341533020372b90 100644 (file)
@@ -296,7 +296,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt, u8 *pme
        if (ret == _SUCCESS)
                ret = rtw_sctx_wait(&sctx);
 
-        return ret;
+       return ret;
 }
 
 void _rtw_write_port_cancel(struct adapter *adapter)
index 7ab5ff039c8807da5d5d9fbcdac16859a4fa4a3b..6519a7b3f833794f8218d6d1563f997ef74bef48 100644 (file)
@@ -4419,7 +4419,7 @@ s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntfr
        if (ret == _SUCCESS)
                ret = rtw_sctx_wait(&sctx);
 
-        return ret;
+       return ret;
 }
 
 s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe)
index a594e51d2e1ca974b9bb946b56e9e9457c533c2e..01662f78e53da64ec540c725fc4077b30afe2e46 100644 (file)
@@ -685,7 +685,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr
 
 _func_enter_;
 
-       hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);;
+       hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
 
        if (pattrib->encrypt == _TKIP_) {/* if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_PRIVACY_) */
                /* encode mic code */
index 52b3fba0fae147590b350f22a93f2690ace4715f..a291d7ae6f4225b19a9cb6dcb123a0ccf5b2b67c 100644 (file)
@@ -2304,7 +2304,7 @@ void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool
                if (registry_par->antdiv_cfg == 2) { /*  2:By EFUSE */
                        pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E]&0x18)>>3;
                        if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
-                               pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION&0x18)>>3;;
+                               pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION&0x18)>>3;
                } else {
                        pHalData->AntDivCfg = registry_par->antdiv_cfg;  /*  0:OFF , 1:ON, 2:By EFUSE */
                }
index 05e2475cfd61347f6c5c8e0b824da1aec76e9450..511f61cbb9e0ae175585048e0324a67f1de3e3b9 100644 (file)
@@ -86,7 +86,7 @@ void update_recvframe_attrib_88e(union recv_frame *precvframe, struct recv_stat
        pattrib = &precvframe->u.hdr.attrib;
        _rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
 
-       pattrib->crc_err = (u8)((le32_to_cpu(report.rxdw0) >> 14) & 0x1);;/* u8)prxreport->crc32; */
+       pattrib->crc_err = (u8)((le32_to_cpu(report.rxdw0) >> 14) & 0x1);/* u8)prxreport->crc32; */
 
        /*  update rx report to recv_frame attribute */
        pattrib->pkt_rpt_type = (u8)((le32_to_cpu(report.rxdw3) >> 14) & 0x3);/* prxreport->rpt_sel; */
index ae545877023428b103df7af913ca9e10753ed939..a002d2e75e9f6193339314017601c67e3e4d079e 100644 (file)
@@ -7228,25 +7228,25 @@ static int rtw_mp_thermal(struct net_device *dev,
        if (copy_from_user(extra, wrqu->pointer, wrqu->length))
                return -EFAULT;
 
-        bwrite = strncmp(extra, "write", 6); /*  strncmp true is 0 */
+       bwrite = strncmp(extra, "write", 6); /*  strncmp true is 0 */
 
-        Hal_GetThermalMeter(padapter, &val);
+       Hal_GetThermalMeter(padapter, &val);
 
-        if (bwrite == 0) {
-                       EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
-                       if (2 > max_available_size) {
-                               DBG_88E("no available efuse!\n");
-                               return -EFAULT;
-                       }
-                       if (rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL) {
-                               DBG_88E("rtw_efuse_map_write error\n");
-                               return -EFAULT;
-                       } else {
-                                sprintf(extra, " efuse write ok :%d", val);
-                       }
-        } else {
-                        sprintf(extra, "%d", val);
-        }
+       if (bwrite == 0) {
+               EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
+               if (2 > max_available_size) {
+                       DBG_88E("no available efuse!\n");
+                       return -EFAULT;
+               }
+               if (rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL) {
+                       DBG_88E("rtw_efuse_map_write error\n");
+                       return -EFAULT;
+               } else {
+                        sprintf(extra, " efuse write ok :%d", val);
+               }
+       } else {
+                sprintf(extra, "%d", val);
+       }
        wrqu->length = strlen(extra);
 
        return 0;
index a1ae72772c5fa6294ce4543bfda410f5cdb4c673..2ffb4184fd0811f97871d3c9fcab881f54052488 100644 (file)
@@ -52,7 +52,7 @@ u32 rtw_atoi(u8 *s)
        }
        if (flag == 1)
                num = num * -1;
-        return num;
+       return num;
 }
 
 inline u8 *_rtw_vmalloc(u32 sz)
index 7d14779310d370f7a70b35b56a00ef261bd671af..b21b1566424b994019b4c58a90d254e26ec8181b 100644 (file)
@@ -71,7 +71,7 @@ struct rtw_usb_drv {
 };
 
 static struct rtw_usb_drv rtl8188e_usb_drv = {
-       .usbdrv.name = (char *)"r8188eu",
+       .usbdrv.name = "r8188eu",
        .usbdrv.probe = rtw_drv_init,
        .usbdrv.disconnect = rtw_dev_remove,
        .usbdrv.id_table = rtw_usb_id_tbl,
index 1260f10944ef07a5c1707f63c74047f8fe9b9687..eb33c517fcc8241c6a633154a97bd5a7d6ad1f03 100644 (file)
@@ -144,7 +144,7 @@ void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr,
                        return;
                }
 
-               for (j = 0 ; j < pTriple->NumChnls; j++) {
+               for (j = 0; j < pTriple->NumChnls; j++) {
                        pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
                        pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] =
                                                 pTriple->MaxTxPowerInDbm;
index fb7683fa5ffd93d3bcaee6741e7e6a79bae5828a..eeea50260f1d08368ade615e22420945b97c6581 100644 (file)
@@ -87,7 +87,10 @@ static inline void cpMacAddr(unsigned char *des, unsigned char *src)
 #define CIE_WATCHDOG_TH 1
 #define GET_CIE_WATCHDOG(__pIeeeDev)                           \
         (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog)
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
+static inline void RESET_CIE_WATCHDOG(struct rtllib_device *__pIeeeDev)
+{
+       GET_CIE_WATCHDOG(__pIeeeDev) = 0;
+}
 #define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev))
 
 #define IS_DOT11D_STATE_DONE(__pIeeeDev)                       \
index 2cace9a4525aac87d44f6ce5b838aff929097e53..4a35f9b5602d47f1a91431652f740b255759e5de 100644 (file)
@@ -30,7 +30,7 @@
 #include "rtl_dm.h"
 #include "rtl_wx.h"
 
-extern int WDCAPARA_ADD[];
+static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO};
 
 void rtl8192e_start_beacon(struct net_device *dev)
 {
@@ -193,11 +193,12 @@ void rtl8192e_SetHwReg(struct net_device *dev, u8 variable, u8 *val)
 
                dm_init_edca_turbo(dev);
 
-               u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[pAcParam])) <<
+               u4bAcParam = (((le16_to_cpu(
+                                       qos_parameters->tx_op_limit[pAcParam])) <<
                             AC_PARAM_TXOP_LIMIT_OFFSET) |
-                            (((u32)(qos_parameters->cw_max[pAcParam])) <<
+                            ((le16_to_cpu(qos_parameters->cw_max[pAcParam])) <<
                             AC_PARAM_ECW_MAX_OFFSET) |
-                            (((u32)(qos_parameters->cw_min[pAcParam])) <<
+                            ((le16_to_cpu(qos_parameters->cw_min[pAcParam])) <<
                             AC_PARAM_ECW_MIN_OFFSET) |
                             (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
 
@@ -1271,7 +1272,7 @@ void  rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc,
        pdesc->LastSeg = 1;
        pdesc->TxBufferSize = skb->len;
 
-       pdesc->TxBuffAddr = cpu_to_le32(mapping);
+       pdesc->TxBuffAddr = mapping;
 }
 
 void  rtl8192_tx_fill_cmd_desc(struct net_device *dev,
@@ -1301,7 +1302,7 @@ void  rtl8192_tx_fill_cmd_desc(struct net_device *dev,
                entry_tmp->RATid = (u8)DESC_PACKET_TYPE_INIT;
        }
        entry->TxBufferSize = skb->len;
-       entry->TxBuffAddr = cpu_to_le32(mapping);
+       entry->TxBuffAddr = mapping;
        entry->OWN = 1;
 }
 
index fa5603a562c34478c2175b7029afae3a319aa47b..c46c65c5542f3009ce8f91df3ea828e658f85e7c 100644 (file)
@@ -28,7 +28,6 @@
 #include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
 #include "r8192E_cmdpkt.h"
 
-extern int hwwep;
 void CamResetAllEntry(struct net_device *dev)
 {
        u32 ulcommand = 0;
index d93caca9657d2ea8bf50c633425128802649b5e7..c01abc23213efd36255531bda0cef2f753514cfe 100644 (file)
@@ -562,8 +562,8 @@ void rtl8192_update_cap(struct net_device *dev, u16 cap)
 }
 
 static struct rtllib_qos_parameters def_qos_parameters = {
-       {3, 3, 3, 3},
-       {7, 7, 7, 7},
+       {cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3)},
+       {cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7)},
        {2, 2, 2, 2},
        {0, 0, 0, 0},
        {0, 0, 0, 0}
@@ -585,8 +585,6 @@ static void rtl8192_update_beacon(void *data)
        rtl8192_update_cap(dev, net->capability);
 }
 
-int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO};
-
 static void rtl8192_qos_activate(void *data)
 {
        struct r8192_priv *priv = container_of_work_rsl(data, struct r8192_priv,
@@ -1845,7 +1843,7 @@ static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
                struct tx_desc *entry = &ring->desc[ring->idx];
                struct sk_buff *skb = __skb_dequeue(&ring->queue);
 
-               pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
+               pci_unmap_single(priv->pdev, entry->TxBuffAddr,
                        skb->len, PCI_DMA_TODEVICE);
                kfree_skb(skb);
                ring->idx = (ring->idx + 1) % ring->entries;
@@ -1950,7 +1948,7 @@ static void rtl8192_tx_isr(struct net_device *dev, int prio)
                }
 
                skb = __skb_dequeue(&ring->queue);
-               pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
+               pci_unmap_single(priv->pdev, entry->TxBuffAddr,
                skb->len, PCI_DMA_TODEVICE);
 
                kfree_skb(skb);
@@ -2011,7 +2009,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
        fwinfo_size = sizeof(struct tx_fwinfo_8190pci);
 
        header = (struct rtllib_hdr_1addr *)(((u8 *)skb->data) + fwinfo_size);
-       fc = header->frame_ctl;
+       fc = le16_to_cpu(header->frame_ctl);
        type = WLAN_FC_GET_TYPE(fc);
        stype = WLAN_FC_GET_STYPE(fc);
        pda_addr = header->addr1;
@@ -2101,7 +2099,7 @@ static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
                                dev_kfree_skb_any(skb);
                                return -1;
                        }
-                       entry->BufferAddress = cpu_to_le32(*mapping);
+                       entry->BufferAddress = *mapping;
 
                        entry->Length = priv->rxbuffersize;
                        entry->OWN = 1;
@@ -2137,8 +2135,8 @@ static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
 
        for (i = 0; i < entries; i++)
                ring[i].NextDescAddress =
-                       cpu_to_le32((u32)dma + ((i + 1) % entries) *
-                       sizeof(*ring));
+                       (u32)dma + ((i + 1) % entries) *
+                       sizeof(*ring);
 
        return 0;
 }
@@ -2198,7 +2196,7 @@ void rtl8192_pci_resetdescring(struct net_device *dev)
                                                 __skb_dequeue(&ring->queue);
 
                                pci_unmap_single(priv->pdev,
-                                                le32_to_cpu(entry->TxBuffAddr),
+                                                entry->TxBuffAddr,
                                                 skb->len, PCI_DMA_TODEVICE);
                                kfree_skb(skb);
                                ring->idx = (ring->idx + 1) % ring->entries;
@@ -2400,7 +2398,7 @@ static void rtl8192_rx_normal(struct net_device *dev)
                        }
                }
 done:
-               pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
+               pdesc->BufferAddress = *((dma_addr_t *)skb->cb);
                pdesc->OWN = 1;
                pdesc->Length = priv->rxbuffersize;
                if (priv->rx_idx[rx_queue_idx] == priv->rxringcount-1)
@@ -2692,7 +2690,7 @@ out:
 }
 
 
-irqreturn_t rtl8192_interrupt(int irq, void *netdev)
+static irqreturn_t rtl8192_interrupt(int irq, void *netdev)
 {
        struct net_device *dev = (struct net_device *) netdev;
        struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
index b015bf61cf057b718fb780ec40f5ea7f1658eb38..ce239be8f2f6957c2b720ab50f772390ca612da7 100644 (file)
 #define MAX_RX_COUNT                           64
 #define MAX_TX_QUEUE_COUNT                     9
 
+extern int hwwep;
+
 enum RTL819x_PHY_PARAM {
        RTL819X_PHY_MACPHY_REG                  = 0,
        RTL819X_PHY_MACPHY_REG_PG               = 1,
index 32fbbc9d0d92cf40534ee3d1464119b17d80e602..adc6cc7ca3d6f2070dae8448a3d3b9f61c2a2d20 100644 (file)
@@ -115,14 +115,14 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst,
 
        if (ACT_ADDBARSP == type) {
                RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n");
-               tmp = cpu_to_le16(StatusCode);
+               tmp = StatusCode;
                memcpy(tag, (u8 *)&tmp, 2);
                tag += 2;
        }
-       tmp = cpu_to_le16(pBA->BaParamSet.shortData);
+       tmp = pBA->BaParamSet.shortData;
        memcpy(tag, (u8 *)&tmp, 2);
        tag += 2;
-       tmp = cpu_to_le16(pBA->BaTimeoutValue);
+       tmp = pBA->BaTimeoutValue;
        memcpy(tag, (u8 *)&tmp, 2);
        tag += 2;
 
@@ -178,10 +178,10 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
        *tag ++= ACT_CAT_BA;
        *tag ++= ACT_DELBA;
 
-       tmp = cpu_to_le16(DelbaParamSet.shortData);
+       tmp = DelbaParamSet.shortData;
        memcpy(tag, (u8 *)&tmp, 2);
        tag += 2;
-       tmp = cpu_to_le16(ReasonCode);
+       tmp = ReasonCode;
        memcpy(tag, (u8 *)&tmp, 2);
        tag += 2;
 
index e51cb49ce10edef2f0f8b35e87bf1b9a0ee3e969..5e5c76bcdbd049e539da4c5b5079ddf7ed574e9b 100644 (file)
@@ -443,13 +443,13 @@ static struct lib80211_crypto_ops rtllib_crypt_ccmp = {
 };
 
 
-int __init rtllib_crypto_ccmp_init(void)
+static int __init rtllib_crypto_ccmp_init(void)
 {
        return lib80211_register_crypto_ops(&rtllib_crypt_ccmp);
 }
 
 
-void __exit rtllib_crypto_ccmp_exit(void)
+static void __exit rtllib_crypto_ccmp_exit(void)
 {
        lib80211_unregister_crypto_ops(&rtllib_crypt_ccmp);
 }
index 5cfd73baf1cc489325054afdaaa92b6f2c0192a7..d2768986c53e72dc46f2f2bb75c402b4ee3d34f5 100644 (file)
@@ -173,7 +173,7 @@ static inline u16 Mk16(u8 hi, u8 lo)
 
 static inline u16 Mk16_le(u16 *v)
 {
-       return le16_to_cpu(*v);
+       return *v;
 }
 
 
@@ -752,13 +752,13 @@ static struct lib80211_crypto_ops rtllib_crypt_tkip = {
 };
 
 
-int __init rtllib_crypto_tkip_init(void)
+static int __init rtllib_crypto_tkip_init(void)
 {
        return lib80211_register_crypto_ops(&rtllib_crypt_tkip);
 }
 
 
-void __exit rtllib_crypto_tkip_exit(void)
+static void __exit rtllib_crypto_tkip_exit(void)
 {
        lib80211_unregister_crypto_ops(&rtllib_crypt_tkip);
 }
index c4df6e01ef7401692db11509ea6abf162269efa7..b0e5f1ff07eeabb2f0aed1f148221ea29805f217 100644 (file)
@@ -270,13 +270,13 @@ static struct lib80211_crypto_ops rtllib_crypt_wep = {
 };
 
 
-int __init rtllib_crypto_wep_init(void)
+static int __init rtllib_crypto_wep_init(void)
 {
        return lib80211_register_crypto_ops(&rtllib_crypt_wep);
 }
 
 
-void __exit rtllib_crypto_wep_exit(void)
+static void __exit rtllib_crypto_wep_exit(void)
 {
        lib80211_unregister_crypto_ops(&rtllib_crypt_wep);
 }
index 51d46e04d3f51a3634d0fa58d66969fb06a1e47b..136909eff6d5ce77d747fd2592d4f9154abbcedd 100644 (file)
@@ -237,7 +237,7 @@ static const struct file_operations fops = {
        .release = single_release,
 };
 
-int __init rtllib_init(void)
+static int __init rtllib_init(void)
 {
        struct proc_dir_entry *e;
 
@@ -257,7 +257,7 @@ int __init rtllib_init(void)
        return 0;
 }
 
-void __exit rtllib_exit(void)
+static void __exit rtllib_exit(void)
 {
        if (rtllib_proc) {
                remove_proc_entry("debug_level", rtllib_proc);
index 1a011b9b9da61840789103ef5c9dd4631806a202..1fab69d313ba75dee3ec9c9728f1dd2837b8a0a9 100644 (file)
@@ -490,7 +490,7 @@ void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prx
                        } else {
                                u16 len;
                        /* Leave Ethernet header part of hdr and full payload */
-                               len = htons(sub_skb->len);
+                               len = sub_skb->len;
                                memcpy(skb_push(sub_skb, 2), &len, 2);
                                memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
                                memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
@@ -1224,7 +1224,7 @@ static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee,
                        } else {
                                u16 len;
                                /* Leave Ethernet header part of hdr and full payload */
-                               len = htons(sub_skb->len);
+                               len = sub_skb->len;
                                memcpy(skb_push(sub_skb, 2), &len, 2);
                                memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
                                memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
@@ -1632,13 +1632,13 @@ static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info
                /* WMM spec P.11: The minimum value for AIFSN shall be 2 */
                qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2 : qos_param->aifs[aci];
 
-               qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F;
+               qos_param->cw_min[aci] = cpu_to_le16(ac_params->ecw_min_max & 0x0F);
 
-               qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4;
+               qos_param->cw_max[aci] = cpu_to_le16((ac_params->ecw_min_max & 0xF0) >> 4);
 
                qos_param->flag[aci] =
                    (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
-               qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit);
+               qos_param->tx_op_limit[aci] = ac_params->tx_op_limit;
        }
        return rc;
 }
@@ -2260,9 +2260,9 @@ static inline int rtllib_network_init(
        memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
        network->capability = le16_to_cpu(beacon->capability);
        network->last_scanned = jiffies;
-       network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
-       network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
-       network->beacon_interval = le32_to_cpu(beacon->beacon_interval);
+       network->time_stamp[0] = beacon->time_stamp[0];
+       network->time_stamp[1] = beacon->time_stamp[1];
+       network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
        /* Where to pull this? beacon->listen_interval;*/
        network->listen_interval = 0x0A;
        network->rates_len = network->rates_ex_len = 0;
@@ -2528,29 +2528,30 @@ static inline void rtllib_process_probe_response(
                "'%s' ( %pM ): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
                escape_essid(info_element->data, info_element->len),
                beacon->header.addr3,
-               (beacon->capability & (1<<0xf)) ? '1' : '0',
-               (beacon->capability & (1<<0xe)) ? '1' : '0',
-               (beacon->capability & (1<<0xd)) ? '1' : '0',
-               (beacon->capability & (1<<0xc)) ? '1' : '0',
-               (beacon->capability & (1<<0xb)) ? '1' : '0',
-               (beacon->capability & (1<<0xa)) ? '1' : '0',
-               (beacon->capability & (1<<0x9)) ? '1' : '0',
-               (beacon->capability & (1<<0x8)) ? '1' : '0',
-               (beacon->capability & (1<<0x7)) ? '1' : '0',
-               (beacon->capability & (1<<0x6)) ? '1' : '0',
-               (beacon->capability & (1<<0x5)) ? '1' : '0',
-               (beacon->capability & (1<<0x4)) ? '1' : '0',
-               (beacon->capability & (1<<0x3)) ? '1' : '0',
-               (beacon->capability & (1<<0x2)) ? '1' : '0',
-               (beacon->capability & (1<<0x1)) ? '1' : '0',
-               (beacon->capability & (1<<0x0)) ? '1' : '0');
+               (le16_to_cpu(beacon->capability) & (1<<0xf)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0xe)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0xd)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0xc)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0xb)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0xa)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x9)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x8)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x7)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x6)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x5)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x4)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x3)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x2)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x1)) ? '1' : '0',
+               (le16_to_cpu(beacon->capability) & (1<<0x0)) ? '1' : '0');
 
        if (rtllib_network_init(ieee, beacon, network, stats)) {
                RTLLIB_DEBUG_SCAN("Dropped '%s' ( %pM) via %s.\n",
                                  escape_essid(info_element->data,
                                  info_element->len),
                                  beacon->header.addr3,
-                                 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+                                 WLAN_FC_GET_STYPE(
+                                         le16_to_cpu(beacon->header.frame_ctl)) ==
                                  RTLLIB_STYPE_PROBE_RESP ?
                                  "PROBE RESPONSE" : "BEACON");
                goto free_network;
@@ -2560,7 +2561,7 @@ static inline void rtllib_process_probe_response(
        if (!rtllib_legal_channel(ieee, network->channel))
                goto free_network;
 
-       if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+       if (WLAN_FC_GET_STYPE(le16_to_cpu(beacon->header.frame_ctl)) ==
            RTLLIB_STYPE_PROBE_RESP) {
                if (IsPassiveChannel(ieee, network->channel)) {
                        printk(KERN_INFO "GetScanInfo(): For Global Domain, "
@@ -2629,7 +2630,8 @@ static inline void rtllib_process_probe_response(
                RTLLIB_DEBUG_SCAN("Adding '%s' ( %pM) via %s.\n",
                                  escape_essid(network->ssid,
                                  network->ssid_len), network->bssid,
-                                 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+                                 WLAN_FC_GET_STYPE(
+                                         le16_to_cpu(beacon->header.frame_ctl)) ==
                                  RTLLIB_STYPE_PROBE_RESP ?
                                  "PROBE RESPONSE" : "BEACON");
                memcpy(target, network, sizeof(*target));
@@ -2640,7 +2642,8 @@ static inline void rtllib_process_probe_response(
                RTLLIB_DEBUG_SCAN("Updating '%s' ( %pM) via %s.\n",
                                  escape_essid(target->ssid,
                                  target->ssid_len), target->bssid,
-                                 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+                                 WLAN_FC_GET_STYPE(
+                                         le16_to_cpu(beacon->header.frame_ctl)) ==
                                  RTLLIB_STYPE_PROBE_RESP ?
                                  "PROBE RESPONSE" : "BEACON");
 
@@ -2682,15 +2685,17 @@ void rtllib_rx_mgt(struct rtllib_device *ieee,
 {
        struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data ;
 
-       if (WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_PROBE_RESP &&
-           WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_BEACON)
+       if ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) !=
+           RTLLIB_STYPE_PROBE_RESP) &&
+           (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) !=
+           RTLLIB_STYPE_BEACON))
                ieee->last_rx_ps_time = jiffies;
 
-       switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
+       switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
 
        case RTLLIB_STYPE_BEACON:
                RTLLIB_DEBUG_MGMT("received BEACON (%d)\n",
-                                 WLAN_FC_GET_STYPE(header->frame_ctl));
+                                 WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)));
                RTLLIB_DEBUG_SCAN("Beacon\n");
                rtllib_process_probe_response(
                                ieee, (struct rtllib_probe_response *)header,
@@ -2705,14 +2710,15 @@ void rtllib_rx_mgt(struct rtllib_device *ieee,
 
        case RTLLIB_STYPE_PROBE_RESP:
                RTLLIB_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
-                       WLAN_FC_GET_STYPE(header->frame_ctl));
+                       WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)));
                RTLLIB_DEBUG_SCAN("Probe response\n");
                rtllib_process_probe_response(ieee,
                              (struct rtllib_probe_response *)header, stats);
                break;
        case RTLLIB_STYPE_PROBE_REQ:
                RTLLIB_DEBUG_MGMT("received PROBE RESQUEST (%d)\n",
-                                 WLAN_FC_GET_STYPE(header->frame_ctl));
+                                 WLAN_FC_GET_STYPE(
+                                         le16_to_cpu(header->frame_ctl)));
                RTLLIB_DEBUG_SCAN("Probe request\n");
                if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
                    ((ieee->iw_mode == IW_MODE_ADHOC ||
index 933bd6deaca123035dd271dfd0ddf67bbc290e57..eeec19cde229e2c09b06ac438752b0f52f666226 100644 (file)
@@ -227,7 +227,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
        /* called with 2nd param 0, no mgmt lock required */
        rtllib_sta_wakeup(ieee, 0);
 
-       if (header->frame_ctl == RTLLIB_STYPE_BEACON)
+       if (le16_to_cpu(header->frame_ctl) == RTLLIB_STYPE_BEACON)
                tcb_desc->queue_index = BEACON_QUEUE;
        else
                tcb_desc->queue_index = MGNT_QUEUE;
@@ -295,7 +295,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb,
        u16 fc, type, stype;
        struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
 
-       fc = header->frame_ctl;
+       fc = le16_to_cpu(header->frame_ctl);
        type = WLAN_FC_GET_TYPE(fc);
        stype = WLAN_FC_GET_STYPE(fc);
 
@@ -807,18 +807,18 @@ inline struct sk_buff *rtllib_authentication_req(struct rtllib_network *beacon,
        auth = (struct rtllib_authentication *)
                skb_put(skb, sizeof(struct rtllib_authentication));
 
-       auth->header.frame_ctl = RTLLIB_STYPE_AUTH;
+       auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH);
        if (challengelen)
-               auth->header.frame_ctl |= RTLLIB_FCTL_WEP;
+               auth->header.frame_ctl |= cpu_to_le16(RTLLIB_FCTL_WEP);
 
-       auth->header.duration_id = 0x013a;
+       auth->header.duration_id = cpu_to_le16(0x013a);
        memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
        memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
        memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
        if (ieee->auth_mode == 0)
                auth->algorithm = WLAN_AUTH_OPEN;
        else if (ieee->auth_mode == 1)
-               auth->algorithm = WLAN_AUTH_SHARED_KEY;
+               auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY);
        else if (ieee->auth_mode == 2)
                auth->algorithm = WLAN_AUTH_OPEN;
        auth->transaction = cpu_to_le16(ieee->associate_seq);
@@ -921,8 +921,8 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, u8 *dest)
 
        if (ieee->short_slot && (ieee->current_network.capability &
            WLAN_CAPABILITY_SHORT_SLOT_TIME))
-               cpu_to_le16((beacon_buf->capability |=
-                                WLAN_CAPABILITY_SHORT_SLOT_TIME));
+               beacon_buf->capability |=
+                       cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
 
        crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
        if (encrypt)
@@ -952,7 +952,7 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, u8 *dest)
                u16 val16;
                *(tag++) = MFIE_TYPE_IBSS_SET;
                *(tag++) = 2;
-                val16 = cpu_to_le16(ieee->current_network.atim_window);
+               val16 = ieee->current_network.atim_window;
                memcpy((u8 *)tag, (u8 *)&val16, 2);
                tag += 2;
        }
@@ -1260,7 +1260,7 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon,
 
 
        hdr->header.frame_ctl = RTLLIB_STYPE_ASSOC_REQ;
-       hdr->header.duration_id = 37;
+       hdr->header.duration_id = cpu_to_le16(37);
        memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
        memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
        memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
@@ -1279,7 +1279,7 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon,
                hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
 
 
-       hdr->listen_interval = beacon->listen_interval;
+       hdr->listen_interval = cpu_to_le16(beacon->listen_interval);
 
        hdr->info_element[0].id = MFIE_TYPE_SSID;
 
@@ -3633,7 +3633,7 @@ out:
 }
 EXPORT_SYMBOL(rtllib_wpa_supplicant_ioctl);
 
-void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib)
+static void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib)
 {
        u8      OpMode;
        u8      i;
@@ -3658,7 +3658,7 @@ void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib)
 
 }
 
-void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta,
+static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta,
                                    u8 asRsn)
 {
        u8 i;
@@ -3684,7 +3684,7 @@ void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta,
 
 }
 
-void
+static void
 rtllib_MgntDisconnectAP(
        struct rtllib_device *rtllib,
        u8 asRsn
index 3183627823fb58fb3def9fb89090f98281732ec4..77964885b3f22d2d51dae39b93da7e78088ee312 100644 (file)
@@ -171,7 +171,7 @@ inline int rtllib_put_snap(u8 *data, u16 h_proto)
        snap->oui[1] = oui[1];
        snap->oui[2] = oui[2];
 
-       *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
+       *(u16 *)(data + SNAP_SIZE) = h_proto;
 
        return SNAP_SIZE + sizeof(u16);
 }
@@ -231,7 +231,7 @@ static struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size,
 
        memset(txb, 0, sizeof(struct rtllib_txb));
        txb->nr_frags = nr_frags;
-       txb->frag_size = txb_size;
+       txb->frag_size = cpu_to_le16(txb_size);
 
        for (i = 0; i < nr_frags; i++) {
                txb->fragments[i] = dev_alloc_skb(txb_size);
@@ -610,7 +610,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
                        }
 
                        txb->encrypted = 0;
-                       txb->payload_size = skb->len;
+                       txb->payload_size = cpu_to_le16(skb->len);
                        memcpy(skb_put(txb->fragments[0], skb->len), skb->data,
                               skb->len);
 
@@ -764,7 +764,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
                        goto failed;
                }
                txb->encrypted = encrypt;
-               txb->payload_size = bytes;
+               txb->payload_size = cpu_to_le16(bytes);
 
                if (qos_actived)
                        txb->queue_index = UP2AC(skb->priority);
@@ -812,10 +812,10 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
                        }
                        if ((qos_actived) && (!bIsMulticast)) {
                                frag_hdr->seq_ctl =
-                                        rtllib_query_seqnum(ieee, skb_frag,
-                                                            header.addr1);
+                                        cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag,
+                                                            header.addr1));
                                frag_hdr->seq_ctl =
-                                        cpu_to_le16(frag_hdr->seq_ctl<<4 | i);
+                                        cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctl)<<4 | i);
                        } else {
                                frag_hdr->seq_ctl =
                                         cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
@@ -870,7 +870,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
                }
 
                txb->encrypted = 0;
-               txb->payload_size = skb->len;
+               txb->payload_size = cpu_to_le16(skb->len);
                memcpy(skb_put(txb->fragments[0], skb->len), skb->data,
                       skb->len);
        }
index 8fa0f9d49a8aedb6800d25e07b004a61c4a18531..3ea99aea4385343c101a18da5f757f63070b90c0 100644 (file)
@@ -1043,9 +1043,6 @@ void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf)
        struct  sta_priv *pstapriv = &adapter->stapriv;
        struct  recv_reorder_ctrl *precvreorder_ctrl = NULL;
 
-       netdev_info(adapter->pnetdev, "%s: mac = %pM, seq = %d, tid = %d\n",
-                   __func__, pAddbareq_pram->MacAddress,
-           pAddbareq_pram->StartSeqNum, pAddbareq_pram->tid);
        psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress);
        if (psta) {
                precvreorder_ctrl =
diff --git a/drivers/staging/rts5208/Kconfig b/drivers/staging/rts5208/Kconfig
new file mode 100644 (file)
index 0000000..055655c
--- /dev/null
@@ -0,0 +1,15 @@
+config RTS5208
+       tristate "Realtek PCI-E Card Reader RTS5208/5288 support"
+       depends on PCI && SCSI
+       help
+         Say Y here to include driver code to support the Realtek
+         PCI-E card reader rts5208/rts5288.
+
+         If this driver is compiled as a module, it will be named rts5208.
+
+config RTS5208_DEBUG
+       bool "Realtek PCI-E Card Reader RTS5208/5288 verbose debug"
+       depends on RTS5208
+       help
+         Say Y here in order to have the rts5208 code generate
+         verbose debugging messages.
diff --git a/drivers/staging/rts5208/Makefile b/drivers/staging/rts5208/Makefile
new file mode 100644 (file)
index 0000000..17b4471
--- /dev/null
@@ -0,0 +1,6 @@
+obj-$(CONFIG_RTS5208) := rts5208.o
+
+ccflags-y := -Idrivers/scsi
+
+rts5208-y := rtsx.o rtsx_chip.o rtsx_transport.o rtsx_scsi.o \
+       rtsx_card.o general.o sd.o xd.o ms.o spi.o
diff --git a/drivers/staging/rts5208/TODO b/drivers/staging/rts5208/TODO
new file mode 100644 (file)
index 0000000..57bcf58
--- /dev/null
@@ -0,0 +1,7 @@
+TODO:
+- use kernel coding style
+- checkpatch.pl fixes
+- We will use the stack in drivers/mmc to implement
+  rts5208/5288 in the future
+
+Micky Ching <micky_ching@realsil.com.cn>
\ No newline at end of file
diff --git a/drivers/staging/rts5208/debug.h b/drivers/staging/rts5208/debug.h
new file mode 100644 (file)
index 0000000..5ba8a3a
--- /dev/null
@@ -0,0 +1,43 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_DEBUG_H
+#define __REALTEK_RTSX_DEBUG_H
+
+#include <linux/kernel.h>
+
+#define RTSX_STOR "rts5208: "
+
+#ifdef CONFIG_RTS5208_DEBUG
+#define RTSX_DEBUGP(x...) pr_debug(RTSX_STOR x)
+#define RTSX_DEBUGPN(x...) pr_debug(x)
+#define RTSX_DEBUGPX(x...) printk(x)
+#define RTSX_DEBUG(x) x
+#else
+#define RTSX_DEBUGP(x...)
+#define RTSX_DEBUGPN(x...)
+#define RTSX_DEBUGPX(x...)
+#define RTSX_DEBUG(x)
+#endif
+
+#endif   /* __REALTEK_RTSX_DEBUG_H */
diff --git a/drivers/staging/rts5208/general.c b/drivers/staging/rts5208/general.c
new file mode 100644 (file)
index 0000000..eada934
--- /dev/null
@@ -0,0 +1,35 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#include "general.h"
+
+int bit1cnt_long(u32 data)
+{
+       int i, cnt = 0;
+       for (i = 0; i < 32; i++) {
+               if (data & 0x01)
+                       cnt++;
+               data >>= 1;
+       }
+       return cnt;
+}
+
diff --git a/drivers/staging/rts5208/general.h b/drivers/staging/rts5208/general.h
new file mode 100644 (file)
index 0000000..90a1f92
--- /dev/null
@@ -0,0 +1,31 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __RTSX_GENERAL_H
+#define __RTSX_GENERAL_H
+
+#include "rtsx.h"
+
+int bit1cnt_long(u32 data);
+
+#endif /* __RTSX_GENERAL_H */
diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c
new file mode 100644 (file)
index 0000000..edf979f
--- /dev/null
@@ -0,0 +1,4208 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+
+#include "rtsx.h"
+#include "rtsx_transport.h"
+#include "rtsx_scsi.h"
+#include "rtsx_card.h"
+#include "ms.h"
+
+static inline void ms_set_err_code(struct rtsx_chip *chip, u8 err_code)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+
+       ms_card->err_code = err_code;
+}
+
+static inline int ms_check_err_code(struct rtsx_chip *chip, u8 err_code)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+
+       return (ms_card->err_code == err_code);
+}
+
+static int ms_parse_err_code(struct rtsx_chip *chip)
+{
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode,
+                       u8 tpc, u8 cnt, u8 cfg)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       u8 *ptr;
+
+       RTSX_DEBUGP("ms_transfer_tpc: tpc = 0x%x\n", tpc);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+               0x01, PINGPONG_BUFFER);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER,
+               0xFF, MS_TRANSFER_START | trans_mode);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER,
+               MS_TRANSFER_END, MS_TRANSFER_END);
+
+       rtsx_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0);
+
+       retval = rtsx_send_cmd(chip, MS_CARD, 5000);
+       if (retval < 0) {
+               rtsx_clear_ms_error(chip);
+               ms_set_err_code(chip, MS_TO_ERROR);
+               TRACE_RET(chip, ms_parse_err_code(chip));
+       }
+
+       ptr = rtsx_get_cmd_data(chip) + 1;
+
+       if (!(tpc & 0x08)) {            /* Read Packet */
+               if (*ptr & MS_CRC16_ERR) {
+                       ms_set_err_code(chip, MS_CRC16_ERROR);
+                       TRACE_RET(chip, ms_parse_err_code(chip));
+               }
+       } else {                        /* Write Packet */
+               if (CHK_MSPRO(ms_card) && !(*ptr & 0x80)) {
+                       if (*ptr & (MS_INT_ERR | MS_INT_CMDNK)) {
+                               ms_set_err_code(chip, MS_CMD_NK);
+                               TRACE_RET(chip, ms_parse_err_code(chip));
+                       }
+               }
+       }
+
+       if (*ptr & MS_RDY_TIMEOUT) {
+               rtsx_clear_ms_error(chip);
+               ms_set_err_code(chip, MS_TO_ERROR);
+               TRACE_RET(chip, ms_parse_err_code(chip));
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode,
+                       u8 tpc, u16 sec_cnt, u8 cfg, int mode_2k,
+                       int use_sg, void *buf, int buf_len)
+{
+       int retval;
+       u8 val, err_code = 0;
+       enum dma_data_direction dir;
+
+       if (!buf || !buf_len)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (trans_mode == MS_TM_AUTO_READ) {
+               dir = DMA_FROM_DEVICE;
+               err_code = MS_FLASH_READ_ERROR;
+       } else if (trans_mode == MS_TM_AUTO_WRITE) {
+               dir = DMA_TO_DEVICE;
+               err_code = MS_FLASH_WRITE_ERROR;
+       } else {
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
+       rtsx_add_cmd(chip, WRITE_REG_CMD,
+                    MS_SECTOR_CNT_H, 0xFF, (u8)(sec_cnt >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, (u8)sec_cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
+
+       if (mode_2k) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD,
+                            MS_CFG, MS_2K_SECTOR_MODE, MS_2K_SECTOR_MODE);
+       } else {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, 0);
+       }
+
+       trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD,
+                    MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode);
+       rtsx_add_cmd(chip, CHECK_REG_CMD,
+                    MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END);
+
+       rtsx_send_cmd_no_wait(chip);
+
+       retval = rtsx_transfer_data(chip, MS_CARD, buf, buf_len,
+                                   use_sg, dir, chip->mspro_timeout);
+       if (retval < 0) {
+               ms_set_err_code(chip, err_code);
+               if (retval == -ETIMEDOUT)
+                       retval = STATUS_TIMEDOUT;
+               else
+                       retval = STATUS_FAIL;
+
+               TRACE_RET(chip, retval);
+       }
+
+       RTSX_READ_REG(chip, MS_TRANS_CFG, &val);
+       if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_write_bytes(struct rtsx_chip *chip,
+                         u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+
+       if (!data || (data_len < cnt))
+               TRACE_RET(chip, STATUS_ERROR);
+
+       rtsx_init_cmd(chip);
+
+       for (i = 0; i < cnt; i++) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD,
+                            PPBUF_BASE2 + i, 0xFF, data[i]);
+       }
+       if (cnt % 2)
+               rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, 0xFF);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+               0x01, PINGPONG_BUFFER);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD,
+                    MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES);
+       rtsx_add_cmd(chip, CHECK_REG_CMD,
+                    MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END);
+
+       retval = rtsx_send_cmd(chip, MS_CARD, 5000);
+       if (retval < 0) {
+               u8 val = 0;
+
+               rtsx_read_register(chip, MS_TRANS_CFG, &val);
+               RTSX_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val);
+
+               rtsx_clear_ms_error(chip);
+
+               if (!(tpc & 0x08)) {
+                       if (val & MS_CRC16_ERR) {
+                               ms_set_err_code(chip, MS_CRC16_ERROR);
+                               TRACE_RET(chip, ms_parse_err_code(chip));
+                       }
+               } else {
+                       if (CHK_MSPRO(ms_card) && !(val & 0x80)) {
+                               if (val & (MS_INT_ERR | MS_INT_CMDNK)) {
+                                       ms_set_err_code(chip, MS_CMD_NK);
+                                       TRACE_RET(chip,
+                                               ms_parse_err_code(chip));
+                               }
+                       }
+               }
+
+               if (val & MS_RDY_TIMEOUT) {
+                       ms_set_err_code(chip, MS_TO_ERROR);
+                       TRACE_RET(chip, ms_parse_err_code(chip));
+               }
+
+               ms_set_err_code(chip, MS_TO_ERROR);
+               TRACE_RET(chip, ms_parse_err_code(chip));
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_read_bytes(struct rtsx_chip *chip,
+                       u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u8 *ptr;
+
+       if (!data)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+               0x01, PINGPONG_BUFFER);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
+               MS_TRANSFER_START | MS_TM_READ_BYTES);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER,
+               MS_TRANSFER_END, MS_TRANSFER_END);
+
+       for (i = 0; i < data_len - 1; i++)
+              rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0);
+
+       if (data_len % 2)
+               rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, 0);
+       else
+               rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1,
+                       0, 0);
+
+       retval = rtsx_send_cmd(chip, MS_CARD, 5000);
+       if (retval < 0) {
+               u8 val = 0;
+
+               rtsx_read_register(chip, MS_TRANS_CFG, &val);
+               rtsx_clear_ms_error(chip);
+
+               if (!(tpc & 0x08)) {
+                       if (val & MS_CRC16_ERR) {
+                               ms_set_err_code(chip, MS_CRC16_ERROR);
+                               TRACE_RET(chip, ms_parse_err_code(chip));
+                       }
+               } else {
+                       if (CHK_MSPRO(ms_card) && !(val & 0x80)) {
+                               if (val & (MS_INT_ERR | MS_INT_CMDNK)) {
+                                       ms_set_err_code(chip, MS_CMD_NK);
+                                       TRACE_RET(chip,
+                                               ms_parse_err_code(chip));
+                               }
+                       }
+               }
+
+               if (val & MS_RDY_TIMEOUT) {
+                       ms_set_err_code(chip, MS_TO_ERROR);
+                       TRACE_RET(chip, ms_parse_err_code(chip));
+               }
+
+               ms_set_err_code(chip, MS_TO_ERROR);
+               TRACE_RET(chip, ms_parse_err_code(chip));
+       }
+
+       ptr = rtsx_get_cmd_data(chip) + 1;
+
+       for (i = 0; i < data_len; i++)
+               data[i] = ptr[i];
+
+       if ((tpc == PRO_READ_SHORT_DATA) && (data_len == 8)) {
+               RTSX_DEBUGP("Read format progress:\n");
+               RTSX_DUMP(ptr, cnt);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_set_rw_reg_addr(struct rtsx_chip *chip,
+               u8 read_start, u8 read_cnt, u8 write_start, u8 write_cnt)
+{
+       int retval, i;
+       u8 data[4];
+
+       data[0] = read_start;
+       data[1] = read_cnt;
+       data[2] = write_start;
+       data[3] = write_cnt;
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, SET_RW_REG_ADRS, 4,
+                                       NO_WAIT_INT, data, 4);
+               if (retval == STATUS_SUCCESS)
+                       return STATUS_SUCCESS;
+               rtsx_clear_ms_error(chip);
+       }
+
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+static int ms_send_cmd(struct rtsx_chip *chip, u8 cmd, u8 cfg)
+{
+       u8 data[2];
+
+       data[0] = cmd;
+       data[1] = 0;
+
+       return ms_write_bytes(chip, PRO_SET_CMD, 1, cfg, data, 1);
+}
+
+static int ms_set_init_para(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+
+       if (CHK_HG8BIT(ms_card)) {
+               if (chip->asic_code)
+                       ms_card->ms_clock = chip->asic_ms_hg_clk;
+               else
+                       ms_card->ms_clock = chip->fpga_ms_hg_clk;
+
+       } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) {
+               if (chip->asic_code)
+                       ms_card->ms_clock = chip->asic_ms_4bit_clk;
+               else
+                       ms_card->ms_clock = chip->fpga_ms_4bit_clk;
+
+       } else {
+               if (chip->asic_code)
+                       ms_card->ms_clock = chip->asic_ms_1bit_clk;
+               else
+                       ms_card->ms_clock = chip->fpga_ms_1bit_clk;
+       }
+
+       retval = switch_clock(chip, ms_card->ms_clock);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = select_card(chip, MS_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_switch_clock(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+
+       retval = select_card(chip, MS_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = switch_clock(chip, ms_card->ms_clock);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_pull_ctl_disable(struct rtsx_chip *chip)
+{
+       if (CHECK_PID(chip, 0x5208)) {
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF,
+                       MS_D1_PD | MS_D2_PD | MS_CLK_PD | MS_D6_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF,
+                       MS_D3_PD | MS_D0_PD | MS_BS_PD | XD_D4_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF,
+                       MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF,
+                       XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF,
+                       MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF,
+                       MS_D5_PD | MS_D4_PD);
+       } else if (CHECK_PID(chip, 0x5288)) {
+               if (CHECK_BARO_PKG(chip, QFN)) {
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55);
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55);
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B);
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69);
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_pull_ctl_enable(struct rtsx_chip *chip)
+{
+       int retval;
+
+       rtsx_init_cmd(chip);
+
+       if (CHECK_PID(chip, 0x5208)) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,
+                       MS_D1_PD | MS_D2_PD | MS_CLK_NP | MS_D6_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,
+                       MS_D3_PD | MS_D0_PD | MS_BS_NP | XD_D4_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,
+                       MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,
+                       XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,
+                       MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF,
+                       MS_D5_PD | MS_D4_PD);
+       } else if (CHECK_PID(chip, 0x5288)) {
+               if (CHECK_BARO_PKG(chip, QFN)) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD,
+                                    CARD_PULL_CTL1, 0xFF, 0x55);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD,
+                                    CARD_PULL_CTL2, 0xFF, 0x45);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD,
+                                    CARD_PULL_CTL3, 0xFF, 0x4B);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD,
+                                    CARD_PULL_CTL4, 0xFF, 0x29);
+               }
+       }
+
+       retval = rtsx_send_cmd(chip, MS_CARD, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_prepare_reset(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       u8 oc_mask = 0;
+
+       ms_card->ms_type = 0;
+       ms_card->check_ms_flow = 0;
+       ms_card->switch_8bit_fail = 0;
+       ms_card->delay_write.delay_write_flag = 0;
+
+       ms_card->pro_under_formatting = 0;
+
+       retval = ms_power_off_card3v3(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (!chip->ft2_fast_mode)
+               wait_timeout(250);
+
+       retval = enable_card_clock(chip, MS_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (chip->asic_code) {
+               retval = ms_pull_ctl_enable(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else {
+               RTSX_WRITE_REG(chip, FPGA_PULL_CTL,
+                       FPGA_MS_PULL_CTL_BIT | 0x20, 0);
+       }
+
+       if (!chip->ft2_fast_mode) {
+               retval = card_power_on(chip, MS_CARD);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               wait_timeout(150);
+
+#ifdef SUPPORT_OCP
+               if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
+                       oc_mask = MS_OC_NOW | MS_OC_EVER;
+               else
+                       oc_mask = SD_OC_NOW | SD_OC_EVER;
+
+               if (chip->ocp_stat & oc_mask) {
+                       RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
+                                    chip->ocp_stat);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+#endif
+       }
+
+       RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, MS_OUTPUT_EN);
+
+       if (chip->asic_code) {
+               RTSX_WRITE_REG(chip, MS_CFG, 0xFF,
+                       SAMPLE_TIME_RISING | PUSH_TIME_DEFAULT |
+                       NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1);
+       } else {
+               RTSX_WRITE_REG(chip, MS_CFG, 0xFF,
+                       SAMPLE_TIME_FALLING | PUSH_TIME_DEFAULT |
+                       NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1);
+       }
+       RTSX_WRITE_REG(chip, MS_TRANS_CFG,
+               0xFF, NO_WAIT_INT | NO_AUTO_READ_INT_REG);
+       RTSX_WRITE_REG(chip, CARD_STOP,
+               MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR);
+
+       retval = ms_set_init_para(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u8 val;
+
+       retval = ms_set_rw_reg_addr(chip, Pro_StatusReg, 6, SystemParm, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG,
+                                       6, NO_WAIT_INT);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_READ_REG(chip, PPBUF_BASE2 + 2, &val);
+       RTSX_DEBUGP("Type register: 0x%x\n", val);
+       if (val != 0x01) {
+               if (val != 0x02)
+                       ms_card->check_ms_flow = 1;
+
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_READ_REG(chip, PPBUF_BASE2 + 4, &val);
+       RTSX_DEBUGP("Category register: 0x%x\n", val);
+       if (val != 0) {
+               ms_card->check_ms_flow = 1;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_READ_REG(chip, PPBUF_BASE2 + 5, &val);
+       RTSX_DEBUGP("Class register: 0x%x\n", val);
+       if (val == 0) {
+               RTSX_READ_REG(chip, PPBUF_BASE2, &val);
+               if (val & WRT_PRTCT)
+                       chip->card_wp |= MS_CARD;
+               else
+                       chip->card_wp &= ~MS_CARD;
+
+       } else if ((val == 0x01) || (val == 0x02) || (val == 0x03)) {
+               chip->card_wp |= MS_CARD;
+       } else {
+               ms_card->check_ms_flow = 1;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       ms_card->ms_type |= TYPE_MSPRO;
+
+       RTSX_READ_REG(chip, PPBUF_BASE2 + 3, &val);
+       RTSX_DEBUGP("IF Mode register: 0x%x\n", val);
+       if (val == 0) {
+               ms_card->ms_type &= 0x0F;
+       } else if (val == 7) {
+               if (switch_8bit_bus)
+                       ms_card->ms_type |= MS_HG;
+               else
+                       ms_card->ms_type &= 0x0F;
+
+       } else {
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_confirm_cpu_startup(struct rtsx_chip *chip)
+{
+       int retval, i, k;
+       u8 val;
+
+       /* Confirm CPU StartUp */
+       k = 0;
+       do {
+               if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                       ms_set_err_code(chip, MS_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+                       retval = ms_read_bytes(chip, GET_INT, 1,
+                                       NO_WAIT_INT, &val, 1);
+                       if (retval == STATUS_SUCCESS)
+                               break;
+               }
+               if (i == MS_MAX_RETRY_COUNT)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (k > 100)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               k++;
+               wait_timeout(100);
+       } while (!(val & INT_REG_CED));
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (val & INT_REG_ERR) {
+               if (val & INT_REG_CMDNK)
+                       chip->card_wp |= (MS_CARD);
+               else
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+       /* --  end confirm CPU startup */
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_switch_parallel_bus(struct rtsx_chip *chip)
+{
+       int retval, i;
+       u8 data[2];
+
+       data[0] = PARALLEL_4BIT_IF;
+       data[1] = 0;
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT,
+                                       data, 2);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_switch_8bit_bus(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u8 data[2];
+
+       data[0] = PARALLEL_8BIT_IF;
+       data[1] = 0;
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, WRITE_REG, 1,
+                                       NO_WAIT_INT, data, 2);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, MS_CFG, 0x98,
+               MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING);
+       ms_card->ms_type |= MS_8BIT;
+       retval = ms_set_init_para(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT,
+                                       1, NO_WAIT_INT);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+
+       for (i = 0; i < 3; i++) {
+               retval = ms_prepare_reset(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = ms_identify_media_type(chip, switch_8bit_bus);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = ms_confirm_cpu_startup(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = ms_switch_parallel_bus(chip);
+               if (retval != STATUS_SUCCESS) {
+                       if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                               ms_set_err_code(chip, MS_NO_CARD);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       continue;
+               } else {
+                       break;
+               }
+       }
+
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       /* Switch MS-PRO into Parallel mode */
+       RTSX_WRITE_REG(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4);
+       RTSX_WRITE_REG(chip, MS_CFG, PUSH_TIME_ODD, PUSH_TIME_ODD);
+
+       retval = ms_set_init_para(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       /* If MSPro HG Card, We shall try to switch to 8-bit bus */
+       if (CHK_MSHG(ms_card) && chip->support_ms_8bit && switch_8bit_bus) {
+               retval = ms_switch_8bit_bus(chip);
+               if (retval != STATUS_SUCCESS) {
+                       ms_card->switch_8bit_fail = 1;
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+#ifdef XC_POWERCLASS
+static int msxc_change_power(struct rtsx_chip *chip, u8 mode)
+{
+       int retval;
+       u8 buf[6];
+
+       ms_cleanup_work(chip);
+
+       retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       buf[0] = 0;
+       buf[1] = mode;
+       buf[2] = 0;
+       buf[3] = 0;
+       buf[4] = 0;
+       buf[5] = 0;
+
+       retval = ms_write_bytes(chip, PRO_WRITE_REG , 6, NO_WAIT_INT, buf, 6);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_READ_REG(chip, MS_TRANS_CFG, buf);
+       if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+#endif
+
+static int ms_read_attribute_info(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u8 val, *buf, class_code, device_type, sub_class, data[16];
+       u16 total_blk = 0, blk_size = 0;
+#ifdef SUPPORT_MSXC
+       u32 xc_total_blk = 0, xc_blk_size = 0;
+#endif
+       u32 sys_info_addr = 0, sys_info_size;
+#ifdef SUPPORT_PCGL_1P18
+       u32 model_name_addr = 0, model_name_size;
+       int found_sys_info = 0, found_model_name = 0;
+#endif
+
+       retval = ms_set_rw_reg_addr(chip, Pro_IntReg, 2, Pro_SystemParm, 7);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (CHK_MS8BIT(ms_card))
+               data[0] = PARALLEL_8BIT_IF;
+       else
+               data[0] = PARALLEL_4BIT_IF;
+
+       data[1] = 0;
+
+       data[2] = 0x40;
+       data[3] = 0;
+       data[4] = 0;
+       data[5] = 0;
+       data[6] = 0;
+       data[7] = 0;
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, PRO_WRITE_REG, 7, NO_WAIT_INT,
+                                       data, 8);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       buf = kmalloc(64 * 512, GFP_KERNEL);
+       if (buf == NULL)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT);
+               if (retval != STATUS_SUCCESS)
+                       continue;
+
+               retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
+               if (retval != STATUS_SUCCESS) {
+                       kfree(buf);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+               if (!(val & MS_INT_BREQ)) {
+                       kfree(buf);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+               retval = ms_transfer_data(chip, MS_TM_AUTO_READ,
+                                       PRO_READ_LONG_DATA, 0x40, WAIT_INT,
+                                       0, 0, buf, 64 * 512);
+               if (retval == STATUS_SUCCESS)
+                       break;
+               else
+                       rtsx_clear_ms_error(chip);
+       }
+       if (retval != STATUS_SUCCESS) {
+               kfree(buf);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       i = 0;
+       do {
+               retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
+               if (retval != STATUS_SUCCESS) {
+                       kfree(buf);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if ((val & MS_INT_CED) || !(val & MS_INT_BREQ))
+                       break;
+
+               retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ,
+                                       PRO_READ_LONG_DATA, 0, WAIT_INT);
+               if (retval != STATUS_SUCCESS) {
+                       kfree(buf);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               i++;
+       } while (i < 1024);
+
+       if (retval != STATUS_SUCCESS) {
+               kfree(buf);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if ((buf[0] != 0xa5) && (buf[1] != 0xc3)) {
+               /* Signature code is wrong */
+               kfree(buf);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if ((buf[4] < 1) || (buf[4] > 12)) {
+               kfree(buf);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       for (i = 0; i < buf[4]; i++) {
+               int cur_addr_off = 16 + i * 12;
+
+#ifdef SUPPORT_MSXC
+               if ((buf[cur_addr_off + 8] == 0x10) ||
+                       (buf[cur_addr_off + 8] == 0x13))
+#else
+               if (buf[cur_addr_off + 8] == 0x10)
+#endif
+               {
+                       sys_info_addr = ((u32)buf[cur_addr_off + 0] << 24) |
+                               ((u32)buf[cur_addr_off + 1] << 16) |
+                               ((u32)buf[cur_addr_off + 2] << 8) |
+                               buf[cur_addr_off + 3];
+                       sys_info_size = ((u32)buf[cur_addr_off + 4] << 24) |
+                               ((u32)buf[cur_addr_off + 5] << 16) |
+                               ((u32)buf[cur_addr_off + 6] << 8) |
+                               buf[cur_addr_off + 7];
+                       RTSX_DEBUGP("sys_info_addr = 0x%x, sys_info_size = 0x%x\n",
+                               sys_info_addr, sys_info_size);
+                       if (sys_info_size != 96)  {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if (sys_info_addr < 0x1A0) {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if ((sys_info_size + sys_info_addr) > 0x8000) {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+#ifdef SUPPORT_MSXC
+                       if (buf[cur_addr_off + 8] == 0x13)
+                               ms_card->ms_type |= MS_XC;
+#endif
+#ifdef SUPPORT_PCGL_1P18
+                       found_sys_info = 1;
+#else
+                       break;
+#endif
+               }
+#ifdef SUPPORT_PCGL_1P18
+               if (buf[cur_addr_off + 8] == 0x15) {
+                       model_name_addr = ((u32)buf[cur_addr_off + 0] << 24) |
+                               ((u32)buf[cur_addr_off + 1] << 16) |
+                               ((u32)buf[cur_addr_off + 2] << 8) |
+                               buf[cur_addr_off + 3];
+                       model_name_size = ((u32)buf[cur_addr_off + 4] << 24) |
+                               ((u32)buf[cur_addr_off + 5] << 16) |
+                               ((u32)buf[cur_addr_off + 6] << 8) |
+                               buf[cur_addr_off + 7];
+                       RTSX_DEBUGP("model_name_addr = 0x%x, model_name_size = 0x%x\n",
+                               model_name_addr, model_name_size);
+                       if (model_name_size != 48)  {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if (model_name_addr < 0x1A0) {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if ((model_name_size + model_name_addr) > 0x8000) {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       found_model_name = 1;
+               }
+
+               if (found_sys_info && found_model_name)
+                       break;
+#endif
+       }
+
+       if (i == buf[4]) {
+               kfree(buf);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       class_code =  buf[sys_info_addr + 0];
+       device_type = buf[sys_info_addr + 56];
+       sub_class = buf[sys_info_addr + 46];
+#ifdef SUPPORT_MSXC
+       if (CHK_MSXC(ms_card)) {
+               xc_total_blk = ((u32)buf[sys_info_addr + 6] << 24) |
+                               ((u32)buf[sys_info_addr + 7] << 16) |
+                               ((u32)buf[sys_info_addr + 8] << 8) |
+                               buf[sys_info_addr + 9];
+               xc_blk_size = ((u32)buf[sys_info_addr + 32] << 24) |
+                               ((u32)buf[sys_info_addr + 33] << 16) |
+                               ((u32)buf[sys_info_addr + 34] << 8) |
+                               buf[sys_info_addr + 35];
+               RTSX_DEBUGP("xc_total_blk = 0x%x, xc_blk_size = 0x%x\n",
+                       xc_total_blk, xc_blk_size);
+       } else {
+               total_blk = ((u16)buf[sys_info_addr + 6] << 8) |
+                       buf[sys_info_addr + 7];
+               blk_size = ((u16)buf[sys_info_addr + 2] << 8) |
+                       buf[sys_info_addr + 3];
+               RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n",
+                       total_blk, blk_size);
+       }
+#else
+       total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7];
+       blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3];
+       RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, blk_size);
+#endif
+
+       RTSX_DEBUGP("class_code = 0x%x, device_type = 0x%x, sub_class = 0x%x\n",
+                       class_code, device_type, sub_class);
+
+       memcpy(ms_card->raw_sys_info, buf + sys_info_addr, 96);
+#ifdef SUPPORT_PCGL_1P18
+       memcpy(ms_card->raw_model_name, buf + model_name_addr, 48);
+#endif
+
+       kfree(buf);
+
+#ifdef SUPPORT_MSXC
+       if (CHK_MSXC(ms_card)) {
+               if (class_code != 0x03)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else {
+               if (class_code != 0x02)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+#else
+       if (class_code != 0x02)
+               TRACE_RET(chip, STATUS_FAIL);
+#endif
+
+       if (device_type != 0x00) {
+               if ((device_type == 0x01) || (device_type == 0x02) ||
+                               (device_type == 0x03)) {
+                       chip->card_wp |= MS_CARD;
+               } else {
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       if (sub_class & 0xC0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_DEBUGP("class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n",
+               class_code, device_type, sub_class);
+
+#ifdef SUPPORT_MSXC
+       if (CHK_MSXC(ms_card)) {
+               chip->capacity[chip->card2lun[MS_CARD]] =
+                       ms_card->capacity = xc_total_blk * xc_blk_size;
+       } else {
+               chip->capacity[chip->card2lun[MS_CARD]] =
+                       ms_card->capacity = total_blk * blk_size;
+       }
+#else
+       ms_card->capacity = total_blk * blk_size;
+       chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity;
+#endif
+
+       return STATUS_SUCCESS;
+}
+
+#ifdef SUPPORT_MAGIC_GATE
+static int mg_set_tpc_para_sub(struct rtsx_chip *chip,
+                       int type, u8 mg_entry_num);
+#endif
+
+static int reset_ms_pro(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+#ifdef XC_POWERCLASS
+       u8 change_power_class;
+
+       if (chip->ms_power_class_en & 0x02)
+               change_power_class = 2;
+       else if (chip->ms_power_class_en & 0x01)
+               change_power_class = 1;
+       else
+               change_power_class = 0;
+#endif
+
+#ifdef XC_POWERCLASS
+Retry:
+#endif
+       retval = ms_pro_reset_flow(chip, 1);
+       if (retval != STATUS_SUCCESS) {
+               if (ms_card->switch_8bit_fail) {
+                       retval = ms_pro_reset_flow(chip, 0);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+               } else {
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       retval = ms_read_attribute_info(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+#ifdef XC_POWERCLASS
+       if (CHK_HG8BIT(ms_card))
+               change_power_class = 0;
+
+       if (change_power_class && CHK_MSXC(ms_card)) {
+               u8 power_class_en = chip->ms_power_class_en;
+
+               RTSX_DEBUGP("power_class_en = 0x%x\n", power_class_en);
+               RTSX_DEBUGP("change_power_class = %d\n", change_power_class);
+
+               if (change_power_class)
+                       power_class_en &= (1 << (change_power_class - 1));
+               else
+                       power_class_en = 0;
+
+               if (power_class_en) {
+                       u8 power_class_mode =
+                               (ms_card->raw_sys_info[46] & 0x18) >> 3;
+                       RTSX_DEBUGP("power_class_mode = 0x%x",
+                               power_class_mode);
+                       if (change_power_class > power_class_mode)
+                               change_power_class = power_class_mode;
+                       if (change_power_class) {
+                               retval = msxc_change_power(chip,
+                                                       change_power_class);
+                               if (retval != STATUS_SUCCESS) {
+                                       change_power_class--;
+                                       goto Retry;
+                               }
+                       }
+               }
+       }
+#endif
+
+#ifdef SUPPORT_MAGIC_GATE
+       retval = mg_set_tpc_para_sub(chip, 0, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+#endif
+
+       if (CHK_HG8BIT(ms_card))
+               chip->card_bus_width[chip->card2lun[MS_CARD]] = 8;
+       else
+               chip->card_bus_width[chip->card2lun[MS_CARD]] = 4;
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_read_status_reg(struct rtsx_chip *chip)
+{
+       int retval;
+       u8 val[2];
+
+       retval = ms_set_rw_reg_addr(chip, StatusReg0, 2, 0, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) {
+               ms_set_err_code(chip, MS_FLASH_READ_ERROR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+
+static int ms_read_extra_data(struct rtsx_chip *chip,
+               u16 block_addr, u8 page_num, u8 *buf, int buf_len)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u8 val, data[10];
+
+       retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
+                               SystemParm, 6);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (CHK_MS4BIT(ms_card)) {
+               /* Parallel interface */
+               data[0] = 0x88;
+       } else {
+               /* Serial interface */
+               data[0] = 0x80;
+       }
+       data[1] = 0;
+       data[2] = (u8)(block_addr >> 8);
+       data[3] = (u8)block_addr;
+       data[4] = 0x40;
+       data[5] = page_num;
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT,
+                                       data, 6);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+       retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (val & INT_REG_CMDNK) {
+               ms_set_err_code(chip, MS_CMD_NK);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+       if (val & INT_REG_CED) {
+               if (val & INT_REG_ERR) {
+                       retval = ms_read_status_reg(chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
+                                               MS_EXTRA_SIZE, SystemParm, 6);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       retval = ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT,
+                       data, MS_EXTRA_SIZE);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (buf && buf_len) {
+               if (buf_len > MS_EXTRA_SIZE)
+                       buf_len = MS_EXTRA_SIZE;
+               memcpy(buf, data, buf_len);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_write_extra_data(struct rtsx_chip *chip,
+               u16 block_addr, u8 page_num, u8 *buf, int buf_len)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u8 val, data[16];
+
+       if (!buf || (buf_len < MS_EXTRA_SIZE))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
+                               SystemParm, 6 + MS_EXTRA_SIZE);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (CHK_MS4BIT(ms_card))
+               data[0] = 0x88;
+       else
+               data[0] = 0x80;
+
+       data[1] = 0;
+       data[2] = (u8)(block_addr >> 8);
+       data[3] = (u8)block_addr;
+       data[4] = 0x40;
+       data[5] = page_num;
+
+       for (i = 6; i < MS_EXTRA_SIZE + 6; i++)
+               data[i] = buf[i - 6];
+
+       retval = ms_write_bytes(chip, WRITE_REG , (6+MS_EXTRA_SIZE),
+                               NO_WAIT_INT, data, 16);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+       retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (val & INT_REG_CMDNK) {
+               ms_set_err_code(chip, MS_CMD_NK);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+       if (val & INT_REG_CED) {
+               if (val & INT_REG_ERR) {
+                       ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+
+static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       u8 val, data[6];
+
+       retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
+                               SystemParm, 6);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (CHK_MS4BIT(ms_card))
+               data[0] = 0x88;
+       else
+               data[0] = 0x80;
+
+       data[1] = 0;
+       data[2] = (u8)(block_addr >> 8);
+       data[3] = (u8)block_addr;
+       data[4] = 0x20;
+       data[5] = page_num;
+
+       retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+       retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (val & INT_REG_CMDNK) {
+               ms_set_err_code(chip, MS_CMD_NK);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (val & INT_REG_CED) {
+               if (val & INT_REG_ERR) {
+                       if (!(val & INT_REG_BREQ)) {
+                               ms_set_err_code(chip,  MS_FLASH_READ_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       retval = ms_read_status_reg(chip);
+                       if (retval != STATUS_SUCCESS)
+                               ms_set_err_code(chip,  MS_FLASH_WRITE_ERROR);
+
+               } else {
+                       if (!(val & INT_REG_BREQ)) {
+                               ms_set_err_code(chip, MS_BREQ_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+       }
+
+       retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA,
+                               0, NO_WAIT_INT);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+
+static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       u8 val, data[8], extra[MS_EXTRA_SIZE];
+
+       retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
+                               SystemParm, 7);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+
+       if (CHK_MS4BIT(ms_card))
+               data[0] = 0x88;
+       else
+               data[0] = 0x80;
+
+       data[1] = 0;
+       data[2] = (u8)(phy_blk >> 8);
+       data[3] = (u8)phy_blk;
+       data[4] = 0x80;
+       data[5] = 0;
+       data[6] = extra[0] & 0x7F;
+       data[7] = 0xFF;
+
+       retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 7);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+       retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (val & INT_REG_CMDNK) {
+               ms_set_err_code(chip, MS_CMD_NK);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (val & INT_REG_CED) {
+               if (val & INT_REG_ERR) {
+                       ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+
+static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i = 0;
+       u8 val, data[6];
+
+       retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
+                               SystemParm, 6);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+
+       if (CHK_MS4BIT(ms_card))
+               data[0] = 0x88;
+       else
+               data[0] = 0x80;
+
+       data[1] = 0;
+       data[2] = (u8)(phy_blk >> 8);
+       data[3] = (u8)phy_blk;
+       data[4] = 0;
+       data[5] = 0;
+
+       retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+ERASE_RTY:
+       retval = ms_send_cmd(chip, BLOCK_ERASE, WAIT_INT);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+       retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (val & INT_REG_CMDNK) {
+               if (i < 3) {
+                       i++;
+                       goto ERASE_RTY;
+               }
+
+               ms_set_err_code(chip, MS_CMD_NK);
+               ms_set_bad_block(chip, phy_blk);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (val & INT_REG_CED) {
+               if (val & INT_REG_ERR) {
+                       ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+
+static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len)
+{
+       if (!extra || (extra_len < MS_EXTRA_SIZE))
+               return;
+
+       memset(extra, 0xFF, MS_EXTRA_SIZE);
+
+       if (type == setPS_NG) {
+               /* set page status as 1:NG,and block status keep 1:OK */
+               extra[0] = 0xB8;
+       } else {
+               /* set page status as 0:Data Error,and block status keep 1:OK */
+               extra[0] = 0x98;
+       }
+
+       extra[2] = (u8)(log_blk >> 8);
+       extra[3] = (u8)log_blk;
+}
+
+static int ms_init_page(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk,
+                       u8 start_page, u8 end_page)
+{
+       int retval;
+       u8 extra[MS_EXTRA_SIZE], i;
+
+       memset(extra, 0xff, MS_EXTRA_SIZE);
+
+       extra[0] = 0xf8;        /* Block, page OK, data erased */
+       extra[1] = 0xff;
+       extra[2] = (u8)(log_blk >> 8);
+       extra[3] = (u8)log_blk;
+
+       for (i = start_page; i < end_page; i++) {
+               if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                       ms_set_err_code(chip, MS_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = ms_write_extra_data(chip, phy_blk, i,
+                                       extra, MS_EXTRA_SIZE);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
+               u16 log_blk, u8 start_page, u8 end_page)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, rty_cnt, uncorrect_flag = 0;
+       u8 extra[MS_EXTRA_SIZE], val, i, j, data[16];
+
+       RTSX_DEBUGP("Copy page from 0x%x to 0x%x, logical block is 0x%x\n",
+               old_blk, new_blk, log_blk);
+       RTSX_DEBUGP("start_page = %d, end_page = %d\n", start_page, end_page);
+
+       retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_read_status_reg(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_READ_REG(chip, PPBUF_BASE2, &val);
+
+       if (val & BUF_FULL) {
+               retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (!(val & INT_REG_CED)) {
+                       ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       for (i = start_page; i < end_page; i++) {
+               if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                       ms_set_err_code(chip, MS_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE);
+
+               retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
+                                       MS_EXTRA_SIZE, SystemParm, 6);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               ms_set_err_code(chip, MS_NO_ERROR);
+
+               if (CHK_MS4BIT(ms_card))
+                       data[0] = 0x88;
+               else
+                       data[0] = 0x80;
+
+               data[1] = 0;
+               data[2] = (u8)(old_blk >> 8);
+               data[3] = (u8)old_blk;
+               data[4] = 0x20;
+               data[5] = i;
+
+               retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT,
+                                       data, 6);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               ms_set_err_code(chip, MS_NO_ERROR);
+               retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (val & INT_REG_CMDNK) {
+                       ms_set_err_code(chip, MS_CMD_NK);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if (val & INT_REG_CED) {
+                       if (val & INT_REG_ERR) {
+                               retval = ms_read_status_reg(chip);
+                               if (retval != STATUS_SUCCESS) {
+                                       uncorrect_flag = 1;
+                                       RTSX_DEBUGP("Uncorrectable error\n");
+                               } else {
+                                       uncorrect_flag = 0;
+                               }
+
+                               retval = ms_transfer_tpc(chip,
+                                                       MS_TM_NORMAL_READ,
+                                                       READ_PAGE_DATA,
+                                                       0, NO_WAIT_INT);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                               if (uncorrect_flag) {
+                                       ms_set_page_status(log_blk, setPS_NG,
+                                                       extra, MS_EXTRA_SIZE);
+                                       if (i == 0)
+                                               extra[0] &= 0xEF;
+
+                                       ms_write_extra_data(chip, old_blk, i,
+                                                       extra, MS_EXTRA_SIZE);
+                                       RTSX_DEBUGP("page %d : extra[0] = 0x%x\n", i, extra[0]);
+                                       MS_SET_BAD_BLOCK_FLG(ms_card);
+
+                                       ms_set_page_status(log_blk, setPS_Error,
+                                                       extra, MS_EXTRA_SIZE);
+                                       ms_write_extra_data(chip, new_blk, i,
+                                                       extra, MS_EXTRA_SIZE);
+                                       continue;
+                               }
+
+                               for (rty_cnt = 0; rty_cnt < MS_MAX_RETRY_COUNT;
+                                    rty_cnt++) {
+                                       retval = ms_transfer_tpc(
+                                               chip,
+                                               MS_TM_NORMAL_WRITE,
+                                               WRITE_PAGE_DATA,
+                                               0, NO_WAIT_INT);
+                                       if (retval == STATUS_SUCCESS)
+                                               break;
+                               }
+                               if (rty_cnt == MS_MAX_RETRY_COUNT)
+                                       TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       if (!(val & INT_REG_BREQ)) {
+                               ms_set_err_code(chip, MS_BREQ_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
+                               MS_EXTRA_SIZE, SystemParm, (6+MS_EXTRA_SIZE));
+
+               ms_set_err_code(chip, MS_NO_ERROR);
+
+               if (CHK_MS4BIT(ms_card))
+                       data[0] = 0x88;
+               else
+                       data[0] = 0x80;
+
+               data[1] = 0;
+               data[2] = (u8)(new_blk >> 8);
+               data[3] = (u8)new_blk;
+               data[4] = 0x20;
+               data[5] = i;
+
+               if ((extra[0] & 0x60) != 0x60)
+                       data[6] = extra[0];
+               else
+                       data[6] = 0xF8;
+
+               data[6 + 1] = 0xFF;
+               data[6 + 2] = (u8)(log_blk >> 8);
+               data[6 + 3] = (u8)log_blk;
+
+               for (j = 4; j <= MS_EXTRA_SIZE; j++)
+                       data[6 + j] = 0xFF;
+
+               retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE),
+                                       NO_WAIT_INT, data, 16);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               ms_set_err_code(chip, MS_NO_ERROR);
+               retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (val & INT_REG_CMDNK) {
+                       ms_set_err_code(chip, MS_CMD_NK);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if (val & INT_REG_CED) {
+                       if (val & INT_REG_ERR) {
+                               ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               if (i == 0) {
+                       retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
+                                               MS_EXTRA_SIZE, SystemParm, 7);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       ms_set_err_code(chip, MS_NO_ERROR);
+
+                       if (CHK_MS4BIT(ms_card))
+                               data[0] = 0x88;
+                       else
+                               data[0] = 0x80;
+
+                       data[1] = 0;
+                       data[2] = (u8)(old_blk >> 8);
+                       data[3] = (u8)old_blk;
+                       data[4] = 0x80;
+                       data[5] = 0;
+                       data[6] = 0xEF;
+                       data[7] = 0xFF;
+
+                       retval = ms_write_bytes(chip, WRITE_REG, 7,
+                                               NO_WAIT_INT, data, 8);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       ms_set_err_code(chip, MS_NO_ERROR);
+                       retval = ms_read_bytes(chip, GET_INT, 1,
+                                       NO_WAIT_INT, &val, 1);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       if (val & INT_REG_CMDNK) {
+                               ms_set_err_code(chip, MS_CMD_NK);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       if (val & INT_REG_CED) {
+                               if (val & INT_REG_ERR) {
+                                       ms_set_err_code(chip,
+                                                       MS_FLASH_WRITE_ERROR);
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+                       }
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+
+static int reset_ms(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       u16 i, reg_addr, block_size;
+       u8 val, extra[MS_EXTRA_SIZE], j, *ptr;
+#ifndef SUPPORT_MAGIC_GATE
+       u16 eblock_cnt;
+#endif
+
+       retval = ms_prepare_reset(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_card->ms_type |= TYPE_MS;
+
+       retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_read_status_reg(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_READ_REG(chip, PPBUF_BASE2, &val);
+       if (val & WRT_PRTCT)
+               chip->card_wp |= MS_CARD;
+       else
+               chip->card_wp &= ~MS_CARD;
+
+       i = 0;
+
+RE_SEARCH:
+       /* Search Boot Block */
+       while (i < (MAX_DEFECTIVE_BLOCK + 2)) {
+               if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                       ms_set_err_code(chip, MS_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = ms_read_extra_data(chip, i, 0, extra, MS_EXTRA_SIZE);
+               if (retval != STATUS_SUCCESS) {
+                       i++;
+                       continue;
+               }
+
+               if (extra[0] & BLOCK_OK) {
+                       if (!(extra[1] & NOT_BOOT_BLOCK)) {
+                               ms_card->boot_block = i;
+                               break;
+                       }
+               }
+               i++;
+       }
+
+       if (i == (MAX_DEFECTIVE_BLOCK + 2)) {
+               RTSX_DEBUGP("No boot block found!");
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       for (j = 0; j < 3; j++) {
+               retval = ms_read_page(chip, ms_card->boot_block, j);
+               if (retval != STATUS_SUCCESS) {
+                       if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) {
+                               i = ms_card->boot_block + 1;
+                               ms_set_err_code(chip, MS_NO_ERROR);
+                               goto RE_SEARCH;
+                       }
+               }
+       }
+
+       retval = ms_read_page(chip, ms_card->boot_block, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       /* Read MS system information as sys_info */
+       rtsx_init_cmd(chip);
+
+       for (i = 0; i < 96; i++)
+               rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 0x1A0 + i, 0, 0);
+
+       retval = rtsx_send_cmd(chip, MS_CARD, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ptr = rtsx_get_cmd_data(chip);
+       memcpy(ms_card->raw_sys_info, ptr, 96);
+
+       /* Read useful block contents */
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0);
+       rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0);
+
+       for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3;
+            reg_addr++)
+               rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
+
+       for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++)
+               rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
+
+       rtsx_add_cmd(chip, READ_REG_CMD, MS_Device_Type, 0, 0);
+       rtsx_add_cmd(chip, READ_REG_CMD, MS_4bit_Support, 0, 0);
+
+       retval = rtsx_send_cmd(chip, MS_CARD, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ptr = rtsx_get_cmd_data(chip);
+
+       RTSX_DEBUGP("Boot block data:\n");
+       RTSX_DUMP(ptr, 16);
+
+       /* Block ID error
+        * HEADER_ID0, HEADER_ID1
+        */
+       if (ptr[0] != 0x00 || ptr[1] != 0x01) {
+               i = ms_card->boot_block + 1;
+               goto RE_SEARCH;
+       }
+
+       /* Page size error
+        * PAGE_SIZE_0, PAGE_SIZE_1
+        */
+       if (ptr[12] != 0x02 || ptr[13] != 0x00) {
+               i = ms_card->boot_block + 1;
+               goto RE_SEARCH;
+       }
+
+       if ((ptr[14] == 1) || (ptr[14] == 3))
+               chip->card_wp |= MS_CARD;
+
+       /* BLOCK_SIZE_0, BLOCK_SIZE_1 */
+       block_size = ((u16)ptr[6] << 8) | ptr[7];
+       if (block_size == 0x0010) {
+               /* Block size 16KB */
+               ms_card->block_shift = 5;
+               ms_card->page_off = 0x1F;
+       } else if (block_size == 0x0008) {
+               /* Block size 8KB */
+               ms_card->block_shift = 4;
+               ms_card->page_off = 0x0F;
+       }
+
+       /* BLOCK_COUNT_0, BLOCK_COUNT_1 */
+       ms_card->total_block = ((u16)ptr[8] << 8) | ptr[9];
+
+#ifdef SUPPORT_MAGIC_GATE
+       j = ptr[10];
+
+       if (ms_card->block_shift == 4)  { /* 4MB or 8MB */
+               if (j < 2)  { /* Effective block for 4MB: 0x1F0 */
+                       ms_card->capacity = 0x1EE0;
+               } else { /* Effective block for 8MB: 0x3E0 */
+                       ms_card->capacity = 0x3DE0;
+               }
+       } else  { /* 16MB, 32MB, 64MB or 128MB */
+               if (j < 5)  { /* Effective block for 16MB: 0x3E0 */
+                       ms_card->capacity = 0x7BC0;
+               } else if (j < 0xA) { /* Effective block for 32MB: 0x7C0 */
+                       ms_card->capacity = 0xF7C0;
+               } else if (j < 0x11) { /* Effective block for 64MB: 0xF80 */
+                       ms_card->capacity = 0x1EF80;
+               } else { /* Effective block for 128MB: 0x1F00 */
+                       ms_card->capacity = 0x3DF00;
+               }
+       }
+#else
+       /* EBLOCK_COUNT_0, EBLOCK_COUNT_1 */
+       eblock_cnt = ((u16)ptr[10] << 8) | ptr[11];
+
+       ms_card->capacity = ((u32)eblock_cnt - 2) << ms_card->block_shift;
+#endif
+
+       chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity;
+
+       /* Switch I/F Mode */
+       if (ptr[15]) {
+               retval = ms_set_rw_reg_addr(chip, 0, 0, SystemParm, 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               RTSX_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88);
+               RTSX_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0);
+
+               retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG , 1,
+                                       NO_WAIT_INT);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               RTSX_WRITE_REG(chip, MS_CFG, 0x58 | MS_NO_CHECK_INT,
+                       MS_BUS_WIDTH_4 | PUSH_TIME_ODD | MS_NO_CHECK_INT);
+
+               ms_card->ms_type |= MS_4BIT;
+       }
+
+       if (CHK_MS4BIT(ms_card))
+               chip->card_bus_width[chip->card2lun[MS_CARD]] = 4;
+       else
+               chip->card_bus_width[chip->card2lun[MS_CARD]] = 1;
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_init_l2p_tbl(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int size, i, seg_no, retval;
+       u16 defect_block, reg_addr;
+       u8 val1, val2;
+
+       ms_card->segment_cnt = ms_card->total_block >> 9;
+       RTSX_DEBUGP("ms_card->segment_cnt = %d\n", ms_card->segment_cnt);
+
+       size = ms_card->segment_cnt * sizeof(struct zone_entry);
+       ms_card->segment = vzalloc(size);
+       if (ms_card->segment == NULL)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_read_page(chip, ms_card->boot_block, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_GOTO(chip, INIT_FAIL);
+
+       reg_addr = PPBUF_BASE2;
+       for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) {
+               retval = rtsx_read_register(chip, reg_addr++, &val1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, INIT_FAIL);
+
+               retval = rtsx_read_register(chip, reg_addr++, &val2);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, INIT_FAIL);
+
+               defect_block = ((u16)val1 << 8) | val2;
+               if (defect_block == 0xFFFF)
+                       break;
+
+               seg_no = defect_block / 512;
+               ms_card->segment[seg_no].defect_list[ms_card->segment[seg_no].disable_count++] = defect_block;
+       }
+
+       for (i = 0; i < ms_card->segment_cnt; i++) {
+               ms_card->segment[i].build_flag = 0;
+               ms_card->segment[i].l2p_table = NULL;
+               ms_card->segment[i].free_table = NULL;
+               ms_card->segment[i].get_index = 0;
+               ms_card->segment[i].set_index = 0;
+               ms_card->segment[i].unused_blk_cnt = 0;
+
+               RTSX_DEBUGP("defective block count of segment %d is %d\n",
+                                       i, ms_card->segment[i].disable_count);
+       }
+
+       return STATUS_SUCCESS;
+
+INIT_FAIL:
+       if (ms_card->segment) {
+               vfree(ms_card->segment);
+               ms_card->segment = NULL;
+       }
+
+       return STATUS_FAIL;
+}
+
+static u16 ms_get_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       struct zone_entry *segment;
+
+       if (ms_card->segment == NULL)
+               return 0xFFFF;
+
+       segment = &(ms_card->segment[seg_no]);
+
+       if (segment->l2p_table)
+               return segment->l2p_table[log_off];
+
+       return 0xFFFF;
+}
+
+static void ms_set_l2p_tbl(struct rtsx_chip *chip,
+                       int seg_no, u16 log_off, u16 phy_blk)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       struct zone_entry *segment;
+
+       if (ms_card->segment == NULL)
+               return;
+
+       segment = &(ms_card->segment[seg_no]);
+       if (segment->l2p_table)
+               segment->l2p_table[log_off] = phy_blk;
+}
+
+static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       struct zone_entry *segment;
+       int seg_no;
+
+       seg_no = (int)phy_blk >> 9;
+       segment = &(ms_card->segment[seg_no]);
+
+       segment->free_table[segment->set_index++] = phy_blk;
+       if (segment->set_index >= MS_FREE_TABLE_CNT)
+               segment->set_index = 0;
+
+       segment->unused_blk_cnt++;
+}
+
+static u16 ms_get_unused_block(struct rtsx_chip *chip, int seg_no)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       struct zone_entry *segment;
+       u16 phy_blk;
+
+       segment = &(ms_card->segment[seg_no]);
+
+       if (segment->unused_blk_cnt <= 0)
+               return 0xFFFF;
+
+       phy_blk = segment->free_table[segment->get_index];
+       segment->free_table[segment->get_index++] = 0xFFFF;
+       if (segment->get_index >= MS_FREE_TABLE_CNT)
+               segment->get_index = 0;
+
+       segment->unused_blk_cnt--;
+
+       return phy_blk;
+}
+
+static const unsigned short ms_start_idx[] = {0, 494, 990, 1486, 1982, 2478,
+                                             2974, 3470, 3966, 4462, 4958,
+                                             5454, 5950, 6446, 6942, 7438,
+                                             7934};
+
+static int ms_arbitrate_l2p(struct rtsx_chip *chip, u16 phy_blk,
+                       u16 log_off, u8 us1, u8 us2)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       struct zone_entry *segment;
+       int seg_no;
+       u16 tmp_blk;
+
+       seg_no = (int)phy_blk >> 9;
+       segment = &(ms_card->segment[seg_no]);
+       tmp_blk = segment->l2p_table[log_off];
+
+       if (us1 != us2) {
+               if (us1 == 0) {
+                       if (!(chip->card_wp & MS_CARD))
+                               ms_erase_block(chip, tmp_blk);
+
+                       ms_set_unused_block(chip, tmp_blk);
+                       segment->l2p_table[log_off] = phy_blk;
+               } else {
+                       if (!(chip->card_wp & MS_CARD))
+                               ms_erase_block(chip, phy_blk);
+
+                       ms_set_unused_block(chip, phy_blk);
+               }
+       } else {
+               if (phy_blk < tmp_blk) {
+                       if (!(chip->card_wp & MS_CARD))
+                               ms_erase_block(chip, phy_blk);
+
+                       ms_set_unused_block(chip, phy_blk);
+               } else {
+                       if (!(chip->card_wp & MS_CARD))
+                               ms_erase_block(chip, tmp_blk);
+
+                       ms_set_unused_block(chip, tmp_blk);
+                       segment->l2p_table[log_off] = phy_blk;
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       struct zone_entry *segment;
+       int retval, table_size, disable_cnt, defect_flag, i;
+       u16 start, end, phy_blk, log_blk, tmp_blk;
+       u8 extra[MS_EXTRA_SIZE], us1, us2;
+
+       RTSX_DEBUGP("ms_build_l2p_tbl: %d\n", seg_no);
+
+       if (ms_card->segment == NULL) {
+               retval = ms_init_l2p_tbl(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, retval);
+       }
+
+       if (ms_card->segment[seg_no].build_flag) {
+               RTSX_DEBUGP("l2p table of segment %d has been built\n", seg_no);
+               return STATUS_SUCCESS;
+       }
+
+       if (seg_no == 0)
+               table_size = 494;
+       else
+               table_size = 496;
+
+       segment = &(ms_card->segment[seg_no]);
+
+       if (segment->l2p_table == NULL) {
+               segment->l2p_table = vmalloc(table_size * 2);
+               if (segment->l2p_table == NULL)
+                       TRACE_GOTO(chip, BUILD_FAIL);
+       }
+       memset((u8 *)(segment->l2p_table), 0xff, table_size * 2);
+
+       if (segment->free_table == NULL) {
+               segment->free_table = vmalloc(MS_FREE_TABLE_CNT * 2);
+               if (segment->free_table == NULL)
+                       TRACE_GOTO(chip, BUILD_FAIL);
+       }
+       memset((u8 *)(segment->free_table), 0xff, MS_FREE_TABLE_CNT * 2);
+
+       start = (u16)seg_no << 9;
+       end = (u16)(seg_no + 1) << 9;
+
+       disable_cnt = segment->disable_count;
+
+       segment->get_index = segment->set_index = 0;
+       segment->unused_blk_cnt = 0;
+
+       for (phy_blk = start; phy_blk < end; phy_blk++) {
+               if (disable_cnt) {
+                       defect_flag = 0;
+                       for (i = 0; i < segment->disable_count; i++) {
+                               if (phy_blk == segment->defect_list[i]) {
+                                       defect_flag = 1;
+                                       break;
+                               }
+                       }
+                       if (defect_flag) {
+                               disable_cnt--;
+                               continue;
+                       }
+               }
+
+               retval = ms_read_extra_data(chip, phy_blk, 0,
+                                       extra, MS_EXTRA_SIZE);
+               if (retval != STATUS_SUCCESS) {
+                       RTSX_DEBUGP("read extra data fail\n");
+                       ms_set_bad_block(chip, phy_blk);
+                       continue;
+               }
+
+               if (seg_no == ms_card->segment_cnt - 1) {
+                       if (!(extra[1] & NOT_TRANSLATION_TABLE)) {
+                               if (!(chip->card_wp & MS_CARD)) {
+                                       retval = ms_erase_block(chip, phy_blk);
+                                       if (retval != STATUS_SUCCESS)
+                                               continue;
+                                       extra[2] = 0xff;
+                                       extra[3] = 0xff;
+                               }
+                       }
+               }
+
+               if (!(extra[0] & BLOCK_OK))
+                       continue;
+               if (!(extra[1] & NOT_BOOT_BLOCK))
+                       continue;
+               if ((extra[0] & PAGE_OK) != PAGE_OK)
+                       continue;
+
+               log_blk = ((u16)extra[2] << 8) | extra[3];
+
+               if (log_blk == 0xFFFF) {
+                       if (!(chip->card_wp & MS_CARD)) {
+                               retval = ms_erase_block(chip, phy_blk);
+                               if (retval != STATUS_SUCCESS)
+                                       continue;
+                       }
+                       ms_set_unused_block(chip, phy_blk);
+                       continue;
+               }
+
+               if ((log_blk < ms_start_idx[seg_no]) ||
+                               (log_blk >= ms_start_idx[seg_no+1])) {
+                       if (!(chip->card_wp & MS_CARD)) {
+                               retval = ms_erase_block(chip, phy_blk);
+                               if (retval != STATUS_SUCCESS)
+                                       continue;
+                       }
+                       ms_set_unused_block(chip, phy_blk);
+                       continue;
+               }
+
+               if (segment->l2p_table[log_blk - ms_start_idx[seg_no]] == 0xFFFF) {
+                       segment->l2p_table[log_blk - ms_start_idx[seg_no]] = phy_blk;
+                       continue;
+               }
+
+               us1 = extra[0] & 0x10;
+               tmp_blk = segment->l2p_table[log_blk - ms_start_idx[seg_no]];
+               retval = ms_read_extra_data(chip, tmp_blk, 0,
+                                       extra, MS_EXTRA_SIZE);
+               if (retval != STATUS_SUCCESS)
+                       continue;
+               us2 = extra[0] & 0x10;
+
+               (void)ms_arbitrate_l2p(chip, phy_blk,
+                               log_blk-ms_start_idx[seg_no], us1, us2);
+               continue;
+       }
+
+       segment->build_flag = 1;
+
+       RTSX_DEBUGP("unused block count: %d\n", segment->unused_blk_cnt);
+
+       /* Logical Address Confirmation Process */
+       if (seg_no == ms_card->segment_cnt - 1) {
+               if (segment->unused_blk_cnt < 2)
+                       chip->card_wp |= MS_CARD;
+       } else {
+               if (segment->unused_blk_cnt < 1)
+                       chip->card_wp |= MS_CARD;
+       }
+
+       if (chip->card_wp & MS_CARD)
+               return STATUS_SUCCESS;
+
+       for (log_blk = ms_start_idx[seg_no];
+            log_blk < ms_start_idx[seg_no + 1]; log_blk++) {
+               if (segment->l2p_table[log_blk-ms_start_idx[seg_no]] == 0xFFFF) {
+                       phy_blk = ms_get_unused_block(chip, seg_no);
+                       if (phy_blk == 0xFFFF) {
+                               chip->card_wp |= MS_CARD;
+                               return STATUS_SUCCESS;
+                       }
+                       retval = ms_init_page(chip, phy_blk, log_blk, 0, 1);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_GOTO(chip, BUILD_FAIL);
+
+                       segment->l2p_table[log_blk-ms_start_idx[seg_no]] = phy_blk;
+                       if (seg_no == ms_card->segment_cnt - 1) {
+                               if (segment->unused_blk_cnt < 2) {
+                                       chip->card_wp |= MS_CARD;
+                                       return STATUS_SUCCESS;
+                               }
+                       } else {
+                               if (segment->unused_blk_cnt < 1) {
+                                       chip->card_wp |= MS_CARD;
+                                       return STATUS_SUCCESS;
+                               }
+                       }
+               }
+       }
+
+       /* Make boot block be the first normal block */
+       if (seg_no == 0) {
+               for (log_blk = 0; log_blk < 494; log_blk++) {
+                       tmp_blk = segment->l2p_table[log_blk];
+                       if (tmp_blk < ms_card->boot_block) {
+                               RTSX_DEBUGP("Boot block is not the first normal block.\n");
+
+                               if (chip->card_wp & MS_CARD)
+                                       break;
+
+                               phy_blk = ms_get_unused_block(chip, 0);
+                               retval = ms_copy_page(chip, tmp_blk, phy_blk,
+                                               log_blk, 0, ms_card->page_off + 1);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                               segment->l2p_table[log_blk] = phy_blk;
+
+                               retval = ms_set_bad_block(chip, tmp_blk);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+       }
+
+       return STATUS_SUCCESS;
+
+BUILD_FAIL:
+       segment->build_flag = 0;
+       if (segment->l2p_table) {
+               vfree(segment->l2p_table);
+               segment->l2p_table = NULL;
+       }
+       if (segment->free_table) {
+               vfree(segment->free_table);
+               segment->free_table = NULL;
+       }
+
+       return STATUS_FAIL;
+}
+
+
+int reset_ms_card(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+
+       memset(ms_card, 0, sizeof(struct ms_info));
+
+       retval = enable_card_clock(chip, MS_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = select_card(chip, MS_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_card->ms_type = 0;
+
+       retval = reset_ms_pro(chip);
+       if (retval != STATUS_SUCCESS) {
+               if (ms_card->check_ms_flow) {
+                       retval = reset_ms(chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+               } else {
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       retval = ms_set_init_para(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (!CHK_MSPRO(ms_card)) {
+               /* Build table for the last segment,
+                * to check if L2P table block exists, erasing it
+                */
+               retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_DEBUGP("ms_card->ms_type = 0x%x\n", ms_card->ms_type);
+
+       return STATUS_SUCCESS;
+}
+
+static int mspro_set_rw_cmd(struct rtsx_chip *chip,
+                       u32 start_sec, u16 sec_cnt, u8 cmd)
+{
+       int retval, i;
+       u8 data[8];
+
+       data[0] = cmd;
+       data[1] = (u8)(sec_cnt >> 8);
+       data[2] = (u8)sec_cnt;
+       data[3] = (u8)(start_sec >> 24);
+       data[4] = (u8)(start_sec >> 16);
+       data[5] = (u8)(start_sec >> 8);
+       data[6] = (u8)start_sec;
+       data[7] = 0;
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7,
+                                       WAIT_INT, data, 8);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+
+void mspro_stop_seq_mode(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       if (ms_card->seq_mode) {
+               retval = ms_switch_clock(chip);
+               if (retval != STATUS_SUCCESS)
+                       return;
+
+               ms_card->seq_mode = 0;
+               ms_card->total_sec_cnt = 0;
+               ms_send_cmd(chip, PRO_STOP, WAIT_INT);
+
+               rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
+       }
+}
+
+static inline int ms_auto_tune_clock(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       if (chip->asic_code) {
+               if (ms_card->ms_clock > 30)
+                       ms_card->ms_clock -= 20;
+       } else {
+               if (ms_card->ms_clock == CLK_80)
+                       ms_card->ms_clock = CLK_60;
+               else if (ms_card->ms_clock == CLK_60)
+                       ms_card->ms_clock = CLK_40;
+       }
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int mspro_rw_multi_sector(struct scsi_cmnd *srb,
+                               struct rtsx_chip *chip, u32 start_sector,
+                               u16 sector_cnt)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, mode_2k = 0;
+       u16 count;
+       u8 val, trans_mode, rw_tpc, rw_cmd;
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+
+       ms_card->cleanup_counter = 0;
+
+       if (CHK_MSHG(ms_card)) {
+               if ((start_sector % 4) || (sector_cnt % 4)) {
+                       if (srb->sc_data_direction == DMA_FROM_DEVICE) {
+                               rw_tpc = PRO_READ_LONG_DATA;
+                               rw_cmd = PRO_READ_DATA;
+                       } else {
+                               rw_tpc = PRO_WRITE_LONG_DATA;
+                               rw_cmd = PRO_WRITE_DATA;
+                       }
+               } else {
+                       if (srb->sc_data_direction == DMA_FROM_DEVICE) {
+                               rw_tpc = PRO_READ_QUAD_DATA;
+                               rw_cmd = PRO_READ_2K_DATA;
+                       } else {
+                               rw_tpc = PRO_WRITE_QUAD_DATA;
+                               rw_cmd = PRO_WRITE_2K_DATA;
+                       }
+                       mode_2k = 1;
+               }
+       } else {
+               if (srb->sc_data_direction == DMA_FROM_DEVICE) {
+                       rw_tpc = PRO_READ_LONG_DATA;
+                       rw_cmd = PRO_READ_DATA;
+               } else {
+                       rw_tpc = PRO_WRITE_LONG_DATA;
+                       rw_cmd = PRO_WRITE_DATA;
+               }
+       }
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (srb->sc_data_direction == DMA_FROM_DEVICE)
+               trans_mode = MS_TM_AUTO_READ;
+       else
+               trans_mode = MS_TM_AUTO_WRITE;
+
+       RTSX_READ_REG(chip, MS_TRANS_CFG, &val);
+
+       if (ms_card->seq_mode) {
+               if ((ms_card->pre_dir != srb->sc_data_direction)
+                               || ((ms_card->pre_sec_addr + ms_card->pre_sec_cnt) != start_sector)
+                               || (mode_2k && (ms_card->seq_mode & MODE_512_SEQ))
+                               || (!mode_2k && (ms_card->seq_mode & MODE_2K_SEQ))
+                               || !(val & MS_INT_BREQ)
+                               || ((ms_card->total_sec_cnt + sector_cnt) > 0xFE00)) {
+                       ms_card->seq_mode = 0;
+                       ms_card->total_sec_cnt = 0;
+                       if (val & MS_INT_BREQ) {
+                               retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                               rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
+                       }
+               }
+       }
+
+       if (!ms_card->seq_mode) {
+               ms_card->total_sec_cnt = 0;
+               if (sector_cnt >= SEQ_START_CRITERIA) {
+                       if ((ms_card->capacity - start_sector) > 0xFE00)
+                               count = 0xFE00;
+                       else
+                               count = (u16)(ms_card->capacity - start_sector);
+
+                       if (count > sector_cnt) {
+                               if (mode_2k)
+                                       ms_card->seq_mode |= MODE_2K_SEQ;
+                               else
+                                       ms_card->seq_mode |= MODE_512_SEQ;
+                       }
+               } else {
+                       count = sector_cnt;
+               }
+               retval = mspro_set_rw_cmd(chip, start_sector, count, rw_cmd);
+               if (retval != STATUS_SUCCESS) {
+                       ms_card->seq_mode = 0;
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       retval = ms_transfer_data(chip, trans_mode, rw_tpc, sector_cnt,
+                               WAIT_INT, mode_2k, scsi_sg_count(srb),
+                               scsi_sglist(srb), scsi_bufflen(srb));
+       if (retval != STATUS_SUCCESS) {
+               ms_card->seq_mode = 0;
+               rtsx_read_register(chip, MS_TRANS_CFG, &val);
+               rtsx_clear_ms_error(chip);
+
+               if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                       chip->rw_need_retry = 0;
+                       RTSX_DEBUGP("No card exist, exit mspro_rw_multi_sector\n");
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if (val & MS_INT_BREQ)
+                       ms_send_cmd(chip, PRO_STOP, WAIT_INT);
+
+               if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) {
+                       RTSX_DEBUGP("MSPro CRC error, tune clock!\n");
+                       chip->rw_need_retry = 1;
+                       ms_auto_tune_clock(chip);
+               }
+
+               TRACE_RET(chip, retval);
+       }
+
+       if (ms_card->seq_mode) {
+               ms_card->pre_sec_addr = start_sector;
+               ms_card->pre_sec_cnt = sector_cnt;
+               ms_card->pre_dir = srb->sc_data_direction;
+               ms_card->total_sec_cnt += sector_cnt;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int mspro_read_format_progress(struct rtsx_chip *chip,
+                               const int short_data_len)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u32 total_progress, cur_progress;
+       u8 cnt, tmp;
+       u8 data[8];
+
+       RTSX_DEBUGP("mspro_read_format_progress, short_data_len = %d\n",
+               short_data_len);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS) {
+               ms_card->format_status = FORMAT_FAIL;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp);
+       if (retval != STATUS_SUCCESS) {
+               ms_card->format_status = FORMAT_FAIL;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (!(tmp & MS_INT_BREQ)) {
+               if ((tmp & (MS_INT_CED | MS_INT_BREQ | MS_INT_CMDNK | MS_INT_ERR)) == MS_INT_CED) {
+                       ms_card->format_status = FORMAT_SUCCESS;
+                       return STATUS_SUCCESS;
+               }
+               ms_card->format_status = FORMAT_FAIL;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (short_data_len >= 256)
+               cnt = 0;
+       else
+               cnt = (u8)short_data_len;
+
+       retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT,
+                               MS_NO_CHECK_INT);
+       if (retval != STATUS_SUCCESS) {
+               ms_card->format_status = FORMAT_FAIL;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, cnt, WAIT_INT,
+                       data, 8);
+       if (retval != STATUS_SUCCESS) {
+               ms_card->format_status = FORMAT_FAIL;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       total_progress = (data[0] << 24) | (data[1] << 16) |
+               (data[2] << 8) | data[3];
+       cur_progress = (data[4] << 24) | (data[5] << 16) |
+               (data[6] << 8) | data[7];
+
+       RTSX_DEBUGP("total_progress = %d, cur_progress = %d\n",
+                               total_progress, cur_progress);
+
+       if (total_progress == 0) {
+               ms_card->progress = 0;
+       } else {
+               u64 ulltmp = (u64)cur_progress * (u64)65535;
+               do_div(ulltmp, total_progress);
+               ms_card->progress = (u16)ulltmp;
+       }
+       RTSX_DEBUGP("progress = %d\n", ms_card->progress);
+
+       for (i = 0; i < 5000; i++) {
+               retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp);
+               if (retval != STATUS_SUCCESS) {
+                       ms_card->format_status = FORMAT_FAIL;
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+               if (tmp & (MS_INT_CED | MS_INT_CMDNK |
+                               MS_INT_BREQ | MS_INT_ERR))
+                       break;
+
+               wait_timeout(1);
+       }
+
+       retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, 0);
+       if (retval != STATUS_SUCCESS) {
+               ms_card->format_status = FORMAT_FAIL;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (i == 5000) {
+               ms_card->format_status = FORMAT_FAIL;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) {
+               ms_card->format_status = FORMAT_FAIL;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (tmp & MS_INT_CED) {
+               ms_card->format_status = FORMAT_SUCCESS;
+               ms_card->pro_under_formatting = 0;
+       } else if (tmp & MS_INT_BREQ) {
+               ms_card->format_status = FORMAT_IN_PROGRESS;
+       } else {
+               ms_card->format_status = FORMAT_FAIL;
+               ms_card->pro_under_formatting = 0;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+void mspro_polling_format_status(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int i;
+
+       if (ms_card->pro_under_formatting &&
+               (rtsx_get_stat(chip) != RTSX_STAT_SS)) {
+               rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+               for (i = 0; i < 65535; i++) {
+                       mspro_read_format_progress(chip, MS_SHORT_DATA_LEN);
+                       if (ms_card->format_status != FORMAT_IN_PROGRESS)
+                               break;
+               }
+       }
+
+       return;
+}
+
+int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+               int short_data_len, int quick_format)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u8 buf[8], tmp;
+       u16 para;
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, Pro_TPCParm, 0x01);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       memset(buf, 0, 2);
+       switch (short_data_len) {
+       case 32:
+               buf[0] = 0;
+               break;
+       case 64:
+               buf[0] = 1;
+               break;
+       case 128:
+               buf[0] = 2;
+               break;
+       case 256:
+       default:
+               buf[0] = 3;
+               break;
+       }
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, PRO_WRITE_REG, 1,
+                                       NO_WAIT_INT, buf, 2);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (quick_format)
+               para = 0x0000;
+       else
+               para = 0x0001;
+
+       retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_READ_REG(chip, MS_TRANS_CFG, &tmp);
+
+       if (tmp & (MS_INT_CMDNK | MS_INT_ERR))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) {
+               ms_card->pro_under_formatting = 1;
+               ms_card->progress = 0;
+               ms_card->format_status = FORMAT_IN_PROGRESS;
+               return STATUS_SUCCESS;
+       }
+
+       if (tmp & MS_INT_CED) {
+               ms_card->pro_under_formatting = 0;
+               ms_card->progress = 0;
+               ms_card->format_status = FORMAT_SUCCESS;
+               set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE);
+               return STATUS_SUCCESS;
+       }
+
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+
+static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk,
+                               u16 log_blk, u8 start_page, u8 end_page,
+                               u8 *buf, unsigned int *index,
+                               unsigned int *offset)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u8 extra[MS_EXTRA_SIZE], page_addr, val, trans_cfg, data[6];
+       u8 *ptr;
+
+       retval = ms_read_extra_data(chip, phy_blk, start_page,
+                               extra, MS_EXTRA_SIZE);
+       if (retval == STATUS_SUCCESS) {
+               if ((extra[1] & 0x30) != 0x30) {
+                       ms_set_err_code(chip, MS_FLASH_READ_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
+                               SystemParm, 6);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (CHK_MS4BIT(ms_card))
+               data[0] = 0x88;
+       else
+               data[0] = 0x80;
+
+       data[1] = 0;
+       data[2] = (u8)(phy_blk >> 8);
+       data[3] = (u8)phy_blk;
+       data[4] = 0;
+       data[5] = start_page;
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT,
+                                       data, 6);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+
+       retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ptr = buf;
+
+       for (page_addr = start_page; page_addr < end_page; page_addr++) {
+               ms_set_err_code(chip, MS_NO_ERROR);
+
+               if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                       ms_set_err_code(chip, MS_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (val & INT_REG_CMDNK) {
+                       ms_set_err_code(chip, MS_CMD_NK);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+               if (val & INT_REG_ERR) {
+                       if (val & INT_REG_BREQ) {
+                               retval = ms_read_status_reg(chip);
+                               if (retval != STATUS_SUCCESS) {
+                                       if (!(chip->card_wp & MS_CARD)) {
+                                               reset_ms(chip);
+                                               ms_set_page_status(log_blk, setPS_NG, extra, MS_EXTRA_SIZE);
+                                               ms_write_extra_data(chip, phy_blk,
+                                                               page_addr, extra, MS_EXTRA_SIZE);
+                                       }
+                                       ms_set_err_code(chip, MS_FLASH_READ_ERROR);
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+                       } else {
+                               ms_set_err_code(chip, MS_FLASH_READ_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               } else {
+                       if (!(val & INT_REG_BREQ)) {
+                               ms_set_err_code(chip, MS_BREQ_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               if (page_addr == (end_page - 1)) {
+                       if (!(val & INT_REG_CED)) {
+                               retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT,
+                                       &val, 1);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       if (!(val & INT_REG_CED)) {
+                               ms_set_err_code(chip, MS_FLASH_READ_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       trans_cfg = NO_WAIT_INT;
+               } else {
+                       trans_cfg = WAIT_INT;
+               }
+
+               rtsx_init_cmd(chip);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG,
+                       0xFF, trans_cfg);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+                       0x01, RING_BUFFER);
+
+               trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
+                               MS_TRANSFER_START |  MS_TM_NORMAL_READ);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER,
+                       MS_TRANSFER_END, MS_TRANSFER_END);
+
+               rtsx_send_cmd_no_wait(chip);
+
+               retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr,
+                                               512, scsi_sg_count(chip->srb),
+                                               index, offset, DMA_FROM_DEVICE,
+                                               chip->ms_timeout);
+               if (retval < 0) {
+                       if (retval == -ETIMEDOUT) {
+                               ms_set_err_code(chip, MS_TO_ERROR);
+                               rtsx_clear_ms_error(chip);
+                               TRACE_RET(chip, STATUS_TIMEDOUT);
+                       }
+
+                       retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
+                       if (retval != STATUS_SUCCESS) {
+                               ms_set_err_code(chip, MS_TO_ERROR);
+                               rtsx_clear_ms_error(chip);
+                               TRACE_RET(chip, STATUS_TIMEDOUT);
+                       }
+                       if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) {
+                               ms_set_err_code(chip, MS_CRC16_ERROR);
+                               rtsx_clear_ms_error(chip);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               if (scsi_sg_count(chip->srb) == 0)
+                       ptr += 512;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk,
+                               u16 new_blk, u16 log_blk, u8 start_page,
+                               u8 end_page, u8 *buf, unsigned int *index,
+                               unsigned int *offset)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, i;
+       u8 page_addr, val, data[16];
+       u8 *ptr;
+
+       if (!start_page) {
+               retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
+                                       SystemParm, 7);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (CHK_MS4BIT(ms_card))
+                       data[0] = 0x88;
+               else
+                       data[0] = 0x80;
+
+               data[1] = 0;
+               data[2] = (u8)(old_blk >> 8);
+               data[3] = (u8)old_blk;
+               data[4] = 0x80;
+               data[5] = 0;
+               data[6] = 0xEF;
+               data[7] = 0xFF;
+
+               retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT,
+                                       data, 8);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               ms_set_err_code(chip, MS_NO_ERROR);
+               retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1,
+                                       NO_WAIT_INT);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
+                               SystemParm, (6 + MS_EXTRA_SIZE));
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+
+       if (CHK_MS4BIT(ms_card))
+               data[0] = 0x88;
+       else
+               data[0] = 0x80;
+
+       data[1] = 0;
+       data[2] = (u8)(new_blk >> 8);
+       data[3] = (u8)new_blk;
+       if ((end_page - start_page) == 1)
+               data[4] = 0x20;
+       else
+               data[4] = 0;
+
+       data[5] = start_page;
+       data[6] = 0xF8;
+       data[7] = 0xFF;
+       data[8] = (u8)(log_blk >> 8);
+       data[9] = (u8)log_blk;
+
+       for (i = 0x0A; i < 0x10; i++)
+               data[i] = 0xFF;
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, WRITE_REG, 6 + MS_EXTRA_SIZE,
+                                       NO_WAIT_INT, data, 16);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ptr = buf;
+       for (page_addr = start_page; page_addr < end_page; page_addr++) {
+               ms_set_err_code(chip, MS_NO_ERROR);
+
+               if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                       ms_set_err_code(chip, MS_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if (val & INT_REG_CMDNK) {
+                       ms_set_err_code(chip, MS_CMD_NK);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+               if (val & INT_REG_ERR) {
+                       ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+               if (!(val & INT_REG_BREQ)) {
+                       ms_set_err_code(chip, MS_BREQ_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               udelay(30);
+
+               rtsx_init_cmd(chip);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC,
+                       0xFF, WRITE_PAGE_DATA);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG,
+                       0xFF, WAIT_INT);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+                       0x01, RING_BUFFER);
+
+               trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
+                               MS_TRANSFER_START |  MS_TM_NORMAL_WRITE);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER,
+                       MS_TRANSFER_END, MS_TRANSFER_END);
+
+               rtsx_send_cmd_no_wait(chip);
+
+               retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr,
+                                               512, scsi_sg_count(chip->srb),
+                                               index, offset, DMA_TO_DEVICE,
+                                               chip->ms_timeout);
+               if (retval < 0) {
+                       ms_set_err_code(chip, MS_TO_ERROR);
+                       rtsx_clear_ms_error(chip);
+
+                       if (retval == -ETIMEDOUT)
+                               TRACE_RET(chip, STATUS_TIMEDOUT);
+                       else
+                               TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if ((end_page - start_page) == 1) {
+                       if (!(val & INT_REG_CED)) {
+                               ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               } else {
+                       if (page_addr == (end_page - 1)) {
+                               if (!(val & INT_REG_CED)) {
+                                       retval = ms_send_cmd(chip, BLOCK_END,
+                                                       WAIT_INT);
+                                       if (retval != STATUS_SUCCESS)
+                                               TRACE_RET(chip, STATUS_FAIL);
+                               }
+
+                               retval = ms_read_bytes(chip, GET_INT, 1,
+                                               NO_WAIT_INT, &val, 1);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       if ((page_addr == (end_page - 1)) ||
+                               (page_addr == ms_card->page_off)) {
+                               if (!(val & INT_REG_CED)) {
+                                       ms_set_err_code(chip,
+                                                       MS_FLASH_WRITE_ERROR);
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+                       }
+               }
+
+               if (scsi_sg_count(chip->srb) == 0)
+                       ptr += 512;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+
+static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
+               u16 log_blk, u8 page_off)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval, seg_no;
+
+       retval = ms_copy_page(chip, old_blk, new_blk, log_blk,
+                       page_off, ms_card->page_off + 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       seg_no = old_blk >> 9;
+
+       if (MS_TST_BAD_BLOCK_FLG(ms_card)) {
+               MS_CLR_BAD_BLOCK_FLG(ms_card);
+               ms_set_bad_block(chip, old_blk);
+       } else {
+               retval = ms_erase_block(chip, old_blk);
+               if (retval == STATUS_SUCCESS)
+                       ms_set_unused_block(chip, old_blk);
+       }
+
+       ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk);
+
+       return STATUS_SUCCESS;
+}
+
+static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
+               u16 log_blk, u8 start_page)
+{
+       int retval;
+
+       if (start_page) {
+               retval = ms_copy_page(chip, old_blk, new_blk, log_blk,
+                               0, start_page);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+#ifdef MS_DELAY_WRITE
+int ms_delay_write(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       struct ms_delay_write_tag *delay_write = &(ms_card->delay_write);
+       int retval;
+
+       if (delay_write->delay_write_flag) {
+               retval = ms_set_init_para(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               delay_write->delay_write_flag = 0;
+               retval = ms_finish_write(chip,
+                                       delay_write->old_phyblock,
+                                       delay_write->new_phyblock,
+                                       delay_write->logblock,
+                                       delay_write->pageoff);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+#endif
+
+static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       if (srb->sc_data_direction == DMA_FROM_DEVICE)
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+       else
+               set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
+}
+
+static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+                       u32 start_sector, u16 sector_cnt)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int retval, seg_no;
+       unsigned int index = 0, offset = 0;
+       u16 old_blk = 0, new_blk = 0, log_blk, total_sec_cnt = sector_cnt;
+       u8 start_page, end_page = 0, page_cnt;
+       u8 *ptr;
+#ifdef MS_DELAY_WRITE
+       struct ms_delay_write_tag *delay_write = &(ms_card->delay_write);
+#endif
+
+       ms_set_err_code(chip, MS_NO_ERROR);
+
+       ms_card->cleanup_counter = 0;
+
+       ptr = (u8 *)scsi_sglist(srb);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS) {
+               ms_rw_fail(srb, chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       log_blk = (u16)(start_sector >> ms_card->block_shift);
+       start_page = (u8)(start_sector & ms_card->page_off);
+
+       for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) {
+               if (log_blk < ms_start_idx[seg_no+1])
+                       break;
+       }
+
+       if (ms_card->segment[seg_no].build_flag == 0) {
+               retval = ms_build_l2p_tbl(chip, seg_no);
+               if (retval != STATUS_SUCCESS) {
+                       chip->card_fail |= MS_CARD;
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       if (srb->sc_data_direction == DMA_TO_DEVICE) {
+#ifdef MS_DELAY_WRITE
+               if (delay_write->delay_write_flag &&
+                               (delay_write->logblock == log_blk) &&
+                               (start_page > delay_write->pageoff)) {
+                       delay_write->delay_write_flag = 0;
+                       retval = ms_copy_page(chip,
+                               delay_write->old_phyblock,
+                               delay_write->new_phyblock, log_blk,
+                               delay_write->pageoff, start_page);
+                       if (retval != STATUS_SUCCESS) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       old_blk = delay_write->old_phyblock;
+                       new_blk = delay_write->new_phyblock;
+               } else if (delay_write->delay_write_flag &&
+                               (delay_write->logblock == log_blk) &&
+                               (start_page == delay_write->pageoff)) {
+                       delay_write->delay_write_flag = 0;
+                       old_blk = delay_write->old_phyblock;
+                       new_blk = delay_write->new_phyblock;
+               } else {
+                       retval = ms_delay_write(chip);
+                       if (retval != STATUS_SUCCESS) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+#endif
+                       old_blk = ms_get_l2p_tbl(chip, seg_no,
+                                               log_blk - ms_start_idx[seg_no]);
+                       new_blk  = ms_get_unused_block(chip, seg_no);
+                       if ((old_blk == 0xFFFF) || (new_blk == 0xFFFF)) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       retval = ms_prepare_write(chip, old_blk, new_blk,
+                                               log_blk, start_page);
+                       if (retval != STATUS_SUCCESS) {
+                               if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                                       set_sense_type(chip, lun,
+                                               SENSE_TYPE_MEDIA_NOT_PRESENT);
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+#ifdef MS_DELAY_WRITE
+               }
+#endif
+       } else {
+#ifdef MS_DELAY_WRITE
+               retval = ms_delay_write(chip);
+               if (retval != STATUS_SUCCESS) {
+                       if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_NOT_PRESENT);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+#endif
+               old_blk = ms_get_l2p_tbl(chip, seg_no,
+                                       log_blk - ms_start_idx[seg_no]);
+               if (old_blk == 0xFFFF) {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n",
+               seg_no, old_blk, new_blk);
+
+       while (total_sec_cnt) {
+               if ((start_page + total_sec_cnt) > (ms_card->page_off + 1))
+                       end_page = ms_card->page_off + 1;
+               else
+                       end_page = start_page + (u8)total_sec_cnt;
+
+               page_cnt = end_page - start_page;
+
+               RTSX_DEBUGP("start_page = %d, end_page = %d, page_cnt = %d\n",
+                               start_page, end_page, page_cnt);
+
+               if (srb->sc_data_direction == DMA_FROM_DEVICE) {
+                       retval = ms_read_multiple_pages(chip,
+                               old_blk, log_blk, start_page, end_page,
+                               ptr, &index, &offset);
+               } else {
+                       retval = ms_write_multiple_pages(chip, old_blk,
+                               new_blk, log_blk, start_page, end_page,
+                               ptr, &index, &offset);
+               }
+
+               if (retval != STATUS_SUCCESS) {
+                       toggle_gpio(chip, 1);
+                       if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_NOT_PRESENT);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       ms_rw_fail(srb, chip);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if (srb->sc_data_direction == DMA_TO_DEVICE) {
+                       if (end_page == (ms_card->page_off + 1)) {
+                               retval = ms_erase_block(chip, old_blk);
+                               if (retval == STATUS_SUCCESS)
+                                       ms_set_unused_block(chip, old_blk);
+
+                               ms_set_l2p_tbl(chip, seg_no,
+                                       log_blk - ms_start_idx[seg_no],
+                                       new_blk);
+                       }
+               }
+
+               total_sec_cnt -= page_cnt;
+               if (scsi_sg_count(srb) == 0)
+                       ptr += page_cnt * 512;
+
+               if (total_sec_cnt == 0)
+                       break;
+
+               log_blk++;
+
+               for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1;
+                               seg_no++) {
+                       if (log_blk < ms_start_idx[seg_no+1])
+                               break;
+               }
+
+               if (ms_card->segment[seg_no].build_flag == 0) {
+                       retval = ms_build_l2p_tbl(chip, seg_no);
+                       if (retval != STATUS_SUCCESS) {
+                               chip->card_fail |= MS_CARD;
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_NOT_PRESENT);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               old_blk = ms_get_l2p_tbl(chip, seg_no,
+                                       log_blk - ms_start_idx[seg_no]);
+               if (old_blk == 0xFFFF) {
+                       ms_rw_fail(srb, chip);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if (srb->sc_data_direction == DMA_TO_DEVICE) {
+                       new_blk = ms_get_unused_block(chip, seg_no);
+                       if (new_blk == 0xFFFF) {
+                               ms_rw_fail(srb, chip);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n",
+                       seg_no, old_blk, new_blk);
+
+               start_page = 0;
+       }
+
+       if (srb->sc_data_direction == DMA_TO_DEVICE) {
+               if (end_page < (ms_card->page_off + 1)) {
+#ifdef MS_DELAY_WRITE
+                       delay_write->delay_write_flag = 1;
+                       delay_write->old_phyblock = old_blk;
+                       delay_write->new_phyblock = new_blk;
+                       delay_write->logblock = log_blk;
+                       delay_write->pageoff = end_page;
+#else
+                       retval = ms_finish_write(chip, old_blk, new_blk,
+                                               log_blk, end_page);
+                       if (retval != STATUS_SUCCESS) {
+                               if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
+                                       set_sense_type(chip, lun,
+                                               SENSE_TYPE_MEDIA_NOT_PRESENT);
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+
+                               ms_rw_fail(srb, chip);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+#endif
+               }
+       }
+
+       scsi_set_resid(srb, 0);
+
+       return STATUS_SUCCESS;
+}
+
+int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+       u32 start_sector, u16 sector_cnt)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+
+       if (CHK_MSPRO(ms_card))
+               retval = mspro_rw_multi_sector(srb, chip, start_sector,
+                                       sector_cnt);
+       else
+               retval = ms_rw_multi_sector(srb, chip, start_sector,
+                                       sector_cnt);
+
+       return retval;
+}
+
+
+void ms_free_l2p_tbl(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int i = 0;
+
+       if (ms_card->segment != NULL) {
+               for (i = 0; i < ms_card->segment_cnt; i++) {
+                       if (ms_card->segment[i].l2p_table != NULL) {
+                               vfree(ms_card->segment[i].l2p_table);
+                               ms_card->segment[i].l2p_table = NULL;
+                       }
+                       if (ms_card->segment[i].free_table != NULL) {
+                               vfree(ms_card->segment[i].free_table);
+                               ms_card->segment[i].free_table = NULL;
+                       }
+               }
+               vfree(ms_card->segment);
+               ms_card->segment = NULL;
+       }
+}
+
+#ifdef SUPPORT_MAGIC_GATE
+
+#ifdef READ_BYTES_WAIT_INT
+static int ms_poll_int(struct rtsx_chip *chip)
+{
+       int retval;
+       u8 val;
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANS_CFG, MS_INT_CED, MS_INT_CED);
+
+       retval = rtsx_send_cmd(chip, MS_CARD, 5000);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       val = *rtsx_get_cmd_data(chip);
+       if (val & MS_INT_ERR)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+#endif
+
+#ifdef MS_SAMPLE_INT_ERR
+static int check_ms_err(struct rtsx_chip *chip)
+{
+       int retval;
+       u8 val;
+
+       retval = rtsx_read_register(chip, MS_TRANSFER, &val);
+       if (retval != STATUS_SUCCESS)
+               return 1;
+       if (val & MS_TRANSFER_ERR)
+               return 1;
+
+       retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
+       if (retval != STATUS_SUCCESS)
+               return 1;
+
+       if (val & (MS_INT_ERR | MS_INT_CMDNK))
+               return 1;
+
+       return 0;
+}
+#else
+static int check_ms_err(struct rtsx_chip *chip)
+{
+       int retval;
+       u8 val;
+
+       retval = rtsx_read_register(chip, MS_TRANSFER, &val);
+       if (retval != STATUS_SUCCESS)
+               return 1;
+       if (val & MS_TRANSFER_ERR)
+               return 1;
+
+       return 0;
+}
+#endif
+
+static int mg_send_ex_cmd(struct rtsx_chip *chip, u8 cmd, u8 entry_num)
+{
+       int retval, i;
+       u8 data[8];
+
+       data[0] = cmd;
+       data[1] = 0;
+       data[2] = 0;
+       data[3] = 0;
+       data[4] = 0;
+       data[5] = 0;
+       data[6] = entry_num;
+       data[7] = 0;
+
+       for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
+               retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT,
+                                       data, 8);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (i == MS_MAX_RETRY_COUNT)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (check_ms_err(chip)) {
+               rtsx_clear_ms_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type,
+                       u8 mg_entry_num)
+{
+       int retval;
+       u8 buf[6];
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       if (type == 0)
+               retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_TPCParm, 1);
+       else
+               retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6);
+
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       buf[0] = 0;
+       buf[1] = 0;
+       if (type == 1) {
+               buf[2] = 0;
+               buf[3] = 0;
+               buf[4] = 0;
+               buf[5] = mg_entry_num;
+       }
+       retval = ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6,
+                               NO_WAIT_INT, buf, 6);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       int i;
+       unsigned int lun = SCSI_LUN(srb);
+       u8 buf1[32], buf2[12];
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       if (scsi_bufflen(srb) < 12) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       ms_cleanup_work(chip);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = mg_send_ex_cmd(chip, MG_SET_LID, 0);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       memset(buf1, 0, 32);
+       rtsx_stor_get_xfer_buf(buf2, min_t(int, 12, scsi_bufflen(srb)), srb);
+       for (i = 0; i < 8; i++)
+               buf1[8+i] = buf2[4+i];
+
+       retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT,
+                               buf1, 32);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+       if (check_ms_err(chip)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
+               rtsx_clear_ms_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval = STATUS_FAIL;
+       int bufflen;
+       unsigned int lun = SCSI_LUN(srb);
+       u8 *buf = NULL;
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       ms_cleanup_work(chip);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       buf = kmalloc(1540, GFP_KERNEL);
+       if (!buf)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       buf[0] = 0x04;
+       buf[1] = 0x1A;
+       buf[2] = 0x00;
+       buf[3] = 0x00;
+
+       retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               TRACE_GOTO(chip, GetEKBFinish);
+       }
+
+       retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
+                               3, WAIT_INT, 0, 0, buf + 4, 1536);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               rtsx_clear_ms_error(chip);
+               TRACE_GOTO(chip, GetEKBFinish);
+       }
+       if (check_ms_err(chip)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               rtsx_clear_ms_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       bufflen = min_t(int, 1052, scsi_bufflen(srb));
+       rtsx_stor_set_xfer_buf(buf, bufflen, srb);
+
+GetEKBFinish:
+       kfree(buf);
+       return retval;
+}
+
+int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       int bufflen;
+       int i;
+       unsigned int lun = SCSI_LUN(srb);
+       u8 buf[32];
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       ms_cleanup_work(chip);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = mg_send_ex_cmd(chip, MG_GET_ID, 0);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT,
+                       buf, 32);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+       if (check_ms_err(chip)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+               rtsx_clear_ms_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       memcpy(ms_card->magic_gate_id, buf, 16);
+
+#ifdef READ_BYTES_WAIT_INT
+       retval = ms_poll_int(chip);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+#endif
+
+       retval = mg_send_ex_cmd(chip, MG_SET_RD, 0);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       bufflen = min_t(int, 12, scsi_bufflen(srb));
+       rtsx_stor_get_xfer_buf(buf, bufflen, srb);
+
+       for (i = 0; i < 8; i++)
+               buf[i] = buf[4+i];
+
+       for (i = 0; i < 24; i++)
+               buf[8+i] = 0;
+
+       retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA,
+                               32, WAIT_INT, buf, 32);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+       if (check_ms_err(chip)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+               rtsx_clear_ms_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       ms_card->mg_auth = 0;
+
+       return STATUS_SUCCESS;
+}
+
+int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       int bufflen;
+       unsigned int lun = SCSI_LUN(srb);
+       u8 buf1[32], buf2[36];
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       ms_cleanup_work(chip);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT,
+                       buf1, 32);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+       if (check_ms_err(chip)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               rtsx_clear_ms_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       buf2[0] = 0x00;
+       buf2[1] = 0x22;
+       buf2[2] = 0x00;
+       buf2[3] = 0x00;
+
+       memcpy(buf2 + 4, ms_card->magic_gate_id, 16);
+       memcpy(buf2 + 20, buf1, 16);
+
+       bufflen = min_t(int, 36, scsi_bufflen(srb));
+       rtsx_stor_set_xfer_buf(buf2, bufflen, srb);
+
+#ifdef READ_BYTES_WAIT_INT
+       retval = ms_poll_int(chip);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+#endif
+
+       return STATUS_SUCCESS;
+}
+
+int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       int i;
+       int bufflen;
+       unsigned int lun = SCSI_LUN(srb);
+       u8 buf[32];
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       ms_cleanup_work(chip);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       bufflen = min_t(int, 12, scsi_bufflen(srb));
+       rtsx_stor_get_xfer_buf(buf, bufflen, srb);
+
+       for (i = 0; i < 8; i++)
+               buf[i] = buf[4+i];
+
+       for (i = 0; i < 24; i++)
+               buf[8+i] = 0;
+
+       retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT,
+                               buf, 32);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+       if (check_ms_err(chip)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+               rtsx_clear_ms_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       ms_card->mg_auth = 1;
+
+       return STATUS_SUCCESS;
+}
+
+int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       int bufflen;
+       unsigned int lun = SCSI_LUN(srb);
+       u8 *buf = NULL;
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       ms_cleanup_work(chip);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       buf = kmalloc(1028, GFP_KERNEL);
+       if (!buf)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       buf[0] = 0x04;
+       buf[1] = 0x02;
+       buf[2] = 0x00;
+       buf[3] = 0x00;
+
+       retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               TRACE_GOTO(chip, GetICVFinish);
+       }
+
+       retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
+                               2, WAIT_INT, 0, 0, buf + 4, 1024);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               rtsx_clear_ms_error(chip);
+               TRACE_GOTO(chip, GetICVFinish);
+       }
+       if (check_ms_err(chip)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               rtsx_clear_ms_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       bufflen = min_t(int, 1028, scsi_bufflen(srb));
+       rtsx_stor_set_xfer_buf(buf, bufflen, srb);
+
+GetICVFinish:
+       kfree(buf);
+       return retval;
+}
+
+int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       int bufflen;
+#ifdef MG_SET_ICV_SLOW
+       int i;
+#endif
+       unsigned int lun = SCSI_LUN(srb);
+       u8 *buf = NULL;
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       ms_cleanup_work(chip);
+
+       retval = ms_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       buf = kmalloc(1028, GFP_KERNEL);
+       if (!buf)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       bufflen = min_t(int, 1028, scsi_bufflen(srb));
+       rtsx_stor_get_xfer_buf(buf, bufflen, srb);
+
+       retval = mg_send_ex_cmd(chip, MG_SET_IBD, ms_card->mg_entry_num);
+       if (retval != STATUS_SUCCESS) {
+               if (ms_card->mg_auth == 0) {
+                       if ((buf[5] & 0xC0) != 0)
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
+                       else
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MG_WRITE_ERR);
+               } else {
+                       set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
+               }
+               TRACE_GOTO(chip, SetICVFinish);
+       }
+
+#ifdef MG_SET_ICV_SLOW
+       for (i = 0; i < 2; i++) {
+               udelay(50);
+
+               rtsx_init_cmd(chip);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC,
+                       0xFF, PRO_WRITE_LONG_DATA);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+                       0x01, RING_BUFFER);
+
+               trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
+                               MS_TRANSFER_START |  MS_TM_NORMAL_WRITE);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER,
+                       MS_TRANSFER_END, MS_TRANSFER_END);
+
+               rtsx_send_cmd_no_wait(chip);
+
+               retval = rtsx_transfer_data(chip, MS_CARD, buf + 4 + i*512,
+                                       512, 0, DMA_TO_DEVICE, 3000);
+               if ((retval < 0) || check_ms_err(chip)) {
+                       rtsx_clear_ms_error(chip);
+                       if (ms_card->mg_auth == 0) {
+                               if ((buf[5] & 0xC0) != 0)
+                                       set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
+                               else
+                                       set_sense_type(chip, lun,
+                                               SENSE_TYPE_MG_WRITE_ERR);
+                       } else {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MG_WRITE_ERR);
+                       }
+                       retval = STATUS_FAIL;
+                       TRACE_GOTO(chip, SetICVFinish);
+               }
+       }
+#else
+       retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA,
+                               2, WAIT_INT, 0, 0, buf + 4, 1024);
+       if ((retval != STATUS_SUCCESS) || check_ms_err(chip)) {
+               rtsx_clear_ms_error(chip);
+               if (ms_card->mg_auth == 0) {
+                       if ((buf[5] & 0xC0) != 0)
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
+                       else
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MG_WRITE_ERR);
+               } else {
+                       set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
+               }
+               TRACE_GOTO(chip, SetICVFinish);
+       }
+#endif
+
+SetICVFinish:
+       kfree(buf);
+       return retval;
+}
+
+#endif /* SUPPORT_MAGIC_GATE */
+
+void ms_cleanup_work(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+
+       if (CHK_MSPRO(ms_card)) {
+               if (ms_card->seq_mode) {
+                       RTSX_DEBUGP("MS Pro: stop transmission\n");
+                       mspro_stop_seq_mode(chip);
+                       ms_card->cleanup_counter = 0;
+               }
+               if (CHK_MSHG(ms_card)) {
+                       rtsx_write_register(chip, MS_CFG,
+                               MS_2K_SECTOR_MODE, 0x00);
+               }
+       }
+#ifdef MS_DELAY_WRITE
+       else if ((!CHK_MSPRO(ms_card)) && ms_card->delay_write.delay_write_flag) {
+               RTSX_DEBUGP("MS: delay write\n");
+               ms_delay_write(chip);
+               ms_card->cleanup_counter = 0;
+       }
+#endif
+}
+
+int ms_power_off_card3v3(struct rtsx_chip *chip)
+{
+       int retval;
+
+       retval = disable_card_clock(chip, MS_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (chip->asic_code) {
+               retval = ms_pull_ctl_disable(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else {
+               RTSX_WRITE_REG(chip, FPGA_PULL_CTL,
+                       FPGA_MS_PULL_CTL_BIT | 0x20, FPGA_MS_PULL_CTL_BIT);
+       }
+       RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, 0);
+       if (!chip->ft2_fast_mode) {
+               retval = card_power_off(chip, MS_CARD);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int release_ms_card(struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+
+       RTSX_DEBUGP("release_ms_card\n");
+
+#ifdef MS_DELAY_WRITE
+       ms_card->delay_write.delay_write_flag = 0;
+#endif
+       ms_card->pro_under_formatting = 0;
+
+       chip->card_ready &= ~MS_CARD;
+       chip->card_fail &= ~MS_CARD;
+       chip->card_wp &= ~MS_CARD;
+
+       ms_free_l2p_tbl(chip);
+
+       memset(ms_card->raw_sys_info, 0, 96);
+#ifdef SUPPORT_PCGL_1P18
+       memset(ms_card->raw_model_name, 0, 48);
+#endif
+
+       retval = ms_power_off_card3v3(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
diff --git a/drivers/staging/rts5208/ms.h b/drivers/staging/rts5208/ms.h
new file mode 100644 (file)
index 0000000..26c5b03
--- /dev/null
@@ -0,0 +1,227 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_MS_H
+#define __REALTEK_RTSX_MS_H
+
+#define MS_DELAY_WRITE
+
+#define        MS_MAX_RETRY_COUNT      3
+
+#define        MS_EXTRA_SIZE           0x9
+
+#define        WRT_PRTCT               0x01
+
+/* Error Code */
+#define        MS_NO_ERROR                             0x00
+#define        MS_CRC16_ERROR                          0x80
+#define        MS_TO_ERROR                             0x40
+#define        MS_NO_CARD                              0x20
+#define        MS_NO_MEMORY                            0x10
+#define        MS_CMD_NK                               0x08
+#define        MS_FLASH_READ_ERROR                     0x04
+#define        MS_FLASH_WRITE_ERROR                    0x02
+#define        MS_BREQ_ERROR                           0x01
+#define        MS_NOT_FOUND                            0x03
+
+/* Transfer Protocol Command */
+#define READ_PAGE_DATA                         0x02
+#define READ_REG                               0x04
+#define        GET_INT                                 0x07
+#define WRITE_PAGE_DATA                                0x0D
+#define WRITE_REG                              0x0B
+#define SET_RW_REG_ADRS                                0x08
+#define SET_CMD                                        0x0E
+
+#define        PRO_READ_LONG_DATA                      0x02
+#define        PRO_READ_SHORT_DATA                     0x03
+#define PRO_READ_REG                           0x04
+#define        PRO_READ_QUAD_DATA                      0x05
+#define PRO_GET_INT                            0x07
+#define        PRO_WRITE_LONG_DATA                     0x0D
+#define        PRO_WRITE_SHORT_DATA                    0x0C
+#define        PRO_WRITE_QUAD_DATA                     0x0A
+#define PRO_WRITE_REG                          0x0B
+#define PRO_SET_RW_REG_ADRS                    0x08
+#define PRO_SET_CMD                            0x0E
+#define PRO_EX_SET_CMD                         0x09
+
+#ifdef SUPPORT_MAGIC_GATE
+
+#define MG_GET_ID              0x40
+#define MG_SET_LID             0x41
+#define MG_GET_LEKB            0x42
+#define MG_SET_RD              0x43
+#define MG_MAKE_RMS            0x44
+#define MG_MAKE_KSE            0x45
+#define MG_SET_IBD             0x46
+#define MG_GET_IBD             0x47
+
+#endif
+
+#ifdef XC_POWERCLASS
+#define XC_CHG_POWER           0x16
+#endif
+
+#define BLOCK_READ     0xAA
+#define        BLOCK_WRITE     0x55
+#define BLOCK_END      0x33
+#define BLOCK_ERASE    0x99
+#define FLASH_STOP     0xCC
+
+#define SLEEP          0x5A
+#define CLEAR_BUF      0xC3
+#define MS_RESET       0x3C
+
+#define PRO_READ_DATA          0x20
+#define        PRO_WRITE_DATA          0x21
+#define PRO_READ_ATRB          0x24
+#define PRO_STOP               0x25
+#define PRO_ERASE              0x26
+#define        PRO_READ_2K_DATA        0x27
+#define        PRO_WRITE_2K_DATA       0x28
+
+#define PRO_FORMAT             0x10
+#define PRO_SLEEP              0x11
+
+#define        IntReg                  0x01
+#define StatusReg0             0x02
+#define StatusReg1             0x03
+
+#define SystemParm             0x10
+#define BlockAdrs              0x11
+#define CMDParm                        0x14
+#define PageAdrs               0x15
+
+#define OverwriteFlag          0x16
+#define ManagemenFlag          0x17
+#define LogicalAdrs            0x18
+#define ReserveArea            0x1A
+
+#define        Pro_IntReg              0x01
+#define Pro_StatusReg          0x02
+#define Pro_TypeReg            0x04
+#define        Pro_IFModeReg           0x05
+#define Pro_CatagoryReg                0x06
+#define Pro_ClassReg           0x07
+
+
+#define Pro_SystemParm         0x10
+#define Pro_DataCount1         0x11
+#define Pro_DataCount0         0x12
+#define Pro_DataAddr3          0x13
+#define Pro_DataAddr2          0x14
+#define Pro_DataAddr1          0x15
+#define Pro_DataAddr0          0x16
+
+#define Pro_TPCParm            0x17
+#define Pro_CMDParm            0x18
+
+#define        INT_REG_CED             0x80
+#define        INT_REG_ERR             0x40
+#define        INT_REG_BREQ            0x20
+#define        INT_REG_CMDNK           0x01
+
+#define        BLOCK_BOOT              0xC0
+#define        BLOCK_OK                0x80
+#define        PAGE_OK                 0x60
+#define        DATA_COMPL              0x10
+
+#define        NOT_BOOT_BLOCK          0x4
+#define        NOT_TRANSLATION_TABLE   0x8
+
+#define        HEADER_ID0              PPBUF_BASE2
+#define        HEADER_ID1              (PPBUF_BASE2 + 1)
+#define        DISABLED_BLOCK0         (PPBUF_BASE2 + 0x170 + 4)
+#define        DISABLED_BLOCK1         (PPBUF_BASE2 + 0x170 + 5)
+#define        DISABLED_BLOCK2         (PPBUF_BASE2 + 0x170 + 6)
+#define        DISABLED_BLOCK3         (PPBUF_BASE2 + 0x170 + 7)
+#define        BLOCK_SIZE_0            (PPBUF_BASE2 + 0x1a0 + 2)
+#define        BLOCK_SIZE_1            (PPBUF_BASE2 + 0x1a0 + 3)
+#define        BLOCK_COUNT_0           (PPBUF_BASE2 + 0x1a0 + 4)
+#define        BLOCK_COUNT_1           (PPBUF_BASE2 + 0x1a0 + 5)
+#define        EBLOCK_COUNT_0          (PPBUF_BASE2 + 0x1a0 + 6)
+#define        EBLOCK_COUNT_1          (PPBUF_BASE2 + 0x1a0 + 7)
+#define        PAGE_SIZE_0             (PPBUF_BASE2 + 0x1a0 + 8)
+#define        PAGE_SIZE_1             (PPBUF_BASE2 + 0x1a0 + 9)
+
+#define MS_Device_Type         (PPBUF_BASE2 + 0x1D8)
+
+#define        MS_4bit_Support         (PPBUF_BASE2 + 0x1D3)
+
+#define setPS_NG       1
+#define setPS_Error    0
+
+#define        PARALLEL_8BIT_IF        0x40
+#define        PARALLEL_4BIT_IF        0x00
+#define        SERIAL_IF               0x80
+
+#define BUF_FULL       0x10
+#define BUF_EMPTY      0x20
+
+#define        MEDIA_BUSY      0x80
+#define        FLASH_BUSY      0x40
+#define        DATA_ERROR      0x20
+#define        STS_UCDT        0x10
+#define        EXTRA_ERROR     0x08
+#define        STS_UCEX        0x04
+#define        FLAG_ERROR      0x02
+#define        STS_UCFG        0x01
+
+#define MS_SHORT_DATA_LEN      32
+
+#define FORMAT_SUCCESS         0
+#define FORMAT_FAIL            1
+#define FORMAT_IN_PROGRESS     2
+
+#define        MS_SET_BAD_BLOCK_FLG(ms_card)   ((ms_card)->multi_flag |= 0x80)
+#define MS_CLR_BAD_BLOCK_FLG(ms_card)  ((ms_card)->multi_flag &= 0x7F)
+#define MS_TST_BAD_BLOCK_FLG(ms_card)  ((ms_card)->multi_flag & 0x80)
+
+void mspro_polling_format_status(struct rtsx_chip *chip);
+
+void mspro_stop_seq_mode(struct rtsx_chip *chip);
+int reset_ms_card(struct rtsx_chip *chip);
+int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+       u32 start_sector, u16 sector_cnt);
+int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+               int short_data_len, int quick_format);
+void ms_free_l2p_tbl(struct rtsx_chip *chip);
+void ms_cleanup_work(struct rtsx_chip *chip);
+int ms_power_off_card3v3(struct rtsx_chip *chip);
+int release_ms_card(struct rtsx_chip *chip);
+#ifdef MS_DELAY_WRITE
+int ms_delay_write(struct rtsx_chip *chip);
+#endif
+
+#ifdef SUPPORT_MAGIC_GATE
+int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+#endif
+
+#endif  /* __REALTEK_RTSX_MS_H */
diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c
new file mode 100644 (file)
index 0000000..7882f57
--- /dev/null
@@ -0,0 +1,1069 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+
+#include "rtsx.h"
+#include "rtsx_chip.h"
+#include "rtsx_transport.h"
+#include "rtsx_scsi.h"
+#include "rtsx_card.h"
+#include "general.h"
+
+#include "ms.h"
+#include "sd.h"
+#include "xd.h"
+
+MODULE_DESCRIPTION("Realtek PCI-Express card reader rts5208/rts5288 driver");
+MODULE_LICENSE("GPL");
+
+static unsigned int delay_use = 1;
+module_param(delay_use, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
+
+static int ss_en;
+module_param(ss_en, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ss_en, "enable selective suspend");
+
+static int ss_interval = 50;
+module_param(ss_interval, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ss_interval, "Interval to enter ss state in seconds");
+
+static int auto_delink_en;
+module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(auto_delink_en, "enable auto delink");
+
+static unsigned char aspm_l0s_l1_en;
+module_param(aspm_l0s_l1_en, byte, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(aspm_l0s_l1_en, "enable device aspm");
+
+static int msi_en;
+module_param(msi_en, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(msi_en, "enable msi");
+
+static irqreturn_t rtsx_interrupt(int irq, void *dev_id);
+
+/***********************************************************************
+ * Host functions
+ ***********************************************************************/
+
+static const char *host_info(struct Scsi_Host *host)
+{
+       return "SCSI emulation for PCI-Express Mass Storage devices";
+}
+
+static int slave_alloc(struct scsi_device *sdev)
+{
+       /*
+        * Set the INQUIRY transfer length to 36.  We don't use any of
+        * the extra data and many devices choke if asked for more or
+        * less than 36 bytes.
+        */
+       sdev->inquiry_len = 36;
+       return 0;
+}
+
+static int slave_configure(struct scsi_device *sdev)
+{
+       /* Scatter-gather buffers (all but the last) must have a length
+        * divisible by the bulk maxpacket size.  Otherwise a data packet
+        * would end up being short, causing a premature end to the data
+        * transfer.  Since high-speed bulk pipes have a maxpacket size
+        * of 512, we'll use that as the scsi device queue's DMA alignment
+        * mask.  Guaranteeing proper alignment of the first buffer will
+        * have the desired effect because, except at the beginning and
+        * the end, scatter-gather buffers follow page boundaries. */
+       blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
+
+       /* Set the SCSI level to at least 2.  We'll leave it at 3 if that's
+        * what is originally reported.  We need this to avoid confusing
+        * the SCSI layer with devices that report 0 or 1, but need 10-byte
+        * commands (ala ATAPI devices behind certain bridges, or devices
+        * which simply have broken INQUIRY data).
+        *
+        * NOTE: This means /dev/sg programs (ala cdrecord) will get the
+        * actual information.  This seems to be the preference for
+        * programs like that.
+        *
+        * NOTE: This also means that /proc/scsi/scsi and sysfs may report
+        * the actual value or the modified one, depending on where the
+        * data comes from.
+        */
+       if (sdev->scsi_level < SCSI_2)
+               sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2;
+
+       return 0;
+}
+
+
+/***********************************************************************
+ * /proc/scsi/ functions
+ ***********************************************************************/
+
+/* we use this macro to help us write into the buffer */
+#undef SPRINTF
+#define SPRINTF(args...) \
+       do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
+
+/* queue a command */
+/* This is always called with scsi_lock(host) held */
+static int queuecommand_lck(struct scsi_cmnd *srb,
+                       void (*done)(struct scsi_cmnd *))
+{
+       struct rtsx_dev *dev = host_to_rtsx(srb->device->host);
+       struct rtsx_chip *chip = dev->chip;
+
+       /* check for state-transition errors */
+       if (chip->srb != NULL) {
+               dev_err(&dev->pci->dev, "Error in %s: chip->srb = %p\n",
+                       __func__, chip->srb);
+               return SCSI_MLQUEUE_HOST_BUSY;
+       }
+
+       /* fail the command if we are disconnecting */
+       if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) {
+               dev_info(&dev->pci->dev, "Fail command during disconnect\n");
+               srb->result = DID_NO_CONNECT << 16;
+               done(srb);
+               return 0;
+       }
+
+       /* enqueue the command and wake up the control thread */
+       srb->scsi_done = done;
+       chip->srb = srb;
+       complete(&dev->cmnd_ready);
+
+       return 0;
+}
+
+static DEF_SCSI_QCMD(queuecommand)
+
+/***********************************************************************
+ * Error handling functions
+ ***********************************************************************/
+
+/* Command timeout and abort */
+static int command_abort(struct scsi_cmnd *srb)
+{
+       struct Scsi_Host *host = srb->device->host;
+       struct rtsx_dev *dev = host_to_rtsx(host);
+       struct rtsx_chip *chip = dev->chip;
+
+       dev_info(&dev->pci->dev, "%s called\n", __func__);
+
+       scsi_lock(host);
+
+       /* Is this command still active? */
+       if (chip->srb != srb) {
+               scsi_unlock(host);
+               dev_info(&dev->pci->dev, "-- nothing to abort\n");
+               return FAILED;
+       }
+
+       rtsx_set_stat(chip, RTSX_STAT_ABORT);
+
+       scsi_unlock(host);
+
+       /* Wait for the aborted command to finish */
+       wait_for_completion(&dev->notify);
+
+       return SUCCESS;
+}
+
+/* This invokes the transport reset mechanism to reset the state of the
+ * device */
+static int device_reset(struct scsi_cmnd *srb)
+{
+       int result = 0;
+       struct rtsx_dev *dev = host_to_rtsx(srb->device->host);
+
+       dev_info(&dev->pci->dev, "%s called\n", __func__);
+
+       return result < 0 ? FAILED : SUCCESS;
+}
+
+/* Simulate a SCSI bus reset by resetting the device's USB port. */
+static int bus_reset(struct scsi_cmnd *srb)
+{
+       int result = 0;
+       struct rtsx_dev *dev = host_to_rtsx(srb->device->host);
+
+       dev_info(&dev->pci->dev, "%s called\n", __func__);
+
+       return result < 0 ? FAILED : SUCCESS;
+}
+
+
+/*
+ * this defines our host template, with which we'll allocate hosts
+ */
+
+static struct scsi_host_template rtsx_host_template = {
+       /* basic userland interface stuff */
+       .name =                         CR_DRIVER_NAME,
+       .proc_name =                    CR_DRIVER_NAME,
+       .info =                         host_info,
+
+       /* command interface -- queued only */
+       .queuecommand =                 queuecommand,
+
+       /* error and abort handlers */
+       .eh_abort_handler =             command_abort,
+       .eh_device_reset_handler =      device_reset,
+       .eh_bus_reset_handler =         bus_reset,
+
+       /* queue commands only, only one command per LUN */
+       .can_queue =                    1,
+       .cmd_per_lun =                  1,
+
+       /* unknown initiator id */
+       .this_id =                      -1,
+
+       .slave_alloc =                  slave_alloc,
+       .slave_configure =              slave_configure,
+
+       /* lots of sg segments can be handled */
+       .sg_tablesize =                 SG_ALL,
+
+       /* limit the total size of a transfer to 120 KB */
+       .max_sectors =                  240,
+
+       /* merge commands... this seems to help performance, but
+        * periodically someone should test to see which setting is more
+        * optimal.
+        */
+       .use_clustering =               1,
+
+       /* emulated HBA */
+       .emulated =                     1,
+
+       /* we do our own delay after a device or bus reset */
+       .skip_settle_delay =            1,
+
+       /* module management */
+       .module =                       THIS_MODULE
+};
+
+
+static int rtsx_acquire_irq(struct rtsx_dev *dev)
+{
+       struct rtsx_chip *chip = dev->chip;
+
+       dev_info(&dev->pci->dev, "%s: chip->msi_en = %d, pci->irq = %d\n",
+                __func__, chip->msi_en, dev->pci->irq);
+
+       if (request_irq(dev->pci->irq, rtsx_interrupt,
+                       chip->msi_en ? 0 : IRQF_SHARED,
+                       CR_DRIVER_NAME, dev)) {
+               dev_err(&dev->pci->dev,
+                       "rtsx: unable to grab IRQ %d, disabling device\n",
+                       dev->pci->irq);
+               return -1;
+       }
+
+       dev->irq = dev->pci->irq;
+       pci_intx(dev->pci, !chip->msi_en);
+
+       return 0;
+}
+
+
+int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val)
+{
+       struct pci_dev *pdev;
+       u8 data;
+       u8 devfn = (dev << 3) | func;
+
+       pdev = pci_get_bus_and_slot(bus, devfn);
+       if (!pdev)
+               return -1;
+
+       pci_read_config_byte(pdev, offset, &data);
+       if (val)
+               *val = data;
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+/*
+ * power management
+ */
+static int rtsx_suspend(struct pci_dev *pci, pm_message_t state)
+{
+       struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
+       struct rtsx_chip *chip;
+
+       if (!dev)
+               return 0;
+
+       /* lock the device pointers */
+       mutex_lock(&(dev->dev_mutex));
+
+       chip = dev->chip;
+
+       rtsx_do_before_power_down(chip, PM_S3);
+
+       if (dev->irq >= 0) {
+               synchronize_irq(dev->irq);
+               free_irq(dev->irq, (void *)dev);
+               dev->irq = -1;
+       }
+
+       if (chip->msi_en)
+               pci_disable_msi(pci);
+
+       pci_save_state(pci);
+       pci_enable_wake(pci, pci_choose_state(pci, state), 1);
+       pci_disable_device(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
+
+       /* unlock the device pointers */
+       mutex_unlock(&dev->dev_mutex);
+
+       return 0;
+}
+
+static int rtsx_resume(struct pci_dev *pci)
+{
+       struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
+       struct rtsx_chip *chip;
+
+       if (!dev)
+               return 0;
+
+       chip = dev->chip;
+
+       /* lock the device pointers */
+       mutex_lock(&(dev->dev_mutex));
+
+       pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               dev_err(&dev->pci->dev,
+                       "%s: pci_enable_device failed, disabling device\n",
+                       CR_DRIVER_NAME);
+               /* unlock the device pointers */
+               mutex_unlock(&dev->dev_mutex);
+               return -EIO;
+       }
+       pci_set_master(pci);
+
+       if (chip->msi_en) {
+               if (pci_enable_msi(pci) < 0)
+                       chip->msi_en = 0;
+       }
+
+       if (rtsx_acquire_irq(dev) < 0) {
+               /* unlock the device pointers */
+               mutex_unlock(&dev->dev_mutex);
+               return -EIO;
+       }
+
+       rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00);
+       rtsx_init_chip(chip);
+
+       /* unlock the device pointers */
+       mutex_unlock(&dev->dev_mutex);
+
+       return 0;
+}
+#endif /* CONFIG_PM */
+
+static void rtsx_shutdown(struct pci_dev *pci)
+{
+       struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
+       struct rtsx_chip *chip;
+
+       if (!dev)
+               return;
+
+       chip = dev->chip;
+
+       rtsx_do_before_power_down(chip, PM_S1);
+
+       if (dev->irq >= 0) {
+               synchronize_irq(dev->irq);
+               free_irq(dev->irq, (void *)dev);
+               dev->irq = -1;
+       }
+
+       if (chip->msi_en)
+               pci_disable_msi(pci);
+
+       pci_disable_device(pci);
+
+       return;
+}
+
+static int rtsx_control_thread(void *__dev)
+{
+       struct rtsx_dev *dev = (struct rtsx_dev *)__dev;
+       struct rtsx_chip *chip = dev->chip;
+       struct Scsi_Host *host = rtsx_to_host(dev);
+
+       for (;;) {
+               if (wait_for_completion_interruptible(&dev->cmnd_ready))
+                       break;
+
+               /* lock the device pointers */
+               mutex_lock(&(dev->dev_mutex));
+
+               /* if the device has disconnected, we are free to exit */
+               if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) {
+                       dev_info(&dev->pci->dev, "-- rtsx-control exiting\n");
+                       mutex_unlock(&dev->dev_mutex);
+                       break;
+               }
+
+               /* lock access to the state */
+               scsi_lock(host);
+
+               /* has the command aborted ? */
+               if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) {
+                       chip->srb->result = DID_ABORT << 16;
+                       goto SkipForAbort;
+               }
+
+               scsi_unlock(host);
+
+               /* reject the command if the direction indicator
+                * is UNKNOWN
+                */
+               if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) {
+                       dev_err(&dev->pci->dev, "UNKNOWN data direction\n");
+                       chip->srb->result = DID_ERROR << 16;
+               }
+
+               /* reject if target != 0 or if LUN is higher than
+                * the maximum known LUN
+                */
+               else if (chip->srb->device->id) {
+                       dev_err(&dev->pci->dev, "Bad target number (%d:%d)\n",
+                               chip->srb->device->id,
+                               chip->srb->device->lun);
+                       chip->srb->result = DID_BAD_TARGET << 16;
+               }
+
+               else if (chip->srb->device->lun > chip->max_lun) {
+                       dev_err(&dev->pci->dev, "Bad LUN (%d:%d)\n",
+                               chip->srb->device->id,
+                               chip->srb->device->lun);
+                       chip->srb->result = DID_BAD_TARGET << 16;
+               }
+
+               /* we've got a command, let's do it! */
+               else {
+                       RTSX_DEBUG(scsi_show_command(chip->srb));
+                       rtsx_invoke_transport(chip->srb, chip);
+               }
+
+               /* lock access to the state */
+               scsi_lock(host);
+
+               /* did the command already complete because of a disconnect? */
+               if (!chip->srb)
+                       ;               /* nothing to do */
+
+               /* indicate that the command is done */
+               else if (chip->srb->result != DID_ABORT << 16) {
+                       chip->srb->scsi_done(chip->srb);
+               } else {
+SkipForAbort:
+                       dev_err(&dev->pci->dev, "scsi command aborted\n");
+               }
+
+               if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) {
+                       complete(&(dev->notify));
+
+                       rtsx_set_stat(chip, RTSX_STAT_IDLE);
+               }
+
+               /* finished working on this command */
+               chip->srb = NULL;
+               scsi_unlock(host);
+
+               /* unlock the device pointers */
+               mutex_unlock(&dev->dev_mutex);
+       } /* for (;;) */
+
+       /* notify the exit routine that we're actually exiting now
+        *
+        * complete()/wait_for_completion() is similar to up()/down(),
+        * except that complete() is safe in the case where the structure
+        * is getting deleted in a parallel mode of execution (i.e. just
+        * after the down() -- that's necessary for the thread-shutdown
+        * case.
+        *
+        * complete_and_exit() goes even further than this -- it is safe in
+        * the case that the thread of the caller is going away (not just
+        * the structure) -- this is necessary for the module-remove case.
+        * This is important in preemption kernels, which transfer the flow
+        * of execution immediately upon a complete().
+        */
+       complete_and_exit(&dev->control_exit, 0);
+}
+
+
+static int rtsx_polling_thread(void *__dev)
+{
+       struct rtsx_dev *dev = (struct rtsx_dev *)__dev;
+       struct rtsx_chip *chip = dev->chip;
+       struct sd_info *sd_card = &(chip->sd_card);
+       struct xd_info *xd_card = &(chip->xd_card);
+       struct ms_info *ms_card = &(chip->ms_card);
+
+       sd_card->cleanup_counter = 0;
+       xd_card->cleanup_counter = 0;
+       ms_card->cleanup_counter = 0;
+
+       /* Wait until SCSI scan finished */
+       wait_timeout((delay_use + 5) * 1000);
+
+       for (;;) {
+
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(POLLING_INTERVAL);
+
+               /* lock the device pointers */
+               mutex_lock(&(dev->dev_mutex));
+
+               /* if the device has disconnected, we are free to exit */
+               if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) {
+                       dev_info(&dev->pci->dev, "-- rtsx-polling exiting\n");
+                       mutex_unlock(&dev->dev_mutex);
+                       break;
+               }
+
+               mutex_unlock(&dev->dev_mutex);
+
+               mspro_polling_format_status(chip);
+
+               /* lock the device pointers */
+               mutex_lock(&(dev->dev_mutex));
+
+               rtsx_polling_func(chip);
+
+               /* unlock the device pointers */
+               mutex_unlock(&dev->dev_mutex);
+       }
+
+       complete_and_exit(&dev->polling_exit, 0);
+}
+
+/*
+ * interrupt handler
+ */
+static irqreturn_t rtsx_interrupt(int irq, void *dev_id)
+{
+       struct rtsx_dev *dev = dev_id;
+       struct rtsx_chip *chip;
+       int retval;
+       u32 status;
+
+       if (dev)
+               chip = dev->chip;
+       else
+               return IRQ_NONE;
+
+       if (!chip)
+               return IRQ_NONE;
+
+       spin_lock(&dev->reg_lock);
+
+       retval = rtsx_pre_handle_interrupt(chip);
+       if (retval == STATUS_FAIL) {
+               spin_unlock(&dev->reg_lock);
+               if (chip->int_reg == 0xFFFFFFFF)
+                       return IRQ_HANDLED;
+               else
+                       return IRQ_NONE;
+       }
+
+       status = chip->int_reg;
+
+       if (dev->check_card_cd) {
+               if (!(dev->check_card_cd & status)) {
+                       /* card not exist, return TRANS_RESULT_FAIL */
+                       dev->trans_result = TRANS_RESULT_FAIL;
+                       if (dev->done)
+                               complete(dev->done);
+                       goto Exit;
+               }
+       }
+
+       if (status & (NEED_COMPLETE_INT | DELINK_INT)) {
+               if (status & (TRANS_FAIL_INT | DELINK_INT)) {
+                       if (status & DELINK_INT)
+                               RTSX_SET_DELINK(chip);
+                       dev->trans_result = TRANS_RESULT_FAIL;
+                       if (dev->done)
+                               complete(dev->done);
+               } else if (status & TRANS_OK_INT) {
+                       dev->trans_result = TRANS_RESULT_OK;
+                       if (dev->done)
+                               complete(dev->done);
+               } else if (status & DATA_DONE_INT) {
+                       dev->trans_result = TRANS_NOT_READY;
+                       if (dev->done && (dev->trans_state == STATE_TRANS_SG))
+                               complete(dev->done);
+               }
+       }
+
+Exit:
+       spin_unlock(&dev->reg_lock);
+       return IRQ_HANDLED;
+}
+
+
+/* Release all our dynamic resources */
+static void rtsx_release_resources(struct rtsx_dev *dev)
+{
+       dev_info(&dev->pci->dev, "-- %s\n", __func__);
+
+       /* Tell the control thread to exit.  The SCSI host must
+        * already have been removed so it won't try to queue
+        * any more commands.
+        */
+       dev_info(&dev->pci->dev, "-- sending exit command to thread\n");
+       complete(&dev->cmnd_ready);
+       if (dev->ctl_thread)
+               wait_for_completion(&dev->control_exit);
+       if (dev->polling_thread)
+               wait_for_completion(&dev->polling_exit);
+
+       wait_timeout(200);
+
+       if (dev->rtsx_resv_buf) {
+               dma_free_coherent(&(dev->pci->dev), RTSX_RESV_BUF_LEN,
+                               dev->rtsx_resv_buf, dev->rtsx_resv_buf_addr);
+               dev->chip->host_cmds_ptr = NULL;
+               dev->chip->host_sg_tbl_ptr = NULL;
+       }
+
+       if (dev->irq > 0)
+               free_irq(dev->irq, (void *)dev);
+       if (dev->chip->msi_en)
+               pci_disable_msi(dev->pci);
+       if (dev->remap_addr)
+               iounmap(dev->remap_addr);
+
+       pci_disable_device(dev->pci);
+       pci_release_regions(dev->pci);
+
+       rtsx_release_chip(dev->chip);
+       kfree(dev->chip);
+}
+
+/* First stage of disconnect processing: stop all commands and remove
+ * the host */
+static void quiesce_and_remove_host(struct rtsx_dev *dev)
+{
+       struct Scsi_Host *host = rtsx_to_host(dev);
+       struct rtsx_chip *chip = dev->chip;
+
+       /* Prevent new transfers, stop the current command, and
+        * interrupt a SCSI-scan or device-reset delay */
+       mutex_lock(&dev->dev_mutex);
+       scsi_lock(host);
+       rtsx_set_stat(chip, RTSX_STAT_DISCONNECT);
+       scsi_unlock(host);
+       mutex_unlock(&dev->dev_mutex);
+       wake_up(&dev->delay_wait);
+       wait_for_completion(&dev->scanning_done);
+
+       /* Wait some time to let other threads exist */
+       wait_timeout(100);
+
+       /* queuecommand won't accept any new commands and the control
+        * thread won't execute a previously-queued command.  If there
+        * is such a command pending, complete it with an error. */
+       mutex_lock(&dev->dev_mutex);
+       if (chip->srb) {
+               chip->srb->result = DID_NO_CONNECT << 16;
+               scsi_lock(host);
+               chip->srb->scsi_done(dev->chip->srb);
+               chip->srb = NULL;
+               scsi_unlock(host);
+       }
+       mutex_unlock(&dev->dev_mutex);
+
+       /* Now we own no commands so it's safe to remove the SCSI host */
+       scsi_remove_host(host);
+}
+
+/* Second stage of disconnect processing: deallocate all resources */
+static void release_everything(struct rtsx_dev *dev)
+{
+       rtsx_release_resources(dev);
+
+       /* Drop our reference to the host; the SCSI core will free it
+        * when the refcount becomes 0. */
+       scsi_host_put(rtsx_to_host(dev));
+}
+
+/* Thread to carry out delayed SCSI-device scanning */
+static int rtsx_scan_thread(void *__dev)
+{
+       struct rtsx_dev *dev = (struct rtsx_dev *)__dev;
+       struct rtsx_chip *chip = dev->chip;
+
+       /* Wait for the timeout to expire or for a disconnect */
+       if (delay_use > 0) {
+               dev_info(&dev->pci->dev,
+                        "%s: waiting for device to settle before scanning\n",
+                        CR_DRIVER_NAME);
+               wait_event_interruptible_timeout(dev->delay_wait,
+                               rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT),
+                               delay_use * HZ);
+       }
+
+       /* If the device is still connected, perform the scanning */
+       if (!rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) {
+               scsi_scan_host(rtsx_to_host(dev));
+               dev_info(&dev->pci->dev, "%s: device scan complete\n",
+                        CR_DRIVER_NAME);
+
+               /* Should we unbind if no devices were detected? */
+       }
+
+       complete_and_exit(&dev->scanning_done, 0);
+}
+
+static void rtsx_init_options(struct rtsx_chip *chip)
+{
+       chip->vendor_id = chip->rtsx->pci->vendor;
+       chip->product_id = chip->rtsx->pci->device;
+       chip->adma_mode = 1;
+       chip->lun_mc = 0;
+       chip->driver_first_load = 1;
+#ifdef HW_AUTO_SWITCH_SD_BUS
+       chip->sdio_in_charge = 0;
+#endif
+
+       chip->mspro_formatter_enable = 1;
+       chip->ignore_sd = 0;
+       chip->use_hw_setting = 0;
+       chip->lun_mode = DEFAULT_SINGLE;
+       chip->auto_delink_en = auto_delink_en;
+       chip->ss_en = ss_en;
+       chip->ss_idle_period = ss_interval * 1000;
+       chip->remote_wakeup_en = 0;
+       chip->aspm_l0s_l1_en = aspm_l0s_l1_en;
+       chip->dynamic_aspm = 1;
+       chip->fpga_sd_sdr104_clk = CLK_200;
+       chip->fpga_sd_ddr50_clk = CLK_100;
+       chip->fpga_sd_sdr50_clk = CLK_100;
+       chip->fpga_sd_hs_clk = CLK_100;
+       chip->fpga_mmc_52m_clk = CLK_80;
+       chip->fpga_ms_hg_clk = CLK_80;
+       chip->fpga_ms_4bit_clk = CLK_80;
+       chip->fpga_ms_1bit_clk = CLK_40;
+       chip->asic_sd_sdr104_clk = 203;
+       chip->asic_sd_sdr50_clk = 98;
+       chip->asic_sd_ddr50_clk = 98;
+       chip->asic_sd_hs_clk = 98;
+       chip->asic_mmc_52m_clk = 98;
+       chip->asic_ms_hg_clk = 117;
+       chip->asic_ms_4bit_clk = 78;
+       chip->asic_ms_1bit_clk = 39;
+       chip->ssc_depth_sd_sdr104 = SSC_DEPTH_2M;
+       chip->ssc_depth_sd_sdr50 = SSC_DEPTH_2M;
+       chip->ssc_depth_sd_ddr50 = SSC_DEPTH_1M;
+       chip->ssc_depth_sd_hs = SSC_DEPTH_1M;
+       chip->ssc_depth_mmc_52m = SSC_DEPTH_1M;
+       chip->ssc_depth_ms_hg = SSC_DEPTH_1M;
+       chip->ssc_depth_ms_4bit = SSC_DEPTH_512K;
+       chip->ssc_depth_low_speed = SSC_DEPTH_512K;
+       chip->ssc_en = 1;
+       chip->sd_speed_prior = 0x01040203;
+       chip->sd_current_prior = 0x00010203;
+       chip->sd_ctl = SD_PUSH_POINT_AUTO |
+                      SD_SAMPLE_POINT_AUTO |
+                      SUPPORT_MMC_DDR_MODE;
+       chip->sd_ddr_tx_phase = 0;
+       chip->mmc_ddr_tx_phase = 1;
+       chip->sd_default_tx_phase = 15;
+       chip->sd_default_rx_phase = 15;
+       chip->pmos_pwr_on_interval = 200;
+       chip->sd_voltage_switch_delay = 1000;
+       chip->ms_power_class_en = 3;
+
+       chip->sd_400mA_ocp_thd = 1;
+       chip->sd_800mA_ocp_thd = 5;
+       chip->ms_ocp_thd = 2;
+
+       chip->card_drive_sel = 0x55;
+       chip->sd30_drive_sel_1v8 = 0x03;
+       chip->sd30_drive_sel_3v3 = 0x01;
+
+       chip->do_delink_before_power_down = 1;
+       chip->auto_power_down = 1;
+       chip->polling_config = 0;
+
+       chip->force_clkreq_0 = 1;
+       chip->ft2_fast_mode = 0;
+
+       chip->sdio_retry_cnt = 1;
+
+       chip->xd_timeout = 2000;
+       chip->sd_timeout = 10000;
+       chip->ms_timeout = 2000;
+       chip->mspro_timeout = 15000;
+
+       chip->power_down_in_ss = 1;
+
+       chip->sdr104_en = 1;
+       chip->sdr50_en = 1;
+       chip->ddr50_en = 1;
+
+       chip->delink_stage1_step = 100;
+       chip->delink_stage2_step = 40;
+       chip->delink_stage3_step = 20;
+
+       chip->auto_delink_in_L1 = 1;
+       chip->blink_led = 1;
+       chip->msi_en = msi_en;
+       chip->hp_watch_bios_hotplug = 0;
+       chip->max_payload = 0;
+       chip->phy_voltage = 0;
+
+       chip->support_ms_8bit = 1;
+       chip->s3_pwr_off_delay = 1000;
+}
+
+static int rtsx_probe(struct pci_dev *pci,
+                               const struct pci_device_id *pci_id)
+{
+       struct Scsi_Host *host;
+       struct rtsx_dev *dev;
+       int err = 0;
+       struct task_struct *th;
+
+       RTSX_DEBUGP("Realtek PCI-E card reader detected\n");
+
+       err = pci_enable_device(pci);
+       if (err < 0) {
+               dev_err(&pci->dev, "PCI enable device failed!\n");
+               return err;
+       }
+
+       err = pci_request_regions(pci, CR_DRIVER_NAME);
+       if (err < 0) {
+               dev_err(&pci->dev, "PCI request regions for %s failed!\n",
+                       CR_DRIVER_NAME);
+               pci_disable_device(pci);
+               return err;
+       }
+
+       /*
+        * Ask the SCSI layer to allocate a host structure, with extra
+        * space at the end for our private rtsx_dev structure.
+        */
+       host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev));
+       if (!host) {
+               dev_err(&pci->dev, "Unable to allocate the scsi host\n");
+               pci_release_regions(pci);
+               pci_disable_device(pci);
+               return -ENOMEM;
+       }
+
+       dev = host_to_rtsx(host);
+       memset(dev, 0, sizeof(struct rtsx_dev));
+
+       dev->chip = kzalloc(sizeof(struct rtsx_chip), GFP_KERNEL);
+       if (dev->chip == NULL)
+               goto errout;
+
+       spin_lock_init(&dev->reg_lock);
+       mutex_init(&(dev->dev_mutex));
+       init_completion(&dev->cmnd_ready);
+       init_completion(&dev->control_exit);
+       init_completion(&dev->polling_exit);
+       init_completion(&(dev->notify));
+       init_completion(&dev->scanning_done);
+       init_waitqueue_head(&dev->delay_wait);
+
+       dev->pci = pci;
+       dev->irq = -1;
+
+       dev_info(&pci->dev, "Resource length: 0x%x\n",
+                (unsigned int)pci_resource_len(pci, 0));
+       dev->addr = pci_resource_start(pci, 0);
+       dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci, 0));
+       if (dev->remap_addr == NULL) {
+               dev_err(&pci->dev, "ioremap error\n");
+               err = -ENXIO;
+               goto errout;
+       }
+
+       /*
+        * Using "unsigned long" cast here to eliminate gcc warning in
+        * 64-bit system
+        */
+       dev_info(&pci->dev, "Original address: 0x%lx, remapped address: 0x%lx\n",
+                (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr));
+
+       dev->rtsx_resv_buf = dma_alloc_coherent(&(pci->dev), RTSX_RESV_BUF_LEN,
+                       &(dev->rtsx_resv_buf_addr), GFP_KERNEL);
+       if (dev->rtsx_resv_buf == NULL) {
+               dev_err(&pci->dev, "alloc dma buffer fail\n");
+               err = -ENXIO;
+               goto errout;
+       }
+       dev->chip->host_cmds_ptr = dev->rtsx_resv_buf;
+       dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr;
+       dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN;
+       dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr +
+                                     HOST_CMDS_BUF_LEN;
+
+       dev->chip->rtsx = dev;
+
+       rtsx_init_options(dev->chip);
+
+       dev_info(&pci->dev, "pci->irq = %d\n", pci->irq);
+
+       if (dev->chip->msi_en) {
+               if (pci_enable_msi(pci) < 0)
+                       dev->chip->msi_en = 0;
+       }
+
+       if (rtsx_acquire_irq(dev) < 0) {
+               err = -EBUSY;
+               goto errout;
+       }
+
+       pci_set_master(pci);
+       synchronize_irq(dev->irq);
+
+       rtsx_init_chip(dev->chip);
+
+       /* set the supported max_lun and max_id for the scsi host
+        * NOTE: the minimal value of max_id is 1 */
+       host->max_id = 1;
+       host->max_lun = dev->chip->max_lun;
+
+       /* Start up our control thread */
+       th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME);
+       if (IS_ERR(th)) {
+               dev_err(&pci->dev, "Unable to start control thread\n");
+               err = PTR_ERR(th);
+               goto errout;
+       }
+       dev->ctl_thread = th;
+
+       err = scsi_add_host(host, &pci->dev);
+       if (err) {
+               dev_err(&pci->dev, "Unable to add the scsi host\n");
+               goto errout;
+       }
+
+       /* Start up the thread for delayed SCSI-device scanning */
+       th = kthread_run(rtsx_scan_thread, dev, "rtsx-scan");
+       if (IS_ERR(th)) {
+               dev_err(&pci->dev, "Unable to start the device-scanning thread\n");
+               complete(&dev->scanning_done);
+               quiesce_and_remove_host(dev);
+               err = PTR_ERR(th);
+               goto errout;
+       }
+
+       /* Start up the thread for polling thread */
+       th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling");
+       if (IS_ERR(th)) {
+               dev_err(&pci->dev, "Unable to start the device-polling thread\n");
+               quiesce_and_remove_host(dev);
+               err = PTR_ERR(th);
+               goto errout;
+       }
+       dev->polling_thread = th;
+
+       pci_set_drvdata(pci, dev);
+
+       return 0;
+
+       /* We come here if there are any problems */
+errout:
+       dev_err(&pci->dev, "rtsx_probe() failed\n");
+       release_everything(dev);
+
+       return err;
+}
+
+
+static void rtsx_remove(struct pci_dev *pci)
+{
+       struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
+
+       dev_info(&pci->dev, "rtsx_remove() called\n");
+
+       quiesce_and_remove_host(dev);
+       release_everything(dev);
+
+       pci_set_drvdata(pci, NULL);
+}
+
+/* PCI IDs */
+static DEFINE_PCI_DEVICE_TABLE(rtsx_ids) = {
+       { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5208), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+       { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5288), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+       { 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, rtsx_ids);
+
+/* pci_driver definition */
+static struct pci_driver driver = {
+       .name = CR_DRIVER_NAME,
+       .id_table = rtsx_ids,
+       .probe = rtsx_probe,
+       .remove = rtsx_remove,
+#ifdef CONFIG_PM
+       .suspend = rtsx_suspend,
+       .resume = rtsx_resume,
+#endif
+       .shutdown = rtsx_shutdown,
+};
+
+static int __init rtsx_init(void)
+{
+       pr_info("Initializing Realtek PCIE storage driver...\n");
+
+       return pci_register_driver(&driver);
+}
+
+static void __exit rtsx_exit(void)
+{
+       pr_info("rtsx_exit() called\n");
+
+       pci_unregister_driver(&driver);
+
+       pr_info("%s module exit\n", CR_DRIVER_NAME);
+}
+
+module_init(rtsx_init)
+module_exit(rtsx_exit)
diff --git a/drivers/staging/rts5208/rtsx.h b/drivers/staging/rts5208/rtsx.h
new file mode 100644 (file)
index 0000000..3f048e0
--- /dev/null
@@ -0,0 +1,186 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_H
+#define __REALTEK_RTSX_H
+
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/mutex.h>
+#include <linux/cdrom.h>
+#include <linux/workqueue.h>
+#include <linux/timer.h>
+#include <linux/time.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_devinfo.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_host.h>
+
+#include "debug.h"
+#include "trace.h"
+#include "general.h"
+
+#define CR_DRIVER_NAME         "rts5208"
+
+#define pci_get_bus_and_slot(bus, devfn)       \
+       pci_get_domain_bus_and_slot(0, (bus), (devfn))
+
+/*
+ * macros for easy use
+ */
+#define rtsx_writel(chip, reg, value) \
+       iowrite32(value, (chip)->rtsx->remap_addr + reg)
+#define rtsx_readl(chip, reg) \
+       ioread32((chip)->rtsx->remap_addr + reg)
+#define rtsx_writew(chip, reg, value) \
+       iowrite16(value, (chip)->rtsx->remap_addr + reg)
+#define rtsx_readw(chip, reg) \
+       ioread16((chip)->rtsx->remap_addr + reg)
+#define rtsx_writeb(chip, reg, value) \
+       iowrite8(value, (chip)->rtsx->remap_addr + reg)
+#define rtsx_readb(chip, reg) \
+       ioread8((chip)->rtsx->remap_addr + reg)
+
+#define rtsx_read_config_byte(chip, where, val) \
+       pci_read_config_byte((chip)->rtsx->pci, where, val)
+
+#define rtsx_write_config_byte(chip, where, val) \
+       pci_write_config_byte((chip)->rtsx->pci, where, val)
+
+#define wait_timeout_x(task_state, msecs)              \
+do {                                                   \
+               set_current_state((task_state));        \
+               schedule_timeout((msecs) * HZ / 1000);  \
+} while (0)
+#define wait_timeout(msecs)    wait_timeout_x(TASK_INTERRUPTIBLE, (msecs))
+
+
+#define STATE_TRANS_NONE       0
+#define STATE_TRANS_CMD                1
+#define STATE_TRANS_BUF                2
+#define STATE_TRANS_SG         3
+
+#define TRANS_NOT_READY                0
+#define TRANS_RESULT_OK                1
+#define TRANS_RESULT_FAIL      2
+
+#define SCSI_LUN(srb)          ((srb)->device->lun)
+
+typedef unsigned long DELAY_PARA_T;
+
+struct rtsx_chip;
+
+struct rtsx_dev {
+       struct pci_dev *pci;
+
+       /* pci resources */
+       unsigned long           addr;
+       void __iomem            *remap_addr;
+       int irq;
+
+       /* locks */
+       spinlock_t              reg_lock;
+
+       struct task_struct      *ctl_thread;     /* the control thread   */
+       struct task_struct      *polling_thread; /* the polling thread   */
+
+       /* mutual exclusion and synchronization structures */
+       struct completion       cmnd_ready;      /* to sleep thread on      */
+       struct completion       control_exit;    /* control thread exit     */
+       struct completion       polling_exit;    /* polling thread exit     */
+       struct completion       notify;          /* thread begin/end        */
+       struct completion       scanning_done;   /* wait for scan thread    */
+
+       wait_queue_head_t       delay_wait;      /* wait during scan, reset */
+       struct mutex            dev_mutex;
+
+       /* host reserved buffer */
+       void                    *rtsx_resv_buf;
+       dma_addr_t              rtsx_resv_buf_addr;
+
+       char                    trans_result;
+       char                    trans_state;
+
+       struct completion       *done;
+       /* Whether interrupt handler should care card cd info */
+       u32                     check_card_cd;
+
+       struct rtsx_chip        *chip;
+};
+
+typedef struct rtsx_dev rtsx_dev_t;
+
+/* Convert between rtsx_dev and the corresponding Scsi_Host */
+static inline struct Scsi_Host *rtsx_to_host(struct rtsx_dev *dev)
+{
+       return container_of((void *) dev, struct Scsi_Host, hostdata);
+}
+static inline struct rtsx_dev *host_to_rtsx(struct Scsi_Host *host)
+{
+       return (struct rtsx_dev *) host->hostdata;
+}
+
+static inline void get_current_time(u8 *timeval_buf, int buf_len)
+{
+       struct timeval tv;
+
+       if (!timeval_buf || (buf_len < 8))
+               return;
+
+       do_gettimeofday(&tv);
+
+       timeval_buf[0] = (u8)(tv.tv_sec >> 24);
+       timeval_buf[1] = (u8)(tv.tv_sec >> 16);
+       timeval_buf[2] = (u8)(tv.tv_sec >> 8);
+       timeval_buf[3] = (u8)(tv.tv_sec);
+       timeval_buf[4] = (u8)(tv.tv_usec >> 24);
+       timeval_buf[5] = (u8)(tv.tv_usec >> 16);
+       timeval_buf[6] = (u8)(tv.tv_usec >> 8);
+       timeval_buf[7] = (u8)(tv.tv_usec);
+}
+
+/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
+ * single queue element srb for write access */
+#define scsi_unlock(host)      spin_unlock_irq(host->host_lock)
+#define scsi_lock(host)                spin_lock_irq(host->host_lock)
+
+#define lock_state(chip)       spin_lock_irq(&((chip)->rtsx->reg_lock))
+#define unlock_state(chip)     spin_unlock_irq(&((chip)->rtsx->reg_lock))
+
+/* struct scsi_cmnd transfer buffer access utilities */
+enum xfer_buf_dir      {TO_XFER_BUF, FROM_XFER_BUF};
+
+int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val);
+
+#endif  /* __REALTEK_RTSX_H */
diff --git a/drivers/staging/rts5208/rtsx_card.c b/drivers/staging/rts5208/rtsx_card.c
new file mode 100644 (file)
index 0000000..3055eb1
--- /dev/null
@@ -0,0 +1,1126 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+#include <linux/kernel.h>
+
+#include "rtsx.h"
+#include "rtsx_transport.h"
+#include "rtsx_scsi.h"
+#include "rtsx_card.h"
+
+#include "rtsx_sys.h"
+#include "general.h"
+
+#include "sd.h"
+#include "xd.h"
+#include "ms.h"
+
+void do_remaining_work(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+#ifdef XD_DELAY_WRITE
+       struct xd_info *xd_card = &(chip->xd_card);
+#endif
+       struct ms_info *ms_card = &(chip->ms_card);
+
+       if (chip->card_ready & SD_CARD) {
+               if (sd_card->seq_mode) {
+                       rtsx_set_stat(chip, RTSX_STAT_RUN);
+                       sd_card->cleanup_counter++;
+               } else {
+                       sd_card->cleanup_counter = 0;
+               }
+       }
+
+#ifdef XD_DELAY_WRITE
+       if (chip->card_ready & XD_CARD) {
+               if (xd_card->delay_write.delay_write_flag) {
+                       rtsx_set_stat(chip, RTSX_STAT_RUN);
+                       xd_card->cleanup_counter++;
+               } else {
+                       xd_card->cleanup_counter = 0;
+               }
+       }
+#endif
+
+       if (chip->card_ready & MS_CARD) {
+               if (CHK_MSPRO(ms_card)) {
+                       if (ms_card->seq_mode) {
+                               rtsx_set_stat(chip, RTSX_STAT_RUN);
+                               ms_card->cleanup_counter++;
+                       } else {
+                               ms_card->cleanup_counter = 0;
+                       }
+               } else {
+#ifdef MS_DELAY_WRITE
+                       if (ms_card->delay_write.delay_write_flag) {
+                               rtsx_set_stat(chip, RTSX_STAT_RUN);
+                               ms_card->cleanup_counter++;
+                       } else {
+                               ms_card->cleanup_counter = 0;
+                       }
+#endif
+               }
+       }
+
+       if (sd_card->cleanup_counter > POLLING_WAIT_CNT)
+               sd_cleanup_work(chip);
+
+       if (xd_card->cleanup_counter > POLLING_WAIT_CNT)
+               xd_cleanup_work(chip);
+
+       if (ms_card->cleanup_counter > POLLING_WAIT_CNT)
+               ms_cleanup_work(chip);
+}
+
+void try_to_switch_sdio_ctrl(struct rtsx_chip *chip)
+{
+       u8 reg1 = 0, reg2 = 0;
+
+       rtsx_read_register(chip, 0xFF34, &reg1);
+       rtsx_read_register(chip, 0xFF38, &reg2);
+       RTSX_DEBUGP("reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", reg1, reg2);
+       if ((reg1 & 0xC0) && (reg2 & 0xC0)) {
+               chip->sd_int = 1;
+               rtsx_write_register(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL);
+               rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON);
+       }
+}
+
+#ifdef SUPPORT_SDIO_ASPM
+void dynamic_configure_sdio_aspm(struct rtsx_chip *chip)
+{
+       u8 buf[12], reg;
+       int i;
+
+       for (i = 0; i < 12; i++)
+               rtsx_read_register(chip, 0xFF08 + i, &buf[i]);
+       rtsx_read_register(chip, 0xFF25, &reg);
+       if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) {
+               chip->sdio_counter = 0;
+               chip->sdio_idle = 0;
+       } else {
+               if (!chip->sdio_idle) {
+                       chip->sdio_counter++;
+                       if (chip->sdio_counter >= SDIO_IDLE_COUNT) {
+                               chip->sdio_counter = 0;
+                               chip->sdio_idle = 1;
+                       }
+               }
+       }
+       memcpy(chip->sdio_raw_data, buf, 12);
+
+       if (chip->sdio_idle) {
+               if (!chip->sdio_aspm) {
+                       RTSX_DEBUGP("SDIO enter ASPM!\n");
+                       rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC,
+                                       0x30 | (chip->aspm_level[1] << 2));
+                       chip->sdio_aspm = 1;
+               }
+       } else {
+               if (chip->sdio_aspm) {
+                       RTSX_DEBUGP("SDIO exit ASPM!\n");
+                       rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30);
+                       chip->sdio_aspm = 0;
+               }
+       }
+}
+#endif
+
+void do_reset_sd_card(struct rtsx_chip *chip)
+{
+       int retval;
+
+       RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
+                    chip->sd_reset_counter, chip->card2lun[SD_CARD]);
+
+       if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) {
+               clear_bit(SD_NR, &(chip->need_reset));
+               chip->sd_reset_counter = 0;
+               chip->sd_show_cnt = 0;
+               return;
+       }
+
+       chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0;
+
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+       rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0);
+
+       retval = reset_sd_card(chip);
+       if (chip->need_release & SD_CARD)
+               return;
+       if (retval == STATUS_SUCCESS) {
+               clear_bit(SD_NR, &(chip->need_reset));
+               chip->sd_reset_counter = 0;
+               chip->sd_show_cnt = 0;
+               chip->card_ready |= SD_CARD;
+               chip->card_fail &= ~SD_CARD;
+               chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw;
+       } else {
+               if (chip->sd_io || (chip->sd_reset_counter >= MAX_RESET_CNT)) {
+                       clear_bit(SD_NR, &(chip->need_reset));
+                       chip->sd_reset_counter = 0;
+                       chip->sd_show_cnt = 0;
+               } else {
+                       chip->sd_reset_counter++;
+               }
+               chip->card_ready &= ~SD_CARD;
+               chip->card_fail |= SD_CARD;
+               chip->capacity[chip->card2lun[SD_CARD]] = 0;
+               chip->rw_card[chip->card2lun[SD_CARD]] = NULL;
+
+               rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0);
+               if (!chip->ft2_fast_mode)
+                       card_power_off(chip, SD_CARD);
+               if (chip->sd_io) {
+                       chip->sd_int = 0;
+                       try_to_switch_sdio_ctrl(chip);
+               } else {
+                       disable_card_clock(chip, SD_CARD);
+               }
+       }
+}
+
+void do_reset_xd_card(struct rtsx_chip *chip)
+{
+       int retval;
+
+       RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
+                    chip->xd_reset_counter, chip->card2lun[XD_CARD]);
+
+       if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) {
+               clear_bit(XD_NR, &(chip->need_reset));
+               chip->xd_reset_counter = 0;
+               chip->xd_show_cnt = 0;
+               return;
+       }
+
+       chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0;
+
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+       rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0);
+
+       retval = reset_xd_card(chip);
+       if (chip->need_release & XD_CARD)
+               return;
+       if (retval == STATUS_SUCCESS) {
+               clear_bit(XD_NR, &(chip->need_reset));
+               chip->xd_reset_counter = 0;
+               chip->card_ready |= XD_CARD;
+               chip->card_fail &= ~XD_CARD;
+               chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw;
+       } else {
+               if (chip->xd_reset_counter >= MAX_RESET_CNT) {
+                       clear_bit(XD_NR, &(chip->need_reset));
+                       chip->xd_reset_counter = 0;
+                       chip->xd_show_cnt = 0;
+               } else {
+                       chip->xd_reset_counter++;
+               }
+               chip->card_ready &= ~XD_CARD;
+               chip->card_fail |= XD_CARD;
+               chip->capacity[chip->card2lun[XD_CARD]] = 0;
+               chip->rw_card[chip->card2lun[XD_CARD]] = NULL;
+
+               rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0);
+               if (!chip->ft2_fast_mode)
+                       card_power_off(chip, XD_CARD);
+               disable_card_clock(chip, XD_CARD);
+       }
+}
+
+void do_reset_ms_card(struct rtsx_chip *chip)
+{
+       int retval;
+
+       RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
+                    chip->ms_reset_counter, chip->card2lun[MS_CARD]);
+
+       if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) {
+               clear_bit(MS_NR, &(chip->need_reset));
+               chip->ms_reset_counter = 0;
+               chip->ms_show_cnt = 0;
+               return;
+       }
+
+       chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0;
+
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+       rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0);
+
+       retval = reset_ms_card(chip);
+       if (chip->need_release & MS_CARD)
+               return;
+       if (retval == STATUS_SUCCESS) {
+               clear_bit(MS_NR, &(chip->need_reset));
+               chip->ms_reset_counter = 0;
+               chip->card_ready |= MS_CARD;
+               chip->card_fail &= ~MS_CARD;
+               chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw;
+       } else {
+               if (chip->ms_reset_counter >= MAX_RESET_CNT) {
+                       clear_bit(MS_NR, &(chip->need_reset));
+                       chip->ms_reset_counter = 0;
+                       chip->ms_show_cnt = 0;
+               } else {
+                       chip->ms_reset_counter++;
+               }
+               chip->card_ready &= ~MS_CARD;
+               chip->card_fail |= MS_CARD;
+               chip->capacity[chip->card2lun[MS_CARD]] = 0;
+               chip->rw_card[chip->card2lun[MS_CARD]] = NULL;
+
+               rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0);
+               if (!chip->ft2_fast_mode)
+                       card_power_off(chip, MS_CARD);
+               disable_card_clock(chip, MS_CARD);
+       }
+}
+
+static void release_sdio(struct rtsx_chip *chip)
+{
+       if (chip->sd_io) {
+               rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR,
+                               SD_STOP | SD_CLR_ERR);
+
+               if (chip->chip_insert_with_sdio) {
+                       chip->chip_insert_with_sdio = 0;
+
+                       if (CHECK_PID(chip, 0x5288))
+                               rtsx_write_register(chip, 0xFE5A, 0x08, 0x00);
+                       else
+                               rtsx_write_register(chip, 0xFE70, 0x80, 0x00);
+               }
+
+               rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0);
+               chip->sd_io = 0;
+       }
+}
+
+void rtsx_power_off_card(struct rtsx_chip *chip)
+{
+       if ((chip->card_ready & SD_CARD) || chip->sd_io) {
+               sd_cleanup_work(chip);
+               sd_power_off_card3v3(chip);
+       }
+
+       if (chip->card_ready & XD_CARD) {
+               xd_cleanup_work(chip);
+               xd_power_off_card3v3(chip);
+       }
+
+       if (chip->card_ready & MS_CARD) {
+               ms_cleanup_work(chip);
+               ms_power_off_card3v3(chip);
+       }
+}
+
+void rtsx_release_cards(struct rtsx_chip *chip)
+{
+       chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
+
+       if ((chip->card_ready & SD_CARD) || chip->sd_io) {
+               if (chip->int_reg & SD_EXIST)
+                       sd_cleanup_work(chip);
+               release_sd_card(chip);
+       }
+
+       if (chip->card_ready & XD_CARD) {
+               if (chip->int_reg & XD_EXIST)
+                       xd_cleanup_work(chip);
+               release_xd_card(chip);
+       }
+
+       if (chip->card_ready & MS_CARD) {
+               if (chip->int_reg & MS_EXIST)
+                       ms_cleanup_work(chip);
+               release_ms_card(chip);
+       }
+}
+
+void rtsx_reset_cards(struct rtsx_chip *chip)
+{
+       if (!chip->need_reset)
+               return;
+
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);
+
+       rtsx_disable_aspm(chip);
+
+       if ((chip->need_reset & SD_CARD) && chip->chip_insert_with_sdio)
+               clear_bit(SD_NR, &(chip->need_reset));
+
+       if (chip->need_reset & XD_CARD) {
+               chip->card_exist |= XD_CARD;
+
+               if (chip->xd_show_cnt >= MAX_SHOW_CNT)
+                       do_reset_xd_card(chip);
+               else
+                       chip->xd_show_cnt++;
+       }
+       if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) {
+               if (chip->card_exist & XD_CARD) {
+                       clear_bit(SD_NR, &(chip->need_reset));
+                       clear_bit(MS_NR, &(chip->need_reset));
+               }
+       }
+       if (chip->need_reset & SD_CARD) {
+               chip->card_exist |= SD_CARD;
+
+               if (chip->sd_show_cnt >= MAX_SHOW_CNT) {
+                       rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
+                       do_reset_sd_card(chip);
+               } else {
+                       chip->sd_show_cnt++;
+               }
+       }
+       if (chip->need_reset & MS_CARD) {
+               chip->card_exist |= MS_CARD;
+
+               if (chip->ms_show_cnt >= MAX_SHOW_CNT)
+                       do_reset_ms_card(chip);
+               else
+                       chip->ms_show_cnt++;
+       }
+}
+
+void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip)
+{
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);
+
+       if (reset_chip)
+               rtsx_reset_chip(chip);
+
+       chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
+
+       if ((chip->int_reg & SD_EXIST) && (chip->need_reinit & SD_CARD)) {
+               release_sdio(chip);
+               release_sd_card(chip);
+
+               wait_timeout(100);
+
+               chip->card_exist |= SD_CARD;
+               do_reset_sd_card(chip);
+       }
+
+       if ((chip->int_reg & XD_EXIST) && (chip->need_reinit & XD_CARD)) {
+               release_xd_card(chip);
+
+               wait_timeout(100);
+
+               chip->card_exist |= XD_CARD;
+               do_reset_xd_card(chip);
+       }
+
+       if ((chip->int_reg & MS_EXIST) && (chip->need_reinit & MS_CARD)) {
+               release_ms_card(chip);
+
+               wait_timeout(100);
+
+               chip->card_exist |= MS_CARD;
+               do_reset_ms_card(chip);
+       }
+
+       chip->need_reinit = 0;
+}
+
+#ifdef DISABLE_CARD_INT
+void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, unsigned long *need_release)
+{
+       u8 release_map = 0, reset_map = 0;
+
+       chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
+
+       if (chip->card_exist) {
+               if (chip->card_exist & XD_CARD) {
+                       if (!(chip->int_reg & XD_EXIST))
+                               release_map |= XD_CARD;
+               } else if (chip->card_exist & SD_CARD) {
+                       if (!(chip->int_reg & SD_EXIST))
+                               release_map |= SD_CARD;
+               } else if (chip->card_exist & MS_CARD) {
+                       if (!(chip->int_reg & MS_EXIST))
+                               release_map |= MS_CARD;
+               }
+       } else {
+               if (chip->int_reg & XD_EXIST)
+                       reset_map |= XD_CARD;
+               else if (chip->int_reg & SD_EXIST)
+                       reset_map |= SD_CARD;
+               else if (chip->int_reg & MS_EXIST)
+                       reset_map |= MS_CARD;
+       }
+
+       if (reset_map) {
+               int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0;
+               int i;
+
+               for (i = 0; i < (DEBOUNCE_CNT); i++) {
+                       chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
+
+                       if (chip->int_reg & XD_EXIST)
+                               xd_cnt++;
+                       else
+                               xd_cnt = 0;
+
+                       if (chip->int_reg & SD_EXIST)
+                               sd_cnt++;
+                       else
+                               sd_cnt = 0;
+
+                       if (chip->int_reg & MS_EXIST)
+                               ms_cnt++;
+                       else
+                               ms_cnt = 0;
+
+                       wait_timeout(30);
+               }
+
+               reset_map = 0;
+               if (!(chip->card_exist & XD_CARD) && (xd_cnt > (DEBOUNCE_CNT-1)))
+                       reset_map |= XD_CARD;
+               if (!(chip->card_exist & SD_CARD) && (sd_cnt > (DEBOUNCE_CNT-1)))
+                       reset_map |= SD_CARD;
+               if (!(chip->card_exist & MS_CARD) && (ms_cnt > (DEBOUNCE_CNT-1)))
+                       reset_map |= MS_CARD;
+       }
+
+       if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN))
+               rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0x00);
+
+       if (need_reset)
+               *need_reset = reset_map;
+       if (need_release)
+               *need_release = release_map;
+}
+#endif
+
+void rtsx_init_cards(struct rtsx_chip *chip)
+{
+       if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) {
+               RTSX_DEBUGP("Reset chip in polling thread!\n");
+               rtsx_reset_chip(chip);
+               RTSX_CLR_DELINK(chip);
+       }
+
+#ifdef DISABLE_CARD_INT
+       card_cd_debounce(chip, &(chip->need_reset), &(chip->need_release));
+#endif
+
+       if (chip->need_release) {
+               if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) {
+                       if (chip->int_reg & XD_EXIST) {
+                               clear_bit(SD_NR, &(chip->need_release));
+                               clear_bit(MS_NR, &(chip->need_release));
+                       }
+               }
+
+               if (!(chip->card_exist & SD_CARD) && !chip->sd_io)
+                       clear_bit(SD_NR, &(chip->need_release));
+               if (!(chip->card_exist & XD_CARD))
+                       clear_bit(XD_NR, &(chip->need_release));
+               if (!(chip->card_exist & MS_CARD))
+                       clear_bit(MS_NR, &(chip->need_release));
+
+               RTSX_DEBUGP("chip->need_release = 0x%x\n", (unsigned int)(chip->need_release));
+
+#ifdef SUPPORT_OCP
+               if (chip->need_release) {
+                       if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER))
+                               rtsx_write_register(chip, OCPCLR,
+                                               CARD_OC_INT_CLR | CARD_OC_CLR,
+                                               CARD_OC_INT_CLR | CARD_OC_CLR);
+                       chip->ocp_stat = 0;
+               }
+#endif
+               if (chip->need_release) {
+                       rtsx_set_stat(chip, RTSX_STAT_RUN);
+                       rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);
+               }
+
+               if (chip->need_release & SD_CARD) {
+                       clear_bit(SD_NR, &(chip->need_release));
+                       chip->card_exist &= ~SD_CARD;
+                       chip->card_ejected &= ~SD_CARD;
+                       chip->card_fail &= ~SD_CARD;
+                       CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]);
+                       chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0;
+                       rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
+
+                       release_sdio(chip);
+                       release_sd_card(chip);
+               }
+
+               if (chip->need_release & XD_CARD) {
+                       clear_bit(XD_NR, &(chip->need_release));
+                       chip->card_exist &= ~XD_CARD;
+                       chip->card_ejected &= ~XD_CARD;
+                       chip->card_fail &= ~XD_CARD;
+                       CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]);
+                       chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0;
+
+                       release_xd_card(chip);
+
+                       if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN))
+                               rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0xC0);
+               }
+
+               if (chip->need_release & MS_CARD) {
+                       clear_bit(MS_NR, &(chip->need_release));
+                       chip->card_exist &= ~MS_CARD;
+                       chip->card_ejected &= ~MS_CARD;
+                       chip->card_fail &= ~MS_CARD;
+                       CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]);
+                       chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0;
+
+                       release_ms_card(chip);
+               }
+
+               RTSX_DEBUGP("chip->card_exist = 0x%x\n", chip->card_exist);
+
+               if (!chip->card_exist)
+                       turn_off_led(chip, LED_GPIO);
+       }
+
+       if (chip->need_reset) {
+               RTSX_DEBUGP("chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset));
+
+               rtsx_reset_cards(chip);
+       }
+
+       if (chip->need_reinit) {
+               RTSX_DEBUGP("chip->need_reinit = 0x%x\n", (unsigned int)(chip->need_reinit));
+
+               rtsx_reinit_cards(chip, 0);
+       }
+}
+
+static inline u8 double_depth(u8 depth)
+{
+       return ((depth > 1) ? (depth - 1) : depth);
+}
+
+int switch_ssc_clock(struct rtsx_chip *chip, int clk)
+{
+       int retval;
+       u8 N = (u8)(clk - 2), min_N, max_N;
+       u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask;
+       int sd_vpclk_phase_reset = 0;
+
+       if (chip->cur_clk == clk)
+               return STATUS_SUCCESS;
+
+       min_N = 60;
+       max_N = 120;
+       max_div = CLK_DIV_4;
+
+       RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n", clk, chip->cur_clk);
+
+       if ((clk <= 2) || (N > max_N))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       mcu_cnt = (u8)(125/clk + 3);
+       if (mcu_cnt > 7)
+               mcu_cnt = 7;
+
+       div = CLK_DIV_1;
+       while ((N < min_N) && (div < max_div)) {
+               N = (N + 2) * 2 - 2;
+               div++;
+       }
+       RTSX_DEBUGP("N = %d, div = %d\n", N, div);
+
+       if (chip->ssc_en) {
+               ssc_depth = 0x01;
+               N -= 2;
+       } else {
+               ssc_depth = 0;
+       }
+
+       ssc_depth_mask = 0x03;
+
+       RTSX_DEBUGP("ssc_depth = %d\n", ssc_depth);
+
+       rtsx_init_cmd(chip);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
+       if (sd_vpclk_phase_reset) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET);
+       }
+
+       retval = rtsx_send_cmd(chip, 0, WAIT_TIME);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       udelay(10);
+       RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0);
+
+       chip->cur_clk = clk;
+
+       return STATUS_SUCCESS;
+}
+
+int switch_normal_clock(struct rtsx_chip *chip, int clk)
+{
+       u8 sel, div, mcu_cnt;
+       int sd_vpclk_phase_reset = 0;
+
+       if (chip->cur_clk == clk)
+               return STATUS_SUCCESS;
+
+       switch (clk) {
+       case CLK_20:
+               RTSX_DEBUGP("Switch clock to 20MHz\n");
+               sel = SSC_80;
+               div = CLK_DIV_4;
+               mcu_cnt = 7;
+               break;
+
+       case CLK_30:
+               RTSX_DEBUGP("Switch clock to 30MHz\n");
+               sel = SSC_120;
+               div = CLK_DIV_4;
+               mcu_cnt = 7;
+               break;
+
+       case CLK_40:
+               RTSX_DEBUGP("Switch clock to 40MHz\n");
+               sel = SSC_80;
+               div = CLK_DIV_2;
+               mcu_cnt = 7;
+               break;
+
+       case CLK_50:
+               RTSX_DEBUGP("Switch clock to 50MHz\n");
+               sel = SSC_100;
+               div = CLK_DIV_2;
+               mcu_cnt = 6;
+               break;
+
+       case CLK_60:
+               RTSX_DEBUGP("Switch clock to 60MHz\n");
+               sel = SSC_120;
+               div = CLK_DIV_2;
+               mcu_cnt = 6;
+               break;
+
+       case CLK_80:
+               RTSX_DEBUGP("Switch clock to 80MHz\n");
+               sel = SSC_80;
+               div = CLK_DIV_1;
+               mcu_cnt = 5;
+               break;
+
+       case CLK_100:
+               RTSX_DEBUGP("Switch clock to 100MHz\n");
+               sel = SSC_100;
+               div = CLK_DIV_1;
+               mcu_cnt = 5;
+               break;
+
+       case CLK_120:
+               RTSX_DEBUGP("Switch clock to 120MHz\n");
+               sel = SSC_120;
+               div = CLK_DIV_1;
+               mcu_cnt = 5;
+               break;
+
+       case CLK_150:
+               RTSX_DEBUGP("Switch clock to 150MHz\n");
+               sel = SSC_150;
+               div = CLK_DIV_1;
+               mcu_cnt = 4;
+               break;
+
+       case CLK_200:
+               RTSX_DEBUGP("Switch clock to 200MHz\n");
+               sel = SSC_200;
+               div = CLK_DIV_1;
+               mcu_cnt = 4;
+               break;
+
+       default:
+               RTSX_DEBUGP("Try to switch to an illegal clock (%d)\n", clk);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ);
+       if (sd_vpclk_phase_reset) {
+               RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
+               RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, 0);
+       }
+       RTSX_WRITE_REG(chip, CLK_DIV, 0xFF, (div << 4) | mcu_cnt);
+       RTSX_WRITE_REG(chip, CLK_SEL, 0xFF, sel);
+
+       if (sd_vpclk_phase_reset) {
+               udelay(200);
+               RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET);
+               RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET);
+               udelay(200);
+       }
+       RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, 0);
+
+       chip->cur_clk = clk;
+
+       return STATUS_SUCCESS;
+}
+
+void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size)
+{
+       if (pack_size > DMA_1024)
+               pack_size = DMA_512;
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, IRQSTAT0, DMA_DONE_INT, DMA_DONE_INT);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(byte_cnt >> 24));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(byte_cnt >> 16));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(byte_cnt >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC0, 0xFF, (u8)byte_cnt);
+
+       if (dir == DMA_FROM_DEVICE) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK,
+                            DMA_DIR_FROM_CARD | DMA_EN | pack_size);
+       } else {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK,
+                            DMA_DIR_TO_CARD | DMA_EN | pack_size);
+       }
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
+}
+
+int enable_card_clock(struct rtsx_chip *chip, u8 card)
+{
+       u8 clk_en = 0;
+
+       if (card & XD_CARD)
+               clk_en |= XD_CLK_EN;
+       if (card & SD_CARD)
+               clk_en |= SD_CLK_EN;
+       if (card & MS_CARD)
+               clk_en |= MS_CLK_EN;
+
+       RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, clk_en);
+
+       return STATUS_SUCCESS;
+}
+
+int disable_card_clock(struct rtsx_chip *chip, u8 card)
+{
+       u8 clk_en = 0;
+
+       if (card & XD_CARD)
+               clk_en |= XD_CLK_EN;
+       if (card & SD_CARD)
+               clk_en |= SD_CLK_EN;
+       if (card & MS_CARD)
+               clk_en |= MS_CLK_EN;
+
+       RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, 0);
+
+       return STATUS_SUCCESS;
+}
+
+int card_power_on(struct rtsx_chip *chip, u8 card)
+{
+       int retval;
+       u8 mask, val1, val2;
+
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) {
+               mask = MS_POWER_MASK;
+               val1 = MS_PARTIAL_POWER_ON;
+               val2 = MS_POWER_ON;
+       } else {
+               mask = SD_POWER_MASK;
+               val1 = SD_PARTIAL_POWER_ON;
+               val2 = SD_POWER_ON;
+       }
+
+       rtsx_init_cmd(chip);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       udelay(chip->pmos_pwr_on_interval);
+
+       rtsx_init_cmd(chip);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+int card_power_off(struct rtsx_chip *chip, u8 card)
+{
+       u8 mask, val;
+
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) {
+               mask = MS_POWER_MASK;
+               val = MS_POWER_OFF;
+       } else {
+               mask = SD_POWER_MASK;
+               val = SD_POWER_OFF;
+       }
+
+       RTSX_WRITE_REG(chip, CARD_PWR_CTL, mask, val);
+
+       return STATUS_SUCCESS;
+}
+
+int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt)
+{
+       int retval;
+       unsigned int lun = SCSI_LUN(srb);
+       int i;
+
+       if (chip->rw_card[lun] == NULL)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       for (i = 0; i < 3; i++) {
+               chip->rw_need_retry = 0;
+
+               retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt);
+               if (retval != STATUS_SUCCESS) {
+                       if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) {
+                               rtsx_release_chip(chip);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if (detect_card_cd(chip, chip->cur_card) != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       if (!chip->rw_need_retry) {
+                               RTSX_DEBUGP("RW fail, but no need to retry\n");
+                               break;
+                       }
+               } else {
+                       chip->rw_need_retry = 0;
+                       break;
+               }
+
+               RTSX_DEBUGP("Retry RW, (i = %d)\n", i);
+       }
+
+       return retval;
+}
+
+int card_share_mode(struct rtsx_chip *chip, int card)
+{
+       u8 mask, value;
+
+       if (CHECK_PID(chip, 0x5208)) {
+               mask = CARD_SHARE_MASK;
+               if (card == SD_CARD)
+                       value = CARD_SHARE_48_SD;
+               else if (card == MS_CARD)
+                       value = CARD_SHARE_48_MS;
+               else if (card == XD_CARD)
+                       value = CARD_SHARE_48_XD;
+               else
+                       TRACE_RET(chip, STATUS_FAIL);
+
+       } else if (CHECK_PID(chip, 0x5288)) {
+               mask = 0x03;
+               if (card == SD_CARD)
+                       value = CARD_SHARE_BAROSSA_SD;
+               else if (card == MS_CARD)
+                       value = CARD_SHARE_BAROSSA_MS;
+               else if (card == XD_CARD)
+                       value = CARD_SHARE_BAROSSA_XD;
+               else
+                       TRACE_RET(chip, STATUS_FAIL);
+
+       } else {
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_WRITE_REG(chip, CARD_SHARE_MODE, mask, value);
+
+       return STATUS_SUCCESS;
+}
+
+
+int select_card(struct rtsx_chip *chip, int card)
+{
+       int retval;
+
+       if (chip->cur_card != card) {
+               u8 mod;
+
+               if (card == SD_CARD)
+                       mod = SD_MOD_SEL;
+               else if (card == MS_CARD)
+                       mod = MS_MOD_SEL;
+               else if (card == XD_CARD)
+                       mod = XD_MOD_SEL;
+               else if (card == SPI_CARD)
+                       mod = SPI_MOD_SEL;
+               else
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               RTSX_WRITE_REG(chip, CARD_SELECT, 0x07, mod);
+               chip->cur_card = card;
+
+               retval =  card_share_mode(chip, card);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+void toggle_gpio(struct rtsx_chip *chip, u8 gpio)
+{
+       u8 temp_reg;
+
+       rtsx_read_register(chip, CARD_GPIO, &temp_reg);
+       temp_reg ^= (0x01 << gpio);
+       rtsx_write_register(chip, CARD_GPIO, 0xFF, temp_reg);
+}
+
+void turn_on_led(struct rtsx_chip *chip, u8 gpio)
+{
+       if (CHECK_PID(chip, 0x5288))
+               rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio));
+       else
+               rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0);
+}
+
+void turn_off_led(struct rtsx_chip *chip, u8 gpio)
+{
+       if (CHECK_PID(chip, 0x5288))
+               rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0);
+       else
+               rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio));
+}
+
+int detect_card_cd(struct rtsx_chip *chip, int card)
+{
+       u32 card_cd, status;
+
+       if (card == SD_CARD) {
+               card_cd = SD_EXIST;
+       } else if (card == MS_CARD) {
+               card_cd = MS_EXIST;
+       } else if (card == XD_CARD) {
+               card_cd = XD_EXIST;
+       } else {
+               RTSX_DEBUGP("Wrong card type: 0x%x\n", card);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       status = rtsx_readl(chip, RTSX_BIPR);
+       if (!(status & card_cd))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+int check_card_exist(struct rtsx_chip *chip, unsigned int lun)
+{
+       if (chip->card_exist & chip->lun2card[lun])
+               return 1;
+
+       return 0;
+}
+
+int check_card_ready(struct rtsx_chip *chip, unsigned int lun)
+{
+       if (chip->card_ready & chip->lun2card[lun])
+               return 1;
+
+       return 0;
+}
+
+int check_card_wp(struct rtsx_chip *chip, unsigned int lun)
+{
+       if (chip->card_wp & chip->lun2card[lun])
+               return 1;
+
+       return 0;
+}
+
+int check_card_fail(struct rtsx_chip *chip, unsigned int lun)
+{
+       if (chip->card_fail & chip->lun2card[lun])
+               return 1;
+
+       return 0;
+}
+
+int check_card_ejected(struct rtsx_chip *chip, unsigned int lun)
+{
+       if (chip->card_ejected & chip->lun2card[lun])
+               return 1;
+
+       return 0;
+}
+
+u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun)
+{
+       if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD)
+               return (u8)XD_CARD;
+       else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD)
+               return (u8)SD_CARD;
+       else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD)
+               return (u8)MS_CARD;
+
+       return 0;
+}
+
+void eject_card(struct rtsx_chip *chip, unsigned int lun)
+{
+       do_remaining_work(chip);
+
+       if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) {
+               release_sd_card(chip);
+               chip->card_ejected |= SD_CARD;
+               chip->card_ready &= ~SD_CARD;
+               chip->capacity[lun] = 0;
+       } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) {
+               release_xd_card(chip);
+               chip->card_ejected |= XD_CARD;
+               chip->card_ready &= ~XD_CARD;
+               chip->capacity[lun] = 0;
+       } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) {
+               release_ms_card(chip);
+               chip->card_ejected |= MS_CARD;
+               chip->card_ready &= ~MS_CARD;
+               chip->capacity[lun] = 0;
+       }
+}
diff --git a/drivers/staging/rts5208/rtsx_card.h b/drivers/staging/rts5208/rtsx_card.h
new file mode 100644 (file)
index 0000000..4528b61
--- /dev/null
@@ -0,0 +1,1098 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_CARD_H
+#define __REALTEK_RTSX_CARD_H
+
+#include "debug.h"
+#include "rtsx.h"
+#include "rtsx_chip.h"
+#include "rtsx_transport.h"
+#include "sd.h"
+
+#define SSC_POWER_DOWN         0x01
+#define SD_OC_POWER_DOWN       0x02
+#define MS_OC_POWER_DOWN       0x04
+#define ALL_POWER_DOWN         0x07
+#define OC_POWER_DOWN          0x06
+
+#define PMOS_STRG_MASK         0x10
+#define PMOS_STRG_800mA                0x10
+#define PMOS_STRG_400mA                0x00
+
+#define POWER_OFF              0x03
+#define PARTIAL_POWER_ON       0x01
+#define POWER_ON               0x00
+
+#define MS_POWER_OFF           0x0C
+#define MS_PARTIAL_POWER_ON    0x04
+#define MS_POWER_ON            0x00
+#define MS_POWER_MASK          0x0C
+
+#define SD_POWER_OFF           0x03
+#define SD_PARTIAL_POWER_ON    0x01
+#define SD_POWER_ON            0x00
+#define SD_POWER_MASK          0x03
+
+#define XD_OUTPUT_EN           0x02
+#define SD_OUTPUT_EN           0x04
+#define MS_OUTPUT_EN           0x08
+#define SPI_OUTPUT_EN          0x10
+
+#define CLK_LOW_FREQ           0x01
+
+#define CLK_DIV_1              0x01
+#define CLK_DIV_2              0x02
+#define CLK_DIV_4              0x03
+#define CLK_DIV_8              0x04
+
+#define SSC_80                 0
+#define SSC_100                        1
+#define SSC_120                        2
+#define SSC_150                        3
+#define SSC_200                        4
+
+#define XD_CLK_EN              0x02
+#define SD_CLK_EN              0x04
+#define MS_CLK_EN              0x08
+#define SPI_CLK_EN             0x10
+
+#define XD_MOD_SEL             1
+#define SD_MOD_SEL             2
+#define MS_MOD_SEL             3
+#define SPI_MOD_SEL            4
+
+#define CHANGE_CLK             0x01
+
+#define        SD_CRC7_ERR                     0x80
+#define        SD_CRC16_ERR                    0x40
+#define        SD_CRC_WRITE_ERR                0x20
+#define        SD_CRC_WRITE_ERR_MASK           0x1C
+#define        GET_CRC_TIME_OUT                0x02
+#define        SD_TUNING_COMPARE_ERR           0x01
+
+#define        SD_RSP_80CLK_TIMEOUT            0x01
+
+#define        SD_CLK_TOGGLE_EN                0x80
+#define        SD_CLK_FORCE_STOP               0x40
+#define        SD_DAT3_STATUS                  0x10
+#define        SD_DAT2_STATUS                  0x08
+#define        SD_DAT1_STATUS                  0x04
+#define        SD_DAT0_STATUS                  0x02
+#define        SD_CMD_STATUS                   0x01
+
+#define        SD_IO_USING_1V8                 0x80
+#define        SD_IO_USING_3V3                 0x7F
+#define        TYPE_A_DRIVING                  0x00
+#define        TYPE_B_DRIVING                  0x01
+#define        TYPE_C_DRIVING                  0x02
+#define        TYPE_D_DRIVING                  0x03
+
+#define        DDR_FIX_RX_DAT                  0x00
+#define        DDR_VAR_RX_DAT                  0x80
+#define        DDR_FIX_RX_DAT_EDGE             0x00
+#define        DDR_FIX_RX_DAT_14_DELAY         0x40
+#define        DDR_FIX_RX_CMD                  0x00
+#define        DDR_VAR_RX_CMD                  0x20
+#define        DDR_FIX_RX_CMD_POS_EDGE         0x00
+#define        DDR_FIX_RX_CMD_14_DELAY         0x10
+#define        SD20_RX_POS_EDGE                0x00
+#define        SD20_RX_14_DELAY                0x08
+#define SD20_RX_SEL_MASK               0x08
+
+#define        DDR_FIX_TX_CMD_DAT              0x00
+#define        DDR_VAR_TX_CMD_DAT              0x80
+#define        DDR_FIX_TX_DAT_14_TSU           0x00
+#define        DDR_FIX_TX_DAT_12_TSU           0x40
+#define        DDR_FIX_TX_CMD_NEG_EDGE         0x00
+#define        DDR_FIX_TX_CMD_14_AHEAD         0x20
+#define        SD20_TX_NEG_EDGE                0x00
+#define        SD20_TX_14_AHEAD                0x10
+#define SD20_TX_SEL_MASK               0x10
+#define        DDR_VAR_SDCLK_POL_SWAP          0x01
+
+#define        SD_TRANSFER_START               0x80
+#define        SD_TRANSFER_END                 0x40
+#define SD_STAT_IDLE                   0x20
+#define        SD_TRANSFER_ERR                 0x10
+#define        SD_TM_NORMAL_WRITE              0x00
+#define        SD_TM_AUTO_WRITE_3              0x01
+#define        SD_TM_AUTO_WRITE_4              0x02
+#define        SD_TM_AUTO_READ_3               0x05
+#define        SD_TM_AUTO_READ_4               0x06
+#define        SD_TM_CMD_RSP                   0x08
+#define        SD_TM_AUTO_WRITE_1              0x09
+#define        SD_TM_AUTO_WRITE_2              0x0A
+#define        SD_TM_NORMAL_READ               0x0C
+#define        SD_TM_AUTO_READ_1               0x0D
+#define        SD_TM_AUTO_READ_2               0x0E
+#define        SD_TM_AUTO_TUNING               0x0F
+
+#define PHASE_CHANGE                   0x80
+#define PHASE_NOT_RESET                        0x40
+
+#define DCMPS_CHANGE                   0x80
+#define DCMPS_CHANGE_DONE              0x40
+#define DCMPS_ERROR                    0x20
+#define DCMPS_CURRENT_PHASE            0x1F
+
+#define SD_CLK_DIVIDE_0                        0x00
+#define        SD_CLK_DIVIDE_256               0xC0
+#define        SD_CLK_DIVIDE_128               0x80
+#define        SD_BUS_WIDTH_1                  0x00
+#define        SD_BUS_WIDTH_4                  0x01
+#define        SD_BUS_WIDTH_8                  0x02
+#define        SD_ASYNC_FIFO_NOT_RST           0x10
+#define        SD_20_MODE                      0x00
+#define        SD_DDR_MODE                     0x04
+#define        SD_30_MODE                      0x08
+
+#define SD_CLK_DIVIDE_MASK             0xC0
+
+#define SD_CMD_IDLE                    0x80
+
+#define SD_DATA_IDLE                   0x80
+
+#define DCM_RESET                      0x08
+#define DCM_LOCKED                     0x04
+#define DCM_208M                       0x00
+#define DCM_TX                         0x01
+#define DCM_RX                         0x02
+
+#define DRP_START                      0x80
+#define DRP_DONE                       0x40
+
+#define DRP_WRITE                      0x80
+#define DRP_READ                       0x00
+#define DCM_WRITE_ADDRESS_50           0x50
+#define DCM_WRITE_ADDRESS_51           0x51
+#define DCM_READ_ADDRESS_00            0x00
+#define DCM_READ_ADDRESS_51            0x51
+
+#define        SD_CALCULATE_CRC7               0x00
+#define        SD_NO_CALCULATE_CRC7            0x80
+#define        SD_CHECK_CRC16                  0x00
+#define        SD_NO_CHECK_CRC16               0x40
+#define SD_NO_CHECK_WAIT_CRC_TO                0x20
+#define        SD_WAIT_BUSY_END                0x08
+#define        SD_NO_WAIT_BUSY_END             0x00
+#define        SD_CHECK_CRC7                   0x00
+#define        SD_NO_CHECK_CRC7                0x04
+#define        SD_RSP_LEN_0                    0x00
+#define        SD_RSP_LEN_6                    0x01
+#define        SD_RSP_LEN_17                   0x02
+#define        SD_RSP_TYPE_R0                  0x04
+#define        SD_RSP_TYPE_R1                  0x01
+#define        SD_RSP_TYPE_R1b                 0x09
+#define        SD_RSP_TYPE_R2                  0x02
+#define        SD_RSP_TYPE_R3                  0x05
+#define        SD_RSP_TYPE_R4                  0x05
+#define        SD_RSP_TYPE_R5                  0x01
+#define        SD_RSP_TYPE_R6                  0x01
+#define        SD_RSP_TYPE_R7                  0x01
+
+#define        SD_RSP_80CLK_TIMEOUT_EN         0x01
+
+#define        SAMPLE_TIME_RISING              0x00
+#define        SAMPLE_TIME_FALLING             0x80
+#define        PUSH_TIME_DEFAULT               0x00
+#define        PUSH_TIME_ODD                   0x40
+#define        NO_EXTEND_TOGGLE                0x00
+#define        EXTEND_TOGGLE_CHK               0x20
+#define        MS_BUS_WIDTH_1                  0x00
+#define        MS_BUS_WIDTH_4                  0x10
+#define        MS_BUS_WIDTH_8                  0x18
+#define        MS_2K_SECTOR_MODE               0x04
+#define        MS_512_SECTOR_MODE              0x00
+#define        MS_TOGGLE_TIMEOUT_EN            0x00
+#define        MS_TOGGLE_TIMEOUT_DISEN         0x01
+#define MS_NO_CHECK_INT                        0x02
+
+#define        WAIT_INT                        0x80
+#define        NO_WAIT_INT                     0x00
+#define        NO_AUTO_READ_INT_REG            0x00
+#define        AUTO_READ_INT_REG               0x40
+#define        MS_CRC16_ERR                    0x20
+#define        MS_RDY_TIMEOUT                  0x10
+#define        MS_INT_CMDNK                    0x08
+#define        MS_INT_BREQ                     0x04
+#define        MS_INT_ERR                      0x02
+#define        MS_INT_CED                      0x01
+
+#define        MS_TRANSFER_START               0x80
+#define        MS_TRANSFER_END                 0x40
+#define        MS_TRANSFER_ERR                 0x20
+#define        MS_BS_STATE                     0x10
+#define        MS_TM_READ_BYTES                0x00
+#define        MS_TM_NORMAL_READ               0x01
+#define        MS_TM_WRITE_BYTES               0x04
+#define        MS_TM_NORMAL_WRITE              0x05
+#define        MS_TM_AUTO_READ                 0x08
+#define        MS_TM_AUTO_WRITE                0x0C
+
+#define CARD_SHARE_MASK                        0x0F
+#define CARD_SHARE_MULTI_LUN           0x00
+#define        CARD_SHARE_NORMAL               0x00
+#define        CARD_SHARE_48_XD                0x02
+#define        CARD_SHARE_48_SD                0x04
+#define        CARD_SHARE_48_MS                0x08
+#define CARD_SHARE_BAROSSA_XD          0x00
+#define CARD_SHARE_BAROSSA_SD          0x01
+#define CARD_SHARE_BAROSSA_MS          0x02
+
+#define        MS_DRIVE_8                      0x00
+#define        MS_DRIVE_4                      0x40
+#define        MS_DRIVE_12                     0x80
+#define        SD_DRIVE_8                      0x00
+#define        SD_DRIVE_4                      0x10
+#define        SD_DRIVE_12                     0x20
+#define        XD_DRIVE_8                      0x00
+#define        XD_DRIVE_4                      0x04
+#define        XD_DRIVE_12                     0x08
+
+#define SPI_STOP               0x01
+#define XD_STOP                        0x02
+#define SD_STOP                        0x04
+#define MS_STOP                        0x08
+#define SPI_CLR_ERR            0x10
+#define XD_CLR_ERR             0x20
+#define SD_CLR_ERR             0x40
+#define MS_CLR_ERR             0x80
+
+#define CRC_FIX_CLK            (0x00 << 0)
+#define CRC_VAR_CLK0           (0x01 << 0)
+#define CRC_VAR_CLK1           (0x02 << 0)
+#define SD30_FIX_CLK           (0x00 << 2)
+#define SD30_VAR_CLK0          (0x01 << 2)
+#define SD30_VAR_CLK1          (0x02 << 2)
+#define SAMPLE_FIX_CLK         (0x00 << 4)
+#define SAMPLE_VAR_CLK0                (0x01 << 4)
+#define SAMPLE_VAR_CLK1                (0x02 << 4)
+
+#define SDIO_VER_20            0x80
+#define SDIO_VER_10            0x00
+#define SDIO_VER_CHG           0x40
+#define SDIO_BUS_AUTO_SWITCH   0x10
+
+#define PINGPONG_BUFFER                0x01
+#define RING_BUFFER            0x00
+
+#define RB_FLUSH               0x80
+
+#define DMA_DONE_INT_EN                        0x80
+#define SUSPEND_INT_EN                 0x40
+#define LINK_RDY_INT_EN                        0x20
+#define LINK_DOWN_INT_EN               0x10
+
+#define DMA_DONE_INT                   0x80
+#define SUSPEND_INT                    0x40
+#define LINK_RDY_INT                   0x20
+#define LINK_DOWN_INT                  0x10
+
+#define MRD_ERR_INT_EN                 0x40
+#define MWR_ERR_INT_EN                 0x20
+#define SCSI_CMD_INT_EN                        0x10
+#define TLP_RCV_INT_EN                 0x08
+#define TLP_TRSMT_INT_EN               0x04
+#define MRD_COMPLETE_INT_EN            0x02
+#define MWR_COMPLETE_INT_EN            0x01
+
+#define MRD_ERR_INT                    0x40
+#define MWR_ERR_INT                    0x20
+#define SCSI_CMD_INT                   0x10
+#define TLP_RX_INT                     0x08
+#define TLP_TX_INT                     0x04
+#define MRD_COMPLETE_INT               0x02
+#define MWR_COMPLETE_INT               0x01
+
+#define MSG_RX_INT_EN                  0x08
+#define MRD_RX_INT_EN                  0x04
+#define MWR_RX_INT_EN                  0x02
+#define CPLD_RX_INT_EN                 0x01
+
+#define MSG_RX_INT                     0x08
+#define MRD_RX_INT                     0x04
+#define MWR_RX_INT                     0x02
+#define CPLD_RX_INT                    0x01
+
+#define MSG_TX_INT_EN                  0x08
+#define MRD_TX_INT_EN                  0x04
+#define MWR_TX_INT_EN                  0x02
+#define CPLD_TX_INT_EN                 0x01
+
+#define MSG_TX_INT                     0x08
+#define MRD_TX_INT                     0x04
+#define MWR_TX_INT                     0x02
+#define CPLD_TX_INT                    0x01
+
+#define DMA_RST                                0x80
+#define DMA_BUSY                       0x04
+#define DMA_DIR_TO_CARD                        0x00
+#define DMA_DIR_FROM_CARD              0x02
+#define DMA_EN                         0x01
+#define DMA_128                                (0 << 4)
+#define DMA_256                                (1 << 4)
+#define DMA_512                                (2 << 4)
+#define DMA_1024                       (3 << 4)
+#define DMA_PACK_SIZE_MASK             0x30
+
+#define        XD_PWR_OFF_DELAY0               0x00
+#define        XD_PWR_OFF_DELAY1               0x02
+#define        XD_PWR_OFF_DELAY2               0x04
+#define        XD_PWR_OFF_DELAY3               0x06
+#define        XD_AUTO_PWR_OFF_EN              0xF7
+#define        XD_NO_AUTO_PWR_OFF              0x08
+
+#define        XD_TIME_RWN_1                   0x00
+#define        XD_TIME_RWN_STEP                0x20
+#define        XD_TIME_RW_1                    0x00
+#define        XD_TIME_RW_STEP                 0x04
+#define        XD_TIME_SETUP_1                 0x00
+#define        XD_TIME_SETUP_STEP              0x01
+
+#define        XD_ECC2_UNCORRECTABLE           0x80
+#define        XD_ECC2_ERROR                   0x40
+#define        XD_ECC1_UNCORRECTABLE           0x20
+#define        XD_ECC1_ERROR                   0x10
+#define        XD_RDY                          0x04
+#define        XD_CE_EN                        0xFD
+#define        XD_CE_DISEN                     0x02
+#define        XD_WP_EN                        0xFE
+#define        XD_WP_DISEN                     0x01
+
+#define        XD_TRANSFER_START               0x80
+#define        XD_TRANSFER_END                 0x40
+#define        XD_PPB_EMPTY                    0x20
+#define        XD_RESET                        0x00
+#define        XD_ERASE                        0x01
+#define        XD_READ_STATUS                  0x02
+#define        XD_READ_ID                      0x03
+#define        XD_READ_REDUNDANT               0x04
+#define        XD_READ_PAGES                   0x05
+#define        XD_SET_CMD                      0x06
+#define        XD_NORMAL_READ                  0x07
+#define        XD_WRITE_PAGES                  0x08
+#define        XD_NORMAL_WRITE                 0x09
+#define        XD_WRITE_REDUNDANT              0x0A
+#define        XD_SET_ADDR                     0x0B
+
+#define        XD_PPB_TO_SIE                   0x80
+#define        XD_TO_PPB_ONLY                  0x00
+#define        XD_BA_TRANSFORM                 0x40
+#define        XD_BA_NO_TRANSFORM              0x00
+#define        XD_NO_CALC_ECC                  0x20
+#define        XD_CALC_ECC                     0x00
+#define        XD_IGNORE_ECC                   0x10
+#define        XD_CHECK_ECC                    0x00
+#define        XD_DIRECT_TO_RB                 0x08
+#define        XD_ADDR_LENGTH_0                0x00
+#define        XD_ADDR_LENGTH_1                0x01
+#define        XD_ADDR_LENGTH_2                0x02
+#define        XD_ADDR_LENGTH_3                0x03
+#define        XD_ADDR_LENGTH_4                0x04
+
+#define        XD_GPG                          0xFF
+#define        XD_BPG                          0x00
+
+#define        XD_GBLK                         0xFF
+#define        XD_LATER_BBLK                   0xF0
+
+#define        XD_ECC2_ALL1                    0x80
+#define        XD_ECC1_ALL1                    0x40
+#define        XD_BA2_ALL0                     0x20
+#define        XD_BA1_ALL0                     0x10
+#define        XD_BA1_BA2_EQL                  0x04
+#define        XD_BA2_VALID                    0x02
+#define        XD_BA1_VALID                    0x01
+
+#define        XD_PGSTS_ZEROBIT_OVER4          0x00
+#define        XD_PGSTS_NOT_FF                 0x02
+#define        XD_AUTO_CHK_DATA_STATUS         0x01
+
+#define        RSTB_MODE_DETECT                0x80
+#define        MODE_OUT_VLD                    0x40
+#define        MODE_OUT_0_NONE                 0x00
+#define        MODE_OUT_10_NONE                0x04
+#define        MODE_OUT_10_47                  0x05
+#define        MODE_OUT_10_180                 0x06
+#define        MODE_OUT_10_680                 0x07
+#define        MODE_OUT_16_NONE                0x08
+#define        MODE_OUT_16_47                  0x09
+#define        MODE_OUT_16_180                 0x0A
+#define        MODE_OUT_16_680                 0x0B
+#define        MODE_OUT_NONE_NONE              0x0C
+#define        MODE_OUT_NONE_47                0x0D
+#define        MODE_OUT_NONE_180               0x0E
+#define        MODE_OUT_NONE_680               0x0F
+
+#define        CARD_OC_INT_EN                  0x20
+#define        CARD_DETECT_EN                  0x08
+
+#define MS_DETECT_EN                   0x80
+#define MS_OCP_INT_EN                  0x40
+#define MS_OCP_INT_CLR                 0x20
+#define MS_OC_CLR                      0x10
+#define SD_DETECT_EN                   0x08
+#define SD_OCP_INT_EN                  0x04
+#define SD_OCP_INT_CLR                 0x02
+#define SD_OC_CLR                      0x01
+
+#define        CARD_OCP_DETECT                 0x80
+#define        CARD_OC_NOW                     0x08
+#define        CARD_OC_EVER                    0x04
+
+#define MS_OCP_DETECT                  0x80
+#define MS_OC_NOW                      0x40
+#define MS_OC_EVER                     0x20
+#define SD_OCP_DETECT                  0x08
+#define SD_OC_NOW                      0x04
+#define SD_OC_EVER                     0x02
+
+#define        CARD_OC_INT_CLR                 0x08
+#define        CARD_OC_CLR                     0x02
+
+#define SD_OCP_GLITCH_MASK             0x07
+#define SD_OCP_GLITCH_6_4              0x00
+#define SD_OCP_GLITCH_64               0x01
+#define SD_OCP_GLITCH_640              0x02
+#define SD_OCP_GLITCH_1000             0x03
+#define SD_OCP_GLITCH_2000             0x04
+#define SD_OCP_GLITCH_4000             0x05
+#define SD_OCP_GLITCH_8000             0x06
+#define SD_OCP_GLITCH_10000            0x07
+
+#define MS_OCP_GLITCH_MASK             0x70
+#define MS_OCP_GLITCH_6_4              (0x00 << 4)
+#define MS_OCP_GLITCH_64               (0x01 << 4)
+#define MS_OCP_GLITCH_640              (0x02 << 4)
+#define MS_OCP_GLITCH_1000             (0x03 << 4)
+#define MS_OCP_GLITCH_2000             (0x04 << 4)
+#define MS_OCP_GLITCH_4000             (0x05 << 4)
+#define MS_OCP_GLITCH_8000             (0x06 << 4)
+#define MS_OCP_GLITCH_10000            (0x07 << 4)
+
+#define OCP_TIME_60                    0x00
+#define OCP_TIME_100                   (0x01 << 3)
+#define OCP_TIME_200                   (0x02 << 3)
+#define OCP_TIME_400                   (0x03 << 3)
+#define OCP_TIME_600                   (0x04 << 3)
+#define OCP_TIME_800                   (0x05 << 3)
+#define OCP_TIME_1100                  (0x06 << 3)
+#define OCP_TIME_MASK                  0x38
+
+#define MS_OCP_TIME_60                 0x00
+#define MS_OCP_TIME_100                        (0x01 << 4)
+#define MS_OCP_TIME_200                        (0x02 << 4)
+#define MS_OCP_TIME_400                        (0x03 << 4)
+#define MS_OCP_TIME_600                        (0x04 << 4)
+#define MS_OCP_TIME_800                        (0x05 << 4)
+#define MS_OCP_TIME_1100               (0x06 << 4)
+#define MS_OCP_TIME_MASK               0x70
+
+#define SD_OCP_TIME_60                 0x00
+#define SD_OCP_TIME_100                        0x01
+#define SD_OCP_TIME_200                        0x02
+#define SD_OCP_TIME_400                        0x03
+#define SD_OCP_TIME_600                        0x04
+#define SD_OCP_TIME_800                        0x05
+#define SD_OCP_TIME_1100               0x06
+#define SD_OCP_TIME_MASK               0x07
+
+#define OCP_THD_315_417                        0x00
+#define OCP_THD_283_783                        (0x01 << 6)
+#define OCP_THD_244_946                        (0x02 << 6)
+#define OCP_THD_191_1080               (0x03 << 6)
+#define OCP_THD_MASK                   0xC0
+
+#define MS_OCP_THD_450                 0x00
+#define MS_OCP_THD_550                 (0x01 << 4)
+#define MS_OCP_THD_650                 (0x02 << 4)
+#define MS_OCP_THD_750                 (0x03 << 4)
+#define MS_OCP_THD_850                 (0x04 << 4)
+#define MS_OCP_THD_950                 (0x05 << 4)
+#define MS_OCP_THD_1050                        (0x06 << 4)
+#define MS_OCP_THD_1150                        (0x07 << 4)
+#define MS_OCP_THD_MASK                        0x70
+
+#define SD_OCP_THD_450                 0x00
+#define SD_OCP_THD_550                 0x01
+#define SD_OCP_THD_650                 0x02
+#define SD_OCP_THD_750                 0x03
+#define SD_OCP_THD_850                 0x04
+#define SD_OCP_THD_950                 0x05
+#define SD_OCP_THD_1050                        0x06
+#define SD_OCP_THD_1150                        0x07
+#define SD_OCP_THD_MASK                        0x07
+
+#define FPGA_MS_PULL_CTL_EN            0xEF
+#define FPGA_SD_PULL_CTL_EN            0xF7
+#define FPGA_XD_PULL_CTL_EN1           0xFE
+#define FPGA_XD_PULL_CTL_EN2           0xFD
+#define FPGA_XD_PULL_CTL_EN3           0xFB
+
+#define FPGA_MS_PULL_CTL_BIT           0x10
+#define FPGA_SD_PULL_CTL_BIT           0x08
+
+#define BLINK_EN                       0x08
+#define LED_GPIO0                      (0 << 4)
+#define LED_GPIO1                      (1 << 4)
+#define LED_GPIO2                      (2 << 4)
+
+#define SDIO_BUS_CTRL          0x01
+#define SDIO_CD_CTRL           0x02
+
+#define SSC_RSTB               0x80
+#define SSC_8X_EN              0x40
+#define SSC_FIX_FRAC           0x20
+#define SSC_SEL_1M             0x00
+#define SSC_SEL_2M             0x08
+#define SSC_SEL_4M             0x10
+#define SSC_SEL_8M             0x18
+
+#define SSC_DEPTH_MASK         0x07
+#define SSC_DEPTH_DISALBE      0x00
+#define SSC_DEPTH_4M           0x01
+#define SSC_DEPTH_2M           0x02
+#define SSC_DEPTH_1M           0x03
+#define SSC_DEPTH_512K         0x04
+#define SSC_DEPTH_256K         0x05
+#define SSC_DEPTH_128K         0x06
+#define SSC_DEPTH_64K          0x07
+
+#define XD_D3_NP               0x00
+#define XD_D3_PD               (0x01 << 6)
+#define XD_D3_PU               (0x02 << 6)
+#define XD_D2_NP               0x00
+#define XD_D2_PD               (0x01 << 4)
+#define XD_D2_PU               (0x02 << 4)
+#define XD_D1_NP               0x00
+#define XD_D1_PD               (0x01 << 2)
+#define XD_D1_PU               (0x02 << 2)
+#define XD_D0_NP               0x00
+#define XD_D0_PD               0x01
+#define XD_D0_PU               0x02
+
+#define SD_D7_NP               0x00
+#define SD_D7_PD               (0x01 << 4)
+#define SD_DAT7_PU             (0x02 << 4)
+#define SD_CLK_NP              0x00
+#define SD_CLK_PD              (0x01 << 2)
+#define SD_CLK_PU              (0x02 << 2)
+#define SD_D5_NP               0x00
+#define SD_D5_PD               0x01
+#define SD_D5_PU               0x02
+
+#define MS_D1_NP               0x00
+#define MS_D1_PD               (0x01 << 6)
+#define MS_D1_PU               (0x02 << 6)
+#define MS_D2_NP               0x00
+#define MS_D2_PD               (0x01 << 4)
+#define MS_D2_PU               (0x02 << 4)
+#define MS_CLK_NP              0x00
+#define MS_CLK_PD              (0x01 << 2)
+#define MS_CLK_PU              (0x02 << 2)
+#define MS_D6_NP               0x00
+#define MS_D6_PD               0x01
+#define MS_D6_PU               0x02
+
+#define XD_D7_NP               0x00
+#define XD_D7_PD               (0x01 << 6)
+#define XD_D7_PU               (0x02 << 6)
+#define XD_D6_NP               0x00
+#define XD_D6_PD               (0x01 << 4)
+#define XD_D6_PU               (0x02 << 4)
+#define XD_D5_NP               0x00
+#define XD_D5_PD               (0x01 << 2)
+#define XD_D5_PU               (0x02 << 2)
+#define XD_D4_NP               0x00
+#define XD_D4_PD               0x01
+#define XD_D4_PU               0x02
+
+#define SD_D6_NP               0x00
+#define SD_D6_PD               (0x01 << 6)
+#define SD_D6_PU               (0x02 << 6)
+#define SD_D0_NP               0x00
+#define SD_D0_PD               (0x01 << 4)
+#define SD_D0_PU               (0x02 << 4)
+#define SD_D1_NP               0x00
+#define SD_D1_PD               0x01
+#define SD_D1_PU               0x02
+
+#define MS_D3_NP               0x00
+#define MS_D3_PD               (0x01 << 6)
+#define MS_D3_PU               (0x02 << 6)
+#define MS_D0_NP               0x00
+#define MS_D0_PD               (0x01 << 4)
+#define MS_D0_PU               (0x02 << 4)
+#define MS_BS_NP               0x00
+#define MS_BS_PD               (0x01 << 2)
+#define MS_BS_PU               (0x02 << 2)
+
+#define XD_WP_NP               0x00
+#define XD_WP_PD               (0x01 << 6)
+#define XD_WP_PU               (0x02 << 6)
+#define XD_CE_NP               0x00
+#define XD_CE_PD               (0x01 << 3)
+#define XD_CE_PU               (0x02 << 3)
+#define XD_CLE_NP              0x00
+#define XD_CLE_PD              (0x01 << 1)
+#define XD_CLE_PU              (0x02 << 1)
+#define XD_CD_PD               0x00
+#define XD_CD_PU               0x01
+
+#define SD_D4_NP               0x00
+#define SD_D4_PD               (0x01 << 6)
+#define SD_D4_PU               (0x02 << 6)
+
+#define MS_D7_NP               0x00
+#define MS_D7_PD               (0x01 << 6)
+#define MS_D7_PU               (0x02 << 6)
+
+#define XD_RDY_NP              0x00
+#define XD_RDY_PD              (0x01 << 6)
+#define XD_RDY_PU              (0x02 << 6)
+#define XD_WE_NP               0x00
+#define XD_WE_PD               (0x01 << 4)
+#define XD_WE_PU               (0x02 << 4)
+#define XD_RE_NP               0x00
+#define XD_RE_PD               (0x01 << 2)
+#define XD_RE_PU               (0x02 << 2)
+#define XD_ALE_NP              0x00
+#define XD_ALE_PD              0x01
+#define XD_ALE_PU              0x02
+
+#define SD_D3_NP               0x00
+#define SD_D3_PD               (0x01 << 4)
+#define SD_D3_PU               (0x02 << 4)
+#define SD_D2_NP               0x00
+#define SD_D2_PD               (0x01 << 2)
+#define SD_D2_PU               (0x02 << 2)
+
+#define MS_INS_PD              0x00
+#define MS_INS_PU              (0x01 << 7)
+#define SD_WP_NP               0x00
+#define SD_WP_PD               (0x01 << 5)
+#define SD_WP_PU               (0x02 << 5)
+#define SD_CD_PD               0x00
+#define SD_CD_PU               (0x01 << 4)
+#define SD_CMD_NP              0x00
+#define SD_CMD_PD              (0x01 << 2)
+#define SD_CMD_PU              (0x02 << 2)
+
+#define MS_D5_NP               0x00
+#define MS_D5_PD               (0x01 << 2)
+#define MS_D5_PU               (0x02 << 2)
+#define MS_D4_NP               0x00
+#define MS_D4_PD               0x01
+#define MS_D4_PU               0x02
+
+#define FORCE_PM_CLOCK         0x10
+#define EN_CLOCK_PM            0x01
+
+#define HOST_ENTER_S3          0x02
+#define HOST_ENTER_S1          0x01
+
+#define AUX_PWR_DETECTED       0x01
+
+#define PHY_DEBUG_MODE         0x01
+
+#define SPI_COMMAND_BIT_8      0xE0
+#define SPI_ADDRESS_BIT_24     0x17
+#define SPI_ADDRESS_BIT_32     0x1F
+
+#define SPI_TRANSFER0_START    0x80
+#define SPI_TRANSFER0_END      0x40
+#define SPI_C_MODE0            0x00
+#define SPI_CA_MODE0           0x01
+#define SPI_CDO_MODE0          0x02
+#define SPI_CDI_MODE0          0x03
+#define SPI_CADO_MODE0         0x04
+#define SPI_CADI_MODE0         0x05
+#define SPI_POLLING_MODE0      0x06
+
+#define SPI_TRANSFER1_START    0x80
+#define SPI_TRANSFER1_END      0x40
+#define SPI_DO_MODE1           0x00
+#define SPI_DI_MODE1           0x01
+
+#define CS_POLARITY_HIGH       0x40
+#define CS_POLARITY_LOW                0x00
+#define DTO_MSB_FIRST          0x00
+#define DTO_LSB_FIRST          0x20
+#define SPI_MASTER             0x00
+#define SPI_SLAVE              0x10
+#define SPI_MODE0              0x00
+#define SPI_MODE1              0x04
+#define SPI_MODE2              0x08
+#define SPI_MODE3              0x0C
+#define SPI_MANUAL             0x00
+#define SPI_HALF_AUTO          0x01
+#define SPI_AUTO               0x02
+#define SPI_EEPROM_AUTO                0x03
+
+#define EDO_TIMING_MASK                0x03
+#define SAMPLE_RISING          0x00
+#define SAMPLE_DELAY_HALF      0x01
+#define SAMPLE_DELAY_ONE       0x02
+#define SAPMLE_DELAY_ONE_HALF  0x03
+#define TCS_MASK               0x0C
+
+#define NOT_BYPASS_SD          0x02
+#define DISABLE_SDIO_FUNC      0x04
+#define SELECT_1LUN            0x08
+
+#define PWR_GATE_EN            0x01
+#define LDO3318_PWR_MASK       0x06
+#define LDO_ON                 0x00
+#define LDO_SUSPEND            0x04
+#define LDO_OFF                        0x06
+
+#define SD_CFG1                        0xFDA0
+#define SD_CFG2                        0xFDA1
+#define SD_CFG3                        0xFDA2
+#define SD_STAT1               0xFDA3
+#define SD_STAT2               0xFDA4
+#define SD_BUS_STAT            0xFDA5
+#define SD_PAD_CTL             0xFDA6
+#define SD_SAMPLE_POINT_CTL    0xFDA7
+#define SD_PUSH_POINT_CTL      0xFDA8
+#define SD_CMD0                        0xFDA9
+#define SD_CMD1                        0xFDAA
+#define SD_CMD2                        0xFDAB
+#define SD_CMD3                        0xFDAC
+#define SD_CMD4                        0xFDAD
+#define SD_CMD5                        0xFDAE
+#define SD_BYTE_CNT_L          0xFDAF
+#define SD_BYTE_CNT_H          0xFDB0
+#define SD_BLOCK_CNT_L         0xFDB1
+#define SD_BLOCK_CNT_H         0xFDB2
+#define SD_TRANSFER            0xFDB3
+#define SD_CMD_STATE           0xFDB5
+#define SD_DATA_STATE          0xFDB6
+
+#define        DCM_DRP_CTL             0xFC23
+#define        DCM_DRP_TRIG            0xFC24
+#define        DCM_DRP_CFG             0xFC25
+#define        DCM_DRP_WR_DATA_L       0xFC26
+#define        DCM_DRP_WR_DATA_H       0xFC27
+#define        DCM_DRP_RD_DATA_L       0xFC28
+#define        DCM_DRP_RD_DATA_H       0xFC29
+#define SD_VPCLK0_CTL          0xFC2A
+#define SD_VPCLK1_CTL          0xFC2B
+#define SD_DCMPS0_CTL          0xFC2C
+#define SD_DCMPS1_CTL          0xFC2D
+#define SD_VPTX_CTL            SD_VPCLK0_CTL
+#define SD_VPRX_CTL            SD_VPCLK1_CTL
+#define SD_DCMPS_TX_CTL                SD_DCMPS0_CTL
+#define SD_DCMPS_RX_CTL                SD_DCMPS1_CTL
+
+#define CARD_CLK_SOURCE                0xFC2E
+
+#define CARD_PWR_CTL           0xFD50
+#define CARD_CLK_SWITCH                0xFD51
+#define CARD_SHARE_MODE                0xFD52
+#define CARD_DRIVE_SEL         0xFD53
+#define CARD_STOP              0xFD54
+#define CARD_OE                        0xFD55
+#define CARD_AUTO_BLINK                0xFD56
+#define CARD_GPIO_DIR          0xFD57
+#define CARD_GPIO              0xFD58
+
+#define CARD_DATA_SOURCE       0xFD5B
+#define CARD_SELECT            0xFD5C
+#define SD30_DRIVE_SEL         0xFD5E
+
+#define CARD_CLK_EN            0xFD69
+
+#define SDIO_CTRL              0xFD6B
+
+#define FPDCTL                 0xFC00
+#define PDINFO                 0xFC01
+
+#define CLK_CTL                        0xFC02
+#define CLK_DIV                        0xFC03
+#define CLK_SEL                        0xFC04
+
+#define SSC_DIV_N_0            0xFC0F
+#define SSC_DIV_N_1            0xFC10
+
+#define RCCTL                  0xFC14
+
+#define FPGA_PULL_CTL          0xFC1D
+
+#define CARD_PULL_CTL1         0xFD60
+#define CARD_PULL_CTL2         0xFD61
+#define CARD_PULL_CTL3         0xFD62
+#define CARD_PULL_CTL4         0xFD63
+#define CARD_PULL_CTL5         0xFD64
+#define CARD_PULL_CTL6         0xFD65
+
+#define IRQEN0                         0xFE20
+#define IRQSTAT0                       0xFE21
+#define IRQEN1                         0xFE22
+#define IRQSTAT1                       0xFE23
+#define TLPRIEN                                0xFE24
+#define TLPRISTAT                      0xFE25
+#define TLPTIEN                                0xFE26
+#define TLPTISTAT                      0xFE27
+#define DMATC0                         0xFE28
+#define DMATC1                         0xFE29
+#define DMATC2                         0xFE2A
+#define DMATC3                         0xFE2B
+#define DMACTL                         0xFE2C
+#define BCTL                           0xFE2D
+#define RBBC0                          0xFE2E
+#define RBBC1                          0xFE2F
+#define RBDAT                          0xFE30
+#define RBCTL                          0xFE34
+#define CFGADDR0                       0xFE35
+#define CFGADDR1                       0xFE36
+#define CFGDATA0                       0xFE37
+#define CFGDATA1                       0xFE38
+#define CFGDATA2                       0xFE39
+#define CFGDATA3                       0xFE3A
+#define CFGRWCTL                       0xFE3B
+#define PHYRWCTL                       0xFE3C
+#define PHYDATA0                       0xFE3D
+#define PHYDATA1                       0xFE3E
+#define PHYADDR                                0xFE3F
+#define MSGRXDATA0                     0xFE40
+#define MSGRXDATA1                     0xFE41
+#define MSGRXDATA2                     0xFE42
+#define MSGRXDATA3                     0xFE43
+#define MSGTXDATA0                     0xFE44
+#define MSGTXDATA1                     0xFE45
+#define MSGTXDATA2                     0xFE46
+#define MSGTXDATA3                     0xFE47
+#define MSGTXCTL                       0xFE48
+#define PETXCFG                                0xFE49
+
+#define CDRESUMECTL                    0xFE52
+#define WAKE_SEL_CTL                   0xFE54
+#define PME_FORCE_CTL                  0xFE56
+#define ASPM_FORCE_CTL                 0xFE57
+#define PM_CLK_FORCE_CTL               0xFE58
+#define PERST_GLITCH_WIDTH             0xFE5C
+#define CHANGE_LINK_STATE              0xFE5B
+#define RESET_LOAD_REG                 0xFE5E
+#define HOST_SLEEP_STATE               0xFE60
+#define MAIN_PWR_OFF_CTL               0xFE70  /* RTS5208 */
+
+#define NFTS_TX_CTRL                   0xFE72
+
+#define PWR_GATE_CTRL                  0xFE75
+#define PWD_SUSPEND_EN                 0xFE76
+
+#define EFUSE_CONTENT                  0xFE5F
+
+#define XD_INIT                                0xFD10
+#define XD_DTCTL                       0xFD11
+#define XD_CTL                         0xFD12
+#define XD_TRANSFER                    0xFD13
+#define XD_CFG                         0xFD14
+#define XD_ADDRESS0                    0xFD15
+#define XD_ADDRESS1                    0xFD16
+#define XD_ADDRESS2                    0xFD17
+#define XD_ADDRESS3                    0xFD18
+#define XD_ADDRESS4                    0xFD19
+#define XD_DAT                         0xFD1A
+#define XD_PAGE_CNT                    0xFD1B
+#define XD_PAGE_STATUS                 0xFD1C
+#define XD_BLOCK_STATUS                        0xFD1D
+#define XD_BLOCK_ADDR1_L               0xFD1E
+#define XD_BLOCK_ADDR1_H               0xFD1F
+#define XD_BLOCK_ADDR2_L               0xFD20
+#define XD_BLOCK_ADDR2_H               0xFD21
+#define XD_BYTE_CNT_L                  0xFD22
+#define XD_BYTE_CNT_H                  0xFD23
+#define        XD_PARITY                       0xFD24
+#define XD_ECC_BIT1                    0xFD25
+#define XD_ECC_BYTE1                   0xFD26
+#define XD_ECC_BIT2                    0xFD27
+#define XD_ECC_BYTE2                   0xFD28
+#define XD_RESERVED0                   0xFD29
+#define XD_RESERVED1                   0xFD2A
+#define XD_RESERVED2                   0xFD2B
+#define XD_RESERVED3                   0xFD2C
+#define XD_CHK_DATA_STATUS             0xFD2D
+#define XD_CATCTL                      0xFD2E
+
+#define MS_CFG                         0xFD40
+#define MS_TPC                         0xFD41
+#define MS_TRANS_CFG                   0xFD42
+#define MS_TRANSFER                    0xFD43
+#define MS_INT_REG                     0xFD44
+#define MS_BYTE_CNT                    0xFD45
+#define MS_SECTOR_CNT_L                        0xFD46
+#define MS_SECTOR_CNT_H                        0xFD47
+#define MS_DBUS_H                      0xFD48
+
+#define SSC_CTL1                       0xFC11
+#define SSC_CTL2                       0xFC12
+
+#define OCPCTL                         0xFC15
+#define OCPSTAT                                0xFC16
+#define OCPCLR                         0xFC17  /* 5208 */
+#define OCPPARA1                       0xFC18
+#define OCPPARA2                       0xFC19
+
+#define EFUSE_OP                       0xFC20
+#define EFUSE_CTRL                     0xFC21
+#define EFUSE_DATA                     0xFC22
+
+#define        SPI_COMMAND                     0xFD80
+#define        SPI_ADDR0                       0xFD81
+#define        SPI_ADDR1                       0xFD82
+#define        SPI_ADDR2                       0xFD83
+#define        SPI_ADDR3                       0xFD84
+#define        SPI_CA_NUMBER                   0xFD85
+#define        SPI_LENGTH0                     0xFD86
+#define        SPI_LENGTH1                     0xFD87
+#define        SPI_DATA                        0xFD88
+#define SPI_DATA_NUMBER                        0xFD89
+#define        SPI_TRANSFER0                   0xFD90
+#define        SPI_TRANSFER1                   0xFD91
+#define        SPI_CONTROL                     0xFD92
+#define        SPI_SIG                         0xFD93
+#define        SPI_TCTL                        0xFD94
+#define        SPI_SLAVE_NUM                   0xFD95
+#define        SPI_CLK_DIVIDER0                0xFD96
+#define        SPI_CLK_DIVIDER1                0xFD97
+
+#define SRAM_BASE                      0xE600
+#define RBUF_BASE                      0xF400
+#define PPBUF_BASE1                    0xF800
+#define PPBUF_BASE2                    0xFA00
+#define IMAGE_FLAG_ADDR0               0xCE80
+#define IMAGE_FLAG_ADDR1               0xCE81
+
+#define READ_OP                        1
+#define WRITE_OP               2
+
+#define LCTLR          0x80
+
+#define POLLING_WAIT_CNT       1
+#define IDLE_MAX_COUNT         10
+#define SDIO_IDLE_COUNT                10
+
+#define DEBOUNCE_CNT                   5
+
+void do_remaining_work(struct rtsx_chip *chip);
+void try_to_switch_sdio_ctrl(struct rtsx_chip *chip);
+void do_reset_sd_card(struct rtsx_chip *chip);
+void do_reset_xd_card(struct rtsx_chip *chip);
+void do_reset_ms_card(struct rtsx_chip *chip);
+void rtsx_power_off_card(struct rtsx_chip *chip);
+void rtsx_release_cards(struct rtsx_chip *chip);
+void rtsx_reset_cards(struct rtsx_chip *chip);
+void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip);
+void rtsx_init_cards(struct rtsx_chip *chip);
+int switch_ssc_clock(struct rtsx_chip *chip, int clk);
+int switch_normal_clock(struct rtsx_chip *chip, int clk);
+int enable_card_clock(struct rtsx_chip *chip, u8 card);
+int disable_card_clock(struct rtsx_chip *chip, u8 card);
+int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+       u32 sec_addr, u16 sec_cnt);
+void trans_dma_enable(enum dma_data_direction dir,
+               struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size);
+void toggle_gpio(struct rtsx_chip *chip, u8 gpio);
+void turn_on_led(struct rtsx_chip *chip, u8 gpio);
+void turn_off_led(struct rtsx_chip *chip, u8 gpio);
+
+int card_share_mode(struct rtsx_chip *chip, int card);
+int select_card(struct rtsx_chip *chip, int card);
+int detect_card_cd(struct rtsx_chip *chip, int card);
+int check_card_exist(struct rtsx_chip *chip, unsigned int lun);
+int check_card_ready(struct rtsx_chip *chip, unsigned int lun);
+int check_card_wp(struct rtsx_chip *chip, unsigned int lun);
+int check_card_fail(struct rtsx_chip *chip, unsigned int lun);
+int check_card_ejected(struct rtsx_chip *chip, unsigned int lun);
+void eject_card(struct rtsx_chip *chip, unsigned int lun);
+u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun);
+
+static inline u32 get_card_size(struct rtsx_chip *chip, unsigned int lun)
+{
+#ifdef SUPPORT_SD_LOCK
+       struct sd_info *sd_card = &(chip->sd_card);
+
+       if ((get_lun_card(chip, lun) == SD_CARD) &&
+               (sd_card->sd_lock_status & SD_LOCKED))
+               return 0;
+       else
+               return chip->capacity[lun];
+#else
+       return chip->capacity[lun];
+#endif
+}
+
+static inline int switch_clock(struct rtsx_chip *chip, int clk)
+{
+       int retval = 0;
+
+       if (chip->asic_code)
+               retval = switch_ssc_clock(chip, clk);
+       else
+               retval = switch_normal_clock(chip, clk);
+
+       return retval;
+}
+
+int card_power_on(struct rtsx_chip *chip, u8 card);
+int card_power_off(struct rtsx_chip *chip, u8 card);
+
+static inline int card_power_off_all(struct rtsx_chip *chip)
+{
+       RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0x0F, 0x0F);
+
+       return STATUS_SUCCESS;
+}
+
+static inline void rtsx_clear_xd_error(struct rtsx_chip *chip)
+{
+       rtsx_write_register(chip, CARD_STOP, XD_STOP | XD_CLR_ERR,
+                       XD_STOP | XD_CLR_ERR);
+}
+
+static inline void rtsx_clear_sd_error(struct rtsx_chip *chip)
+{
+       rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR,
+                       SD_STOP | SD_CLR_ERR);
+}
+
+static inline void rtsx_clear_ms_error(struct rtsx_chip *chip)
+{
+       rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR,
+                       MS_STOP | MS_CLR_ERR);
+}
+
+static inline void rtsx_clear_spi_error(struct rtsx_chip *chip)
+{
+       rtsx_write_register(chip, CARD_STOP, SPI_STOP | SPI_CLR_ERR,
+                       SPI_STOP | SPI_CLR_ERR);
+}
+
+#ifdef SUPPORT_SDIO_ASPM
+void dynamic_configure_sdio_aspm(struct rtsx_chip *chip);
+#endif
+
+#endif  /* __REALTEK_RTSX_CARD_H */
diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c
new file mode 100644 (file)
index 0000000..6426807
--- /dev/null
@@ -0,0 +1,1979 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+#include <linux/vmalloc.h>
+
+#include "rtsx.h"
+#include "rtsx_transport.h"
+#include "rtsx_scsi.h"
+#include "rtsx_card.h"
+#include "rtsx_chip.h"
+#include "rtsx_sys.h"
+#include "general.h"
+
+#include "sd.h"
+#include "xd.h"
+#include "ms.h"
+
+static void rtsx_calibration(struct rtsx_chip *chip)
+{
+       rtsx_write_phy_register(chip, 0x1B, 0x135E);
+       wait_timeout(10);
+       rtsx_write_phy_register(chip, 0x00, 0x0280);
+       rtsx_write_phy_register(chip, 0x01, 0x7112);
+       rtsx_write_phy_register(chip, 0x01, 0x7110);
+       rtsx_write_phy_register(chip, 0x01, 0x7112);
+       rtsx_write_phy_register(chip, 0x01, 0x7113);
+       rtsx_write_phy_register(chip, 0x00, 0x0288);
+}
+
+void rtsx_disable_card_int(struct rtsx_chip *chip)
+{
+       u32 reg = rtsx_readl(chip, RTSX_BIER);
+
+       reg &= ~(XD_INT_EN | SD_INT_EN | MS_INT_EN);
+       rtsx_writel(chip, RTSX_BIER, reg);
+}
+
+void rtsx_enable_card_int(struct rtsx_chip *chip)
+{
+       u32 reg = rtsx_readl(chip, RTSX_BIER);
+       int i;
+
+       for (i = 0; i <= chip->max_lun; i++) {
+               if (chip->lun2card[i] & XD_CARD)
+                       reg |= XD_INT_EN;
+               if (chip->lun2card[i] & SD_CARD)
+                       reg |= SD_INT_EN;
+               if (chip->lun2card[i] & MS_CARD)
+                       reg |= MS_INT_EN;
+       }
+       if (chip->hw_bypass_sd)
+               reg &= ~((u32)SD_INT_EN);
+
+       rtsx_writel(chip, RTSX_BIER, reg);
+}
+
+void rtsx_enable_bus_int(struct rtsx_chip *chip)
+{
+       u32 reg = 0;
+#ifndef DISABLE_CARD_INT
+       int i;
+#endif
+
+       reg = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN;
+
+#ifndef DISABLE_CARD_INT
+       for (i = 0; i <= chip->max_lun; i++) {
+               RTSX_DEBUGP("lun2card[%d] = 0x%02x\n", i, chip->lun2card[i]);
+
+               if (chip->lun2card[i] & XD_CARD)
+                       reg |= XD_INT_EN;
+               if (chip->lun2card[i] & SD_CARD)
+                       reg |= SD_INT_EN;
+               if (chip->lun2card[i] & MS_CARD)
+                       reg |= MS_INT_EN;
+       }
+       if (chip->hw_bypass_sd)
+               reg &= ~((u32)SD_INT_EN);
+#endif
+
+       if (chip->ic_version >= IC_VER_C)
+               reg |= DELINK_INT_EN;
+#ifdef SUPPORT_OCP
+               reg |= OC_INT_EN;
+#endif
+       if (!chip->adma_mode)
+               reg |= DATA_DONE_INT_EN;
+
+       /* Enable Bus Interrupt */
+       rtsx_writel(chip, RTSX_BIER, reg);
+
+       RTSX_DEBUGP("RTSX_BIER: 0x%08x\n", reg);
+}
+
+void rtsx_disable_bus_int(struct rtsx_chip *chip)
+{
+       rtsx_writel(chip, RTSX_BIER, 0);
+}
+
+static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip)
+{
+       if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) {
+               if (chip->asic_code) {
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF,
+                               MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU);
+               } else {
+                       RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF,
+                               FPGA_SD_PULL_CTL_EN);
+               }
+               RTSX_WRITE_REG(chip, CARD_SHARE_MODE, 0xFF, CARD_SHARE_48_SD);
+
+               /* Enable SDIO internal clock */
+               RTSX_WRITE_REG(chip, 0xFF2C, 0x01, 0x01);
+
+               RTSX_WRITE_REG(chip, SDIO_CTRL, 0xFF,
+                       SDIO_BUS_CTRL | SDIO_CD_CTRL);
+
+               chip->sd_int = 1;
+               chip->sd_io = 1;
+       } else {
+               chip->need_reset |= SD_CARD;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+#ifdef HW_AUTO_SWITCH_SD_BUS
+static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip)
+{
+       u8 tmp;
+       int sw_bypass_sd = 0;
+       int retval;
+
+       if (chip->driver_first_load) {
+               if (CHECK_PID(chip, 0x5288)) {
+                       RTSX_READ_REG(chip, 0xFE5A, &tmp);
+                       if (tmp & 0x08)
+                               sw_bypass_sd = 1;
+               } else if (CHECK_PID(chip, 0x5208)) {
+                       RTSX_READ_REG(chip, 0xFE70, &tmp);
+                       if (tmp & 0x80)
+                               sw_bypass_sd = 1;
+               }
+       } else {
+               if (chip->sdio_in_charge)
+                       sw_bypass_sd = 1;
+       }
+       RTSX_DEBUGP("chip->sdio_in_charge = %d\n", chip->sdio_in_charge);
+       RTSX_DEBUGP("chip->driver_first_load = %d\n", chip->driver_first_load);
+       RTSX_DEBUGP("sw_bypass_sd = %d\n", sw_bypass_sd);
+
+       if (sw_bypass_sd) {
+               u8 cd_toggle_mask = 0;
+
+               RTSX_READ_REG(chip, TLPTISTAT, &tmp);
+               cd_toggle_mask = 0x08;
+
+               if (tmp & cd_toggle_mask) {
+                       /* Disable sdio_bus_auto_switch */
+                       if (CHECK_PID(chip, 0x5288))
+                               RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x00);
+                       else if (CHECK_PID(chip, 0x5208))
+                               RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x00);
+
+                       RTSX_WRITE_REG(chip, TLPTISTAT, 0xFF, tmp);
+
+                       chip->need_reset |= SD_CARD;
+               } else {
+                       RTSX_DEBUGP("Chip inserted with SDIO!\n");
+
+                       if (chip->asic_code) {
+                               retval = sd_pull_ctl_enable(chip);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+                       } else {
+                               RTSX_WRITE_REG(chip, FPGA_PULL_CTL,
+                                       FPGA_SD_PULL_CTL_BIT | 0x20, 0);
+                       }
+                       retval = card_share_mode(chip, SD_CARD);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       /* Enable sdio_bus_auto_switch */
+                       if (CHECK_PID(chip, 0x5288))
+                               RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x08);
+                       else if (CHECK_PID(chip, 0x5208))
+                               RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x80);
+
+                       chip->chip_insert_with_sdio = 1;
+                       chip->sd_io = 1;
+               }
+       } else {
+               RTSX_WRITE_REG(chip, TLPTISTAT, 0x08, 0x08);
+
+               chip->need_reset |= SD_CARD;
+       }
+
+       return STATUS_SUCCESS;
+}
+#endif
+
+int rtsx_reset_chip(struct rtsx_chip *chip)
+{
+       int retval;
+
+       rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr);
+
+       rtsx_disable_aspm(chip);
+
+       RTSX_WRITE_REG(chip, HOST_SLEEP_STATE, 0x03, 0x00);
+
+       /* Disable card clock */
+       RTSX_WRITE_REG(chip, CARD_CLK_EN, 0x1E, 0);
+
+#ifdef SUPPORT_OCP
+       /* SSC power on, OCD power on */
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
+               RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, 0);
+       else
+               RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, MS_OC_POWER_DOWN);
+
+       RTSX_WRITE_REG(chip, OCPPARA1, OCP_TIME_MASK, OCP_TIME_800);
+       RTSX_WRITE_REG(chip, OCPPARA2, OCP_THD_MASK, OCP_THD_244_946);
+       RTSX_WRITE_REG(chip, OCPCTL, 0xFF, CARD_OC_INT_EN | CARD_DETECT_EN);
+#else
+       /* OC power down */
+       RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, OC_POWER_DOWN);
+#endif
+
+       if (!CHECK_PID(chip, 0x5288))
+               RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0xFF, 0x03);
+
+       /* Turn off LED */
+       RTSX_WRITE_REG(chip, CARD_GPIO, 0xFF, 0x03);
+
+       /* Reset delink mode */
+       RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x0A, 0);
+
+       /* Card driving select */
+       RTSX_WRITE_REG(chip, CARD_DRIVE_SEL, 0xFF, chip->card_drive_sel);
+
+#ifdef LED_AUTO_BLINK
+       RTSX_WRITE_REG(chip, CARD_AUTO_BLINK, 0xFF,
+                       LED_BLINK_SPEED | BLINK_EN | LED_GPIO0);
+#endif
+
+       if (chip->asic_code) {
+               /* Enable SSC Clock */
+               RTSX_WRITE_REG(chip, SSC_CTL1, 0xFF, SSC_8X_EN | SSC_SEL_4M);
+               RTSX_WRITE_REG(chip, SSC_CTL2, 0xFF, 0x12);
+       }
+
+       /* Disable cd_pwr_save (u_force_rst_core_en=0, u_cd_rst_core_en=0)
+             0xFE5B
+             bit[1]    u_cd_rst_core_en        rst_value = 0
+             bit[2]    u_force_rst_core_en     rst_value = 0
+             bit[5]    u_mac_phy_rst_n_dbg     rst_value = 1
+             bit[4]    u_non_sticky_rst_n_dbg  rst_value = 0
+       */
+       RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x16, 0x10);
+
+       /* Enable ASPM */
+       if (chip->aspm_l0s_l1_en) {
+               if (chip->dynamic_aspm) {
+                       if (CHK_SDIO_EXIST(chip)) {
+                               if (CHECK_PID(chip, 0x5288)) {
+                                       retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en);
+                                       if (retval != STATUS_SUCCESS)
+                                               TRACE_RET(chip, STATUS_FAIL);
+                               }
+                       }
+               } else {
+                       if (CHECK_PID(chip, 0x5208))
+                               RTSX_WRITE_REG(chip, ASPM_FORCE_CTL,
+                                       0xFF, 0x3F);
+
+                       retval = rtsx_write_config_byte(chip, LCTLR,
+                                                       chip->aspm_l0s_l1_en);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       chip->aspm_level[0] = chip->aspm_l0s_l1_en;
+                       if (CHK_SDIO_EXIST(chip)) {
+                               chip->aspm_level[1] = chip->aspm_l0s_l1_en;
+                               if (CHECK_PID(chip, 0x5288))
+                                       retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en);
+                               else
+                                       retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en);
+
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                       }
+
+                       chip->aspm_enabled = 1;
+               }
+       } else {
+               if (chip->asic_code && CHECK_PID(chip, 0x5208)) {
+                       retval = rtsx_write_phy_register(chip, 0x07, 0x0129);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+               }
+               retval = rtsx_write_config_byte(chip, LCTLR,
+                                               chip->aspm_l0s_l1_en);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = rtsx_write_config_byte(chip, 0x81, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (CHK_SDIO_EXIST(chip)) {
+               if (CHECK_PID(chip, 0x5288))
+                       retval = rtsx_write_cfg_dw(chip, 2, 0xC0,
+                                               0xFF00, 0x0100);
+               else
+                       retval = rtsx_write_cfg_dw(chip, 1, 0xC0,
+                                               0xFF00, 0x0100);
+
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+       }
+
+       if (CHECK_PID(chip, 0x5288)) {
+               if (!CHK_SDIO_EXIST(chip)) {
+                       retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF,
+                                               0x0103);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+               }
+       }
+
+       RTSX_WRITE_REG(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT);
+
+       RTSX_WRITE_REG(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80);
+
+       /* Enable PCIE interrupt */
+       if (chip->asic_code) {
+               if (CHECK_PID(chip, 0x5208)) {
+                       if (chip->phy_debug_mode) {
+                               RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0);
+                               rtsx_disable_bus_int(chip);
+                       } else {
+                               rtsx_enable_bus_int(chip);
+                       }
+
+                       if (chip->ic_version >= IC_VER_D) {
+                               u16 reg;
+                               retval = rtsx_read_phy_register(chip, 0x00,
+                                                               &reg);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                               reg &= 0xFE7F;
+                               reg |= 0x80;
+                               retval = rtsx_write_phy_register(chip, 0x00,
+                                                               reg);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                               retval = rtsx_read_phy_register(chip, 0x1C,
+                                                               &reg);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                               reg &= 0xFFF7;
+                               retval = rtsx_write_phy_register(chip, 0x1C,
+                                                               reg);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                       }
+
+                       if (chip->driver_first_load &&
+                               (chip->ic_version < IC_VER_C))
+                               rtsx_calibration(chip);
+
+               } else {
+                       rtsx_enable_bus_int(chip);
+               }
+       } else {
+               rtsx_enable_bus_int(chip);
+       }
+
+       chip->need_reset = 0;
+
+       chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
+
+       if (chip->hw_bypass_sd)
+               goto NextCard;
+       RTSX_DEBUGP("In rtsx_reset_chip, chip->int_reg = 0x%x\n",
+               chip->int_reg);
+       if (chip->int_reg & SD_EXIST) {
+#ifdef HW_AUTO_SWITCH_SD_BUS
+               if (CHECK_PID(chip, 0x5208) && (chip->ic_version < IC_VER_C))
+                       retval = rtsx_pre_handle_sdio_old(chip);
+               else
+                       retval = rtsx_pre_handle_sdio_new(chip);
+
+               RTSX_DEBUGP("chip->need_reset = 0x%x (rtsx_reset_chip)\n",
+                       (unsigned int)(chip->need_reset));
+#else  /* HW_AUTO_SWITCH_SD_BUS */
+               retval = rtsx_pre_handle_sdio_old(chip);
+#endif  /* HW_AUTO_SWITCH_SD_BUS */
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+       } else {
+               chip->sd_io = 0;
+               RTSX_WRITE_REG(chip, SDIO_CTRL, SDIO_BUS_CTRL | SDIO_CD_CTRL,
+                       0);
+       }
+
+NextCard:
+       if (chip->int_reg & XD_EXIST)
+               chip->need_reset |= XD_CARD;
+       if (chip->int_reg & MS_EXIST)
+               chip->need_reset |= MS_CARD;
+       if (chip->int_reg & CARD_EXIST)
+               RTSX_WRITE_REG(chip, SSC_CTL1, SSC_RSTB, SSC_RSTB);
+
+       RTSX_DEBUGP("In rtsx_init_chip, chip->need_reset = 0x%x\n",
+               (unsigned int)(chip->need_reset));
+
+       RTSX_WRITE_REG(chip, RCCTL, 0x01, 0x00);
+
+       if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) {
+               /* Turn off main power when entering S3/S4 state */
+               RTSX_WRITE_REG(chip, MAIN_PWR_OFF_CTL, 0x03, 0x03);
+       }
+
+       if (chip->remote_wakeup_en && !chip->auto_delink_en) {
+               RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x07);
+               if (chip->aux_pwr_exist)
+                       RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x33);
+       } else {
+               RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x04);
+               RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x30);
+       }
+
+       if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D))
+               RTSX_WRITE_REG(chip, PETXCFG, 0x1C, 0x14);
+
+       if (chip->asic_code && CHECK_PID(chip, 0x5208)) {
+               retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (chip->ft2_fast_mode) {
+               RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF,
+                       MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON);
+               udelay(chip->pmos_pwr_on_interval);
+               RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF,
+                       MS_POWER_ON | SD_POWER_ON);
+
+               wait_timeout(200);
+       }
+
+       /* Reset card */
+       rtsx_reset_detected_cards(chip, 0);
+
+       chip->driver_first_load = 0;
+
+       return STATUS_SUCCESS;
+}
+
+static inline int check_sd_speed_prior(u32 sd_speed_prior)
+{
+       int i, fake_para = 0;
+
+       for (i = 0; i < 4; i++) {
+               u8 tmp = (u8)(sd_speed_prior >> (i*8));
+               if ((tmp < 0x01) || (tmp > 0x04)) {
+                       fake_para = 1;
+                       break;
+               }
+       }
+
+       return !fake_para;
+}
+
+static inline int check_sd_current_prior(u32 sd_current_prior)
+{
+       int i, fake_para = 0;
+
+       for (i = 0; i < 4; i++) {
+               u8 tmp = (u8)(sd_current_prior >> (i*8));
+               if (tmp > 0x03) {
+                       fake_para = 1;
+                       break;
+               }
+       }
+
+       return !fake_para;
+}
+
+static int rts5208_init(struct rtsx_chip *chip)
+{
+       int retval;
+       u16 reg = 0;
+       u8 val = 0;
+
+       RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03);
+       RTSX_READ_REG(chip, CLK_SEL, &val);
+       if (val == 0)
+               chip->asic_code = 1;
+       else
+               chip->asic_code = 0;
+
+       if (chip->asic_code) {
+               retval = rtsx_read_phy_register(chip, 0x1C, &reg);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               RTSX_DEBUGP("Value of phy register 0x1C is 0x%x\n", reg);
+               chip->ic_version = (reg >> 4) & 0x07;
+               if (reg & PHY_DEBUG_MODE)
+                       chip->phy_debug_mode = 1;
+               else
+                       chip->phy_debug_mode = 0;
+
+       } else {
+               RTSX_READ_REG(chip, 0xFE80, &val);
+               chip->ic_version = val;
+               chip->phy_debug_mode = 0;
+       }
+
+       RTSX_READ_REG(chip, PDINFO, &val);
+       RTSX_DEBUGP("PDINFO: 0x%x\n", val);
+       if (val & AUX_PWR_DETECTED)
+               chip->aux_pwr_exist = 1;
+       else
+               chip->aux_pwr_exist = 0;
+
+       RTSX_READ_REG(chip, 0xFE50, &val);
+       if (val & 0x01)
+               chip->hw_bypass_sd = 1;
+       else
+               chip->hw_bypass_sd = 0;
+
+       rtsx_read_config_byte(chip, 0x0E, &val);
+       if (val & 0x80)
+               SET_SDIO_EXIST(chip);
+       else
+               CLR_SDIO_EXIST(chip);
+
+       if (chip->use_hw_setting) {
+               RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val);
+               if (val & 0x80)
+                       chip->auto_delink_en = 1;
+               else
+                       chip->auto_delink_en = 0;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int rts5288_init(struct rtsx_chip *chip)
+{
+       int retval;
+       u8 val = 0, max_func;
+       u32 lval = 0;
+
+       RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03);
+       RTSX_READ_REG(chip, CLK_SEL, &val);
+       if (val == 0)
+               chip->asic_code = 1;
+       else
+               chip->asic_code = 0;
+
+       chip->ic_version = 0;
+       chip->phy_debug_mode = 0;
+
+       RTSX_READ_REG(chip, PDINFO, &val);
+       RTSX_DEBUGP("PDINFO: 0x%x\n", val);
+       if (val & AUX_PWR_DETECTED)
+               chip->aux_pwr_exist = 1;
+       else
+               chip->aux_pwr_exist = 0;
+
+       RTSX_READ_REG(chip, CARD_SHARE_MODE, &val);
+       RTSX_DEBUGP("CARD_SHARE_MODE: 0x%x\n", val);
+       if (val & 0x04)
+               chip->baro_pkg = QFN;
+       else
+               chip->baro_pkg = LQFP;
+
+       RTSX_READ_REG(chip, 0xFE5A, &val);
+       if (val & 0x10)
+               chip->hw_bypass_sd = 1;
+       else
+               chip->hw_bypass_sd = 0;
+
+       retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       max_func = (u8)((lval >> 29) & 0x07);
+       RTSX_DEBUGP("Max function number: %d\n", max_func);
+       if (max_func == 0x02)
+               SET_SDIO_EXIST(chip);
+       else
+               CLR_SDIO_EXIST(chip);
+
+       if (chip->use_hw_setting) {
+               RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val);
+               if (val & 0x80)
+                       chip->auto_delink_en = 1;
+               else
+                       chip->auto_delink_en = 0;
+
+               if (CHECK_BARO_PKG(chip, LQFP))
+                       chip->lun_mode = SD_MS_1LUN;
+               else
+                       chip->lun_mode = DEFAULT_SINGLE;
+
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_init_chip(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       struct xd_info *xd_card = &(chip->xd_card);
+       struct ms_info *ms_card = &(chip->ms_card);
+       int retval;
+       unsigned int i;
+
+       RTSX_DEBUGP("Vendor ID: 0x%04x, Product ID: 0x%04x\n",
+                    chip->vendor_id, chip->product_id);
+
+       chip->ic_version = 0;
+
+#ifdef _MSG_TRACE
+       chip->msg_idx = 0;
+#endif
+
+       memset(xd_card, 0, sizeof(struct xd_info));
+       memset(sd_card, 0, sizeof(struct sd_info));
+       memset(ms_card, 0, sizeof(struct ms_info));
+
+       chip->xd_reset_counter = 0;
+       chip->sd_reset_counter = 0;
+       chip->ms_reset_counter = 0;
+
+       chip->xd_show_cnt = MAX_SHOW_CNT;
+       chip->sd_show_cnt = MAX_SHOW_CNT;
+       chip->ms_show_cnt = MAX_SHOW_CNT;
+
+       chip->sd_io = 0;
+       chip->auto_delink_cnt = 0;
+       chip->auto_delink_allowed = 1;
+       rtsx_set_stat(chip, RTSX_STAT_INIT);
+
+       chip->aspm_enabled = 0;
+       chip->chip_insert_with_sdio = 0;
+       chip->sdio_aspm = 0;
+       chip->sdio_idle = 0;
+       chip->sdio_counter = 0;
+       chip->cur_card = 0;
+       chip->phy_debug_mode = 0;
+       chip->sdio_func_exist = 0;
+       memset(chip->sdio_raw_data, 0, 12);
+
+       for (i = 0; i < MAX_ALLOWED_LUN_CNT; i++) {
+               set_sense_type(chip, i, SENSE_TYPE_NO_SENSE);
+               chip->rw_fail_cnt[i] = 0;
+       }
+
+       if (!check_sd_speed_prior(chip->sd_speed_prior))
+               chip->sd_speed_prior = 0x01040203;
+
+       RTSX_DEBUGP("sd_speed_prior = 0x%08x\n", chip->sd_speed_prior);
+
+       if (!check_sd_current_prior(chip->sd_current_prior))
+               chip->sd_current_prior = 0x00010203;
+
+       RTSX_DEBUGP("sd_current_prior = 0x%08x\n", chip->sd_current_prior);
+
+       if ((chip->sd_ddr_tx_phase > 31) || (chip->sd_ddr_tx_phase < 0))
+               chip->sd_ddr_tx_phase = 0;
+
+       if ((chip->mmc_ddr_tx_phase > 31) || (chip->mmc_ddr_tx_phase < 0))
+               chip->mmc_ddr_tx_phase = 0;
+
+       RTSX_WRITE_REG(chip, FPDCTL, SSC_POWER_DOWN, 0);
+       wait_timeout(200);
+       RTSX_WRITE_REG(chip, CLK_DIV, 0x07, 0x07);
+       RTSX_DEBUGP("chip->use_hw_setting = %d\n", chip->use_hw_setting);
+
+       if (CHECK_PID(chip, 0x5208)) {
+               retval = rts5208_init(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+       } else if (CHECK_PID(chip, 0x5288)) {
+               retval = rts5288_init(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+       }
+
+       if (chip->ss_en == 2)
+               chip->ss_en = 0;
+
+       RTSX_DEBUGP("chip->asic_code = %d\n", chip->asic_code);
+       RTSX_DEBUGP("chip->ic_version = 0x%x\n", chip->ic_version);
+       RTSX_DEBUGP("chip->phy_debug_mode = %d\n", chip->phy_debug_mode);
+       RTSX_DEBUGP("chip->aux_pwr_exist = %d\n", chip->aux_pwr_exist);
+       RTSX_DEBUGP("chip->sdio_func_exist = %d\n", chip->sdio_func_exist);
+       RTSX_DEBUGP("chip->hw_bypass_sd = %d\n", chip->hw_bypass_sd);
+       RTSX_DEBUGP("chip->aspm_l0s_l1_en = %d\n", chip->aspm_l0s_l1_en);
+       RTSX_DEBUGP("chip->lun_mode = %d\n", chip->lun_mode);
+       RTSX_DEBUGP("chip->auto_delink_en = %d\n", chip->auto_delink_en);
+       RTSX_DEBUGP("chip->ss_en = %d\n", chip->ss_en);
+       RTSX_DEBUGP("chip->baro_pkg = %d\n", chip->baro_pkg);
+
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
+               chip->card2lun[SD_CARD] = 0;
+               chip->card2lun[MS_CARD] = 1;
+               chip->card2lun[XD_CARD] = 0xFF;
+               chip->lun2card[0] = SD_CARD;
+               chip->lun2card[1] = MS_CARD;
+               chip->max_lun = 1;
+               SET_SDIO_IGNORED(chip);
+       } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) {
+               chip->card2lun[SD_CARD] = 0;
+               chip->card2lun[MS_CARD] = 0;
+               chip->card2lun[XD_CARD] = 0xFF;
+               chip->lun2card[0] = SD_CARD | MS_CARD;
+               chip->max_lun = 0;
+       } else {
+               chip->card2lun[XD_CARD] = 0;
+               chip->card2lun[SD_CARD] = 0;
+               chip->card2lun[MS_CARD] = 0;
+               chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD;
+               chip->max_lun = 0;
+       }
+
+       retval = rtsx_reset_chip(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+void rtsx_release_chip(struct rtsx_chip *chip)
+{
+       xd_free_l2p_tbl(chip);
+       ms_free_l2p_tbl(chip);
+       chip->card_exist = 0;
+       chip->card_ready = 0;
+}
+
+#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK)
+static inline void rtsx_blink_led(struct rtsx_chip *chip)
+{
+       if (chip->card_exist && chip->blink_led) {
+               if (chip->led_toggle_counter < LED_TOGGLE_INTERVAL) {
+                       chip->led_toggle_counter++;
+               } else {
+                       chip->led_toggle_counter = 0;
+                       toggle_gpio(chip, LED_GPIO);
+               }
+       }
+}
+#endif
+
+static void rtsx_monitor_aspm_config(struct rtsx_chip *chip)
+{
+       int maybe_support_aspm, reg_changed;
+       u32 tmp = 0;
+       u8 reg0 = 0, reg1 = 0;
+
+       maybe_support_aspm = 0;
+       reg_changed = 0;
+       rtsx_read_config_byte(chip, LCTLR, &reg0);
+       if (chip->aspm_level[0] != reg0) {
+               reg_changed = 1;
+               chip->aspm_level[0] = reg0;
+       }
+       if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) {
+               rtsx_read_cfg_dw(chip, 1, 0xC0, &tmp);
+               reg1 = (u8)tmp;
+               if (chip->aspm_level[1] != reg1) {
+                       reg_changed = 1;
+                       chip->aspm_level[1] = reg1;
+               }
+
+               if ((reg0 & 0x03) && (reg1 & 0x03))
+                       maybe_support_aspm = 1;
+
+       } else {
+               if (reg0 & 0x03)
+                       maybe_support_aspm = 1;
+
+       }
+
+       if (reg_changed) {
+               if (maybe_support_aspm)
+                       chip->aspm_l0s_l1_en = 0x03;
+
+               RTSX_DEBUGP("aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n",
+                             chip->aspm_level[0], chip->aspm_level[1]);
+
+               if (chip->aspm_l0s_l1_en) {
+                       chip->aspm_enabled = 1;
+               } else {
+                       chip->aspm_enabled = 0;
+                       chip->sdio_aspm = 0;
+               }
+               rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF,
+                               0x30 | chip->aspm_level[0] |
+                               (chip->aspm_level[1] << 2));
+       }
+}
+
+void rtsx_polling_func(struct rtsx_chip *chip)
+{
+#ifdef SUPPORT_SD_LOCK
+       struct sd_info *sd_card = &(chip->sd_card);
+#endif
+       int ss_allowed;
+
+       if (rtsx_chk_stat(chip, RTSX_STAT_SUSPEND))
+               return;
+
+       if (rtsx_chk_stat(chip, RTSX_STAT_DELINK))
+               goto Delink_Stage;
+
+       if (chip->polling_config) {
+               u8 val;
+               rtsx_read_config_byte(chip, 0, &val);
+       }
+
+       if (rtsx_chk_stat(chip, RTSX_STAT_SS))
+               return;
+
+#ifdef SUPPORT_OCP
+       if (chip->ocp_int) {
+               rtsx_read_register(chip, OCPSTAT, &(chip->ocp_stat));
+
+               if (chip->card_exist & SD_CARD)
+                       sd_power_off_card3v3(chip);
+               else if (chip->card_exist & MS_CARD)
+                       ms_power_off_card3v3(chip);
+               else if (chip->card_exist & XD_CARD)
+                       xd_power_off_card3v3(chip);
+
+               chip->ocp_int = 0;
+       }
+#endif
+
+#ifdef SUPPORT_SD_LOCK
+       if (sd_card->sd_erase_status) {
+               if (chip->card_exist & SD_CARD) {
+                       u8 val;
+                       rtsx_read_register(chip, 0xFD30, &val);
+                       if (val & 0x02) {
+                               sd_card->sd_erase_status = SD_NOT_ERASE;
+                               sd_card->sd_lock_notify = 1;
+                               chip->need_reinit |= SD_CARD;
+                       }
+               } else {
+                       sd_card->sd_erase_status = SD_NOT_ERASE;
+               }
+       }
+#endif
+
+       rtsx_init_cards(chip);
+
+       if (chip->ss_en) {
+               ss_allowed = 1;
+
+               if (CHECK_PID(chip, 0x5288)) {
+                       ss_allowed = 0;
+               } else {
+                       if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) {
+                               u32 val;
+                               rtsx_read_cfg_dw(chip, 1, 0x04, &val);
+                               if (val & 0x07)
+                                       ss_allowed = 0;
+
+                       }
+               }
+       } else {
+               ss_allowed = 0;
+       }
+
+       if (ss_allowed && !chip->sd_io) {
+               if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) {
+                       chip->ss_counter = 0;
+               } else {
+                       if (chip->ss_counter <
+                               (chip->ss_idle_period / POLLING_INTERVAL)) {
+                               chip->ss_counter++;
+                       } else {
+                               rtsx_exclusive_enter_ss(chip);
+                               return;
+                       }
+               }
+       }
+
+       if (CHECK_PID(chip, 0x5208)) {
+               rtsx_monitor_aspm_config(chip);
+
+#ifdef SUPPORT_SDIO_ASPM
+               if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) &&
+                               chip->aspm_l0s_l1_en && chip->dynamic_aspm) {
+                       if (chip->sd_io) {
+                               dynamic_configure_sdio_aspm(chip);
+                       } else {
+                               if (!chip->sdio_aspm) {
+                                       RTSX_DEBUGP("SDIO enter ASPM!\n");
+                                       rtsx_write_register(chip,
+                                               ASPM_FORCE_CTL, 0xFC,
+                                               0x30 | (chip->aspm_level[1] << 2));
+                                       chip->sdio_aspm = 1;
+                               }
+                       }
+               }
+#endif
+       }
+
+       if (chip->idle_counter < IDLE_MAX_COUNT) {
+               chip->idle_counter++;
+       } else {
+               if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) {
+                       RTSX_DEBUGP("Idle state!\n");
+                       rtsx_set_stat(chip, RTSX_STAT_IDLE);
+
+#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK)
+                       chip->led_toggle_counter = 0;
+#endif
+                       rtsx_force_power_on(chip, SSC_PDCTL);
+
+                       turn_off_led(chip, LED_GPIO);
+
+                       if (chip->auto_power_down && !chip->card_ready && !chip->sd_io)
+                               rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL);
+
+               }
+       }
+
+       switch (rtsx_get_stat(chip)) {
+       case RTSX_STAT_RUN:
+#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK)
+               rtsx_blink_led(chip);
+#endif
+               do_remaining_work(chip);
+               break;
+
+       case RTSX_STAT_IDLE:
+               if (chip->sd_io && !chip->sd_int)
+                       try_to_switch_sdio_ctrl(chip);
+
+               rtsx_enable_aspm(chip);
+               break;
+
+       default:
+               break;
+       }
+
+
+#ifdef SUPPORT_OCP
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
+#ifdef CONFIG_RTS5208_DEBUG
+               if (chip->ocp_stat &
+                       (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER))
+                       RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
+                               chip->ocp_stat);
+#endif
+
+               if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
+                       if (chip->card_exist & SD_CARD) {
+                               rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN,
+                                               0);
+                               card_power_off(chip, SD_CARD);
+                               chip->card_fail |= SD_CARD;
+                       }
+               }
+               if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) {
+                       if (chip->card_exist & MS_CARD) {
+                               rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN,
+                                               0);
+                               card_power_off(chip, MS_CARD);
+                               chip->card_fail |= MS_CARD;
+                       }
+               }
+       } else {
+               if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
+                       RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
+                               chip->ocp_stat);
+                       if (chip->card_exist & SD_CARD) {
+                               rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN,
+                                               0);
+                               chip->card_fail |= SD_CARD;
+                       } else if (chip->card_exist & MS_CARD) {
+                               rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN,
+                                               0);
+                               chip->card_fail |= MS_CARD;
+                       } else if (chip->card_exist & XD_CARD) {
+                               rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN,
+                                               0);
+                               chip->card_fail |= XD_CARD;
+                       }
+                       card_power_off(chip, SD_CARD);
+               }
+       }
+#endif
+
+Delink_Stage:
+       if (chip->auto_delink_en && chip->auto_delink_allowed &&
+               !chip->card_ready && !chip->card_ejected && !chip->sd_io) {
+               int enter_L1 = chip->auto_delink_in_L1 && (
+                       chip->aspm_l0s_l1_en || chip->ss_en);
+               int delink_stage1_cnt = chip->delink_stage1_step;
+               int delink_stage2_cnt = delink_stage1_cnt +
+                       chip->delink_stage2_step;
+               int delink_stage3_cnt = delink_stage2_cnt +
+                       chip->delink_stage3_step;
+
+               if (chip->auto_delink_cnt <= delink_stage3_cnt) {
+                       if (chip->auto_delink_cnt == delink_stage1_cnt) {
+                               rtsx_set_stat(chip, RTSX_STAT_DELINK);
+
+                               if (chip->asic_code && CHECK_PID(chip, 0x5208))
+                                       rtsx_set_phy_reg_bit(chip, 0x1C, 2);
+
+                               if (chip->card_exist) {
+                                       RTSX_DEBUGP("False card inserted, do force delink\n");
+
+                                       if (enter_L1)
+                                               rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1);
+
+                                       rtsx_write_register(chip,
+                                                       CHANGE_LINK_STATE, 0x0A,
+                                                       0x0A);
+
+                                       if (enter_L1)
+                                               rtsx_enter_L1(chip);
+
+                                       chip->auto_delink_cnt = delink_stage3_cnt + 1;
+                               } else {
+                                       RTSX_DEBUGP("No card inserted, do delink\n");
+
+                                       if (enter_L1)
+                                               rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1);
+
+                                       rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0x02);
+
+                                       if (enter_L1)
+                                               rtsx_enter_L1(chip);
+
+                               }
+                       }
+
+                       if (chip->auto_delink_cnt == delink_stage2_cnt) {
+                               RTSX_DEBUGP("Try to do force delink\n");
+
+                               if (enter_L1)
+                                       rtsx_exit_L1(chip);
+
+                               if (chip->asic_code && CHECK_PID(chip, 0x5208))
+                                       rtsx_set_phy_reg_bit(chip, 0x1C, 2);
+
+                               rtsx_write_register(chip, CHANGE_LINK_STATE,
+                                               0x0A, 0x0A);
+                       }
+
+                       chip->auto_delink_cnt++;
+               }
+       } else {
+               chip->auto_delink_cnt = 0;
+       }
+}
+
+void rtsx_undo_delink(struct rtsx_chip *chip)
+{
+       chip->auto_delink_allowed = 0;
+       rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x00);
+}
+
+/**
+ * rtsx_stop_cmd - stop command transfer and DMA transfer
+ * @chip: Realtek's card reader chip
+ * @card: flash card type
+ *
+ * Stop command transfer and DMA transfer.
+ * This function is called in error handler.
+ */
+void rtsx_stop_cmd(struct rtsx_chip *chip, int card)
+{
+       int i;
+
+       for (i = 0; i <= 8; i++) {
+               int addr = RTSX_HCBAR + i * 4;
+               u32 reg;
+               reg = rtsx_readl(chip, addr);
+               RTSX_DEBUGP("BAR (0x%02x): 0x%08x\n", addr, reg);
+       }
+       rtsx_writel(chip, RTSX_HCBCTLR, STOP_CMD);
+       rtsx_writel(chip, RTSX_HDBCTLR, STOP_DMA);
+
+       for (i = 0; i < 16; i++) {
+               u16 addr = 0xFE20 + (u16)i;
+               u8 val;
+               rtsx_read_register(chip, addr, &val);
+               RTSX_DEBUGP("0x%04X: 0x%02x\n", addr, val);
+       }
+
+       rtsx_write_register(chip, DMACTL, 0x80, 0x80);
+       rtsx_write_register(chip, RBCTL, 0x80, 0x80);
+}
+
+#define MAX_RW_REG_CNT         1024
+
+int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data)
+{
+       int i;
+       u32 val = 3 << 30;
+
+       val |= (u32)(addr & 0x3FFF) << 16;
+       val |= (u32)mask << 8;
+       val |= (u32)data;
+
+       rtsx_writel(chip, RTSX_HAIMR, val);
+
+       for (i = 0; i < MAX_RW_REG_CNT; i++) {
+               val = rtsx_readl(chip, RTSX_HAIMR);
+               if ((val & (1 << 31)) == 0) {
+                       if (data != (u8)val)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       return STATUS_SUCCESS;
+               }
+       }
+
+       TRACE_RET(chip, STATUS_TIMEDOUT);
+}
+
+int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data)
+{
+       u32 val = 2 << 30;
+       int i;
+
+       if (data)
+               *data = 0;
+
+       val |= (u32)(addr & 0x3FFF) << 16;
+
+       rtsx_writel(chip, RTSX_HAIMR, val);
+
+       for (i = 0; i < MAX_RW_REG_CNT; i++) {
+               val = rtsx_readl(chip, RTSX_HAIMR);
+               if ((val & (1 << 31)) == 0)
+                       break;
+       }
+
+       if (i >= MAX_RW_REG_CNT)
+               TRACE_RET(chip, STATUS_TIMEDOUT);
+
+       if (data)
+               *data = (u8)(val & 0xFF);
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask,
+               u32 val)
+{
+       u8 mode = 0, tmp;
+       int i;
+
+       for (i = 0; i < 4; i++) {
+               if (mask & 0xFF) {
+                       RTSX_WRITE_REG(chip, CFGDATA0 + i,
+                                      0xFF, (u8)(val & mask & 0xFF));
+                       mode |= (1 << i);
+               }
+               mask >>= 8;
+               val >>= 8;
+       }
+
+       if (mode) {
+               RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr);
+               RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8));
+
+               RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF,
+                              0x80 | mode | ((func_no & 0x03) << 4));
+
+               for (i = 0; i < MAX_RW_REG_CNT; i++) {
+                       RTSX_READ_REG(chip, CFGRWCTL, &tmp);
+                       if ((tmp & 0x80) == 0)
+                               break;
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val)
+{
+       int i;
+       u8 tmp;
+       u32 data = 0;
+
+       RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr);
+       RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8));
+       RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF, 0x80 | ((func_no & 0x03) << 4));
+
+       for (i = 0; i < MAX_RW_REG_CNT; i++) {
+               RTSX_READ_REG(chip, CFGRWCTL, &tmp);
+               if ((tmp & 0x80) == 0)
+                       break;
+       }
+
+       for (i = 0; i < 4; i++) {
+               RTSX_READ_REG(chip, CFGDATA0 + i, &tmp);
+               data |= (u32)tmp << (i * 8);
+       }
+
+       if (val)
+               *val = data;
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf,
+               int len)
+{
+       u32 *data, *mask;
+       u16 offset = addr % 4;
+       u16 aligned_addr = addr - offset;
+       int dw_len, i, j;
+       int retval;
+
+       RTSX_DEBUGP("%s\n", __func__);
+
+       if (!buf)
+               TRACE_RET(chip, STATUS_NOMEM);
+
+       if ((len + offset) % 4)
+               dw_len = (len + offset) / 4 + 1;
+       else
+               dw_len = (len + offset) / 4;
+
+       RTSX_DEBUGP("dw_len = %d\n", dw_len);
+
+       data = vzalloc(dw_len * 4);
+       if (!data)
+               TRACE_RET(chip, STATUS_NOMEM);
+
+       mask = vzalloc(dw_len * 4);
+       if (!mask) {
+               vfree(data);
+               TRACE_RET(chip, STATUS_NOMEM);
+       }
+
+       j = 0;
+       for (i = 0; i < len; i++) {
+               mask[j] |= 0xFF << (offset * 8);
+               data[j] |= buf[i] << (offset * 8);
+               if (++offset == 4) {
+                       j++;
+                       offset = 0;
+               }
+       }
+
+       RTSX_DUMP(mask, dw_len * 4);
+       RTSX_DUMP(data, dw_len * 4);
+
+       for (i = 0; i < dw_len; i++) {
+               retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4,
+                                       mask[i], data[i]);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(data);
+                       vfree(mask);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       vfree(data);
+       vfree(mask);
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf,
+               int len)
+{
+       u32 *data;
+       u16 offset = addr % 4;
+       u16 aligned_addr = addr - offset;
+       int dw_len, i, j;
+       int retval;
+
+       RTSX_DEBUGP("%s\n", __func__);
+
+       if ((len + offset) % 4)
+               dw_len = (len + offset) / 4 + 1;
+       else
+               dw_len = (len + offset) / 4;
+
+       RTSX_DEBUGP("dw_len = %d\n", dw_len);
+
+       data = vmalloc(dw_len * 4);
+       if (!data)
+               TRACE_RET(chip, STATUS_NOMEM);
+
+       for (i = 0; i < dw_len; i++) {
+               retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4,
+                                       data + i);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(data);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       if (buf) {
+               j = 0;
+
+               for (i = 0; i < len; i++) {
+                       buf[i] = (u8)(data[j] >> (offset * 8));
+                       if (++offset == 4) {
+                               j++;
+                               offset = 0;
+                       }
+               }
+       }
+
+       vfree(data);
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val)
+{
+       int i, finished = 0;
+       u8 tmp;
+
+       RTSX_WRITE_REG(chip, PHYDATA0, 0xFF, (u8)val);
+       RTSX_WRITE_REG(chip, PHYDATA1, 0xFF, (u8)(val >> 8));
+       RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr);
+       RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x81);
+
+       for (i = 0; i < 100000; i++) {
+               RTSX_READ_REG(chip, PHYRWCTL, &tmp);
+               if (!(tmp & 0x80)) {
+                       finished = 1;
+                       break;
+               }
+       }
+
+       if (!finished)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val)
+{
+       int i, finished = 0;
+       u16 data = 0;
+       u8 tmp;
+
+       RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr);
+       RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x80);
+
+       for (i = 0; i < 100000; i++) {
+               RTSX_READ_REG(chip, PHYRWCTL, &tmp);
+               if (!(tmp & 0x80)) {
+                       finished = 1;
+                       break;
+               }
+       }
+
+       if (!finished)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_READ_REG(chip, PHYDATA0, &tmp);
+       data = tmp;
+       RTSX_READ_REG(chip, PHYDATA1, &tmp);
+       data |= (u16)tmp << 8;
+
+       if (val)
+               *val = data;
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val)
+{
+       int i;
+       u8 data = 0;
+
+       RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0x80|addr);
+
+       for (i = 0; i < 100; i++) {
+               RTSX_READ_REG(chip, EFUSE_CTRL, &data);
+               if (!(data & 0x80))
+                       break;
+               udelay(1);
+       }
+
+       if (data & 0x80)
+               TRACE_RET(chip, STATUS_TIMEDOUT);
+
+       RTSX_READ_REG(chip, EFUSE_DATA, &data);
+       if (val)
+               *val = data;
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val)
+{
+       int i, j;
+       u8 data = 0, tmp = 0xFF;
+
+       for (i = 0; i < 8; i++) {
+               if (val & (u8)(1 << i))
+                       continue;
+
+               tmp &= (~(u8)(1 << i));
+               RTSX_DEBUGP("Write 0x%x to 0x%x\n", tmp, addr);
+
+               RTSX_WRITE_REG(chip, EFUSE_DATA, 0xFF, tmp);
+               RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0xA0|addr);
+
+               for (j = 0; j < 100; j++) {
+                       RTSX_READ_REG(chip, EFUSE_CTRL, &data);
+                       if (!(data & 0x80))
+                               break;
+                       wait_timeout(3);
+               }
+
+               if (data & 0x80)
+                       TRACE_RET(chip, STATUS_TIMEDOUT);
+
+               wait_timeout(5);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit)
+{
+       int retval;
+       u16 value;
+
+       retval = rtsx_read_phy_register(chip, reg, &value);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (value & (1 << bit)) {
+               value &= ~(1 << bit);
+               retval = rtsx_write_phy_register(chip, reg, value);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit)
+{
+       int retval;
+       u16 value;
+
+       retval = rtsx_read_phy_register(chip, reg, &value);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (0 == (value & (1 << bit))) {
+               value |= (1 << bit);
+               retval = rtsx_write_phy_register(chip, reg, value);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_check_link_ready(struct rtsx_chip *chip)
+{
+       u8 val;
+
+       RTSX_READ_REG(chip, IRQSTAT0, &val);
+
+       RTSX_DEBUGP("IRQSTAT0: 0x%x\n", val);
+       if (val & LINK_RDY_INT) {
+               RTSX_DEBUGP("Delinked!\n");
+               rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT);
+               return STATUS_FAIL;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate)
+{
+       u32 ultmp;
+
+       RTSX_DEBUGP("%04x set pm_dstate to %d\n", chip->product_id, dstate);
+
+       if (CHK_SDIO_EXIST(chip)) {
+               u8 func_no;
+
+               if (CHECK_PID(chip, 0x5288))
+                       func_no = 2;
+               else
+                       func_no = 1;
+
+               rtsx_read_cfg_dw(chip, func_no, 0x84, &ultmp);
+               RTSX_DEBUGP("pm_dstate of function %d: 0x%x\n", (int)func_no,
+                       ultmp);
+               rtsx_write_cfg_dw(chip, func_no, 0x84, 0xFF, dstate);
+       }
+
+       rtsx_write_config_byte(chip, 0x44, dstate);
+       rtsx_write_config_byte(chip, 0x45, 0);
+}
+
+void rtsx_enter_L1(struct rtsx_chip *chip)
+{
+       rtsx_handle_pm_dstate(chip, 2);
+}
+
+void rtsx_exit_L1(struct rtsx_chip *chip)
+{
+       rtsx_write_config_byte(chip, 0x44, 0);
+       rtsx_write_config_byte(chip, 0x45, 0);
+}
+
+void rtsx_enter_ss(struct rtsx_chip *chip)
+{
+       RTSX_DEBUGP("Enter Selective Suspend State!\n");
+
+       rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT);
+
+       if (chip->power_down_in_ss) {
+               rtsx_power_off_card(chip);
+               rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL);
+       }
+
+       if (CHK_SDIO_EXIST(chip)) {
+               if (CHECK_PID(chip, 0x5288))
+                       rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100);
+               else
+                       rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100);
+       }
+
+       if (chip->auto_delink_en) {
+               rtsx_write_register(chip, HOST_SLEEP_STATE, 0x01, 0x01);
+       } else {
+               if (!chip->phy_debug_mode) {
+                       u32 tmp;
+                       tmp = rtsx_readl(chip, RTSX_BIER);
+                       tmp |= CARD_INT;
+                       rtsx_writel(chip, RTSX_BIER, tmp);
+               }
+
+               rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0);
+       }
+
+       rtsx_enter_L1(chip);
+
+       RTSX_CLR_DELINK(chip);
+       rtsx_set_stat(chip, RTSX_STAT_SS);
+}
+
+void rtsx_exit_ss(struct rtsx_chip *chip)
+{
+       RTSX_DEBUGP("Exit Selective Suspend State!\n");
+
+       rtsx_exit_L1(chip);
+
+       if (chip->power_down_in_ss) {
+               rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);
+               udelay(1000);
+       }
+
+       if (RTSX_TST_DELINK(chip)) {
+               chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
+               rtsx_reinit_cards(chip, 1);
+               RTSX_CLR_DELINK(chip);
+       } else if (chip->power_down_in_ss) {
+               chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
+               rtsx_reinit_cards(chip, 0);
+       }
+}
+
+int rtsx_pre_handle_interrupt(struct rtsx_chip *chip)
+{
+       u32 status, int_enable;
+       int exit_ss = 0;
+#ifdef SUPPORT_OCP
+       u32 ocp_int = 0;
+
+       ocp_int = OC_INT;
+#endif
+
+       if (chip->ss_en) {
+               chip->ss_counter = 0;
+               if (rtsx_get_stat(chip) == RTSX_STAT_SS) {
+                       exit_ss = 1;
+                       rtsx_exit_L1(chip);
+                       rtsx_set_stat(chip, RTSX_STAT_RUN);
+               }
+       }
+
+       int_enable = rtsx_readl(chip, RTSX_BIER);
+       chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
+
+       if (((chip->int_reg & int_enable) == 0) ||
+               (chip->int_reg == 0xFFFFFFFF))
+               return STATUS_FAIL;
+
+       status = chip->int_reg &= (int_enable | 0x7FFFFF);
+
+       if (status & CARD_INT) {
+               chip->auto_delink_cnt = 0;
+
+               if (status & SD_INT) {
+                       if (status & SD_EXIST) {
+                               set_bit(SD_NR, &(chip->need_reset));
+                       } else {
+                               set_bit(SD_NR, &(chip->need_release));
+                               chip->sd_reset_counter = 0;
+                               chip->sd_show_cnt = 0;
+                               clear_bit(SD_NR, &(chip->need_reset));
+                       }
+               } else {
+                       /* If multi-luns, it's possible that
+                          when plugging/unplugging one card
+                          there is another card which still
+                          exists in the slot. In this case,
+                          all existed cards should be reset.
+                       */
+                       if (exit_ss && (status & SD_EXIST))
+                               set_bit(SD_NR, &(chip->need_reinit));
+               }
+               if (!CHECK_PID(chip, 0x5288) || CHECK_BARO_PKG(chip, QFN)) {
+                       if (status & XD_INT) {
+                               if (status & XD_EXIST) {
+                                       set_bit(XD_NR, &(chip->need_reset));
+                               } else {
+                                       set_bit(XD_NR, &(chip->need_release));
+                                       chip->xd_reset_counter = 0;
+                                       chip->xd_show_cnt = 0;
+                                       clear_bit(XD_NR, &(chip->need_reset));
+                               }
+                       } else {
+                               if (exit_ss && (status & XD_EXIST))
+                                       set_bit(XD_NR, &(chip->need_reinit));
+                       }
+               }
+               if (status & MS_INT) {
+                       if (status & MS_EXIST) {
+                               set_bit(MS_NR, &(chip->need_reset));
+                       } else {
+                               set_bit(MS_NR, &(chip->need_release));
+                               chip->ms_reset_counter = 0;
+                               chip->ms_show_cnt = 0;
+                               clear_bit(MS_NR, &(chip->need_reset));
+                       }
+               } else {
+                       if (exit_ss && (status & MS_EXIST))
+                               set_bit(MS_NR, &(chip->need_reinit));
+               }
+       }
+
+#ifdef SUPPORT_OCP
+       chip->ocp_int = ocp_int & status;
+#endif
+
+       if (chip->sd_io) {
+               if (chip->int_reg & DATA_DONE_INT)
+                       chip->int_reg &= ~(u32)DATA_DONE_INT;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat)
+{
+       int retval;
+
+       RTSX_DEBUGP("rtsx_do_before_power_down, pm_stat = %d\n", pm_stat);
+
+       rtsx_set_stat(chip, RTSX_STAT_SUSPEND);
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS)
+               return;
+
+       rtsx_release_cards(chip);
+       rtsx_disable_bus_int(chip);
+       turn_off_led(chip, LED_GPIO);
+
+#ifdef HW_AUTO_SWITCH_SD_BUS
+       if (chip->sd_io) {
+               chip->sdio_in_charge = 1;
+               if (CHECK_PID(chip, 0x5208)) {
+                       rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08);
+                       /* Enable sdio_bus_auto_switch */
+                       rtsx_write_register(chip, 0xFE70, 0x80, 0x80);
+               } else if (CHECK_PID(chip, 0x5288)) {
+                       rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08);
+                       /* Enable sdio_bus_auto_switch */
+                       rtsx_write_register(chip, 0xFE5A, 0x08, 0x08);
+               }
+       }
+#endif
+
+       if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) {
+               /* u_force_clkreq_0 */
+               rtsx_write_register(chip, PETXCFG, 0x08, 0x08);
+       }
+
+       if (pm_stat == PM_S1) {
+               RTSX_DEBUGP("Host enter S1\n");
+               rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03,
+                               HOST_ENTER_S1);
+       } else if (pm_stat == PM_S3) {
+               if (chip->s3_pwr_off_delay > 0)
+                       wait_timeout(chip->s3_pwr_off_delay);
+
+               RTSX_DEBUGP("Host enter S3\n");
+               rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03,
+                               HOST_ENTER_S3);
+       }
+
+       if (chip->do_delink_before_power_down && chip->auto_delink_en)
+               rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 2);
+
+       rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL);
+
+       chip->cur_clk = 0;
+       chip->cur_card = 0;
+       chip->card_exist = 0;
+}
+
+void rtsx_enable_aspm(struct rtsx_chip *chip)
+{
+       if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) {
+               if (!chip->aspm_enabled) {
+                       RTSX_DEBUGP("Try to enable ASPM\n");
+                       chip->aspm_enabled = 1;
+
+                       if (chip->asic_code && CHECK_PID(chip, 0x5208))
+                               rtsx_write_phy_register(chip, 0x07, 0);
+                       if (CHECK_PID(chip, 0x5208)) {
+                               rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3,
+                                       0x30 | chip->aspm_level[0]);
+                       } else {
+                               rtsx_write_config_byte(chip, LCTLR,
+                                               chip->aspm_l0s_l1_en);
+                       }
+
+                       if (CHK_SDIO_EXIST(chip)) {
+                               u16 val = chip->aspm_l0s_l1_en | 0x0100;
+                               if (CHECK_PID(chip, 0x5288))
+                                       rtsx_write_cfg_dw(chip, 2, 0xC0,
+                                                       0xFFFF, val);
+                               else
+                                       rtsx_write_cfg_dw(chip, 1, 0xC0,
+                                                       0xFFFF, val);
+                       }
+               }
+       }
+
+       return;
+}
+
+void rtsx_disable_aspm(struct rtsx_chip *chip)
+{
+       if (CHECK_PID(chip, 0x5208))
+               rtsx_monitor_aspm_config(chip);
+
+       if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) {
+               if (chip->aspm_enabled) {
+                       RTSX_DEBUGP("Try to disable ASPM\n");
+                       chip->aspm_enabled = 0;
+
+                       if (chip->asic_code && CHECK_PID(chip, 0x5208))
+                               rtsx_write_phy_register(chip, 0x07, 0x0129);
+                       if (CHECK_PID(chip, 0x5208))
+                               rtsx_write_register(chip, ASPM_FORCE_CTL,
+                                               0xF3, 0x30);
+                       else
+                               rtsx_write_config_byte(chip, LCTLR, 0x00);
+
+                       wait_timeout(1);
+               }
+       }
+
+       return;
+}
+
+int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
+{
+       int retval;
+       int i, j;
+       u16 reg_addr;
+       u8 *ptr;
+
+       if (!buf)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       ptr = buf;
+       reg_addr = PPBUF_BASE2;
+       for (i = 0; i < buf_len/256; i++) {
+               rtsx_init_cmd(chip);
+
+               for (j = 0; j < 256; j++)
+                       rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0);
+
+               retval = rtsx_send_cmd(chip, 0, 250);
+               if (retval < 0)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               memcpy(ptr, rtsx_get_cmd_data(chip), 256);
+               ptr += 256;
+       }
+
+       if (buf_len%256) {
+               rtsx_init_cmd(chip);
+
+               for (j = 0; j < buf_len%256; j++)
+                       rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0);
+
+               retval = rtsx_send_cmd(chip, 0, 250);
+               if (retval < 0)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       memcpy(ptr, rtsx_get_cmd_data(chip), buf_len%256);
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
+{
+       int retval;
+       int i, j;
+       u16 reg_addr;
+       u8 *ptr;
+
+       if (!buf)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       ptr = buf;
+       reg_addr = PPBUF_BASE2;
+       for (i = 0; i < buf_len/256; i++) {
+               rtsx_init_cmd(chip);
+
+               for (j = 0; j < 256; j++) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF,
+                               *ptr);
+                       ptr++;
+               }
+
+               retval = rtsx_send_cmd(chip, 0, 250);
+               if (retval < 0)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (buf_len%256) {
+               rtsx_init_cmd(chip);
+
+               for (j = 0; j < buf_len%256; j++) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF,
+                               *ptr);
+                       ptr++;
+               }
+
+               retval = rtsx_send_cmd(chip, 0, 250);
+               if (retval < 0)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_check_chip_exist(struct rtsx_chip *chip)
+{
+       if (rtsx_readl(chip, 0) == 0xFFFFFFFF)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl)
+{
+       int retval;
+       u8 mask = 0;
+
+       if (ctl & SSC_PDCTL)
+               mask |= SSC_POWER_DOWN;
+
+#ifdef SUPPORT_OCP
+       if (ctl & OC_PDCTL) {
+               mask |= SD_OC_POWER_DOWN;
+               if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
+                       mask |= MS_OC_POWER_DOWN;
+       }
+#endif
+
+       if (mask) {
+               retval = rtsx_write_register(chip, FPDCTL, mask, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (CHECK_PID(chip, 0x5288))
+                       wait_timeout(200);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl)
+{
+       int retval;
+       u8 mask = 0, val = 0;
+
+       if (ctl & SSC_PDCTL)
+               mask |= SSC_POWER_DOWN;
+
+#ifdef SUPPORT_OCP
+       if (ctl & OC_PDCTL) {
+               mask |= SD_OC_POWER_DOWN;
+               if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
+                       mask |= MS_OC_POWER_DOWN;
+       }
+#endif
+
+       if (mask) {
+               val = mask;
+               retval = rtsx_write_register(chip, FPDCTL, mask, val);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
diff --git a/drivers/staging/rts5208/rtsx_chip.h b/drivers/staging/rts5208/rtsx_chip.h
new file mode 100644 (file)
index 0000000..c25efcc
--- /dev/null
@@ -0,0 +1,1002 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_CHIP_H
+#define __REALTEK_RTSX_CHIP_H
+
+#include "rtsx.h"
+
+#define SUPPORT_CPRM
+#define SUPPORT_OCP
+#define SUPPORT_SDIO_ASPM
+#define SUPPORT_MAGIC_GATE
+#define SUPPORT_MSXC
+#define SUPPORT_SD_LOCK
+/* Hardware switch bus_ctl and cd_ctl automatically */
+#define HW_AUTO_SWITCH_SD_BUS
+/* Enable hardware interrupt write clear */
+#define HW_INT_WRITE_CLR
+/* #define LED_AUTO_BLINK */
+/* #define DISABLE_CARD_INT */
+
+#ifdef SUPPORT_MAGIC_GATE
+       /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICV */
+       #define MG_SET_ICV_SLOW
+       /* HW may miss ERR/CMDNK signal when sampling INT status. */
+       #define MS_SAMPLE_INT_ERR
+       /* HW DO NOT support Wait_INT function during READ_BYTES
+        * transfer mode */
+       #define READ_BYTES_WAIT_INT
+#endif
+
+#ifdef SUPPORT_MSXC
+#define XC_POWERCLASS
+#define SUPPORT_PCGL_1P18
+#endif
+
+#ifndef LED_AUTO_BLINK
+#define REGULAR_BLINK
+#endif
+
+#define LED_BLINK_SPEED                5
+#define LED_TOGGLE_INTERVAL    6
+#define        GPIO_TOGGLE_THRESHOLD   1024
+#define LED_GPIO               0
+
+#define POLLING_INTERVAL       30
+
+#define TRACE_ITEM_CNT         64
+
+#ifndef STATUS_SUCCESS
+#define STATUS_SUCCESS         0
+#endif
+#ifndef STATUS_FAIL
+#define STATUS_FAIL            1
+#endif
+#ifndef STATUS_TIMEDOUT
+#define STATUS_TIMEDOUT                2
+#endif
+#ifndef STATUS_NOMEM
+#define STATUS_NOMEM           3
+#endif
+#ifndef STATUS_READ_FAIL
+#define STATUS_READ_FAIL       4
+#endif
+#ifndef STATUS_WRITE_FAIL
+#define STATUS_WRITE_FAIL      5
+#endif
+#ifndef STATUS_ERROR
+#define STATUS_ERROR           10
+#endif
+
+#define PM_S1                  1
+#define PM_S3                  3
+
+/*
+ * Transport return codes
+ */
+
+#define TRANSPORT_GOOD         0   /* Transport good, command good        */
+#define TRANSPORT_FAILED       1   /* Transport good, command failed   */
+#define TRANSPORT_NO_SENSE     2  /* Command failed, no auto-sense    */
+#define TRANSPORT_ERROR                3   /* Transport bad (i.e. device dead) */
+
+
+/*-----------------------------------
+    Start-Stop-Unit
+-----------------------------------*/
+#define STOP_MEDIUM                    0x00    /* access disable         */
+#define MAKE_MEDIUM_READY              0x01    /* access enable          */
+#define UNLOAD_MEDIUM                  0x02    /* unload                 */
+#define LOAD_MEDIUM                    0x03    /* load                   */
+
+/*-----------------------------------
+    STANDARD_INQUIRY
+-----------------------------------*/
+#define QULIFIRE                0x00
+#define AENC_FNC                0x00
+#define TRML_IOP                0x00
+#define REL_ADR                 0x00
+#define WBUS_32                 0x00
+#define WBUS_16                 0x00
+#define SYNC                    0x00
+#define LINKED                  0x00
+#define CMD_QUE                 0x00
+#define SFT_RE                  0x00
+
+#define VEN_ID_LEN              8               /* Vendor ID Length         */
+#define PRDCT_ID_LEN            16              /* Product ID Length        */
+#define PRDCT_REV_LEN           4               /* Product LOT Length       */
+
+/* Dynamic flag definitions: used in set_bit() etc. */
+#define RTSX_FLIDX_TRANS_ACTIVE                18  /* 0x00040000  transfer is active */
+#define RTSX_FLIDX_ABORTING            20  /* 0x00100000 abort is in
+                                            * progress */
+#define RTSX_FLIDX_DISCONNECTING       21  /* 0x00200000 disconnect
+                                            * in progress */
+#define ABORTING_OR_DISCONNECTING      ((1UL << US_FLIDX_ABORTING) | \
+                                        (1UL << US_FLIDX_DISCONNECTING))
+#define RTSX_FLIDX_RESETTING           22  /* 0x00400000 device reset
+                                            * in progress */
+#define RTSX_FLIDX_TIMED_OUT           23  /* 0x00800000 SCSI
+                                            * midlayer timed out */
+
+#define DRCT_ACCESS_DEV         0x00    /* Direct Access Device      */
+#define RMB_DISC                0x80    /* The Device is Removable   */
+#define ANSI_SCSI2              0x02    /* Based on ANSI-SCSI2       */
+
+#define SCSI                    0x00    /* Interface ID              */
+
+#define        WRITE_PROTECTED_MEDIA 0x07
+
+/*---- sense key ----*/
+#define ILI                     0x20    /* ILI bit is on                    */
+
+#define NO_SENSE                0x00    /* not exist sense key              */
+#define RECOVER_ERR             0x01    /* Target/Logical unit is recoverd  */
+#define NOT_READY               0x02    /* Logical unit is not ready        */
+#define MEDIA_ERR               0x03    /* medium/data error                */
+#define HARDWARE_ERR            0x04    /* hardware error                   */
+#define ILGAL_REQ               0x05    /* CDB/parameter/identify msg error */
+#define UNIT_ATTENTION          0x06    /* unit attention condition occur   */
+#define DAT_PRTCT               0x07    /* read/write is desable            */
+#define BLNC_CHK                0x08    /* find blank/DOF in read           */
+                                       /* write to unblank area            */
+#define CPY_ABRT                0x0a    /* Copy/Compare/Copy&Verify illgal  */
+#define ABRT_CMD                0x0b    /* Target make the command in error */
+#define EQUAL                   0x0c    /* Search Data end with Equal       */
+#define VLM_OVRFLW              0x0d    /* Some data are left in buffer     */
+#define MISCMP                  0x0e    /* find inequality                  */
+
+#define READ_ERR                -1
+#define WRITE_ERR               -2
+
+#define        FIRST_RESET             0x01
+#define        USED_EXIST              0x02
+
+/*-----------------------------------
+    SENSE_DATA
+-----------------------------------*/
+/*---- valid ----*/
+#define SENSE_VALID             0x80    /* Sense data is valid as SCSI2     */
+#define SENSE_INVALID           0x00    /* Sense data is invalid as SCSI2   */
+
+/*---- error code ----*/
+#define CUR_ERR                 0x70    /* current error                    */
+#define DEF_ERR                 0x71    /* specific command error           */
+
+/*---- sense key Information ----*/
+#define SNSKEYINFO_LEN          3       /* length of sense key information   */
+
+#define SKSV                    0x80
+#define CDB_ILLEGAL             0x40
+#define DAT_ILLEGAL             0x00
+#define BPV                     0x08
+#define BIT_ILLEGAL0            0       /* bit0 is illegal                  */
+#define BIT_ILLEGAL1            1       /* bit1 is illegal                  */
+#define BIT_ILLEGAL2            2       /* bit2 is illegal                  */
+#define BIT_ILLEGAL3            3       /* bit3 is illegal                  */
+#define BIT_ILLEGAL4            4       /* bit4 is illegal                  */
+#define BIT_ILLEGAL5            5       /* bit5 is illegal                  */
+#define BIT_ILLEGAL6            6       /* bit6 is illegal                  */
+#define BIT_ILLEGAL7            7       /* bit7 is illegal                  */
+
+/*---- ASC ----*/
+#define ASC_NO_INFO             0x00
+#define ASC_MISCMP              0x1d
+#define ASC_INVLD_CDB           0x24
+#define ASC_INVLD_PARA          0x26
+#define ASC_LU_NOT_READY       0x04
+#define ASC_WRITE_ERR           0x0c
+#define ASC_READ_ERR            0x11
+#define ASC_LOAD_EJCT_ERR       0x53
+#define        ASC_MEDIA_NOT_PRESENT   0x3A
+#define        ASC_MEDIA_CHANGED       0x28
+#define        ASC_MEDIA_IN_PROCESS    0x04
+#define        ASC_WRITE_PROTECT       0x27
+#define ASC_LUN_NOT_SUPPORTED  0x25
+
+/*---- ASQC ----*/
+#define ASCQ_NO_INFO            0x00
+#define        ASCQ_MEDIA_IN_PROCESS   0x01
+#define ASCQ_MISCMP             0x00
+#define ASCQ_INVLD_CDB          0x00
+#define ASCQ_INVLD_PARA         0x02
+#define ASCQ_LU_NOT_READY      0x02
+#define ASCQ_WRITE_ERR          0x02
+#define ASCQ_READ_ERR           0x00
+#define ASCQ_LOAD_EJCT_ERR      0x00
+#define        ASCQ_WRITE_PROTECT      0x00
+
+
+struct sense_data_t {
+       unsigned char   err_code;       /* error code */
+       /* bit7 : valid */
+       /*   (1 : SCSI2) */
+       /*   (0 : Vendor * specific) */
+       /* bit6-0 : error * code */
+       /*  (0x70 : current * error) */
+       /*  (0x71 : specific command error) */
+       unsigned char   seg_no;         /* segment No.                      */
+       unsigned char   sense_key;      /* byte5 : ILI                      */
+       /* bit3-0 : sense key              */
+       unsigned char   info[4];        /* information                       */
+       unsigned char   ad_sense_len;   /* additional sense data length     */
+       unsigned char   cmd_info[4];    /* command specific information      */
+       unsigned char   asc;            /* ASC                              */
+       unsigned char   ascq;           /* ASCQ                             */
+       unsigned char   rfu;            /* FRU                              */
+       unsigned char   sns_key_info[3];/* sense key specific information    */
+};
+
+/* PCI Operation Register Address */
+#define RTSX_HCBAR             0x00
+#define RTSX_HCBCTLR           0x04
+#define RTSX_HDBAR             0x08
+#define RTSX_HDBCTLR           0x0C
+#define RTSX_HAIMR             0x10
+#define RTSX_BIPR              0x14
+#define RTSX_BIER              0x18
+
+/* Host command buffer control register */
+#define STOP_CMD               (0x01 << 28)
+
+/* Host data buffer control register */
+#define SDMA_MODE              0x00
+#define ADMA_MODE              (0x02 << 26)
+#define STOP_DMA               (0x01 << 28)
+#define TRIG_DMA               (0x01 << 31)
+
+/* Bus interrupt pending register */
+#define CMD_DONE_INT           (1 << 31)
+#define DATA_DONE_INT          (1 << 30)
+#define TRANS_OK_INT           (1 << 29)
+#define TRANS_FAIL_INT         (1 << 28)
+#define XD_INT                 (1 << 27)
+#define MS_INT                 (1 << 26)
+#define SD_INT                 (1 << 25)
+#define GPIO0_INT              (1 << 24)
+#define OC_INT                 (1 << 23)
+#define SD_WRITE_PROTECT       (1 << 19)
+#define XD_EXIST               (1 << 18)
+#define MS_EXIST               (1 << 17)
+#define SD_EXIST               (1 << 16)
+#define DELINK_INT             GPIO0_INT
+#define MS_OC_INT              (1 << 23)
+#define SD_OC_INT              (1 << 22)
+
+#define CARD_INT               (XD_INT | MS_INT | SD_INT)
+#define NEED_COMPLETE_INT      (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT)
+#define RTSX_INT               (CMD_DONE_INT | NEED_COMPLETE_INT | CARD_INT | GPIO0_INT | OC_INT)
+
+#define CARD_EXIST             (XD_EXIST | MS_EXIST | SD_EXIST)
+
+/* Bus interrupt enable register */
+#define CMD_DONE_INT_EN                (1 << 31)
+#define DATA_DONE_INT_EN       (1 << 30)
+#define TRANS_OK_INT_EN                (1 << 29)
+#define TRANS_FAIL_INT_EN      (1 << 28)
+#define XD_INT_EN              (1 << 27)
+#define MS_INT_EN              (1 << 26)
+#define SD_INT_EN              (1 << 25)
+#define GPIO0_INT_EN           (1 << 24)
+#define OC_INT_EN              (1 << 23)
+#define DELINK_INT_EN          GPIO0_INT_EN
+#define MS_OC_INT_EN           (1 << 23)
+#define SD_OC_INT_EN           (1 << 22)
+
+
+#define READ_REG_CMD           0
+#define WRITE_REG_CMD          1
+#define CHECK_REG_CMD          2
+
+#define HOST_TO_DEVICE         0
+#define DEVICE_TO_HOST         1
+
+
+#define RTSX_RESV_BUF_LEN      4096
+#define HOST_CMDS_BUF_LEN      1024
+#define HOST_SG_TBL_BUF_LEN    (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN)
+
+#define SD_NR          2
+#define MS_NR          3
+#define XD_NR          4
+#define SPI_NR         7
+#define SD_CARD                (1 << SD_NR)
+#define MS_CARD                (1 << MS_NR)
+#define XD_CARD                (1 << XD_NR)
+#define SPI_CARD       (1 << SPI_NR)
+
+#define MAX_ALLOWED_LUN_CNT    8
+
+#define XD_FREE_TABLE_CNT      1200
+#define MS_FREE_TABLE_CNT      512
+
+
+/* Bit Operation */
+#define SET_BIT(data, idx)     ((data) |= 1 << (idx))
+#define CLR_BIT(data, idx)     ((data) &= ~(1 << (idx)))
+#define CHK_BIT(data, idx)     ((data) & (1 << (idx)))
+
+/* SG descriptor */
+#define SG_INT                 0x04
+#define SG_END                 0x02
+#define SG_VALID               0x01
+
+#define SG_NO_OP               0x00
+#define SG_TRANS_DATA          (0x02 << 4)
+#define SG_LINK_DESC           (0x03 << 4)
+
+struct rtsx_chip;
+
+typedef int (*card_rw_func)(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+                       u32 sec_addr, u16 sec_cnt);
+
+/* Supported Clock */
+enum card_clock        {CLK_20 = 1, CLK_30, CLK_40, CLK_50, CLK_60,
+                CLK_80, CLK_100, CLK_120, CLK_150, CLK_200};
+
+enum RTSX_STAT {RTSX_STAT_INIT, RTSX_STAT_IDLE, RTSX_STAT_RUN, RTSX_STAT_SS,
+                RTSX_STAT_DELINK, RTSX_STAT_SUSPEND,
+                RTSX_STAT_ABORT, RTSX_STAT_DISCONNECT};
+enum IC_VER    {IC_VER_AB, IC_VER_C = 2, IC_VER_D = 3};
+
+#define MAX_RESET_CNT          3
+
+/* For MS Card */
+#define MAX_DEFECTIVE_BLOCK     10
+
+struct zone_entry {
+       u16 *l2p_table;
+       u16 *free_table;
+       u16 defect_list[MAX_DEFECTIVE_BLOCK];  /* For MS card only */
+       int set_index;
+       int get_index;
+       int unused_blk_cnt;
+       int disable_count;
+       /* To indicate whether the L2P table of this zone has been built. */
+       int build_flag;
+};
+
+#define TYPE_SD                        0x0000
+#define TYPE_MMC               0x0001
+
+/* TYPE_SD */
+#define SD_HS                  0x0100
+#define SD_SDR50               0x0200
+#define SD_DDR50               0x0400
+#define SD_SDR104              0x0800
+#define SD_HCXC                        0x1000
+
+/* TYPE_MMC */
+#define MMC_26M                        0x0100
+#define MMC_52M                        0x0200
+#define MMC_4BIT               0x0400
+#define MMC_8BIT               0x0800
+#define MMC_SECTOR_MODE                0x1000
+#define MMC_DDR52              0x2000
+
+/* SD card */
+#define CHK_SD(sd_card)                        (((sd_card)->sd_type & 0xFF) == TYPE_SD)
+#define CHK_SD_HS(sd_card)             (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HS))
+#define CHK_SD_SDR50(sd_card)          (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR50))
+#define CHK_SD_DDR50(sd_card)          (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_DDR50))
+#define CHK_SD_SDR104(sd_card)         (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR104))
+#define CHK_SD_HCXC(sd_card)           (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HCXC))
+#define CHK_SD_HC(sd_card)             (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity <= 0x4000000))
+#define CHK_SD_XC(sd_card)             (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity > 0x4000000))
+#define CHK_SD30_SPEED(sd_card)                (CHK_SD_SDR50(sd_card) || CHK_SD_DDR50(sd_card) || CHK_SD_SDR104(sd_card))
+
+#define SET_SD(sd_card)                        ((sd_card)->sd_type = TYPE_SD)
+#define SET_SD_HS(sd_card)             ((sd_card)->sd_type |= SD_HS)
+#define SET_SD_SDR50(sd_card)          ((sd_card)->sd_type |= SD_SDR50)
+#define SET_SD_DDR50(sd_card)          ((sd_card)->sd_type |= SD_DDR50)
+#define SET_SD_SDR104(sd_card)         ((sd_card)->sd_type |= SD_SDR104)
+#define SET_SD_HCXC(sd_card)           ((sd_card)->sd_type |= SD_HCXC)
+
+#define CLR_SD_HS(sd_card)             ((sd_card)->sd_type &= ~SD_HS)
+#define CLR_SD_SDR50(sd_card)          ((sd_card)->sd_type &= ~SD_SDR50)
+#define CLR_SD_DDR50(sd_card)          ((sd_card)->sd_type &= ~SD_DDR50)
+#define CLR_SD_SDR104(sd_card)         ((sd_card)->sd_type &= ~SD_SDR104)
+#define CLR_SD_HCXC(sd_card)           ((sd_card)->sd_type &= ~SD_HCXC)
+
+/* MMC card */
+#define CHK_MMC(sd_card)               (((sd_card)->sd_type & 0xFF) == TYPE_MMC)
+#define CHK_MMC_26M(sd_card)           (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_26M))
+#define CHK_MMC_52M(sd_card)           (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_52M))
+#define CHK_MMC_4BIT(sd_card)          (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_4BIT))
+#define CHK_MMC_8BIT(sd_card)          (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_8BIT))
+#define CHK_MMC_SECTOR_MODE(sd_card)   (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_SECTOR_MODE))
+#define CHK_MMC_DDR52(sd_card)         (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_DDR52))
+
+#define SET_MMC(sd_card)               ((sd_card)->sd_type = TYPE_MMC)
+#define SET_MMC_26M(sd_card)           ((sd_card)->sd_type |= MMC_26M)
+#define SET_MMC_52M(sd_card)           ((sd_card)->sd_type |= MMC_52M)
+#define SET_MMC_4BIT(sd_card)          ((sd_card)->sd_type |= MMC_4BIT)
+#define SET_MMC_8BIT(sd_card)          ((sd_card)->sd_type |= MMC_8BIT)
+#define SET_MMC_SECTOR_MODE(sd_card)   ((sd_card)->sd_type |= MMC_SECTOR_MODE)
+#define SET_MMC_DDR52(sd_card)         ((sd_card)->sd_type |= MMC_DDR52)
+
+#define CLR_MMC_26M(sd_card)           ((sd_card)->sd_type &= ~MMC_26M)
+#define CLR_MMC_52M(sd_card)           ((sd_card)->sd_type &= ~MMC_52M)
+#define CLR_MMC_4BIT(sd_card)          ((sd_card)->sd_type &= ~MMC_4BIT)
+#define CLR_MMC_8BIT(sd_card)          ((sd_card)->sd_type &= ~MMC_8BIT)
+#define CLR_MMC_SECTOR_MODE(sd_card)   ((sd_card)->sd_type &= ~MMC_SECTOR_MODE)
+#define CLR_MMC_DDR52(sd_card)         ((sd_card)->sd_type &= ~MMC_DDR52)
+
+#define CHK_MMC_HS(sd_card)            (CHK_MMC_52M(sd_card) && CHK_MMC_26M(sd_card))
+#define CLR_MMC_HS(sd_card)                    \
+do {                                           \
+       CLR_MMC_DDR52(sd_card);                 \
+       CLR_MMC_52M(sd_card);                   \
+       CLR_MMC_26M(sd_card);                   \
+} while (0)
+
+#define SD_SUPPORT_CLASS_TEN           0x01
+#define SD_SUPPORT_1V8                 0x02
+
+#define SD_SET_CLASS_TEN(sd_card)      ((sd_card)->sd_setting |= SD_SUPPORT_CLASS_TEN)
+#define SD_CHK_CLASS_TEN(sd_card)      ((sd_card)->sd_setting & SD_SUPPORT_CLASS_TEN)
+#define SD_CLR_CLASS_TEN(sd_card)      ((sd_card)->sd_setting &= ~SD_SUPPORT_CLASS_TEN)
+#define SD_SET_1V8(sd_card)            ((sd_card)->sd_setting |= SD_SUPPORT_1V8)
+#define SD_CHK_1V8(sd_card)            ((sd_card)->sd_setting & SD_SUPPORT_1V8)
+#define SD_CLR_1V8(sd_card)            ((sd_card)->sd_setting &= ~SD_SUPPORT_1V8)
+
+struct sd_info {
+       u16 sd_type;
+       u8 err_code;
+       u8 sd_data_buf_ready;
+       u32 sd_addr;
+       u32 capacity;
+
+       u8 raw_csd[16];
+       u8 raw_scr[8];
+
+       /* Sequential RW */
+       int seq_mode;
+       enum dma_data_direction pre_dir;
+       u32 pre_sec_addr;
+       u16 pre_sec_cnt;
+
+       int cleanup_counter;
+
+       int sd_clock;
+
+       int mmc_dont_switch_bus;
+
+#ifdef SUPPORT_CPRM
+       int sd_pass_thru_en;
+       int pre_cmd_err;
+       u8 last_rsp_type;
+       u8 rsp[17];
+#endif
+
+       u8 func_group1_mask;
+       u8 func_group2_mask;
+       u8 func_group3_mask;
+       u8 func_group4_mask;
+
+       u8 sd_switch_fail;
+       u8 sd_read_phase;
+
+#ifdef SUPPORT_SD_LOCK
+       u8 sd_lock_status;
+       u8 sd_erase_status;
+       u8 sd_lock_notify;
+#endif
+       int need_retune;
+};
+
+struct xd_delay_write_tag {
+       u32 old_phyblock;
+       u32 new_phyblock;
+       u32 logblock;
+       u8 pageoff;
+       u8 delay_write_flag;
+};
+
+struct xd_info {
+       u8 maker_code;
+       u8 device_code;
+       u8 block_shift;
+       u8 page_off;
+       u8 addr_cycle;
+       u16 cis_block;
+       u8 multi_flag;
+       u8 err_code;
+       u32 capacity;
+
+       struct zone_entry *zone;
+       int zone_cnt;
+
+       struct xd_delay_write_tag delay_write;
+       int cleanup_counter;
+
+       int xd_clock;
+};
+
+#define MODE_512_SEQ           0x01
+#define MODE_2K_SEQ            0x02
+
+#define TYPE_MS                        0x0000
+#define TYPE_MSPRO             0x0001
+
+#define MS_4BIT                        0x0100
+#define MS_8BIT                        0x0200
+#define MS_HG                  0x0400
+#define MS_XC                  0x0800
+
+#define HG8BIT                 (MS_HG | MS_8BIT)
+
+#define CHK_MSPRO(ms_card)     (((ms_card)->ms_type & 0xFF) == TYPE_MSPRO)
+#define CHK_HG8BIT(ms_card)    (CHK_MSPRO(ms_card) && (((ms_card)->ms_type & HG8BIT) == HG8BIT))
+#define CHK_MSXC(ms_card)      (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_XC))
+#define CHK_MSHG(ms_card)      (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_HG))
+
+#define CHK_MS8BIT(ms_card)    (((ms_card)->ms_type & MS_8BIT))
+#define CHK_MS4BIT(ms_card)    (((ms_card)->ms_type & MS_4BIT))
+
+struct ms_delay_write_tag {
+       u16 old_phyblock;
+       u16 new_phyblock;
+       u16 logblock;
+       u8 pageoff;
+       u8 delay_write_flag;
+};
+
+struct ms_info {
+       u16 ms_type;
+       u8 block_shift;
+       u8 page_off;
+       u16 total_block;
+       u16 boot_block;
+       u32 capacity;
+
+       u8 check_ms_flow;
+       u8 switch_8bit_fail;
+       u8 err_code;
+
+       struct zone_entry *segment;
+       int segment_cnt;
+
+       int pro_under_formatting;
+       int format_status;
+       u16 progress;
+       u8 raw_sys_info[96];
+#ifdef SUPPORT_PCGL_1P18
+       u8 raw_model_name[48];
+#endif
+
+       u8 multi_flag;
+
+       /* Sequential RW */
+       u8 seq_mode;
+       enum dma_data_direction pre_dir;
+       u32 pre_sec_addr;
+       u16 pre_sec_cnt;
+       u32 total_sec_cnt;
+
+       struct ms_delay_write_tag delay_write;
+
+       int cleanup_counter;
+
+       int ms_clock;
+
+#ifdef SUPPORT_MAGIC_GATE
+       u8 magic_gate_id[16];
+       u8 mg_entry_num;
+       int mg_auth;    /* flag to indicate authentication process */
+#endif
+};
+
+struct spi_info {
+       u8 use_clk;
+       u8 write_en;
+       u16 clk_div;
+       u8 err_code;
+
+       int spi_clock;
+};
+
+
+#ifdef _MSG_TRACE
+struct trace_msg_t {
+       u16 line;
+#define MSG_FUNC_LEN 64
+       char func[MSG_FUNC_LEN];
+#define MSG_FILE_LEN 32
+       char file[MSG_FILE_LEN];
+#define TIME_VAL_LEN 16
+       u8 timeval_buf[TIME_VAL_LEN];
+       u8 valid;
+};
+#endif
+
+/************/
+/* LUN mode */
+/************/
+/* Single LUN, support xD/SD/MS */
+#define DEFAULT_SINGLE         0
+/* 2 LUN mode, support SD/MS */
+#define SD_MS_2LUN             1
+/* Single LUN, but only support SD/MS, for Barossa LQFP */
+#define SD_MS_1LUN             2
+
+#define LAST_LUN_MODE          2
+
+/* Barossa package */
+#define QFN            0
+#define LQFP           1
+
+/******************/
+/* sd_ctl bit map */
+/******************/
+/* SD push point control, bit 0, 1 */
+#define SD_PUSH_POINT_CTL_MASK         0x03
+#define SD_PUSH_POINT_DELAY            0x01
+#define SD_PUSH_POINT_AUTO             0x02
+/* SD sample point control, bit 2, 3 */
+#define SD_SAMPLE_POINT_CTL_MASK       0x0C
+#define SD_SAMPLE_POINT_DELAY          0x04
+#define SD_SAMPLE_POINT_AUTO           0x08
+/* SD DDR Tx phase set by user, bit 4 */
+#define SD_DDR_TX_PHASE_SET_BY_USER    0x10
+/* MMC DDR Tx phase set by user, bit 5 */
+#define MMC_DDR_TX_PHASE_SET_BY_USER   0x20
+/* Support MMC DDR mode, bit 6 */
+#define SUPPORT_MMC_DDR_MODE           0x40
+/* Reset MMC at first */
+#define RESET_MMC_FIRST                        0x80
+
+#define SEQ_START_CRITERIA             0x20
+
+/* MS Power Class En */
+#define POWER_CLASS_2_EN               0x02
+#define POWER_CLASS_1_EN               0x01
+
+#define MAX_SHOW_CNT                   10
+#define MAX_RESET_CNT                  3
+
+#define SDIO_EXIST                     0x01
+#define SDIO_IGNORED                   0x02
+
+#define CHK_SDIO_EXIST(chip)           ((chip)->sdio_func_exist & SDIO_EXIST)
+#define SET_SDIO_EXIST(chip)           ((chip)->sdio_func_exist |= SDIO_EXIST)
+#define CLR_SDIO_EXIST(chip)           ((chip)->sdio_func_exist &= ~SDIO_EXIST)
+
+#define CHK_SDIO_IGNORED(chip)         ((chip)->sdio_func_exist & SDIO_IGNORED)
+#define SET_SDIO_IGNORED(chip)         ((chip)->sdio_func_exist |= SDIO_IGNORED)
+#define CLR_SDIO_IGNORED(chip)         ((chip)->sdio_func_exist &= ~SDIO_IGNORED)
+
+struct rtsx_chip {
+       rtsx_dev_t      *rtsx;
+
+       u32             int_reg; /* Bus interrupt pending register */
+       char            max_lun;
+       void            *context;
+
+       void            *host_cmds_ptr; /* host commands buffer pointer */
+       dma_addr_t      host_cmds_addr;
+       int             ci;                     /* Command Index */
+
+       void            *host_sg_tbl_ptr;       /* SG descriptor table */
+       dma_addr_t      host_sg_tbl_addr;
+       int             sgi;                    /* SG entry index */
+
+       struct scsi_cmnd        *srb;                   /* current srb */
+       struct sense_data_t     sense_buffer[MAX_ALLOWED_LUN_CNT];
+
+       int                     cur_clk;                /* current card clock */
+
+       /* Current accessed card */
+       int                     cur_card;
+
+       unsigned long   need_release;           /* need release bit map */
+       unsigned long   need_reset;             /* need reset
+                                                * bit map */
+       /* Flag to indicate that this card is just resumed from SS state,
+        * and need released before being resetted
+        */
+       unsigned long           need_reinit;
+
+       int                     rw_need_retry;
+
+#ifdef SUPPORT_OCP
+       u32                     ocp_int;
+       u8                      ocp_stat;
+#endif
+
+       u8      card_exist;     /* card exist bit map (physical exist) */
+       u8      card_ready;     /* card ready bit map (reset successfully) */
+       u8      card_fail;      /* card reset fail bit map */
+       u8      card_ejected;   /* card ejected bit map */
+       u8      card_wp;        /* card write protected bit map */
+
+       u8      lun_mc;         /* flag to indicate whether to answer
+                                * MediaChange */
+
+#ifndef LED_AUTO_BLINK
+       int                     led_toggle_counter;
+#endif
+
+       int                     sd_reset_counter;
+       int                     xd_reset_counter;
+       int                     ms_reset_counter;
+
+       /* card bus width */
+       u8                      card_bus_width[MAX_ALLOWED_LUN_CNT];
+       /* card capacity */
+       u32                     capacity[MAX_ALLOWED_LUN_CNT];
+       /* read/write card function pointer */
+       card_rw_func            rw_card[MAX_ALLOWED_LUN_CNT];
+       /* read/write capacity, used for GPIO Toggle */
+       u32                     rw_cap[MAX_ALLOWED_LUN_CNT];
+       /* card to lun mapping table */
+       u8                      card2lun[32];
+       /* lun to card mapping table */
+       u8                      lun2card[MAX_ALLOWED_LUN_CNT];
+
+       int                     rw_fail_cnt[MAX_ALLOWED_LUN_CNT];
+
+       int                     sd_show_cnt;
+       int                     xd_show_cnt;
+       int                     ms_show_cnt;
+
+       /* card information */
+       struct sd_info          sd_card;
+       struct xd_info          xd_card;
+       struct ms_info          ms_card;
+
+       struct spi_info         spi;
+
+#ifdef _MSG_TRACE
+       struct trace_msg_t      trace_msg[TRACE_ITEM_CNT];
+       int                     msg_idx;
+#endif
+
+       int                     auto_delink_cnt;
+       int                     auto_delink_allowed;
+
+       int                     aspm_enabled;
+
+       int                     sdio_aspm;
+       int                     sdio_idle;
+       int                     sdio_counter;
+       u8                      sdio_raw_data[12];
+
+       u8                      sd_io;
+       u8                      sd_int;
+
+       u8                      rtsx_flag;
+
+       int                     ss_counter;
+       int                     idle_counter;
+       enum RTSX_STAT          rtsx_stat;
+
+       u16                     vendor_id;
+       u16                     product_id;
+       u8                      ic_version;
+
+       int                     driver_first_load;
+
+#ifdef HW_AUTO_SWITCH_SD_BUS
+       int                     sdio_in_charge;
+#endif
+
+       u8                      aspm_level[2];
+
+       int                     chip_insert_with_sdio;
+
+       /* Options */
+
+       int adma_mode;
+
+       int auto_delink_en;
+       int ss_en;
+       u8 lun_mode;
+       u8 aspm_l0s_l1_en;
+
+       int power_down_in_ss;
+
+       int sdr104_en;
+       int ddr50_en;
+       int sdr50_en;
+
+       int baro_pkg;
+
+       int asic_code;
+       int phy_debug_mode;
+       int hw_bypass_sd;
+       int sdio_func_exist;
+       int aux_pwr_exist;
+       u8 ms_power_class_en;
+
+       int mspro_formatter_enable;
+
+       int remote_wakeup_en;
+
+       int ignore_sd;
+       int use_hw_setting;
+
+       int ss_idle_period;
+
+       int dynamic_aspm;
+
+       int fpga_sd_sdr104_clk;
+       int fpga_sd_ddr50_clk;
+       int fpga_sd_sdr50_clk;
+       int fpga_sd_hs_clk;
+       int fpga_mmc_52m_clk;
+       int fpga_ms_hg_clk;
+       int fpga_ms_4bit_clk;
+       int fpga_ms_1bit_clk;
+
+       int asic_sd_sdr104_clk;
+       int asic_sd_ddr50_clk;
+       int asic_sd_sdr50_clk;
+       int asic_sd_hs_clk;
+       int asic_mmc_52m_clk;
+       int asic_ms_hg_clk;
+       int asic_ms_4bit_clk;
+       int asic_ms_1bit_clk;
+
+       u8 ssc_depth_sd_sdr104;
+       u8 ssc_depth_sd_ddr50;
+       u8 ssc_depth_sd_sdr50;
+       u8 ssc_depth_sd_hs;
+       u8 ssc_depth_mmc_52m;
+       u8 ssc_depth_ms_hg;
+       u8 ssc_depth_ms_4bit;
+       u8 ssc_depth_low_speed;
+
+       u8 card_drive_sel;
+       u8 sd30_drive_sel_1v8;
+       u8 sd30_drive_sel_3v3;
+
+       u8 sd_400mA_ocp_thd;
+       u8 sd_800mA_ocp_thd;
+       u8 ms_ocp_thd;
+
+       int ssc_en;
+       int msi_en;
+
+       int xd_timeout;
+       int sd_timeout;
+       int ms_timeout;
+       int mspro_timeout;
+
+       int auto_power_down;
+
+       int sd_ddr_tx_phase;
+       int mmc_ddr_tx_phase;
+       int sd_default_tx_phase;
+       int sd_default_rx_phase;
+
+       int pmos_pwr_on_interval;
+       int sd_voltage_switch_delay;
+       int s3_pwr_off_delay;
+
+       int force_clkreq_0;
+       int ft2_fast_mode;
+
+       int do_delink_before_power_down;
+       int polling_config;
+       int sdio_retry_cnt;
+
+       int delink_stage1_step;
+       int delink_stage2_step;
+       int delink_stage3_step;
+
+       int auto_delink_in_L1;
+       int hp_watch_bios_hotplug;
+       int support_ms_8bit;
+
+       u8 blink_led;
+       u8 phy_voltage;
+       u8 max_payload;
+
+       u32 sd_speed_prior;
+       u32 sd_current_prior;
+       u32 sd_ctl;
+};
+
+#define rtsx_set_stat(chip, stat)                              \
+do {                                                           \
+       if ((stat) != RTSX_STAT_IDLE) {                         \
+               (chip)->idle_counter = 0;                       \
+       }                                                       \
+       (chip)->rtsx_stat = (enum RTSX_STAT)(stat);             \
+} while (0)
+#define rtsx_get_stat(chip)            ((chip)->rtsx_stat)
+#define rtsx_chk_stat(chip, stat)      ((chip)->rtsx_stat == (stat))
+
+#define RTSX_SET_DELINK(chip)  ((chip)->rtsx_flag |= 0x01)
+#define RTSX_CLR_DELINK(chip)  ((chip)->rtsx_flag &= 0xFE)
+#define RTSX_TST_DELINK(chip)  ((chip)->rtsx_flag & 0x01)
+
+#define CHECK_PID(chip, pid)           ((chip)->product_id == (pid))
+#define CHECK_BARO_PKG(chip, pkg)      ((chip)->baro_pkg == (pkg))
+#define CHECK_LUN_MODE(chip, mode)     ((chip)->lun_mode == (mode))
+
+/* Power down control */
+#define SSC_PDCTL              0x01
+#define OC_PDCTL               0x02
+
+int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl);
+int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl);
+
+void rtsx_disable_card_int(struct rtsx_chip *chip);
+void rtsx_enable_card_int(struct rtsx_chip *chip);
+void rtsx_enable_bus_int(struct rtsx_chip *chip);
+void rtsx_disable_bus_int(struct rtsx_chip *chip);
+int rtsx_reset_chip(struct rtsx_chip *chip);
+int rtsx_init_chip(struct rtsx_chip *chip);
+void rtsx_release_chip(struct rtsx_chip *chip);
+void rtsx_polling_func(struct rtsx_chip *chip);
+void rtsx_undo_delink(struct rtsx_chip *chip);
+void rtsx_stop_cmd(struct rtsx_chip *chip, int card);
+int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data);
+int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data);
+int rtsx_write_cfg_dw(struct rtsx_chip *chip,
+               u8 func_no, u16 addr, u32 mask, u32 val);
+int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val);
+int rtsx_write_cfg_seq(struct rtsx_chip *chip,
+               u8 func, u16 addr, u8 *buf, int len);
+int rtsx_read_cfg_seq(struct rtsx_chip *chip,
+               u8 func, u16 addr, u8 *buf, int len);
+int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val);
+int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val);
+int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val);
+int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val);
+int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit);
+int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit);
+int rtsx_check_link_ready(struct rtsx_chip *chip);
+void rtsx_enter_ss(struct rtsx_chip *chip);
+void rtsx_exit_ss(struct rtsx_chip *chip);
+int rtsx_pre_handle_interrupt(struct rtsx_chip *chip);
+void rtsx_enter_L1(struct rtsx_chip *chip);
+void rtsx_exit_L1(struct rtsx_chip *chip);
+void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat);
+void rtsx_enable_aspm(struct rtsx_chip *chip);
+void rtsx_disable_aspm(struct rtsx_chip *chip);
+int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len);
+int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len);
+int rtsx_check_chip_exist(struct rtsx_chip *chip);
+
+#define RTSX_WRITE_REG(chip, addr, mask, data)                         \
+       do {                                                            \
+               int retval = rtsx_write_register((chip), (addr), (mask), (data)); \
+               if (retval != STATUS_SUCCESS) {                         \
+                       TRACE_RET((chip), retval);                      \
+               }                                                       \
+       } while (0)
+
+#define RTSX_READ_REG(chip, addr, data)                                        \
+       do {                                                            \
+               int retval = rtsx_read_register((chip), (addr), (data)); \
+               if (retval != STATUS_SUCCESS) {                         \
+                       TRACE_RET((chip), retval);                      \
+               }                                                       \
+       } while (0)
+
+#endif  /* __REALTEK_RTSX_CHIP_H */
diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c
new file mode 100644 (file)
index 0000000..382e73a
--- /dev/null
@@ -0,0 +1,3370 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+
+#include "rtsx.h"
+#include "rtsx_transport.h"
+#include "rtsx_sys.h"
+#include "rtsx_card.h"
+#include "rtsx_chip.h"
+#include "rtsx_scsi.h"
+#include "sd.h"
+#include "ms.h"
+#include "spi.h"
+
+void scsi_show_command(struct scsi_cmnd *srb)
+{
+       char *what = NULL;
+       int i, unknown_cmd = 0;
+
+       switch (srb->cmnd[0]) {
+       case TEST_UNIT_READY:
+               what = "TEST_UNIT_READY";
+               break;
+       case REZERO_UNIT:
+               what = "REZERO_UNIT";
+               break;
+       case REQUEST_SENSE:
+               what = "REQUEST_SENSE";
+               break;
+       case FORMAT_UNIT:
+               what = "FORMAT_UNIT";
+               break;
+       case READ_BLOCK_LIMITS:
+               what = "READ_BLOCK_LIMITS";
+               break;
+       case REASSIGN_BLOCKS:
+               what = "REASSIGN_BLOCKS";
+               break;
+       case READ_6:
+               what = "READ_6";
+               break;
+       case WRITE_6:
+               what = "WRITE_6";
+               break;
+       case SEEK_6:
+               what = "SEEK_6";
+               break;
+       case READ_REVERSE:
+               what = "READ_REVERSE";
+               break;
+       case WRITE_FILEMARKS:
+               what = "WRITE_FILEMARKS";
+               break;
+       case SPACE:
+               what = "SPACE";
+               break;
+       case INQUIRY:
+               what = "INQUIRY";
+               break;
+       case RECOVER_BUFFERED_DATA:
+               what = "RECOVER_BUFFERED_DATA";
+               break;
+       case MODE_SELECT:
+               what = "MODE_SELECT";
+               break;
+       case RESERVE:
+               what = "RESERVE";
+               break;
+       case RELEASE:
+               what = "RELEASE";
+               break;
+       case COPY:
+               what = "COPY";
+               break;
+       case ERASE:
+               what = "ERASE";
+               break;
+       case MODE_SENSE:
+               what = "MODE_SENSE";
+               break;
+       case START_STOP:
+               what = "START_STOP";
+               break;
+       case RECEIVE_DIAGNOSTIC:
+               what = "RECEIVE_DIAGNOSTIC";
+               break;
+       case SEND_DIAGNOSTIC:
+               what = "SEND_DIAGNOSTIC";
+               break;
+       case ALLOW_MEDIUM_REMOVAL:
+               what = "ALLOW_MEDIUM_REMOVAL";
+               break;
+       case SET_WINDOW:
+               what = "SET_WINDOW";
+               break;
+       case READ_CAPACITY:
+               what = "READ_CAPACITY";
+               break;
+       case READ_10:
+               what = "READ_10";
+               break;
+       case WRITE_10:
+               what = "WRITE_10";
+               break;
+       case SEEK_10:
+               what = "SEEK_10";
+               break;
+       case WRITE_VERIFY:
+               what = "WRITE_VERIFY";
+               break;
+       case VERIFY:
+               what = "VERIFY";
+               break;
+       case SEARCH_HIGH:
+               what = "SEARCH_HIGH";
+               break;
+       case SEARCH_EQUAL:
+               what = "SEARCH_EQUAL";
+               break;
+       case SEARCH_LOW:
+               what = "SEARCH_LOW";
+               break;
+       case SET_LIMITS:
+               what = "SET_LIMITS";
+               break;
+       case READ_POSITION:
+               what = "READ_POSITION";
+               break;
+       case SYNCHRONIZE_CACHE:
+               what = "SYNCHRONIZE_CACHE";
+               break;
+       case LOCK_UNLOCK_CACHE:
+               what = "LOCK_UNLOCK_CACHE";
+               break;
+       case READ_DEFECT_DATA:
+               what = "READ_DEFECT_DATA";
+               break;
+       case MEDIUM_SCAN:
+               what = "MEDIUM_SCAN";
+               break;
+       case COMPARE:
+               what = "COMPARE";
+               break;
+       case COPY_VERIFY:
+               what = "COPY_VERIFY";
+               break;
+       case WRITE_BUFFER:
+               what = "WRITE_BUFFER";
+               break;
+       case READ_BUFFER:
+               what = "READ_BUFFER";
+               break;
+       case UPDATE_BLOCK:
+               what = "UPDATE_BLOCK";
+               break;
+       case READ_LONG:
+               what = "READ_LONG";
+               break;
+       case WRITE_LONG:
+               what = "WRITE_LONG";
+               break;
+       case CHANGE_DEFINITION:
+               what = "CHANGE_DEFINITION";
+               break;
+       case WRITE_SAME:
+               what = "WRITE_SAME";
+               break;
+       case GPCMD_READ_SUBCHANNEL:
+               what = "READ SUBCHANNEL";
+               break;
+       case READ_TOC:
+               what = "READ_TOC";
+               break;
+       case GPCMD_READ_HEADER:
+               what = "READ HEADER";
+               break;
+       case GPCMD_PLAY_AUDIO_10:
+               what = "PLAY AUDIO (10)";
+               break;
+       case GPCMD_PLAY_AUDIO_MSF:
+               what = "PLAY AUDIO MSF";
+               break;
+       case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
+               what = "GET EVENT/STATUS NOTIFICATION";
+               break;
+       case GPCMD_PAUSE_RESUME:
+               what = "PAUSE/RESUME";
+               break;
+       case LOG_SELECT:
+               what = "LOG_SELECT";
+               break;
+       case LOG_SENSE:
+               what = "LOG_SENSE";
+               break;
+       case GPCMD_STOP_PLAY_SCAN:
+               what = "STOP PLAY/SCAN";
+               break;
+       case GPCMD_READ_DISC_INFO:
+               what = "READ DISC INFORMATION";
+               break;
+       case GPCMD_READ_TRACK_RZONE_INFO:
+               what = "READ TRACK INFORMATION";
+               break;
+       case GPCMD_RESERVE_RZONE_TRACK:
+               what = "RESERVE TRACK";
+               break;
+       case GPCMD_SEND_OPC:
+               what = "SEND OPC";
+               break;
+       case MODE_SELECT_10:
+               what = "MODE_SELECT_10";
+               break;
+       case GPCMD_REPAIR_RZONE_TRACK:
+               what = "REPAIR TRACK";
+               break;
+       case 0x59:
+               what = "READ MASTER CUE";
+               break;
+       case MODE_SENSE_10:
+               what = "MODE_SENSE_10";
+               break;
+       case GPCMD_CLOSE_TRACK:
+               what = "CLOSE TRACK/SESSION";
+               break;
+       case 0x5C:
+               what = "READ BUFFER CAPACITY";
+               break;
+       case 0x5D:
+               what = "SEND CUE SHEET";
+               break;
+       case GPCMD_BLANK:
+               what = "BLANK";
+               break;
+       case REPORT_LUNS:
+               what = "REPORT LUNS";
+               break;
+       case MOVE_MEDIUM:
+               what = "MOVE_MEDIUM or PLAY AUDIO (12)";
+               break;
+       case READ_12:
+               what = "READ_12";
+               break;
+       case WRITE_12:
+               what = "WRITE_12";
+               break;
+       case WRITE_VERIFY_12:
+               what = "WRITE_VERIFY_12";
+               break;
+       case SEARCH_HIGH_12:
+               what = "SEARCH_HIGH_12";
+               break;
+       case SEARCH_EQUAL_12:
+               what = "SEARCH_EQUAL_12";
+               break;
+       case SEARCH_LOW_12:
+               what = "SEARCH_LOW_12";
+               break;
+       case SEND_VOLUME_TAG:
+               what = "SEND_VOLUME_TAG";
+               break;
+       case READ_ELEMENT_STATUS:
+               what = "READ_ELEMENT_STATUS";
+               break;
+       case GPCMD_READ_CD_MSF:
+               what = "READ CD MSF";
+               break;
+       case GPCMD_SCAN:
+               what = "SCAN";
+               break;
+       case GPCMD_SET_SPEED:
+               what = "SET CD SPEED";
+               break;
+       case GPCMD_MECHANISM_STATUS:
+               what = "MECHANISM STATUS";
+               break;
+       case GPCMD_READ_CD:
+               what = "READ CD";
+               break;
+       case 0xE1:
+               what = "WRITE CONTINUE";
+               break;
+       case WRITE_LONG_2:
+               what = "WRITE_LONG_2";
+               break;
+       case VENDOR_CMND:
+               what = "Realtek's vendor command";
+               break;
+       default:
+               what = "(unknown command)"; unknown_cmd = 1;
+               break;
+       }
+
+       if (srb->cmnd[0] != TEST_UNIT_READY)
+               RTSX_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len);
+
+       if (unknown_cmd) {
+               RTSX_DEBUGP("");
+               for (i = 0; i < srb->cmd_len && i < 16; i++)
+                       RTSX_DEBUGPN(" %02x", srb->cmnd[i]);
+               RTSX_DEBUGPN("\n");
+       }
+}
+
+void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type)
+{
+       switch (sense_type) {
+       case SENSE_TYPE_MEDIA_CHANGE:
+               set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0);
+               break;
+
+       case SENSE_TYPE_MEDIA_NOT_PRESENT:
+               set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0);
+               break;
+
+       case SENSE_TYPE_MEDIA_LBA_OVER_RANGE:
+               set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0);
+               break;
+
+       case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT:
+               set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0);
+               break;
+
+       case SENSE_TYPE_MEDIA_WRITE_PROTECT:
+               set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0);
+               break;
+
+       case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR:
+               set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0);
+               break;
+
+       case SENSE_TYPE_MEDIA_WRITE_ERR:
+               set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0);
+               break;
+
+       case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD:
+               set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0,
+                               ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1);
+               break;
+
+       case SENSE_TYPE_FORMAT_IN_PROGRESS:
+               set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0);
+               break;
+
+       case SENSE_TYPE_FORMAT_CMD_FAILED:
+               set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0);
+               break;
+
+#ifdef SUPPORT_MAGIC_GATE
+       case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB:
+               set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0);
+               break;
+
+       case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN:
+               set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0);
+               break;
+
+       case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM:
+               set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0);
+               break;
+
+       case SENSE_TYPE_MG_WRITE_ERR:
+               set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0);
+               break;
+#endif
+
+#ifdef SUPPORT_SD_LOCK
+       case SENSE_TYPE_MEDIA_READ_FORBIDDEN:
+               set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0);
+               break;
+#endif
+
+       case SENSE_TYPE_NO_SENSE:
+       default:
+               set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0);
+               break;
+       }
+}
+
+void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code,
+               u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0,
+               u16 sns_key_info1)
+{
+       struct sense_data_t *sense = &(chip->sense_buffer[lun]);
+
+       sense->err_code = err_code;
+       sense->sense_key = sense_key;
+       sense->info[0] = (u8)(info >> 24);
+       sense->info[1] = (u8)(info >> 16);
+       sense->info[2] = (u8)(info >> 8);
+       sense->info[3] = (u8)info;
+
+       sense->ad_sense_len = sizeof(struct sense_data_t) - 8;
+       sense->asc = asc;
+       sense->ascq = ascq;
+       if (sns_key_info0 != 0) {
+               sense->sns_key_info[0] = SKSV | sns_key_info0;
+               sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8;
+               sense->sns_key_info[2] = sns_key_info1 & 0x0f;
+       }
+}
+
+static int test_unit_ready(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned int lun = SCSI_LUN(srb);
+
+       if (!check_card_ready(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               return TRANSPORT_FAILED;
+       }
+
+       if (!(CHK_BIT(chip->lun_mc, lun))) {
+               SET_BIT(chip->lun_mc, lun);
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+               return TRANSPORT_FAILED;
+       }
+
+#ifdef SUPPORT_SD_LOCK
+       if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) {
+               struct sd_info *sd_card = &(chip->sd_card);
+               if (sd_card->sd_lock_notify) {
+                       sd_card->sd_lock_notify = 0;
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+                       return TRANSPORT_FAILED;
+               } else if (sd_card->sd_lock_status & SD_LOCKED) {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_READ_FORBIDDEN);
+                       return TRANSPORT_FAILED;
+               }
+       }
+#endif
+
+       return TRANSPORT_GOOD;
+}
+
+static unsigned char formatter_inquiry_str[20] = {
+       'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K',
+#ifdef SUPPORT_MAGIC_GATE
+       '-', 'M', 'G', /* Byte[47:49] */
+#else
+       0x20, 0x20, 0x20,  /* Byte[47:49] */
+#endif
+
+#ifdef SUPPORT_MAGIC_GATE
+       0x0B,  /* Byte[50]: MG, MS, MSPro, MSXC */
+#else
+       0x09,  /* Byte[50]: MS, MSPro, MSXC */
+#endif
+       0x00,  /* Byte[51]: Category Specific Commands */
+       0x00,  /* Byte[52]: Access Control and feature */
+       0x20, 0x20, 0x20, /* Byte[53:55] */
+};
+
+static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned int lun = SCSI_LUN(srb);
+       char *inquiry_default = (char *)"Generic-xD/SD/M.S.      1.00 ";
+       char *inquiry_sdms =    (char *)"Generic-SD/MemoryStick  1.00 ";
+       char *inquiry_sd =      (char *)"Generic-SD/MMC          1.00 ";
+       char *inquiry_ms =      (char *)"Generic-MemoryStick     1.00 ";
+       char *inquiry_string;
+       unsigned char sendbytes;
+       unsigned char *buf;
+       u8 card = get_lun_card(chip, lun);
+       int pro_formatter_flag = 0;
+       unsigned char inquiry_buf[] = {
+               QULIFIRE|DRCT_ACCESS_DEV,
+               RMB_DISC|0x0D,
+               0x00,
+               0x01,
+               0x1f,
+               0x02,
+               0,
+               REL_ADR|WBUS_32|WBUS_16|SYNC|LINKED|CMD_QUE|SFT_RE,
+       };
+
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
+               if (chip->lun2card[lun] == SD_CARD)
+                       inquiry_string = inquiry_sd;
+               else
+                       inquiry_string = inquiry_ms;
+
+       } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) {
+               inquiry_string = inquiry_sdms;
+       } else {
+               inquiry_string = inquiry_default;
+       }
+
+       buf = vmalloc(scsi_bufflen(srb));
+       if (buf == NULL)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+#ifdef SUPPORT_MAGIC_GATE
+       if ((chip->mspro_formatter_enable) &&
+                       (chip->lun2card[lun] & MS_CARD))
+#else
+       if (chip->mspro_formatter_enable)
+#endif
+       {
+               if (!card || (card == MS_CARD))
+                       pro_formatter_flag = 1;
+       }
+
+       if (pro_formatter_flag) {
+               if (scsi_bufflen(srb) < 56)
+                       sendbytes = (unsigned char)(scsi_bufflen(srb));
+               else
+                       sendbytes = 56;
+
+       } else {
+               if (scsi_bufflen(srb) < 36)
+                       sendbytes = (unsigned char)(scsi_bufflen(srb));
+               else
+                       sendbytes = 36;
+       }
+
+       if (sendbytes > 8) {
+               memcpy(buf, inquiry_buf, 8);
+               memcpy(buf + 8, inquiry_string, sendbytes - 8);
+               if (pro_formatter_flag) {
+                       /* Additional Length */
+                       buf[4] = 0x33;
+               }
+       } else {
+               memcpy(buf, inquiry_buf, sendbytes);
+       }
+
+       if (pro_formatter_flag) {
+               if (sendbytes > 36)
+                       memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36);
+       }
+
+       scsi_set_resid(srb, 0);
+
+       rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
+       vfree(buf);
+
+       return TRANSPORT_GOOD;
+}
+
+
+static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned int lun = SCSI_LUN(srb);
+
+       scsi_set_resid(srb, scsi_bufflen(srb));
+
+       if (srb->cmnd[1] == 1)
+               return TRANSPORT_GOOD;
+
+       switch (srb->cmnd[0x4]) {
+       case STOP_MEDIUM:
+               /* Media disabled */
+               return TRANSPORT_GOOD;
+
+       case UNLOAD_MEDIUM:
+               /* Media shall be unload */
+               if (check_card_ready(chip, lun))
+                       eject_card(chip, lun);
+               return TRANSPORT_GOOD;
+
+       case MAKE_MEDIUM_READY:
+       case LOAD_MEDIUM:
+               if (check_card_ready(chip, lun)) {
+                       return TRANSPORT_GOOD;
+               } else {
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+
+               break;
+       }
+
+       TRACE_RET(chip, TRANSPORT_ERROR);
+}
+
+
+static int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int prevent;
+
+       prevent = srb->cmnd[4] & 0x1;
+
+       scsi_set_resid(srb, 0);
+
+       if (prevent) {
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       return TRANSPORT_GOOD;
+}
+
+
+static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct sense_data_t *sense;
+       unsigned int lun = SCSI_LUN(srb);
+       struct ms_info *ms_card = &(chip->ms_card);
+       unsigned char *tmp, *buf;
+
+       sense = &(chip->sense_buffer[lun]);
+
+       if ((get_lun_card(chip, lun) == MS_CARD) &&
+               ms_card->pro_under_formatting) {
+               if (ms_card->format_status == FORMAT_SUCCESS) {
+                       set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+                       ms_card->pro_under_formatting = 0;
+                       ms_card->progress = 0;
+               } else if (ms_card->format_status == FORMAT_IN_PROGRESS) {
+                       /* Logical Unit Not Ready Format in Progress */
+                       set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04,
+                                       0, (u16)(ms_card->progress));
+               } else {
+                       /* Format Command Failed */
+                       set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED);
+                       ms_card->pro_under_formatting = 0;
+                       ms_card->progress = 0;
+               }
+
+               rtsx_set_stat(chip, RTSX_STAT_RUN);
+       }
+
+       buf = vmalloc(scsi_bufflen(srb));
+       if (buf == NULL)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       tmp = (unsigned char *)sense;
+       memcpy(buf, tmp, scsi_bufflen(srb));
+
+       rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
+       vfree(buf);
+
+       scsi_set_resid(srb, 0);
+       /* Reset Sense Data */
+       set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+       return TRANSPORT_GOOD;
+}
+
+static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd,
+               int lun, u8 *buf, int buf_len)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       int sys_info_offset;
+       int data_size = buf_len;
+       int support_format = 0;
+       int i = 0;
+
+       if (cmd == MODE_SENSE) {
+               sys_info_offset = 8;
+               if (data_size > 0x68)
+                       data_size = 0x68;
+
+               buf[i++] = 0x67;  /* Mode Data Length */
+       } else {
+               sys_info_offset = 12;
+               if (data_size > 0x6C)
+                       data_size = 0x6C;
+
+               buf[i++] = 0x00;  /* Mode Data Length (MSB) */
+               buf[i++] = 0x6A;  /* Mode Data Length (LSB) */
+       }
+
+       /* Medium Type Code */
+       if (check_card_ready(chip, lun)) {
+               if (CHK_MSXC(ms_card)) {
+                       support_format = 1;
+                       buf[i++] = 0x40;
+               } else if (CHK_MSPRO(ms_card)) {
+                       support_format = 1;
+                       buf[i++] = 0x20;
+               } else {
+                       buf[i++] = 0x10;
+               }
+
+               /* WP */
+               if (check_card_wp(chip, lun))
+                       buf[i++] = 0x80;
+               else
+                       buf[i++] = 0x00;
+
+       } else {
+               buf[i++] = 0x00;        /* MediaType */
+               buf[i++] = 0x00;        /* WP */
+       }
+
+       buf[i++] = 0x00;                /* Reserved */
+
+       if (cmd == MODE_SENSE_10) {
+               buf[i++] = 0x00;  /* Reserved */
+               buf[i++] = 0x00;  /* Block descriptor length(MSB) */
+               buf[i++] = 0x00;  /* Block descriptor length(LSB) */
+
+               /* The Following Data is the content of "Page 0x20" */
+               if (data_size >= 9)
+                       buf[i++] = 0x20;                /* Page Code */
+               if (data_size >= 10)
+                       buf[i++] = 0x62;                /* Page Length */
+               if (data_size >= 11)
+                       buf[i++] = 0x00;                /* No Access Control */
+               if (data_size >= 12) {
+                       if (support_format)
+                               buf[i++] = 0xC0;        /* SF, SGM */
+                       else
+                               buf[i++] = 0x00;
+               }
+       } else {
+               /* The Following Data is the content of "Page 0x20" */
+               if (data_size >= 5)
+                       buf[i++] = 0x20;                /* Page Code */
+               if (data_size >= 6)
+                       buf[i++] = 0x62;                /* Page Length */
+               if (data_size >= 7)
+                       buf[i++] = 0x00;                /* No Access Control */
+               if (data_size >= 8) {
+                       if (support_format)
+                               buf[i++] = 0xC0;        /* SF, SGM */
+                       else
+                               buf[i++] = 0x00;
+               }
+       }
+
+       if (data_size > sys_info_offset) {
+               /* 96 Bytes Attribute Data */
+               int len = data_size - sys_info_offset;
+               len = (len < 96) ? len : 96;
+
+               memcpy(buf + sys_info_offset, ms_card->raw_sys_info, len);
+       }
+}
+
+static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned int lun = SCSI_LUN(srb);
+       unsigned int dataSize;
+       int status;
+       int pro_formatter_flag;
+       unsigned char pageCode, *buf;
+       u8 card = get_lun_card(chip, lun);
+
+#ifndef SUPPORT_MAGIC_GATE
+       if (!check_card_ready(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               scsi_set_resid(srb, scsi_bufflen(srb));
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+#endif
+
+       pro_formatter_flag = 0;
+       dataSize = 8;
+#ifdef SUPPORT_MAGIC_GATE
+       if ((chip->lun2card[lun] & MS_CARD)) {
+               if (!card || (card == MS_CARD)) {
+                       dataSize = 108;
+                       if (chip->mspro_formatter_enable)
+                               pro_formatter_flag = 1;
+               }
+       }
+#else
+       if (card == MS_CARD) {
+               if (chip->mspro_formatter_enable) {
+                       pro_formatter_flag = 1;
+                       dataSize = 108;
+               }
+       }
+#endif
+
+       buf = kmalloc(dataSize, GFP_KERNEL);
+       if (buf == NULL)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       pageCode = srb->cmnd[2] & 0x3f;
+
+       if ((pageCode == 0x3F) || (pageCode == 0x1C) ||
+               (pageCode == 0x00) ||
+               (pro_formatter_flag && (pageCode == 0x20))) {
+               if (srb->cmnd[0] == MODE_SENSE) {
+                       if ((pageCode == 0x3F) || (pageCode == 0x20)) {
+                               ms_mode_sense(chip, srb->cmnd[0],
+                                             lun, buf, dataSize);
+                       } else {
+                               dataSize = 4;
+                               buf[0] = 0x03;
+                               buf[1] = 0x00;
+                               if (check_card_wp(chip, lun))
+                                       buf[2] = 0x80;
+                               else
+                                       buf[2] = 0x00;
+
+                               buf[3] = 0x00;
+                       }
+               } else {
+                       if ((pageCode == 0x3F) || (pageCode == 0x20)) {
+                               ms_mode_sense(chip, srb->cmnd[0],
+                                             lun, buf, dataSize);
+                       } else {
+                               dataSize = 8;
+                               buf[0] = 0x00;
+                               buf[1] = 0x06;
+                               buf[2] = 0x00;
+                               if (check_card_wp(chip, lun))
+                                       buf[3] = 0x80;
+                               else
+                                       buf[3] = 0x00;
+                               buf[4] = 0x00;
+                               buf[5] = 0x00;
+                               buf[6] = 0x00;
+                               buf[7] = 0x00;
+                       }
+               }
+               status = TRANSPORT_GOOD;
+       } else {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               scsi_set_resid(srb, scsi_bufflen(srb));
+               status = TRANSPORT_FAILED;
+       }
+
+       if (status == TRANSPORT_GOOD) {
+               unsigned int len = min_t(unsigned int, scsi_bufflen(srb),
+                                       dataSize);
+               rtsx_stor_set_xfer_buf(buf, len, srb);
+               scsi_set_resid(srb, scsi_bufflen(srb) - len);
+       }
+       kfree(buf);
+
+       return status;
+}
+
+static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+#ifdef SUPPORT_SD_LOCK
+       struct sd_info *sd_card = &(chip->sd_card);
+#endif
+       unsigned int lun = SCSI_LUN(srb);
+       int retval;
+       u32 start_sec;
+       u16 sec_cnt;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       if (!check_card_ready(chip, lun) || (get_card_size(chip, lun) == 0)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (!(CHK_BIT(chip->lun_mc, lun))) {
+               SET_BIT(chip->lun_mc, lun);
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+               return TRANSPORT_FAILED;
+       }
+
+#ifdef SUPPORT_SD_LOCK
+       if (sd_card->sd_erase_status) {
+               /* Accessing to any card is forbidden
+                * until the erase procedure of SD is completed
+                */
+               RTSX_DEBUGP("SD card being erased!\n");
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (get_lun_card(chip, lun) == SD_CARD) {
+               if (sd_card->sd_lock_status & SD_LOCKED) {
+                       RTSX_DEBUGP("SD card locked!\n");
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_READ_FORBIDDEN);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+#endif
+
+       if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) {
+               start_sec = ((u32)srb->cmnd[2] << 24) |
+                       ((u32)srb->cmnd[3] << 16) |
+                       ((u32)srb->cmnd[4] << 8) | ((u32)srb->cmnd[5]);
+               sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
+       } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) {
+               start_sec = ((u32)(srb->cmnd[1] & 0x1F) << 16) |
+                       ((u32)srb->cmnd[2] << 8) | ((u32)srb->cmnd[3]);
+               sec_cnt = srb->cmnd[4];
+       } else if ((srb->cmnd[0] == VENDOR_CMND) &&
+               (srb->cmnd[1] == SCSI_APP_CMD) &&
+               ((srb->cmnd[2] == PP_READ10) || (srb->cmnd[2] == PP_WRITE10))) {
+               start_sec = ((u32)srb->cmnd[4] << 24) |
+                       ((u32)srb->cmnd[5] << 16) |
+                       ((u32)srb->cmnd[6] << 8) | ((u32)srb->cmnd[7]);
+               sec_cnt = ((u16)(srb->cmnd[9]) << 8) | srb->cmnd[10];
+       } else {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       /* In some test, we will receive a start_sec like 0xFFFFFFFF.
+        * In this situation, start_sec + sec_cnt will overflow, so we
+        * need to judge start_sec at first
+        */
+       if ((start_sec > get_card_size(chip, lun)) ||
+                       ((start_sec + sec_cnt) > get_card_size(chip, lun))) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (sec_cnt == 0) {
+               scsi_set_resid(srb, 0);
+               return TRANSPORT_GOOD;
+       }
+
+       if (chip->rw_fail_cnt[lun] == 3) {
+               RTSX_DEBUGP("read/write fail three times in succession\n");
+               if (srb->sc_data_direction == DMA_FROM_DEVICE)
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               else
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
+
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (srb->sc_data_direction == DMA_TO_DEVICE) {
+               if (check_card_wp(chip, lun)) {
+                       RTSX_DEBUGP("Write protected card!\n");
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_WRITE_PROTECT);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+
+       retval = card_rw(srb, chip, start_sec, sec_cnt);
+       if (retval != STATUS_SUCCESS) {
+               if (chip->need_release & chip->lun2card[lun]) {
+                       chip->rw_fail_cnt[lun] = 0;
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               } else {
+                       chip->rw_fail_cnt[lun]++;
+                       if (srb->sc_data_direction == DMA_FROM_DEVICE)
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       else
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+               }
+               retval = TRANSPORT_FAILED;
+               TRACE_GOTO(chip, Exit);
+       } else {
+               chip->rw_fail_cnt[lun] = 0;
+               retval = TRANSPORT_GOOD;
+       }
+
+       scsi_set_resid(srb, 0);
+
+Exit:
+       return retval;
+}
+
+static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned char *buf;
+       unsigned int lun = SCSI_LUN(srb);
+       unsigned int buf_len;
+       u8 card = get_lun_card(chip, lun);
+       u32 card_size;
+       int desc_cnt;
+       int i = 0;
+
+       if (!check_card_ready(chip, lun)) {
+               if (!chip->mspro_formatter_enable) {
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+
+       buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12;
+
+       buf = kmalloc(buf_len, GFP_KERNEL);
+       if (buf == NULL)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       buf[i++] = 0;
+       buf[i++] = 0;
+       buf[i++] = 0;
+
+       /* Capacity List Length */
+       if ((buf_len > 12) && chip->mspro_formatter_enable &&
+                       (chip->lun2card[lun] & MS_CARD) &&
+                       (!card || (card == MS_CARD))) {
+               buf[i++] = 0x10;
+               desc_cnt = 2;
+       } else {
+               buf[i++] = 0x08;
+               desc_cnt = 1;
+       }
+
+       while (desc_cnt) {
+               if (check_card_ready(chip, lun)) {
+                       card_size = get_card_size(chip, lun);
+                       buf[i++] = (unsigned char)(card_size >> 24);
+                       buf[i++] = (unsigned char)(card_size >> 16);
+                       buf[i++] = (unsigned char)(card_size >> 8);
+                       buf[i++] = (unsigned char)card_size;
+
+                       if (desc_cnt == 2)
+                               buf[i++] = 2;
+                       else
+                               buf[i++] = 0;
+               } else {
+                       buf[i++] = 0xFF;
+                       buf[i++] = 0xFF;
+                       buf[i++] = 0xFF;
+                       buf[i++] = 0xFF;
+
+                       if (desc_cnt == 2)
+                               buf[i++] = 3;
+                       else
+                               buf[i++] = 0;
+               }
+
+               buf[i++] = 0x00;
+               buf[i++] = 0x02;
+               buf[i++] = 0x00;
+
+               desc_cnt--;
+       }
+
+       buf_len = min_t(unsigned int, scsi_bufflen(srb), buf_len);
+       rtsx_stor_set_xfer_buf(buf, buf_len, srb);
+       kfree(buf);
+
+       scsi_set_resid(srb, scsi_bufflen(srb) - buf_len);
+
+       return TRANSPORT_GOOD;
+}
+
+static int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned char *buf;
+       unsigned int lun = SCSI_LUN(srb);
+       u32 card_size;
+
+       if (!check_card_ready(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (!(CHK_BIT(chip->lun_mc, lun))) {
+               SET_BIT(chip->lun_mc, lun);
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+               return TRANSPORT_FAILED;
+       }
+
+       buf = kmalloc(8, GFP_KERNEL);
+       if (buf == NULL)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       card_size = get_card_size(chip, lun);
+       buf[0] = (unsigned char)((card_size - 1) >> 24);
+       buf[1] = (unsigned char)((card_size - 1) >> 16);
+       buf[2] = (unsigned char)((card_size - 1) >> 8);
+       buf[3] = (unsigned char)(card_size - 1);
+
+       buf[4] = 0x00;
+       buf[5] = 0x00;
+       buf[6] = 0x02;
+       buf[7] = 0x00;
+
+       rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
+       kfree(buf);
+
+       scsi_set_resid(srb, 0);
+
+       return TRANSPORT_GOOD;
+}
+
+static int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned short len, i;
+       int retval;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
+
+       buf = vmalloc(len);
+       if (!buf)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS) {
+               vfree(buf);
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       for (i = 0; i < len; i++) {
+               retval = spi_read_eeprom(chip, i, buf + i);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+
+       len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len);
+       rtsx_stor_set_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       vfree(buf);
+
+       return TRANSPORT_GOOD;
+}
+
+static int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned short len, i;
+       int retval;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (len == 511) {
+               retval = spi_erase_eeprom_chip(chip);
+               if (retval != STATUS_SUCCESS) {
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_WRITE_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       } else {
+               len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb),
+                                       len);
+               buf = vmalloc(len);
+               if (buf == NULL)
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+
+               rtsx_stor_get_xfer_buf(buf, len, srb);
+               scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+               for (i = 0; i < len; i++) {
+                       retval = spi_write_eeprom(chip, i, buf[i]);
+                       if (retval != STATUS_SUCCESS) {
+                               vfree(buf);
+                               set_sense_type(chip, SCSI_LUN(srb),
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+                       }
+               }
+
+               vfree(buf);
+       }
+
+       return TRANSPORT_GOOD;
+}
+
+static int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned short addr, len, i;
+       int retval;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3];
+       len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
+
+       if (addr < 0xFC00) {
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       buf = vmalloc(len);
+       if (!buf)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS) {
+               vfree(buf);
+               set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       for (i = 0; i < len; i++) {
+               retval = rtsx_read_register(chip, addr + i, buf + i);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+
+       len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len);
+       rtsx_stor_set_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       vfree(buf);
+
+       return TRANSPORT_GOOD;
+}
+
+static int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned short addr, len, i;
+       int retval;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3];
+       len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
+
+       if (addr < 0xFC00) {
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len);
+       buf = vmalloc(len);
+       if (buf == NULL)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       rtsx_stor_get_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS) {
+               vfree(buf);
+               set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       for (i = 0; i < len; i++) {
+               retval = rtsx_write_register(chip, addr + i, 0xFF, buf[i]);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_WRITE_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+
+       vfree(buf);
+
+       return TRANSPORT_GOOD;
+}
+
+static int get_sd_csd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       unsigned int lun = SCSI_LUN(srb);
+
+       if (!check_card_ready(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (get_lun_card(chip, lun) != SD_CARD) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       scsi_set_resid(srb, 0);
+       rtsx_stor_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb);
+
+       return TRANSPORT_GOOD;
+}
+
+static int toggle_gpio_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       u8 gpio = srb->cmnd[2];
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       if (gpio > 3)
+               gpio = 1;
+       toggle_gpio(chip, gpio);
+
+       return TRANSPORT_GOOD;
+}
+
+#ifdef _MSG_TRACE
+static int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned char *ptr, *buf = NULL;
+       int i, msg_cnt;
+       u8 clear;
+       unsigned int buf_len;
+
+       buf_len = 4 + ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) *
+               TRACE_ITEM_CNT);
+
+       if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) {
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       clear = srb->cmnd[2];
+
+       buf = vmalloc(scsi_bufflen(srb));
+       if (buf == NULL)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+       ptr = buf;
+
+       if (chip->trace_msg[chip->msg_idx].valid)
+               msg_cnt = TRACE_ITEM_CNT;
+       else
+               msg_cnt = chip->msg_idx;
+
+       *(ptr++) = (u8)(msg_cnt >> 24);
+       *(ptr++) = (u8)(msg_cnt >> 16);
+       *(ptr++) = (u8)(msg_cnt >> 8);
+       *(ptr++) = (u8)msg_cnt;
+       RTSX_DEBUGP("Trace message count is %d\n", msg_cnt);
+
+       for (i = 1; i <= msg_cnt; i++) {
+               int j, idx;
+
+               idx = chip->msg_idx - i;
+               if (idx < 0)
+                       idx += TRACE_ITEM_CNT;
+
+               *(ptr++) = (u8)(chip->trace_msg[idx].line >> 8);
+               *(ptr++) = (u8)(chip->trace_msg[idx].line);
+               for (j = 0; j < MSG_FUNC_LEN; j++)
+                       *(ptr++) = chip->trace_msg[idx].func[j];
+
+               for (j = 0; j < MSG_FILE_LEN; j++)
+                       *(ptr++) = chip->trace_msg[idx].file[j];
+
+               for (j = 0; j < TIME_VAL_LEN; j++)
+                       *(ptr++) = chip->trace_msg[idx].timeval_buf[j];
+       }
+
+       rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
+       vfree(buf);
+
+       if (clear) {
+               chip->msg_idx = 0;
+               for (i = 0; i < TRACE_ITEM_CNT; i++)
+                       chip->trace_msg[i].valid = 0;
+       }
+
+       scsi_set_resid(srb, 0);
+       return TRANSPORT_GOOD;
+}
+#endif
+
+static int read_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       u8 addr, buf[4];
+       u32 val;
+       unsigned int len;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = srb->cmnd[4];
+
+       val = rtsx_readl(chip, addr);
+       RTSX_DEBUGP("Host register (0x%x): 0x%x\n", addr, val);
+
+       buf[0] = (u8)(val >> 24);
+       buf[1] = (u8)(val >> 16);
+       buf[2] = (u8)(val >> 8);
+       buf[3] = (u8)val;
+
+       len = min_t(unsigned int, scsi_bufflen(srb), 4);
+       rtsx_stor_set_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       return TRANSPORT_GOOD;
+}
+
+static int write_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       u8 addr, buf[4];
+       u32 val;
+       unsigned int len;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = srb->cmnd[4];
+
+       len = min_t(unsigned int, scsi_bufflen(srb), 4);
+       rtsx_stor_get_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       val = ((u32)buf[0] << 24) | ((u32)buf[1] << 16) | ((u32)buf[2]
+                                                       << 8) | buf[3];
+
+       rtsx_writel(chip, addr, val);
+
+       return TRANSPORT_GOOD;
+}
+
+static int set_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned lun = SCSI_LUN(srb);
+
+       if (srb->cmnd[3] == 1) {
+               /* Variable Clock */
+               struct xd_info *xd_card = &(chip->xd_card);
+               struct sd_info *sd_card = &(chip->sd_card);
+               struct ms_info *ms_card = &(chip->ms_card);
+
+               switch (srb->cmnd[4]) {
+               case XD_CARD:
+                       xd_card->xd_clock = srb->cmnd[5];
+                       break;
+
+               case SD_CARD:
+                       sd_card->sd_clock = srb->cmnd[5];
+                       break;
+
+               case MS_CARD:
+                       ms_card->ms_clock = srb->cmnd[5];
+                       break;
+
+               default:
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       } else if (srb->cmnd[3] == 2) {
+               if (srb->cmnd[4]) {
+                       chip->blink_led = 1;
+               } else {
+                       int retval;
+
+                       chip->blink_led = 0;
+
+                       rtsx_disable_aspm(chip);
+
+                       if (chip->ss_en &&
+                               (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+                               rtsx_exit_ss(chip);
+                               wait_timeout(100);
+                       }
+                       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+                       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+                       if (retval != STATUS_SUCCESS) {
+                               set_sense_type(chip, SCSI_LUN(srb),
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+                       }
+
+                       turn_off_led(chip, LED_GPIO);
+               }
+       } else {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       return TRANSPORT_GOOD;
+}
+
+static int get_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned int lun = SCSI_LUN(srb);
+
+       if (srb->cmnd[3] == 1) {
+               struct xd_info *xd_card = &(chip->xd_card);
+               struct sd_info *sd_card = &(chip->sd_card);
+               struct ms_info *ms_card = &(chip->ms_card);
+               u8 tmp;
+
+               switch (srb->cmnd[4]) {
+               case XD_CARD:
+                       tmp = (u8)(xd_card->xd_clock);
+                       break;
+
+               case SD_CARD:
+                       tmp = (u8)(sd_card->sd_clock);
+                       break;
+
+               case MS_CARD:
+                       tmp = (u8)(ms_card->ms_clock);
+                       break;
+
+               default:
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+
+               rtsx_stor_set_xfer_buf(&tmp, 1, srb);
+       } else if (srb->cmnd[3] == 2) {
+               u8 tmp = chip->blink_led;
+               rtsx_stor_set_xfer_buf(&tmp, 1, srb);
+       } else {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       return TRANSPORT_GOOD;
+}
+
+static int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       unsigned int lun = SCSI_LUN(srb);
+       u16 len;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       len = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
+       len = min_t(u16, len, scsi_bufflen(srb));
+
+       if (srb->sc_data_direction == DMA_FROM_DEVICE)
+               RTSX_DEBUGP("Read from device\n");
+       else
+               RTSX_DEBUGP("Write to device\n");
+
+       retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len,
+                       scsi_sg_count(srb), srb->sc_data_direction, 1000);
+       if (retval < 0) {
+               if (srb->sc_data_direction == DMA_FROM_DEVICE)
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               else
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_WRITE_ERR);
+
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+       scsi_set_resid(srb, 0);
+
+       return TRANSPORT_GOOD;
+}
+
+static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       struct ms_info *ms_card = &(chip->ms_card);
+       int buf_len;
+       unsigned int lun = SCSI_LUN(srb);
+       u8 card = get_lun_card(chip, lun);
+       u8 status[32];
+#ifdef SUPPORT_OCP
+       u8 oc_now_mask = 0, oc_ever_mask = 0;
+#endif
+
+       memset(status, 0, 32);
+
+       status[0] = (u8)(chip->product_id);
+       status[1] = chip->ic_version;
+
+       if (chip->auto_delink_en)
+               status[2] = 0x10;
+       else
+               status[2] = 0x00;
+
+       status[3] = 20;
+       status[4] = 10;
+       status[5] = 05;
+       status[6] = 21;
+
+       if (chip->card_wp)
+               status[7] = 0x20;
+       else
+               status[7] = 0x00;
+
+#ifdef SUPPORT_OCP
+       status[8] = 0;
+       if (CHECK_LUN_MODE(chip,
+               SD_MS_2LUN) && (chip->lun2card[lun] == MS_CARD)) {
+               oc_now_mask = MS_OC_NOW;
+               oc_ever_mask = MS_OC_EVER;
+       } else {
+               oc_now_mask = SD_OC_NOW;
+               oc_ever_mask = SD_OC_EVER;
+       }
+
+       if (chip->ocp_stat & oc_now_mask)
+               status[8] |= 0x02;
+
+       if (chip->ocp_stat & oc_ever_mask)
+               status[8] |= 0x01;
+#endif
+
+       if (card == SD_CARD) {
+               if (CHK_SD(sd_card)) {
+                       if (CHK_SD_HCXC(sd_card)) {
+                               if (sd_card->capacity > 0x4000000)
+                                       status[0x0E] = 0x02;
+                               else
+                                       status[0x0E] = 0x01;
+                       } else {
+                               status[0x0E] = 0x00;
+                       }
+
+                       if (CHK_SD_SDR104(sd_card))
+                               status[0x0F] = 0x03;
+                       else if (CHK_SD_DDR50(sd_card))
+                               status[0x0F] = 0x04;
+                       else if (CHK_SD_SDR50(sd_card))
+                               status[0x0F] = 0x02;
+                       else if (CHK_SD_HS(sd_card))
+                               status[0x0F] = 0x01;
+                       else
+                               status[0x0F] = 0x00;
+               } else {
+                       if (CHK_MMC_SECTOR_MODE(sd_card))
+                               status[0x0E] = 0x01;
+                       else
+                               status[0x0E] = 0x00;
+
+                       if (CHK_MMC_DDR52(sd_card))
+                               status[0x0F] = 0x03;
+                       else if (CHK_MMC_52M(sd_card))
+                               status[0x0F] = 0x02;
+                       else if (CHK_MMC_26M(sd_card))
+                               status[0x0F] = 0x01;
+                       else
+                               status[0x0F] = 0x00;
+               }
+       } else if (card == MS_CARD) {
+               if (CHK_MSPRO(ms_card)) {
+                       if (CHK_MSXC(ms_card))
+                               status[0x0E] = 0x01;
+                       else
+                               status[0x0E] = 0x00;
+
+                       if (CHK_HG8BIT(ms_card))
+                               status[0x0F] = 0x01;
+                       else
+                               status[0x0F] = 0x00;
+               }
+       }
+
+#ifdef SUPPORT_SD_LOCK
+       if (card == SD_CARD) {
+               status[0x17] = 0x80;
+               if (sd_card->sd_erase_status)
+                       status[0x17] |= 0x01;
+               if (sd_card->sd_lock_status & SD_LOCKED) {
+                       status[0x17] |= 0x02;
+                       status[0x07] |= 0x40;
+               }
+               if (sd_card->sd_lock_status & SD_PWD_EXIST)
+                       status[0x17] |= 0x04;
+       } else {
+               status[0x17] = 0x00;
+       }
+
+       RTSX_DEBUGP("status[0x17] = 0x%x\n", status[0x17]);
+#endif
+
+       status[0x18] = 0x8A;
+       status[0x1A] = 0x28;
+#ifdef SUPPORT_SD_LOCK
+       status[0x1F] = 0x01;
+#endif
+
+       buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(status));
+       rtsx_stor_set_xfer_buf(status, buf_len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - buf_len);
+
+       return TRANSPORT_GOOD;
+}
+
+static int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int phy_debug_mode;
+       int retval;
+       u16 reg;
+
+       if (!CHECK_PID(chip, 0x5208)) {
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       phy_debug_mode = (int)(srb->cmnd[3]);
+
+       if (phy_debug_mode) {
+               chip->phy_debug_mode = 1;
+               retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+
+               rtsx_disable_bus_int(chip);
+
+               retval = rtsx_read_phy_register(chip, 0x1C, &reg);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+
+               reg |= 0x0001;
+               retval = rtsx_write_phy_register(chip, 0x1C, reg);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+       } else {
+               chip->phy_debug_mode = 0;
+               retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+
+               rtsx_enable_bus_int(chip);
+
+               retval = rtsx_read_phy_register(chip, 0x1C, &reg);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+
+               reg &= 0xFFFE;
+               retval = rtsx_write_phy_register(chip, 0x1C, reg);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       return TRANSPORT_GOOD;
+}
+
+static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval =  STATUS_SUCCESS;
+       unsigned int lun = SCSI_LUN(srb);
+       u8 cmd_type, mask, value, idx;
+       u16 addr;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       switch (srb->cmnd[3]) {
+       case INIT_BATCHCMD:
+               rtsx_init_cmd(chip);
+               break;
+
+       case ADD_BATCHCMD:
+               cmd_type = srb->cmnd[4];
+               if (cmd_type > 2) {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               addr = (srb->cmnd[5] << 8) | srb->cmnd[6];
+               mask = srb->cmnd[7];
+               value = srb->cmnd[8];
+               rtsx_add_cmd(chip, cmd_type, addr, mask, value);
+               break;
+
+       case SEND_BATCHCMD:
+               retval = rtsx_send_cmd(chip, 0, 1000);
+               break;
+
+       case GET_BATCHRSP:
+               idx = srb->cmnd[4];
+               value = *(rtsx_get_cmd_data(chip) + idx);
+               if (scsi_bufflen(srb) < 1) {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               rtsx_stor_set_xfer_buf(&value, 1, srb);
+               scsi_set_resid(srb, 0);
+               break;
+
+       default:
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       return TRANSPORT_GOOD;
+}
+
+static int suit_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int result;
+
+       switch (srb->cmnd[3]) {
+       case INIT_BATCHCMD:
+       case ADD_BATCHCMD:
+       case SEND_BATCHCMD:
+       case GET_BATCHRSP:
+               result = rw_mem_cmd_buf(srb, chip);
+               break;
+       default:
+               result = TRANSPORT_ERROR;
+       }
+
+       return result;
+}
+
+static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned short addr, len, i;
+       int retval;
+       u8 *buf;
+       u16 val;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
+       len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7];
+
+       if (len % 2)
+               len -= len % 2;
+
+       if (len) {
+               buf = vmalloc(len);
+               if (!buf)
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+
+               retval = rtsx_force_power_on(chip, SSC_PDCTL);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+
+               for (i = 0; i < len / 2; i++) {
+                       retval = rtsx_read_phy_register(chip, addr + i, &val);
+                       if (retval != STATUS_SUCCESS) {
+                               vfree(buf);
+                               set_sense_type(chip, SCSI_LUN(srb),
+                                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+                       }
+
+                       buf[2*i] = (u8)(val >> 8);
+                       buf[2*i+1] = (u8)val;
+               }
+
+               len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb),
+                                       len);
+               rtsx_stor_set_xfer_buf(buf, len, srb);
+               scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+               vfree(buf);
+       }
+
+       return TRANSPORT_GOOD;
+}
+
+static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned short addr, len, i;
+       int retval;
+       u8 *buf;
+       u16 val;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
+       len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7];
+
+       if (len % 2)
+               len -= len % 2;
+
+       if (len) {
+               len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb),
+                                       len);
+
+               buf = vmalloc(len);
+               if (buf == NULL)
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+
+               rtsx_stor_get_xfer_buf(buf, len, srb);
+               scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+               retval = rtsx_force_power_on(chip, SSC_PDCTL);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_WRITE_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+
+               for (i = 0; i < len / 2; i++) {
+                       val = ((u16)buf[2*i] << 8) | buf[2*i+1];
+                       retval = rtsx_write_phy_register(chip, addr + i, val);
+                       if (retval != STATUS_SUCCESS) {
+                               vfree(buf);
+                               set_sense_type(chip, SCSI_LUN(srb),
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+                       }
+               }
+
+               vfree(buf);
+       }
+
+       return TRANSPORT_GOOD;
+}
+
+static int erase_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned short addr;
+       int retval;
+       u8 mode;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       mode = srb->cmnd[3];
+       addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
+
+       if (mode == 0) {
+               retval = spi_erase_eeprom_chip(chip);
+               if (retval != STATUS_SUCCESS) {
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_WRITE_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       } else if (mode == 1) {
+               retval = spi_erase_eeprom_byte(chip, addr);
+               if (retval != STATUS_SUCCESS) {
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_WRITE_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       } else {
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       return TRANSPORT_GOOD;
+}
+
+static int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned short addr, len, i;
+       int retval;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
+       len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7];
+
+       buf = vmalloc(len);
+       if (!buf)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS) {
+               vfree(buf);
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       for (i = 0; i < len; i++) {
+               retval = spi_read_eeprom(chip, addr + i, buf + i);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+
+       len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len);
+       rtsx_stor_set_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       vfree(buf);
+
+       return TRANSPORT_GOOD;
+}
+
+static int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned short addr, len, i;
+       int retval;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
+       len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7];
+
+       len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len);
+       buf = vmalloc(len);
+       if (buf == NULL)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       rtsx_stor_get_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS) {
+               vfree(buf);
+               set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       for (i = 0; i < len; i++) {
+               retval = spi_write_eeprom(chip, addr + i, buf[i]);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_WRITE_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+
+       vfree(buf);
+
+       return TRANSPORT_GOOD;
+}
+
+static int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       u8 addr, len, i;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = srb->cmnd[4];
+       len = srb->cmnd[5];
+
+       buf = vmalloc(len);
+       if (!buf)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS) {
+               vfree(buf);
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       for (i = 0; i < len; i++) {
+               retval = rtsx_read_efuse(chip, addr + i, buf + i);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+
+       len = (u8)min_t(unsigned int, scsi_bufflen(srb), len);
+       rtsx_stor_set_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       vfree(buf);
+
+       return TRANSPORT_GOOD;
+}
+
+static int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval, result = TRANSPORT_GOOD;
+       u16 val;
+       u8 addr, len, i;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       addr = srb->cmnd[4];
+       len = srb->cmnd[5];
+
+       len = (u8)min_t(unsigned int, scsi_bufflen(srb), len);
+       buf = vmalloc(len);
+       if (buf == NULL)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       rtsx_stor_get_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       retval = rtsx_force_power_on(chip, SSC_PDCTL);
+       if (retval != STATUS_SUCCESS) {
+               vfree(buf);
+               TRACE_RET(chip, TRANSPORT_ERROR);
+       }
+
+       if (chip->asic_code) {
+               retval = rtsx_read_phy_register(chip, 0x08, &val);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+               }
+
+               retval = rtsx_write_register(chip, PWR_GATE_CTRL,
+                                       LDO3318_PWR_MASK, LDO_OFF);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+               }
+
+               wait_timeout(600);
+
+               retval = rtsx_write_phy_register(chip, 0x08,
+                                               0x4C00 | chip->phy_voltage);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+               }
+
+               retval = rtsx_write_register(chip, PWR_GATE_CTRL,
+                                       LDO3318_PWR_MASK, LDO_ON);
+               if (retval != STATUS_SUCCESS) {
+                       vfree(buf);
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+               }
+
+               wait_timeout(600);
+       }
+
+       retval = card_power_on(chip, SPI_CARD);
+       if (retval != STATUS_SUCCESS) {
+               vfree(buf);
+               TRACE_RET(chip, TRANSPORT_ERROR);
+       }
+
+       wait_timeout(50);
+
+       for (i = 0; i < len; i++) {
+               retval = rtsx_write_efuse(chip, addr + i, buf[i]);
+               if (retval != STATUS_SUCCESS) {
+                       set_sense_type(chip, SCSI_LUN(srb),
+                               SENSE_TYPE_MEDIA_WRITE_ERR);
+                       result = TRANSPORT_FAILED;
+                       TRACE_GOTO(chip, Exit);
+               }
+       }
+
+Exit:
+       vfree(buf);
+
+       retval = card_power_off(chip, SPI_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       if (chip->asic_code) {
+               retval = rtsx_write_register(chip, PWR_GATE_CTRL,
+                                       LDO3318_PWR_MASK, LDO_OFF);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+
+               wait_timeout(600);
+
+               retval = rtsx_write_phy_register(chip, 0x08, val);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+
+               retval = rtsx_write_register(chip, PWR_GATE_CTRL,
+                                       LDO3318_PWR_MASK, LDO_ON);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+       }
+
+       return result;
+}
+
+static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       u8 func, func_max;
+       u16 addr, len;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       func = srb->cmnd[3];
+       addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
+       len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7];
+
+       RTSX_DEBUGP("%s: func = %d, addr = 0x%x, len = %d\n", __func__, func,
+               addr, len);
+
+       if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip))
+               func_max = 1;
+       else
+               func_max = 0;
+
+       if (func > func_max) {
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       buf = vmalloc(len);
+       if (!buf)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       retval = rtsx_read_cfg_seq(chip, func, addr, buf, len);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               vfree(buf);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       len = (u16)min_t(unsigned int, scsi_bufflen(srb), len);
+       rtsx_stor_set_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       vfree(buf);
+
+       return TRANSPORT_GOOD;
+}
+
+static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       u8 func, func_max;
+       u16 addr, len;
+       u8 *buf;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       func = srb->cmnd[3];
+       addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
+       len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7];
+
+       RTSX_DEBUGP("%s: func = %d, addr = 0x%x\n", __func__, func, addr);
+
+       if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip))
+               func_max = 1;
+       else
+               func_max = 0;
+
+       if (func > func_max) {
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len);
+       buf = vmalloc(len);
+       if (!buf)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       rtsx_stor_get_xfer_buf(buf, len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - len);
+
+       retval = rtsx_write_cfg_seq(chip, func, addr, buf, len);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
+               vfree(buf);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       vfree(buf);
+
+       return TRANSPORT_GOOD;
+}
+
+static int app_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int result;
+
+       switch (srb->cmnd[2]) {
+       case PP_READ10:
+       case PP_WRITE10:
+               result = read_write(srb, chip);
+               break;
+
+       case READ_HOST_REG:
+               result = read_host_reg(srb, chip);
+               break;
+
+       case WRITE_HOST_REG:
+               result = write_host_reg(srb, chip);
+               break;
+
+       case GET_VAR:
+               result = get_variable(srb, chip);
+               break;
+
+       case SET_VAR:
+               result = set_variable(srb, chip);
+               break;
+
+       case DMA_READ:
+       case DMA_WRITE:
+               result = dma_access_ring_buffer(srb, chip);
+               break;
+
+       case READ_PHY:
+               result = read_phy_register(srb, chip);
+               break;
+
+       case WRITE_PHY:
+               result = write_phy_register(srb, chip);
+               break;
+
+       case ERASE_EEPROM2:
+               result = erase_eeprom2(srb, chip);
+               break;
+
+       case READ_EEPROM2:
+               result = read_eeprom2(srb, chip);
+               break;
+
+       case WRITE_EEPROM2:
+               result = write_eeprom2(srb, chip);
+               break;
+
+       case READ_EFUSE:
+               result = read_efuse(srb, chip);
+               break;
+
+       case WRITE_EFUSE:
+               result = write_efuse(srb, chip);
+               break;
+
+       case READ_CFG:
+               result = read_cfg_byte(srb, chip);
+               break;
+
+       case WRITE_CFG:
+               result = write_cfg_byte(srb, chip);
+               break;
+
+       case SET_CHIP_MODE:
+               result = set_chip_mode(srb, chip);
+               break;
+
+       case SUIT_CMD:
+               result = suit_cmd(srb, chip);
+               break;
+
+       case GET_DEV_STATUS:
+               result = get_dev_status(srb, chip);
+               break;
+
+       default:
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       return result;
+}
+
+
+static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       u8 rtsx_status[16];
+       int buf_len;
+       unsigned int lun = SCSI_LUN(srb);
+
+       rtsx_status[0] = (u8)(chip->vendor_id >> 8);
+       rtsx_status[1] = (u8)(chip->vendor_id);
+
+       rtsx_status[2] = (u8)(chip->product_id >> 8);
+       rtsx_status[3] = (u8)(chip->product_id);
+
+       rtsx_status[4] = (u8)lun;
+
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
+               if (chip->lun2card[lun] == SD_CARD)
+                       rtsx_status[5] = 2;
+               else
+                       rtsx_status[5] = 3;
+       } else {
+               if (chip->card_exist) {
+                       if (chip->card_exist & XD_CARD)
+                               rtsx_status[5] = 4;
+                       else if (chip->card_exist & SD_CARD)
+                               rtsx_status[5] = 2;
+                       else if (chip->card_exist & MS_CARD)
+                               rtsx_status[5] = 3;
+                       else
+                               rtsx_status[5] = 7;
+               } else {
+                       rtsx_status[5] = 7;
+               }
+       }
+
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
+               rtsx_status[6] = 2;
+       else
+               rtsx_status[6] = 1;
+
+       rtsx_status[7] = (u8)(chip->product_id);
+       rtsx_status[8] = chip->ic_version;
+
+       if (check_card_exist(chip, lun))
+               rtsx_status[9] = 1;
+       else
+               rtsx_status[9] = 0;
+
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
+               rtsx_status[10] = 0;
+       else
+               rtsx_status[10] = 1;
+
+       if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
+               if (chip->lun2card[lun] == SD_CARD)
+                       rtsx_status[11] = SD_CARD;
+               else
+                       rtsx_status[11] = MS_CARD;
+       } else {
+               rtsx_status[11] = XD_CARD | SD_CARD | MS_CARD;
+       }
+
+       if (check_card_ready(chip, lun))
+               rtsx_status[12] = 1;
+       else
+               rtsx_status[12] = 0;
+
+       if (get_lun_card(chip, lun) == XD_CARD) {
+               rtsx_status[13] = 0x40;
+       } else if (get_lun_card(chip, lun) == SD_CARD) {
+               struct sd_info *sd_card = &(chip->sd_card);
+
+               rtsx_status[13] = 0x20;
+               if (CHK_SD(sd_card)) {
+                       if (CHK_SD_HCXC(sd_card))
+                               rtsx_status[13] |= 0x04;
+                       if (CHK_SD_HS(sd_card))
+                               rtsx_status[13] |= 0x02;
+               } else {
+                       rtsx_status[13] |= 0x08;
+                       if (CHK_MMC_52M(sd_card))
+                               rtsx_status[13] |= 0x02;
+                       if (CHK_MMC_SECTOR_MODE(sd_card))
+                               rtsx_status[13] |= 0x04;
+               }
+       } else if (get_lun_card(chip, lun) == MS_CARD) {
+               struct ms_info *ms_card = &(chip->ms_card);
+
+               if (CHK_MSPRO(ms_card)) {
+                       rtsx_status[13] = 0x38;
+                       if (CHK_HG8BIT(ms_card))
+                               rtsx_status[13] |= 0x04;
+#ifdef SUPPORT_MSXC
+                       if (CHK_MSXC(ms_card))
+                               rtsx_status[13] |= 0x01;
+#endif
+               } else {
+                       rtsx_status[13] = 0x30;
+               }
+       } else {
+               if (CHECK_LUN_MODE(chip, DEFAULT_SINGLE)) {
+#ifdef SUPPORT_SDIO
+                       if (chip->sd_io && chip->sd_int)
+                               rtsx_status[13] = 0x60;
+                       else
+                               rtsx_status[13] = 0x70;
+#else
+                       rtsx_status[13] = 0x70;
+#endif
+               } else {
+                       if (chip->lun2card[lun] == SD_CARD)
+                               rtsx_status[13] = 0x20;
+                       else
+                               rtsx_status[13] = 0x30;
+               }
+       }
+
+       rtsx_status[14] = 0x78;
+       if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip))
+               rtsx_status[15] = 0x83;
+       else
+               rtsx_status[15] = 0x82;
+
+       buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(rtsx_status));
+       rtsx_stor_set_xfer_buf(rtsx_status, buf_len, srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - buf_len);
+
+       return TRANSPORT_GOOD;
+}
+
+static int get_card_bus_width(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned int lun = SCSI_LUN(srb);
+       u8 card, bus_width;
+
+       if (!check_card_ready(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       card = get_lun_card(chip, lun);
+       if ((card == SD_CARD) || (card == MS_CARD)) {
+               bus_width = chip->card_bus_width[lun];
+       } else {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       scsi_set_resid(srb, 0);
+       rtsx_stor_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb);
+
+       return TRANSPORT_GOOD;
+}
+
+static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int result;
+       unsigned int lun = SCSI_LUN(srb);
+       u8 gpio_dir;
+
+       if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       rtsx_force_power_on(chip, SSC_PDCTL);
+
+       rtsx_read_register(chip, CARD_GPIO_DIR, &gpio_dir);
+       rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir & 0x06);
+
+       switch (srb->cmnd[2]) {
+       case SCSI_SPI_GETSTATUS:
+               result = spi_get_status(srb, chip);
+               break;
+
+       case SCSI_SPI_SETPARAMETER:
+               result = spi_set_parameter(srb, chip);
+               break;
+
+       case SCSI_SPI_READFALSHID:
+               result = spi_read_flash_id(srb, chip);
+               break;
+
+       case SCSI_SPI_READFLASH:
+               result = spi_read_flash(srb, chip);
+               break;
+
+       case SCSI_SPI_WRITEFLASH:
+               result = spi_write_flash(srb, chip);
+               break;
+
+       case SCSI_SPI_WRITEFLASHSTATUS:
+               result = spi_write_flash_status(srb, chip);
+               break;
+
+       case SCSI_SPI_ERASEFLASH:
+               result = spi_erase_flash(srb, chip);
+               break;
+
+       default:
+               rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir);
+
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir);
+
+       if (result != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_FAILED);
+
+       return TRANSPORT_GOOD;
+}
+
+static int vendor_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int result;
+
+       switch (srb->cmnd[1]) {
+       case READ_STATUS:
+               result = read_status(srb, chip);
+               break;
+
+       case READ_MEM:
+               result = read_mem(srb, chip);
+               break;
+
+       case WRITE_MEM:
+               result = write_mem(srb, chip);
+               break;
+
+       case READ_EEPROM:
+               result = read_eeprom(srb, chip);
+               break;
+
+       case WRITE_EEPROM:
+               result = write_eeprom(srb, chip);
+               break;
+
+       case TOGGLE_GPIO:
+               result = toggle_gpio_cmd(srb, chip);
+               break;
+
+       case GET_SD_CSD:
+               result = get_sd_csd(srb, chip);
+               break;
+
+       case GET_BUS_WIDTH:
+               result = get_card_bus_width(srb, chip);
+               break;
+
+#ifdef _MSG_TRACE
+       case TRACE_MSG:
+               result = trace_msg_cmd(srb, chip);
+               break;
+#endif
+
+       case SCSI_APP_CMD:
+               result = app_cmd(srb, chip);
+               break;
+
+       case SPI_VENDOR_COMMAND:
+               result = spi_vendor_cmd(srb, chip);
+               break;
+
+       default:
+               set_sense_type(chip, SCSI_LUN(srb),
+                       SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       return result;
+}
+
+#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK)
+void led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned int lun = SCSI_LUN(srb);
+       u16 sec_cnt;
+
+       if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10))
+               sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
+       else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6))
+               sec_cnt = srb->cmnd[4];
+       else
+               return;
+
+       if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) {
+               toggle_gpio(chip, LED_GPIO);
+               chip->rw_cap[lun] = 0;
+       } else {
+               chip->rw_cap[lun] += sec_cnt;
+       }
+}
+#endif
+
+static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int retval, quick_format;
+
+       if (get_lun_card(chip, lun) != MS_CARD) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47) ||
+               (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D) ||
+               (srb->cmnd[7] != 0x74)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+
+               if (!check_card_ready(chip, lun) ||
+                               (get_card_size(chip, lun) == 0)) {
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       if (srb->cmnd[8] & 0x01)
+               quick_format = 0;
+       else
+               quick_format = 1;
+
+       if (!(chip->card_ready & MS_CARD)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (chip->card_wp & MS_CARD) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (!CHK_MSPRO(ms_card)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       scsi_set_resid(srb, 0);
+       return TRANSPORT_GOOD;
+}
+
+#ifdef SUPPORT_PCGL_1P18
+static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       unsigned int lun = SCSI_LUN(srb);
+       u8 dev_info_id, data_len;
+       u8 *buf;
+       unsigned int buf_len;
+       int i;
+
+       if (!check_card_ready(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+       if ((get_lun_card(chip, lun) != MS_CARD)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) ||
+               (srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) ||
+               (srb->cmnd[7] != 0x44)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       dev_info_id = srb->cmnd[3];
+       if ((CHK_MSXC(ms_card) && (dev_info_id == 0x10)) ||
+                       (!CHK_MSXC(ms_card) && (dev_info_id == 0x13)) ||
+                       !CHK_MSPRO(ms_card)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (dev_info_id == 0x15)
+               buf_len = data_len = 0x3A;
+       else
+               buf_len = data_len = 0x6A;
+
+       buf = kmalloc(buf_len, GFP_KERNEL);
+       if (!buf)
+               TRACE_RET(chip, TRANSPORT_ERROR);
+
+       i = 0;
+       /*  GET Memory Stick Media Information Response Header */
+       buf[i++] = 0x00;                /* Data length MSB */
+       buf[i++] = data_len;            /* Data length LSB */
+       /* Device Information Type Code */
+       if (CHK_MSXC(ms_card))
+               buf[i++] = 0x03;
+       else
+               buf[i++] = 0x02;
+
+       /* SGM bit */
+       buf[i++] = 0x01;
+       /* Reserved */
+       buf[i++] = 0x00;
+       buf[i++] = 0x00;
+       buf[i++] = 0x00;
+       /* Number of Device Information */
+       buf[i++] = 0x01;
+
+       /*  Device Information Body */
+
+       /* Device Information ID Number */
+       buf[i++] = dev_info_id;
+       /* Device Information Length */
+       if (dev_info_id == 0x15)
+               data_len = 0x31;
+       else
+               data_len = 0x61;
+
+       buf[i++] = 0x00;                /* Data length MSB */
+       buf[i++] = data_len;            /* Data length LSB */
+       /* Valid Bit */
+       buf[i++] = 0x80;
+       if ((dev_info_id == 0x10) || (dev_info_id == 0x13)) {
+               /* System Information */
+               memcpy(buf+i, ms_card->raw_sys_info, 96);
+       } else {
+               /* Model Name */
+               memcpy(buf+i, ms_card->raw_model_name, 48);
+       }
+
+       rtsx_stor_set_xfer_buf(buf, buf_len, srb);
+
+       if (dev_info_id == 0x15)
+               scsi_set_resid(srb, scsi_bufflen(srb)-0x3C);
+       else
+               scsi_set_resid(srb, scsi_bufflen(srb)-0x6C);
+
+       kfree(buf);
+       return STATUS_SUCCESS;
+}
+#endif
+
+static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval = TRANSPORT_ERROR;
+
+       if (srb->cmnd[2] == MS_FORMAT)
+               retval = ms_format_cmnd(srb, chip);
+#ifdef SUPPORT_PCGL_1P18
+       else if (srb->cmnd[2] == GET_MS_INFORMATION)
+               retval = get_ms_information(srb, chip);
+#endif
+
+       return retval;
+}
+
+#ifdef SUPPORT_CPRM
+static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       unsigned int lun = SCSI_LUN(srb);
+       int result;
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       sd_cleanup_work(chip);
+
+       if (!check_card_ready(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+       if ((get_lun_card(chip, lun) != SD_CARD)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       switch (srb->cmnd[0]) {
+       case SD_PASS_THRU_MODE:
+               result = sd_pass_thru_mode(srb, chip);
+               break;
+
+       case SD_EXECUTE_NO_DATA:
+               result = sd_execute_no_data(srb, chip);
+               break;
+
+       case SD_EXECUTE_READ:
+               result = sd_execute_read_data(srb, chip);
+               break;
+
+       case SD_EXECUTE_WRITE:
+               result = sd_execute_write_data(srb, chip);
+               break;
+
+       case SD_GET_RSP:
+               result = sd_get_cmd_rsp(srb, chip);
+               break;
+
+       case SD_HW_RST:
+               result = sd_hw_rst(srb, chip);
+               break;
+
+       default:
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       return result;
+}
+#endif
+
+#ifdef SUPPORT_MAGIC_GATE
+static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int retval;
+       u8 key_format;
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       ms_cleanup_work(chip);
+
+       if (!check_card_ready(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+       if ((get_lun_card(chip, lun) != MS_CARD)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (srb->cmnd[7] != KC_MG_R_PRO) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (!CHK_MSPRO(ms_card)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       key_format = srb->cmnd[10] & 0x3F;
+       RTSX_DEBUGP("key_format = 0x%x\n", key_format);
+
+       switch (key_format) {
+       case KF_GET_LOC_EKB:
+               if ((scsi_bufflen(srb) == 0x41C) &&
+                       (srb->cmnd[8] == 0x04) &&
+                       (srb->cmnd[9] == 0x1C)) {
+                       retval = mg_get_local_EKB(srb, chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+
+               } else {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               break;
+
+       case KF_RSP_CHG:
+               if ((scsi_bufflen(srb) == 0x24) &&
+                       (srb->cmnd[8] == 0x00) &&
+                       (srb->cmnd[9] == 0x24)) {
+                       retval = mg_get_rsp_chg(srb, chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+
+               } else {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               break;
+
+       case KF_GET_ICV:
+               ms_card->mg_entry_num = srb->cmnd[5];
+               if ((scsi_bufflen(srb) == 0x404) &&
+                       (srb->cmnd[8] == 0x04) &&
+                       (srb->cmnd[9] == 0x04) &&
+                       (srb->cmnd[2] == 0x00) &&
+                       (srb->cmnd[3] == 0x00) &&
+                       (srb->cmnd[4] == 0x00) &&
+                       (srb->cmnd[5] < 32)) {
+                       retval = mg_get_ICV(srb, chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+
+               } else {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               break;
+
+       default:
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       scsi_set_resid(srb, 0);
+       return TRANSPORT_GOOD;
+}
+
+static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct ms_info *ms_card = &(chip->ms_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int retval;
+       u8 key_format;
+
+       RTSX_DEBUGP("--%s--\n", __func__);
+
+       rtsx_disable_aspm(chip);
+
+       if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
+               rtsx_exit_ss(chip);
+               wait_timeout(100);
+       }
+       rtsx_set_stat(chip, RTSX_STAT_RUN);
+
+       ms_cleanup_work(chip);
+
+       if (!check_card_ready(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+       if (check_card_wp(chip, lun)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+       if ((get_lun_card(chip, lun) != MS_CARD)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (srb->cmnd[7] != KC_MG_R_PRO) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (!CHK_MSPRO(ms_card)) {
+               set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       key_format = srb->cmnd[10] & 0x3F;
+       RTSX_DEBUGP("key_format = 0x%x\n", key_format);
+
+       switch (key_format) {
+       case KF_SET_LEAF_ID:
+               if ((scsi_bufflen(srb) == 0x0C) &&
+                       (srb->cmnd[8] == 0x00) &&
+                       (srb->cmnd[9] == 0x0C)) {
+                       retval = mg_set_leaf_id(srb, chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+
+               } else {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               break;
+
+       case KF_CHG_HOST:
+               if ((scsi_bufflen(srb) == 0x0C) &&
+                       (srb->cmnd[8] == 0x00) &&
+                       (srb->cmnd[9] == 0x0C)) {
+                       retval = mg_chg(srb, chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+
+               } else {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               break;
+
+       case KF_RSP_HOST:
+               if ((scsi_bufflen(srb) == 0x0C) &&
+                       (srb->cmnd[8] == 0x00) &&
+                       (srb->cmnd[9] == 0x0C)) {
+                       retval = mg_rsp(srb, chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+
+               } else {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               break;
+
+       case KF_SET_ICV:
+               ms_card->mg_entry_num = srb->cmnd[5];
+               if ((scsi_bufflen(srb) == 0x404) &&
+                       (srb->cmnd[8] == 0x04) &&
+                       (srb->cmnd[9] == 0x04) &&
+                       (srb->cmnd[2] == 0x00) &&
+                       (srb->cmnd[3] == 0x00) &&
+                       (srb->cmnd[4] == 0x00) &&
+                       (srb->cmnd[5] < 32)) {
+                       retval = mg_set_ICV(srb, chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+
+               } else {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               break;
+
+       default:
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       scsi_set_resid(srb, 0);
+       return TRANSPORT_GOOD;
+}
+#endif
+
+int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+#ifdef SUPPORT_SD_LOCK
+       struct sd_info *sd_card = &(chip->sd_card);
+#endif
+       struct ms_info *ms_card = &(chip->ms_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int result;
+
+#ifdef SUPPORT_SD_LOCK
+       if (sd_card->sd_erase_status) {
+               /* Block all SCSI command except for
+                * REQUEST_SENSE and rs_ppstatus
+                */
+               if (!((srb->cmnd[0] == VENDOR_CMND) &&
+                               (srb->cmnd[1] == SCSI_APP_CMD) &&
+                               (srb->cmnd[2] == GET_DEV_STATUS)) &&
+                               (srb->cmnd[0] != REQUEST_SENSE)) {
+                       /* Logical Unit Not Ready Format in Progress */
+                       set_sense_data(chip, lun, CUR_ERR,
+                                      0x02, 0, 0x04, 0x04, 0, 0);
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+#endif
+
+       if ((get_lun_card(chip, lun) == MS_CARD) &&
+                       (ms_card->format_status == FORMAT_IN_PROGRESS)) {
+               if ((srb->cmnd[0] != REQUEST_SENSE) &&
+                       (srb->cmnd[0] != INQUIRY)) {
+                       /* Logical Unit Not Ready Format in Progress */
+                       set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04,
+                                       0, (u16)(ms_card->progress));
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+
+       switch (srb->cmnd[0]) {
+       case READ_10:
+       case WRITE_10:
+       case READ_6:
+       case WRITE_6:
+               result = read_write(srb, chip);
+#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK)
+               led_shine(srb, chip);
+#endif
+               break;
+
+       case TEST_UNIT_READY:
+               result = test_unit_ready(srb, chip);
+               break;
+
+       case INQUIRY:
+               result = inquiry(srb, chip);
+               break;
+
+       case READ_CAPACITY:
+               result = read_capacity(srb, chip);
+               break;
+
+       case START_STOP:
+               result = start_stop_unit(srb, chip);
+               break;
+
+       case ALLOW_MEDIUM_REMOVAL:
+               result = allow_medium_removal(srb, chip);
+               break;
+
+       case REQUEST_SENSE:
+               result = request_sense(srb, chip);
+               break;
+
+       case MODE_SENSE:
+       case MODE_SENSE_10:
+               result = mode_sense(srb, chip);
+               break;
+
+       case 0x23:
+               result = read_format_capacity(srb, chip);
+               break;
+
+       case VENDOR_CMND:
+               result = vendor_cmnd(srb, chip);
+               break;
+
+       case MS_SP_CMND:
+               result = ms_sp_cmnd(srb, chip);
+               break;
+
+#ifdef SUPPORT_CPRM
+       case SD_PASS_THRU_MODE:
+       case SD_EXECUTE_NO_DATA:
+       case SD_EXECUTE_READ:
+       case SD_EXECUTE_WRITE:
+       case SD_GET_RSP:
+       case SD_HW_RST:
+               result = sd_extention_cmnd(srb, chip);
+               break;
+#endif
+
+#ifdef SUPPORT_MAGIC_GATE
+       case CMD_MSPRO_MG_RKEY:
+               result = mg_report_key(srb, chip);
+               break;
+
+       case CMD_MSPRO_MG_SKEY:
+               result = mg_send_key(srb, chip);
+               break;
+#endif
+
+       case FORMAT_UNIT:
+       case MODE_SELECT:
+       case VERIFY:
+               result = TRANSPORT_GOOD;
+               break;
+
+       default:
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               result = TRANSPORT_FAILED;
+       }
+
+       return result;
+}
diff --git a/drivers/staging/rts5208/rtsx_scsi.h b/drivers/staging/rts5208/rtsx_scsi.h
new file mode 100644 (file)
index 0000000..d175057
--- /dev/null
@@ -0,0 +1,143 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_SCSI_H
+#define __REALTEK_RTSX_SCSI_H
+
+#include "rtsx.h"
+#include "rtsx_chip.h"
+
+#define MS_SP_CMND             0xFA
+#define MS_FORMAT              0xA0
+#define GET_MS_INFORMATION     0xB0
+
+#define VENDOR_CMND            0xF0
+
+#define READ_STATUS            0x09
+
+#define READ_EEPROM            0x04
+#define WRITE_EEPROM           0x05
+#define READ_MEM               0x0D
+#define WRITE_MEM              0x0E
+#define GET_BUS_WIDTH          0x13
+#define GET_SD_CSD             0x14
+#define TOGGLE_GPIO            0x15
+#define TRACE_MSG              0x18
+
+#define SCSI_APP_CMD           0x10
+
+#define PP_READ10              0x1A
+#define PP_WRITE10             0x0A
+#define READ_HOST_REG          0x1D
+#define WRITE_HOST_REG         0x0D
+#define SET_VAR                        0x05
+#define GET_VAR                        0x15
+#define DMA_READ               0x16
+#define DMA_WRITE              0x06
+#define GET_DEV_STATUS         0x10
+#define SET_CHIP_MODE          0x27
+#define SUIT_CMD               0xE0
+#define WRITE_PHY              0x07
+#define READ_PHY               0x17
+#define WRITE_EEPROM2          0x03
+#define READ_EEPROM2           0x13
+#define ERASE_EEPROM2          0x23
+#define WRITE_EFUSE            0x04
+#define READ_EFUSE             0x14
+#define WRITE_CFG              0x0E
+#define READ_CFG               0x1E
+
+#define SPI_VENDOR_COMMAND             0x1C
+
+#define        SCSI_SPI_GETSTATUS              0x00
+#define        SCSI_SPI_SETPARAMETER           0x01
+#define        SCSI_SPI_READFALSHID            0x02
+#define        SCSI_SPI_READFLASH              0x03
+#define        SCSI_SPI_WRITEFLASH             0x04
+#define        SCSI_SPI_WRITEFLASHSTATUS       0x05
+#define        SCSI_SPI_ERASEFLASH             0x06
+
+#define INIT_BATCHCMD          0x41
+#define ADD_BATCHCMD           0x42
+#define SEND_BATCHCMD          0x43
+#define GET_BATCHRSP           0x44
+
+#define CHIP_NORMALMODE                0x00
+#define CHIP_DEBUGMODE         0x01
+
+/* SD Pass Through Command Extension */
+#define SD_PASS_THRU_MODE      0xD0
+#define SD_EXECUTE_NO_DATA     0xD1
+#define SD_EXECUTE_READ                0xD2
+#define SD_EXECUTE_WRITE       0xD3
+#define SD_GET_RSP             0xD4
+#define SD_HW_RST              0xD6
+
+#ifdef SUPPORT_MAGIC_GATE
+#define CMD_MSPRO_MG_RKEY      0xA4   /* Report Key Command */
+#define CMD_MSPRO_MG_SKEY      0xA3   /* Send Key Command */
+
+/* CBWCB field: key class */
+#define KC_MG_R_PRO            0xBE   /* MG-R PRO*/
+
+/* CBWCB field: key format */
+#define KF_SET_LEAF_ID         0x31   /* Set Leaf ID */
+#define KF_GET_LOC_EKB         0x32   /* Get Local EKB */
+#define KF_CHG_HOST            0x33   /* Challenge (host) */
+#define KF_RSP_CHG             0x34   /* Response and Challenge (device)  */
+#define KF_RSP_HOST            0x35   /* Response (host) */
+#define KF_GET_ICV             0x36   /* Get ICV */
+#define KF_SET_ICV             0x37   /* SSet ICV */
+#endif
+
+/* Sense type */
+#define        SENSE_TYPE_NO_SENSE                             0
+#define        SENSE_TYPE_MEDIA_CHANGE                         1
+#define        SENSE_TYPE_MEDIA_NOT_PRESENT                    2
+#define        SENSE_TYPE_MEDIA_LBA_OVER_RANGE                 3
+#define        SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT                4
+#define        SENSE_TYPE_MEDIA_WRITE_PROTECT                  5
+#define        SENSE_TYPE_MEDIA_INVALID_CMD_FIELD              6
+#define        SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR             7
+#define        SENSE_TYPE_MEDIA_WRITE_ERR                      8
+#define SENSE_TYPE_FORMAT_IN_PROGRESS                  9
+#define SENSE_TYPE_FORMAT_CMD_FAILED                   10
+#ifdef SUPPORT_MAGIC_GATE
+#define SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB               0x0b
+#define SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN              0x0c
+#define SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM              0x0d
+#define SENSE_TYPE_MG_WRITE_ERR                                0x0e
+#endif
+#ifdef SUPPORT_SD_LOCK
+/* FOR Locked SD card*/
+#define SENSE_TYPE_MEDIA_READ_FORBIDDEN                        0x10
+#endif
+
+void scsi_show_command(struct scsi_cmnd *srb);
+void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type);
+void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code,
+               u8 sense_key, u32 info, u8 asc, u8 ascq,
+               u8 sns_key_info0, u16 sns_key_info1);
+int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+
+#endif   /* __REALTEK_RTSX_SCSI_H */
diff --git a/drivers/staging/rts5208/rtsx_sys.h b/drivers/staging/rts5208/rtsx_sys.h
new file mode 100644 (file)
index 0000000..0b6b4d4
--- /dev/null
@@ -0,0 +1,50 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __RTSX_SYS_H
+#define __RTSX_SYS_H
+
+#include "rtsx.h"
+#include "rtsx_chip.h"
+#include "rtsx_card.h"
+
+typedef dma_addr_t ULONG_PTR;
+
+static inline void rtsx_exclusive_enter_ss(struct rtsx_chip *chip)
+{
+       struct rtsx_dev *dev = chip->rtsx;
+
+       spin_lock(&(dev->reg_lock));
+       rtsx_enter_ss(chip);
+       spin_unlock(&(dev->reg_lock));
+}
+
+static inline void rtsx_reset_detected_cards(struct rtsx_chip *chip, int flag)
+{
+       rtsx_reset_cards(chip);
+}
+
+#define RTSX_MSG_IN_INT(x)
+
+#endif  /* __RTSX_SYS_H */
+
diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c
new file mode 100644 (file)
index 0000000..97b7b01
--- /dev/null
@@ -0,0 +1,769 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+
+#include "rtsx.h"
+#include "rtsx_scsi.h"
+#include "rtsx_transport.h"
+#include "rtsx_chip.h"
+#include "rtsx_card.h"
+#include "debug.h"
+
+/***********************************************************************
+ * Scatter-gather transfer buffer access routines
+ ***********************************************************************/
+
+/* Copy a buffer of length buflen to/from the srb's transfer buffer.
+ * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer
+ * points to a list of s-g entries and we ignore srb->request_bufflen.
+ * For non-scatter-gather transfers, srb->request_buffer points to the
+ * transfer buffer itself and srb->request_bufflen is the buffer's length.)
+ * Update the *index and *offset variables so that the next copy will
+ * pick up from where this one left off. */
+
+unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer,
+       unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index,
+       unsigned int *offset, enum xfer_buf_dir dir)
+{
+       unsigned int cnt;
+
+       /* If not using scatter-gather, just transfer the data directly.
+        * Make certain it will fit in the available buffer space. */
+       if (scsi_sg_count(srb) == 0) {
+               if (*offset >= scsi_bufflen(srb))
+                       return 0;
+               cnt = min(buflen, scsi_bufflen(srb) - *offset);
+               if (dir == TO_XFER_BUF)
+                       memcpy((unsigned char *) scsi_sglist(srb) + *offset,
+                                       buffer, cnt);
+               else
+                       memcpy(buffer, (unsigned char *) scsi_sglist(srb) +
+                                       *offset, cnt);
+               *offset += cnt;
+
+       /* Using scatter-gather.  We have to go through the list one entry
+        * at a time.  Each s-g entry contains some number of pages, and
+        * each page has to be kmap()'ed separately.  If the page is already
+        * in kernel-addressable memory then kmap() will return its address.
+        * If the page is not directly accessible -- such as a user buffer
+        * located in high memory -- then kmap() will map it to a temporary
+        * position in the kernel's virtual address space. */
+       } else {
+               struct scatterlist *sg =
+                               (struct scatterlist *) scsi_sglist(srb)
+                               + *index;
+
+               /* This loop handles a single s-g list entry, which may
+                * include multiple pages.  Find the initial page structure
+                * and the starting offset within the page, and update
+                * the *offset and *index values for the next loop. */
+               cnt = 0;
+               while (cnt < buflen && *index < scsi_sg_count(srb)) {
+                       struct page *page = sg_page(sg) +
+                                       ((sg->offset + *offset) >> PAGE_SHIFT);
+                       unsigned int poff =
+                                       (sg->offset + *offset) & (PAGE_SIZE-1);
+                       unsigned int sglen = sg->length - *offset;
+
+                       if (sglen > buflen - cnt) {
+
+                               /* Transfer ends within this s-g entry */
+                               sglen = buflen - cnt;
+                               *offset += sglen;
+                       } else {
+
+                               /* Transfer continues to next s-g entry */
+                               *offset = 0;
+                               ++*index;
+                               ++sg;
+                       }
+
+                       /* Transfer the data for all the pages in this
+                        * s-g entry.  For each page: call kmap(), do the
+                        * transfer, and call kunmap() immediately after. */
+                       while (sglen > 0) {
+                               unsigned int plen = min(sglen, (unsigned int)
+                                               PAGE_SIZE - poff);
+                               unsigned char *ptr = kmap(page);
+
+                               if (dir == TO_XFER_BUF)
+                                       memcpy(ptr + poff, buffer + cnt, plen);
+                               else
+                                       memcpy(buffer + cnt, ptr + poff, plen);
+                               kunmap(page);
+
+                               /* Start at the beginning of the next page */
+                               poff = 0;
+                               ++page;
+                               cnt += plen;
+                               sglen -= plen;
+                       }
+               }
+       }
+
+       /* Return the amount actually transferred */
+       return cnt;
+}
+
+/* Store the contents of buffer into srb's transfer buffer and set the
+* SCSI residue. */
+void rtsx_stor_set_xfer_buf(unsigned char *buffer,
+       unsigned int buflen, struct scsi_cmnd *srb)
+{
+       unsigned int index = 0, offset = 0;
+
+       rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset,
+                                 TO_XFER_BUF);
+       if (buflen < scsi_bufflen(srb))
+               scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
+}
+
+void rtsx_stor_get_xfer_buf(unsigned char *buffer,
+       unsigned int buflen, struct scsi_cmnd *srb)
+{
+       unsigned int index = 0, offset = 0;
+
+       rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset,
+                                 FROM_XFER_BUF);
+       if (buflen < scsi_bufflen(srb))
+               scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
+}
+
+
+/***********************************************************************
+ * Transport routines
+ ***********************************************************************/
+
+/* Invoke the transport and basic error-handling/recovery methods
+ *
+ * This is used to send the message to the device and receive the response.
+ */
+void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int result;
+
+       result = rtsx_scsi_handler(srb, chip);
+
+       /* if the command gets aborted by the higher layers, we need to
+        * short-circuit all other processing
+        */
+       if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) {
+               RTSX_DEBUGP("-- command was aborted\n");
+               srb->result = DID_ABORT << 16;
+               goto Handle_Errors;
+       }
+
+       /* if there is a transport error, reset and don't auto-sense */
+       if (result == TRANSPORT_ERROR) {
+               RTSX_DEBUGP("-- transport indicates error, resetting\n");
+               srb->result = DID_ERROR << 16;
+               goto Handle_Errors;
+       }
+
+       srb->result = SAM_STAT_GOOD;
+
+       /*
+        * If we have a failure, we're going to do a REQUEST_SENSE
+        * automatically.  Note that we differentiate between a command
+        * "failure" and an "error" in the transport mechanism.
+        */
+       if (result == TRANSPORT_FAILED) {
+               /* set the result so the higher layers expect this data */
+               srb->result = SAM_STAT_CHECK_CONDITION;
+               memcpy(srb->sense_buffer,
+                       (unsigned char *)&(chip->sense_buffer[SCSI_LUN(srb)]),
+                       sizeof(struct sense_data_t));
+       }
+
+       return;
+
+       /* Error and abort processing: try to resynchronize with the device
+        * by issuing a port reset.  If that fails, try a class-specific
+        * device reset. */
+Handle_Errors:
+       return;
+}
+
+void rtsx_add_cmd(struct rtsx_chip *chip,
+               u8 cmd_type, u16 reg_addr, u8 mask, u8 data)
+{
+       u32 *cb = (u32 *)(chip->host_cmds_ptr);
+       u32 val = 0;
+
+       val |= (u32)(cmd_type & 0x03) << 30;
+       val |= (u32)(reg_addr & 0x3FFF) << 16;
+       val |= (u32)mask << 8;
+       val |= (u32)data;
+
+       spin_lock_irq(&chip->rtsx->reg_lock);
+       if (chip->ci < (HOST_CMDS_BUF_LEN / 4))
+               cb[(chip->ci)++] = cpu_to_le32(val);
+
+       spin_unlock_irq(&chip->rtsx->reg_lock);
+}
+
+void rtsx_send_cmd_no_wait(struct rtsx_chip *chip)
+{
+       u32 val = 1 << 31;
+
+       rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr);
+
+       val |= (u32)(chip->ci * 4) & 0x00FFFFFF;
+       /* Hardware Auto Response */
+       val |= 0x40000000;
+       rtsx_writel(chip, RTSX_HCBCTLR, val);
+}
+
+int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout)
+{
+       struct rtsx_dev *rtsx = chip->rtsx;
+       struct completion trans_done;
+       u32 val = 1 << 31;
+       long timeleft;
+       int err = 0;
+
+       if (card == SD_CARD)
+               rtsx->check_card_cd = SD_EXIST;
+       else if (card == MS_CARD)
+               rtsx->check_card_cd = MS_EXIST;
+       else if (card == XD_CARD)
+               rtsx->check_card_cd = XD_EXIST;
+       else
+               rtsx->check_card_cd = 0;
+
+       spin_lock_irq(&rtsx->reg_lock);
+
+       /* set up data structures for the wakeup system */
+       rtsx->done = &trans_done;
+       rtsx->trans_result = TRANS_NOT_READY;
+       init_completion(&trans_done);
+       rtsx->trans_state = STATE_TRANS_CMD;
+
+       rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr);
+
+       val |= (u32)(chip->ci * 4) & 0x00FFFFFF;
+       /* Hardware Auto Response */
+       val |= 0x40000000;
+       rtsx_writel(chip, RTSX_HCBCTLR, val);
+
+       spin_unlock_irq(&rtsx->reg_lock);
+
+       /* Wait for TRANS_OK_INT */
+       timeleft = wait_for_completion_interruptible_timeout(
+               &trans_done, timeout * HZ / 1000);
+       if (timeleft <= 0) {
+               RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+               err = -ETIMEDOUT;
+               TRACE_GOTO(chip, finish_send_cmd);
+       }
+
+       spin_lock_irq(&rtsx->reg_lock);
+       if (rtsx->trans_result == TRANS_RESULT_FAIL)
+               err = -EIO;
+       else if (rtsx->trans_result == TRANS_RESULT_OK)
+               err = 0;
+
+       spin_unlock_irq(&rtsx->reg_lock);
+
+finish_send_cmd:
+       rtsx->done = NULL;
+       rtsx->trans_state = STATE_TRANS_NONE;
+
+       if (err < 0)
+               rtsx_stop_cmd(chip, card);
+
+       return err;
+}
+
+static inline void rtsx_add_sg_tbl(
+       struct rtsx_chip *chip, u32 addr, u32 len, u8 option)
+{
+       u64 *sgb = (u64 *)(chip->host_sg_tbl_ptr);
+       u64 val = 0;
+       u32 temp_len = 0;
+       u8  temp_opt = 0;
+
+       do {
+               if (len > 0x80000) {
+                       temp_len = 0x80000;
+                       temp_opt = option & (~SG_END);
+               } else {
+                       temp_len = len;
+                       temp_opt = option;
+               }
+               val = ((u64)addr << 32) | ((u64)temp_len << 12) | temp_opt;
+
+               if (chip->sgi < (HOST_SG_TBL_BUF_LEN / 8))
+                       sgb[(chip->sgi)++] = cpu_to_le64(val);
+
+               len -= temp_len;
+               addr += temp_len;
+       } while (len);
+}
+
+static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
+               struct scatterlist *sg, int num_sg, unsigned int *index,
+               unsigned int *offset, int size,
+               enum dma_data_direction dma_dir, int timeout)
+{
+       struct rtsx_dev *rtsx = chip->rtsx;
+       struct completion trans_done;
+       u8 dir;
+       int sg_cnt, i, resid;
+       int err = 0;
+       long timeleft;
+       struct scatterlist *sg_ptr;
+       u32 val = TRIG_DMA;
+
+       if ((sg == NULL) || (num_sg <= 0) || !offset || !index)
+               return -EIO;
+
+       if (dma_dir == DMA_TO_DEVICE)
+               dir = HOST_TO_DEVICE;
+       else if (dma_dir == DMA_FROM_DEVICE)
+               dir = DEVICE_TO_HOST;
+       else
+               return -ENXIO;
+
+       if (card == SD_CARD)
+               rtsx->check_card_cd = SD_EXIST;
+       else if (card == MS_CARD)
+               rtsx->check_card_cd = MS_EXIST;
+       else if (card == XD_CARD)
+               rtsx->check_card_cd = XD_EXIST;
+       else
+               rtsx->check_card_cd = 0;
+
+       spin_lock_irq(&rtsx->reg_lock);
+
+       /* set up data structures for the wakeup system */
+       rtsx->done = &trans_done;
+
+       rtsx->trans_state = STATE_TRANS_SG;
+       rtsx->trans_result = TRANS_NOT_READY;
+
+       spin_unlock_irq(&rtsx->reg_lock);
+
+       sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
+
+       resid = size;
+       sg_ptr = sg;
+       chip->sgi = 0;
+       /* Usually the next entry will be @sg@ + 1, but if this sg element
+        * is part of a chained scatterlist, it could jump to the start of
+        * a new scatterlist array. So here we use sg_next to move to
+        * the proper sg
+        */
+       for (i = 0; i < *index; i++)
+               sg_ptr = sg_next(sg_ptr);
+       for (i = *index; i < sg_cnt; i++) {
+               dma_addr_t addr;
+               unsigned int len;
+               u8 option;
+
+               addr = sg_dma_address(sg_ptr);
+               len = sg_dma_len(sg_ptr);
+
+               RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n",
+                            (unsigned int)addr, len);
+               RTSX_DEBUGP("*index = %d, *offset = %d\n", *index, *offset);
+
+               addr += *offset;
+
+               if ((len - *offset) > resid) {
+                       *offset += resid;
+                       len = resid;
+                       resid = 0;
+               } else {
+                       resid -= (len - *offset);
+                       len -= *offset;
+                       *offset = 0;
+                       *index = *index + 1;
+               }
+               if ((i == (sg_cnt - 1)) || !resid)
+                       option = SG_VALID | SG_END | SG_TRANS_DATA;
+               else
+                       option = SG_VALID | SG_TRANS_DATA;
+
+               rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option);
+
+               if (!resid)
+                       break;
+
+               sg_ptr = sg_next(sg_ptr);
+       }
+
+       RTSX_DEBUGP("SG table count = %d\n", chip->sgi);
+
+       val |= (u32)(dir & 0x01) << 29;
+       val |= ADMA_MODE;
+
+       spin_lock_irq(&rtsx->reg_lock);
+
+       init_completion(&trans_done);
+
+       rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr);
+       rtsx_writel(chip, RTSX_HDBCTLR, val);
+
+       spin_unlock_irq(&rtsx->reg_lock);
+
+       timeleft = wait_for_completion_interruptible_timeout(
+               &trans_done, timeout * HZ / 1000);
+       if (timeleft <= 0) {
+               RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
+               RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+               err = -ETIMEDOUT;
+               goto out;
+       }
+
+       spin_lock_irq(&rtsx->reg_lock);
+       if (rtsx->trans_result == TRANS_RESULT_FAIL) {
+               err = -EIO;
+               spin_unlock_irq(&rtsx->reg_lock);
+               goto out;
+       }
+       spin_unlock_irq(&rtsx->reg_lock);
+
+       /* Wait for TRANS_OK_INT */
+       spin_lock_irq(&rtsx->reg_lock);
+       if (rtsx->trans_result == TRANS_NOT_READY) {
+               init_completion(&trans_done);
+               spin_unlock_irq(&rtsx->reg_lock);
+               timeleft = wait_for_completion_interruptible_timeout(
+                       &trans_done, timeout * HZ / 1000);
+               if (timeleft <= 0) {
+                       RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
+                       RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+                       err = -ETIMEDOUT;
+                       goto out;
+               }
+       } else {
+               spin_unlock_irq(&rtsx->reg_lock);
+       }
+
+       spin_lock_irq(&rtsx->reg_lock);
+       if (rtsx->trans_result == TRANS_RESULT_FAIL)
+               err = -EIO;
+       else if (rtsx->trans_result == TRANS_RESULT_OK)
+               err = 0;
+
+       spin_unlock_irq(&rtsx->reg_lock);
+
+out:
+       rtsx->done = NULL;
+       rtsx->trans_state = STATE_TRANS_NONE;
+       dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
+
+       if (err < 0)
+               rtsx_stop_cmd(chip, card);
+
+       return err;
+}
+
+static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
+               struct scatterlist *sg, int num_sg,
+               enum dma_data_direction dma_dir, int timeout)
+{
+       struct rtsx_dev *rtsx = chip->rtsx;
+       struct completion trans_done;
+       u8 dir;
+       int buf_cnt, i;
+       int err = 0;
+       long timeleft;
+       struct scatterlist *sg_ptr;
+
+       if ((sg == NULL) || (num_sg <= 0))
+               return -EIO;
+
+       if (dma_dir == DMA_TO_DEVICE)
+               dir = HOST_TO_DEVICE;
+       else if (dma_dir == DMA_FROM_DEVICE)
+               dir = DEVICE_TO_HOST;
+       else
+               return -ENXIO;
+
+       if (card == SD_CARD)
+               rtsx->check_card_cd = SD_EXIST;
+       else if (card == MS_CARD)
+               rtsx->check_card_cd = MS_EXIST;
+       else if (card == XD_CARD)
+               rtsx->check_card_cd = XD_EXIST;
+       else
+               rtsx->check_card_cd = 0;
+
+       spin_lock_irq(&rtsx->reg_lock);
+
+       /* set up data structures for the wakeup system */
+       rtsx->done = &trans_done;
+
+       rtsx->trans_state = STATE_TRANS_SG;
+       rtsx->trans_result = TRANS_NOT_READY;
+
+       spin_unlock_irq(&rtsx->reg_lock);
+
+       buf_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
+
+       sg_ptr = sg;
+
+       for (i = 0; i <= buf_cnt / (HOST_SG_TBL_BUF_LEN / 8); i++) {
+               u32 val = TRIG_DMA;
+               int sg_cnt, j;
+
+               if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8))
+                       sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8);
+               else
+                       sg_cnt = (HOST_SG_TBL_BUF_LEN / 8);
+
+               chip->sgi = 0;
+               for (j = 0; j < sg_cnt; j++) {
+                       dma_addr_t addr = sg_dma_address(sg_ptr);
+                       unsigned int len = sg_dma_len(sg_ptr);
+                       u8 option;
+
+                       RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n",
+                                    (unsigned int)addr, len);
+
+                       if (j == (sg_cnt - 1))
+                               option = SG_VALID | SG_END | SG_TRANS_DATA;
+                       else
+                               option = SG_VALID | SG_TRANS_DATA;
+
+                       rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option);
+
+                       sg_ptr = sg_next(sg_ptr);
+               }
+
+               RTSX_DEBUGP("SG table count = %d\n", chip->sgi);
+
+               val |= (u32)(dir & 0x01) << 29;
+               val |= ADMA_MODE;
+
+               spin_lock_irq(&rtsx->reg_lock);
+
+               init_completion(&trans_done);
+
+               rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr);
+               rtsx_writel(chip, RTSX_HDBCTLR, val);
+
+               spin_unlock_irq(&rtsx->reg_lock);
+
+               timeleft = wait_for_completion_interruptible_timeout(
+                       &trans_done, timeout * HZ / 1000);
+               if (timeleft <= 0) {
+                       RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
+                       RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+                       err = -ETIMEDOUT;
+                       goto out;
+               }
+
+               spin_lock_irq(&rtsx->reg_lock);
+               if (rtsx->trans_result == TRANS_RESULT_FAIL) {
+                       err = -EIO;
+                       spin_unlock_irq(&rtsx->reg_lock);
+                       goto out;
+               }
+               spin_unlock_irq(&rtsx->reg_lock);
+
+               sg_ptr += sg_cnt;
+       }
+
+       /* Wait for TRANS_OK_INT */
+       spin_lock_irq(&rtsx->reg_lock);
+       if (rtsx->trans_result == TRANS_NOT_READY) {
+               init_completion(&trans_done);
+               spin_unlock_irq(&rtsx->reg_lock);
+               timeleft = wait_for_completion_interruptible_timeout(
+                       &trans_done, timeout * HZ / 1000);
+               if (timeleft <= 0) {
+                       RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
+                       RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+                       err = -ETIMEDOUT;
+                       goto out;
+               }
+       } else {
+               spin_unlock_irq(&rtsx->reg_lock);
+       }
+
+       spin_lock_irq(&rtsx->reg_lock);
+       if (rtsx->trans_result == TRANS_RESULT_FAIL)
+               err = -EIO;
+       else if (rtsx->trans_result == TRANS_RESULT_OK)
+               err = 0;
+
+       spin_unlock_irq(&rtsx->reg_lock);
+
+out:
+       rtsx->done = NULL;
+       rtsx->trans_state = STATE_TRANS_NONE;
+       dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
+
+       if (err < 0)
+               rtsx_stop_cmd(chip, card);
+
+       return err;
+}
+
+static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, size_t len,
+               enum dma_data_direction dma_dir, int timeout)
+{
+       struct rtsx_dev *rtsx = chip->rtsx;
+       struct completion trans_done;
+       dma_addr_t addr;
+       u8 dir;
+       int err = 0;
+       u32 val = (1 << 31);
+       long timeleft;
+
+       if ((buf == NULL) || (len <= 0))
+               return -EIO;
+
+       if (dma_dir == DMA_TO_DEVICE)
+               dir = HOST_TO_DEVICE;
+       else if (dma_dir == DMA_FROM_DEVICE)
+               dir = DEVICE_TO_HOST;
+       else
+               return -ENXIO;
+
+       addr = dma_map_single(&(rtsx->pci->dev), buf, len, dma_dir);
+       if (!addr)
+               return -ENOMEM;
+
+       if (card == SD_CARD)
+               rtsx->check_card_cd = SD_EXIST;
+       else if (card == MS_CARD)
+               rtsx->check_card_cd = MS_EXIST;
+       else if (card == XD_CARD)
+               rtsx->check_card_cd = XD_EXIST;
+       else
+               rtsx->check_card_cd = 0;
+
+       val |= (u32)(dir & 0x01) << 29;
+       val |= (u32)(len & 0x00FFFFFF);
+
+       spin_lock_irq(&rtsx->reg_lock);
+
+       /* set up data structures for the wakeup system */
+       rtsx->done = &trans_done;
+
+       init_completion(&trans_done);
+
+       rtsx->trans_state = STATE_TRANS_BUF;
+       rtsx->trans_result = TRANS_NOT_READY;
+
+       rtsx_writel(chip, RTSX_HDBAR, addr);
+       rtsx_writel(chip, RTSX_HDBCTLR, val);
+
+       spin_unlock_irq(&rtsx->reg_lock);
+
+       /* Wait for TRANS_OK_INT */
+       timeleft = wait_for_completion_interruptible_timeout(
+               &trans_done, timeout * HZ / 1000);
+       if (timeleft <= 0) {
+               RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
+               RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+               err = -ETIMEDOUT;
+               goto out;
+       }
+
+       spin_lock_irq(&rtsx->reg_lock);
+       if (rtsx->trans_result == TRANS_RESULT_FAIL)
+               err = -EIO;
+       else if (rtsx->trans_result == TRANS_RESULT_OK)
+               err = 0;
+
+       spin_unlock_irq(&rtsx->reg_lock);
+
+out:
+       rtsx->done = NULL;
+       rtsx->trans_state = STATE_TRANS_NONE;
+       dma_unmap_single(&(rtsx->pci->dev), addr, len, dma_dir);
+
+       if (err < 0)
+               rtsx_stop_cmd(chip, card);
+
+       return err;
+}
+
+int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card,
+               void *buf, size_t len, int use_sg, unsigned int *index,
+               unsigned int *offset, enum dma_data_direction dma_dir,
+               int timeout)
+{
+       int err = 0;
+
+       /* don't transfer data during abort processing */
+       if (rtsx_chk_stat(chip, RTSX_STAT_ABORT))
+               return -EIO;
+
+       if (use_sg) {
+               err = rtsx_transfer_sglist_adma_partial(chip, card,
+                               (struct scatterlist *)buf, use_sg,
+                               index, offset, (int)len, dma_dir, timeout);
+       } else {
+               err = rtsx_transfer_buf(chip, card,
+                                       buf, len, dma_dir, timeout);
+       }
+
+       if (err < 0) {
+               if (RTSX_TST_DELINK(chip)) {
+                       RTSX_CLR_DELINK(chip);
+                       chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
+                       rtsx_reinit_cards(chip, 1);
+               }
+       }
+
+       return err;
+}
+
+int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len,
+               int use_sg, enum dma_data_direction dma_dir, int timeout)
+{
+       int err = 0;
+
+       RTSX_DEBUGP("use_sg = %d\n", use_sg);
+
+       /* don't transfer data during abort processing */
+       if (rtsx_chk_stat(chip, RTSX_STAT_ABORT))
+               return -EIO;
+
+       if (use_sg) {
+               err = rtsx_transfer_sglist_adma(chip, card,
+                               (struct scatterlist *)buf,
+                               use_sg, dma_dir, timeout);
+       } else {
+               err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout);
+       }
+
+       if (err < 0) {
+               if (RTSX_TST_DELINK(chip)) {
+                       RTSX_CLR_DELINK(chip);
+                       chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
+                       rtsx_reinit_cards(chip, 1);
+               }
+       }
+
+       return err;
+}
+
diff --git a/drivers/staging/rts5208/rtsx_transport.h b/drivers/staging/rts5208/rtsx_transport.h
new file mode 100644 (file)
index 0000000..b4b1123
--- /dev/null
@@ -0,0 +1,66 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_TRANSPORT_H
+#define __REALTEK_RTSX_TRANSPORT_H
+
+#include "rtsx.h"
+#include "rtsx_chip.h"
+
+#define WAIT_TIME      2000
+
+unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer,
+       unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index,
+       unsigned int *offset, enum xfer_buf_dir dir);
+void rtsx_stor_set_xfer_buf(unsigned char *buffer,
+       unsigned int buflen, struct scsi_cmnd *srb);
+void rtsx_stor_get_xfer_buf(unsigned char *buffer,
+       unsigned int buflen, struct scsi_cmnd *srb);
+void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+
+
+#define rtsx_init_cmd(chip)                    ((chip)->ci = 0)
+
+void rtsx_add_cmd(struct rtsx_chip *chip,
+               u8 cmd_type, u16 reg_addr, u8 mask, u8 data);
+void rtsx_send_cmd_no_wait(struct rtsx_chip *chip);
+int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout);
+
+extern inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip)
+{
+#ifdef CMD_USING_SG
+       return (u8 *)(chip->host_sg_tbl_ptr);
+#else
+       return (u8 *)(chip->host_cmds_ptr);
+#endif
+}
+
+int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len,
+               int use_sg, enum dma_data_direction dma_dir, int timeout);
+
+int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card,
+                       void *buf, size_t len,
+                       int use_sg, unsigned int *index, unsigned int *offset,
+                       enum dma_data_direction dma_dir, int timeout);
+
+#endif   /* __REALTEK_RTSX_TRANSPORT_H */
diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c
new file mode 100644 (file)
index 0000000..c7c1f54
--- /dev/null
@@ -0,0 +1,4525 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+
+#include "rtsx.h"
+#include "rtsx_transport.h"
+#include "rtsx_scsi.h"
+#include "rtsx_card.h"
+#include "sd.h"
+
+#define SD_MAX_RETRY_COUNT     3
+
+static u16 REG_SD_CFG1;
+static u16 REG_SD_CFG2;
+static u16 REG_SD_CFG3;
+static u16 REG_SD_STAT1;
+static u16 REG_SD_STAT2;
+static u16 REG_SD_BUS_STAT;
+static u16 REG_SD_PAD_CTL;
+static u16 REG_SD_SAMPLE_POINT_CTL;
+static u16 REG_SD_PUSH_POINT_CTL;
+static u16 REG_SD_CMD0;
+static u16 REG_SD_CMD1;
+static u16 REG_SD_CMD2;
+static u16 REG_SD_CMD3;
+static u16 REG_SD_CMD4;
+static u16 REG_SD_CMD5;
+static u16 REG_SD_BYTE_CNT_L;
+static u16 REG_SD_BYTE_CNT_H;
+static u16 REG_SD_BLOCK_CNT_L;
+static u16 REG_SD_BLOCK_CNT_H;
+static u16 REG_SD_TRANSFER;
+static u16 REG_SD_VPCLK0_CTL;
+static u16 REG_SD_VPCLK1_CTL;
+static u16 REG_SD_DCMPS0_CTL;
+static u16 REG_SD_DCMPS1_CTL;
+
+static inline void sd_set_err_code(struct rtsx_chip *chip, u8 err_code)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+
+       sd_card->err_code |= err_code;
+}
+
+static inline void sd_clr_err_code(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+
+       sd_card->err_code = 0;
+}
+
+static inline int sd_check_err_code(struct rtsx_chip *chip, u8 err_code)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+
+       return sd_card->err_code & err_code;
+}
+
+static void sd_init_reg_addr(struct rtsx_chip *chip)
+{
+       REG_SD_CFG1 = 0xFD31;
+       REG_SD_CFG2 = 0xFD33;
+       REG_SD_CFG3 = 0xFD3E;
+       REG_SD_STAT1 = 0xFD30;
+       REG_SD_STAT2 = 0;
+       REG_SD_BUS_STAT = 0;
+       REG_SD_PAD_CTL = 0;
+       REG_SD_SAMPLE_POINT_CTL = 0;
+       REG_SD_PUSH_POINT_CTL = 0;
+       REG_SD_CMD0 = 0xFD34;
+       REG_SD_CMD1 = 0xFD35;
+       REG_SD_CMD2 = 0xFD36;
+       REG_SD_CMD3 = 0xFD37;
+       REG_SD_CMD4 = 0xFD38;
+       REG_SD_CMD5 = 0xFD5A;
+       REG_SD_BYTE_CNT_L = 0xFD39;
+       REG_SD_BYTE_CNT_H = 0xFD3A;
+       REG_SD_BLOCK_CNT_L = 0xFD3B;
+       REG_SD_BLOCK_CNT_H = 0xFD3C;
+       REG_SD_TRANSFER = 0xFD32;
+       REG_SD_VPCLK0_CTL = 0;
+       REG_SD_VPCLK1_CTL = 0;
+       REG_SD_DCMPS0_CTL = 0;
+       REG_SD_DCMPS1_CTL = 0;
+}
+
+static int sd_check_data0_status(struct rtsx_chip *chip)
+{
+       u8 stat;
+
+       RTSX_READ_REG(chip, REG_SD_STAT1, &stat);
+
+       if (!(stat & SD_DAT0_STATUS)) {
+               sd_set_err_code(chip, SD_BUSY);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx,
+               u32 arg, u8 rsp_type, u8 *rsp, int rsp_len)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       int timeout = 100;
+       u16 reg_addr;
+       u8 *ptr;
+       int stat_idx = 0;
+       int rty_cnt = 0;
+
+       sd_clr_err_code(chip);
+
+       RTSX_DEBUGP("SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg);
+
+       if (rsp_type == SD_RSP_TYPE_R1b)
+               timeout = 3000;
+
+RTY_SEND_CMD:
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+                       0x01, PINGPONG_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER,
+                       0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
+               SD_TRANSFER_END | SD_STAT_IDLE, SD_TRANSFER_END | SD_STAT_IDLE);
+
+       if (rsp_type == SD_RSP_TYPE_R2) {
+               for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16;
+                    reg_addr++)
+                       rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
+
+               stat_idx = 16;
+       } else if (rsp_type != SD_RSP_TYPE_R0) {
+               for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4;
+                    reg_addr++)
+                       rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
+
+               stat_idx = 5;
+       }
+
+       rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0);
+
+       retval = rtsx_send_cmd(chip, SD_CARD, timeout);
+       if (retval < 0) {
+               u8 val;
+
+               rtsx_read_register(chip, REG_SD_STAT1, &val);
+               RTSX_DEBUGP("SD_STAT1: 0x%x\n", val);
+
+               rtsx_read_register(chip, REG_SD_CFG3, &val);
+               RTSX_DEBUGP("SD_CFG3: 0x%x\n", val);
+
+               if (retval == -ETIMEDOUT) {
+                       if (rsp_type & SD_WAIT_BUSY_END) {
+                               retval = sd_check_data0_status(chip);
+                               if (retval != STATUS_SUCCESS) {
+                                       rtsx_clear_sd_error(chip);
+                                       TRACE_RET(chip, retval);
+                               }
+                       } else {
+                               sd_set_err_code(chip, SD_TO_ERR);
+                       }
+                       retval = STATUS_TIMEDOUT;
+               } else {
+                       retval = STATUS_FAIL;
+               }
+               rtsx_clear_sd_error(chip);
+
+               TRACE_RET(chip, retval);
+       }
+
+       if (rsp_type == SD_RSP_TYPE_R0)
+               return STATUS_SUCCESS;
+
+       ptr = rtsx_get_cmd_data(chip) + 1;
+
+       if ((ptr[0] & 0xC0) != 0) {
+               sd_set_err_code(chip, SD_STS_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (!(rsp_type & SD_NO_CHECK_CRC7)) {
+               if (ptr[stat_idx] & SD_CRC7_ERR) {
+                       if (cmd_idx == WRITE_MULTIPLE_BLOCK) {
+                               sd_set_err_code(chip, SD_CRC_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if (rty_cnt < SD_MAX_RETRY_COUNT) {
+                               wait_timeout(20);
+                               rty_cnt++;
+                               goto RTY_SEND_CMD;
+                       } else {
+                               sd_set_err_code(chip, SD_CRC_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+       }
+
+       if ((rsp_type == SD_RSP_TYPE_R1) || (rsp_type == SD_RSP_TYPE_R1b)) {
+               if ((cmd_idx != SEND_RELATIVE_ADDR) &&
+                       (cmd_idx != SEND_IF_COND)) {
+                       if (cmd_idx != STOP_TRANSMISSION) {
+                               if (ptr[1] & 0x80)
+                                       TRACE_RET(chip, STATUS_FAIL);
+                       }
+#ifdef SUPPORT_SD_LOCK
+                       if (ptr[1] & 0x7D)
+#else
+                       if (ptr[1] & 0x7F)
+#endif
+                       {
+                               RTSX_DEBUGP("ptr[1]: 0x%02x\n", ptr[1]);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if (ptr[2] & 0xFF) {
+                               RTSX_DEBUGP("ptr[2]: 0x%02x\n", ptr[2]);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if (ptr[3] & 0x80) {
+                               RTSX_DEBUGP("ptr[3]: 0x%02x\n", ptr[3]);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if (ptr[3] & 0x01)
+                               sd_card->sd_data_buf_ready = 1;
+                       else
+                               sd_card->sd_data_buf_ready = 0;
+               }
+       }
+
+       if (rsp && rsp_len)
+               memcpy(rsp, ptr, rsp_len);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_read_data(struct rtsx_chip *chip,
+                       u8 trans_mode, u8 *cmd, int cmd_len, u16 byte_cnt,
+                       u16 blk_cnt, u8 bus_width, u8 *buf, int buf_len,
+                       int timeout)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       int i;
+
+       sd_clr_err_code(chip);
+
+       if (!buf)
+               buf_len = 0;
+
+       if (buf_len > 512)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       if (cmd_len) {
+               RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40);
+               for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++)
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0 + i,
+                                    0xFF, cmd[i]);
+       }
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF,
+               (u8)byte_cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF,
+               (u8)(byte_cnt >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF,
+               (u8)blk_cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF,
+               (u8)(blk_cnt >> 8));
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
+               SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END|
+               SD_CHECK_CRC7 | SD_RSP_LEN_6);
+       if (trans_mode != SD_TM_AUTO_TUNING)
+               rtsx_add_cmd(chip, WRITE_REG_CMD,
+                       CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+               trans_mode | SD_TRANSFER_START);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END,
+               SD_TRANSFER_END);
+
+       retval = rtsx_send_cmd(chip, SD_CARD, timeout);
+       if (retval < 0) {
+               if (retval == -ETIMEDOUT) {
+                       sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
+                                           SD_RSP_TYPE_R1, NULL, 0);
+               }
+
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (buf && buf_len) {
+               retval = rtsx_read_ppbuf(chip, buf, buf_len);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode,
+               u8 *cmd, int cmd_len, u16 byte_cnt, u16 blk_cnt, u8 bus_width,
+               u8 *buf, int buf_len, int timeout)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       int i;
+
+       sd_clr_err_code(chip);
+
+       if (!buf)
+               buf_len = 0;
+
+       if (buf_len > 512) {
+               /* This function can't write data more than one page */
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (buf && buf_len) {
+               retval = rtsx_write_ppbuf(chip, buf, buf_len);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       rtsx_init_cmd(chip);
+
+       if (cmd_len) {
+               RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40);
+               for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD,
+                                    REG_SD_CMD0 + i, 0xFF, cmd[i]);
+               }
+       }
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF,
+               (u8)byte_cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF,
+               (u8)(byte_cnt >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF,
+               (u8)blk_cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF,
+               (u8)(blk_cnt >> 8));
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
+               SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END |
+               SD_CHECK_CRC7 | SD_RSP_LEN_6);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+               trans_mode | SD_TRANSFER_START);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END,
+               SD_TRANSFER_END);
+
+       retval = rtsx_send_cmd(chip, SD_CARD, timeout);
+       if (retval < 0) {
+               if (retval == -ETIMEDOUT) {
+                       sd_send_cmd_get_rsp(chip, SEND_STATUS,
+                               sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
+               }
+
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_check_csd(struct rtsx_chip *chip, char check_wp)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       int i;
+       u8 csd_ver, trans_speed;
+       u8 rsp[16];
+
+       for (i = 0; i < 6; i++) {
+               if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                       sd_set_err_code(chip, SD_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = sd_send_cmd_get_rsp(chip, SEND_CSD, sd_card->sd_addr,
+                                       SD_RSP_TYPE_R2, rsp, 16);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+
+       if (i == 6)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       memcpy(sd_card->raw_csd, rsp + 1, 15);
+
+       RTSX_DEBUGP("CSD Response:\n");
+       RTSX_DUMP(sd_card->raw_csd, 16);
+
+       csd_ver = (rsp[1] & 0xc0) >> 6;
+       RTSX_DEBUGP("csd_ver = %d\n", csd_ver);
+
+       trans_speed = rsp[4];
+       if ((trans_speed & 0x07) == 0x02) {
+               if ((trans_speed & 0xf8) >= 0x30) {
+                       if (chip->asic_code)
+                               sd_card->sd_clock = 47;
+                       else
+                               sd_card->sd_clock = CLK_50;
+
+               } else if ((trans_speed & 0xf8) == 0x28) {
+                       if (chip->asic_code)
+                               sd_card->sd_clock = 39;
+                       else
+                               sd_card->sd_clock = CLK_40;
+
+               } else if ((trans_speed & 0xf8) == 0x20) {
+                       if (chip->asic_code)
+                               sd_card->sd_clock = 29;
+                       else
+                               sd_card->sd_clock = CLK_30;
+
+               } else if ((trans_speed & 0xf8) >= 0x10) {
+                       if (chip->asic_code)
+                               sd_card->sd_clock = 23;
+                       else
+                               sd_card->sd_clock = CLK_20;
+
+               } else if ((trans_speed & 0x08) >= 0x08) {
+                       if (chip->asic_code)
+                               sd_card->sd_clock = 19;
+                       else
+                               sd_card->sd_clock = CLK_20;
+               } else {
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       } else {
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (CHK_MMC_SECTOR_MODE(sd_card)) {
+               sd_card->capacity = 0;
+       } else {
+               if ((!CHK_SD_HCXC(sd_card)) || (csd_ver == 0)) {
+                       u8 blk_size, c_size_mult;
+                       u16 c_size;
+                       blk_size = rsp[6] & 0x0F;
+                       c_size =  ((u16)(rsp[7] & 0x03) << 10)
+                                       + ((u16)rsp[8] << 2)
+                                       + ((u16)(rsp[9] & 0xC0) >> 6);
+                       c_size_mult = (u8)((rsp[10] & 0x03) << 1);
+                       c_size_mult += (rsp[11] & 0x80) >> 7;
+                       sd_card->capacity = (((u32)(c_size + 1)) *
+                                       (1 << (c_size_mult + 2)))
+                               << (blk_size - 9);
+               } else {
+                       u32 total_sector = 0;
+                       total_sector = (((u32)rsp[8] & 0x3f) << 16) |
+                               ((u32)rsp[9] << 8) | (u32)rsp[10];
+                       sd_card->capacity = (total_sector + 1) << 10;
+               }
+       }
+
+       if (check_wp) {
+               if (rsp[15] & 0x30)
+                       chip->card_wp |= SD_CARD;
+
+               RTSX_DEBUGP("CSD WP Status: 0x%x\n", rsp[15]);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_set_sample_push_timing(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+
+       u8 val = 0;
+
+       if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY)
+               val |= 0x10;
+
+       if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) {
+               if (chip->asic_code) {
+                       if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) {
+                               if (val & 0x10)
+                                       val |= 0x04;
+                               else
+                                       val |= 0x08;
+                       }
+               } else {
+                       if (val & 0x10)
+                               val |= 0x04;
+                       else
+                               val |= 0x08;
+               }
+       } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) ==
+               SD_SAMPLE_POINT_DELAY) {
+               if (val & 0x10)
+                       val |= 0x04;
+               else
+                       val |= 0x08;
+       }
+
+       RTSX_WRITE_REG(chip, REG_SD_CFG1, 0x1C, val);
+
+       return STATUS_SUCCESS;
+}
+
+static void sd_choose_proper_clock(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+
+       if (CHK_SD_SDR104(sd_card)) {
+               if (chip->asic_code)
+                       sd_card->sd_clock = chip->asic_sd_sdr104_clk;
+               else
+                       sd_card->sd_clock = chip->fpga_sd_sdr104_clk;
+
+       } else if (CHK_SD_DDR50(sd_card)) {
+               if (chip->asic_code)
+                       sd_card->sd_clock = chip->asic_sd_ddr50_clk;
+               else
+                       sd_card->sd_clock = chip->fpga_sd_ddr50_clk;
+
+       } else if (CHK_SD_SDR50(sd_card)) {
+               if (chip->asic_code)
+                       sd_card->sd_clock = chip->asic_sd_sdr50_clk;
+               else
+                       sd_card->sd_clock = chip->fpga_sd_sdr50_clk;
+
+       } else if (CHK_SD_HS(sd_card)) {
+               if (chip->asic_code)
+                       sd_card->sd_clock = chip->asic_sd_hs_clk;
+               else
+                       sd_card->sd_clock = chip->fpga_sd_hs_clk;
+
+       } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) {
+               if (chip->asic_code)
+                       sd_card->sd_clock = chip->asic_mmc_52m_clk;
+               else
+                       sd_card->sd_clock = chip->fpga_mmc_52m_clk;
+
+       } else if (CHK_MMC_26M(sd_card)) {
+               if (chip->asic_code)
+                       sd_card->sd_clock = 48;
+               else
+                       sd_card->sd_clock = CLK_50;
+       }
+}
+
+static int sd_set_clock_divider(struct rtsx_chip *chip, u8 clk_div)
+{
+       u8 mask = 0, val = 0;
+
+       mask = 0x60;
+       if (clk_div == SD_CLK_DIVIDE_0)
+               val = 0x00;
+       else if (clk_div == SD_CLK_DIVIDE_128)
+               val = 0x40;
+       else if (clk_div == SD_CLK_DIVIDE_256)
+               val = 0x20;
+
+       RTSX_WRITE_REG(chip, REG_SD_CFG1, mask, val);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_set_init_para(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+
+       retval = sd_set_sample_push_timing(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       sd_choose_proper_clock(chip);
+
+       retval = switch_clock(chip, sd_card->sd_clock);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+int sd_select_card(struct rtsx_chip *chip, int select)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 cmd_idx, cmd_type;
+       u32 addr;
+
+       if (select) {
+               cmd_idx = SELECT_CARD;
+               cmd_type = SD_RSP_TYPE_R1;
+               addr = sd_card->sd_addr;
+       } else {
+               cmd_idx = DESELECT_CARD;
+               cmd_type = SD_RSP_TYPE_R0;
+               addr = 0;
+       }
+
+       retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+#ifdef SUPPORT_SD_LOCK
+static int sd_update_lock_status(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 rsp[5];
+
+       retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
+                               SD_RSP_TYPE_R1, rsp, 5);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (rsp[1] & 0x02)
+               sd_card->sd_lock_status |= SD_LOCKED;
+       else
+               sd_card->sd_lock_status &= ~SD_LOCKED;
+
+       RTSX_DEBUGP("sd_card->sd_lock_status = 0x%x\n",
+               sd_card->sd_lock_status);
+
+       if (rsp[1] & 0x01)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+#endif
+
+static int sd_wait_state_data_ready(struct rtsx_chip *chip, u8 state,
+                               u8 data_ready, int polling_cnt)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval, i;
+       u8 rsp[5];
+
+       for (i = 0; i < polling_cnt; i++) {
+               retval = sd_send_cmd_get_rsp(chip, SEND_STATUS,
+                                       sd_card->sd_addr, SD_RSP_TYPE_R1, rsp,
+                                       5);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (((rsp[3] & 0x1E) == state) &&
+                       ((rsp[3] & 0x01) == data_ready))
+                       return STATUS_SUCCESS;
+       }
+
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+static int sd_change_bank_voltage(struct rtsx_chip *chip, u8 voltage)
+{
+       int retval;
+
+       if (voltage == SD_IO_3V3) {
+               if (chip->asic_code) {
+                       retval = rtsx_write_phy_register(chip, 0x08,
+                                                       0x4FC0 |
+                                                       chip->phy_voltage);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+               } else {
+                       RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, 0);
+               }
+       } else if (voltage == SD_IO_1V8) {
+               if (chip->asic_code) {
+                       retval = rtsx_write_phy_register(chip, 0x08,
+                                                       0x4C40 |
+                                                       chip->phy_voltage);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+               } else {
+                       RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8,
+                               SD_IO_USING_1V8);
+               }
+       } else {
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_voltage_switch(struct rtsx_chip *chip)
+{
+       int retval;
+       u8 stat;
+
+       RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP,
+               SD_CLK_TOGGLE_EN);
+
+       retval = sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1,
+                               NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       udelay(chip->sd_voltage_switch_delay);
+
+       RTSX_READ_REG(chip, SD_BUS_STAT, &stat);
+       if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
+                               SD_DAT1_STATUS | SD_DAT0_STATUS)) {
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_FORCE_STOP);
+       retval = sd_change_bank_voltage(chip, SD_IO_1V8);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       wait_timeout(50);
+
+       RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN);
+       wait_timeout(10);
+
+       RTSX_READ_REG(chip, SD_BUS_STAT, &stat);
+       if ((stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
+                               SD_DAT1_STATUS | SD_DAT0_STATUS)) !=
+                       (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
+                               SD_DAT1_STATUS | SD_DAT0_STATUS)) {
+               RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", stat);
+               rtsx_write_register(chip, SD_BUS_STAT,
+                               SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
+               rtsx_write_register(chip, CARD_CLK_EN, 0xFF, 0);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP,
+               0);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_reset_dcm(struct rtsx_chip *chip, u8 tune_dir)
+{
+       if (tune_dir == TUNE_RX) {
+               RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_RX);
+               RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RX);
+       } else {
+               RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_TX);
+               RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_TX);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       u16 SD_VP_CTL, SD_DCMPS_CTL;
+       u8 val;
+       int retval;
+       int ddr_rx = 0;
+
+       RTSX_DEBUGP("sd_change_phase (sample_point = %d, tune_dir = %d)\n",
+                               sample_point, tune_dir);
+
+       if (tune_dir == TUNE_RX) {
+               SD_VP_CTL = SD_VPRX_CTL;
+               SD_DCMPS_CTL = SD_DCMPS_RX_CTL;
+               if (CHK_SD_DDR50(sd_card))
+                       ddr_rx = 1;
+       } else {
+               SD_VP_CTL = SD_VPTX_CTL;
+               SD_DCMPS_CTL = SD_DCMPS_TX_CTL;
+       }
+
+       if (chip->asic_code) {
+               RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK);
+               RTSX_WRITE_REG(chip, SD_VP_CTL, 0x1F, sample_point);
+               RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
+               RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET,
+                       PHASE_NOT_RESET);
+               RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0);
+       } else {
+#ifdef CONFIG_RTS5208_DEBUG
+               rtsx_read_register(chip, SD_VP_CTL, &val);
+               RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val);
+               rtsx_read_register(chip, SD_DCMPS_CTL, &val);
+               RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val);
+#endif
+
+               if (ddr_rx) {
+                       RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE,
+                               PHASE_CHANGE);
+                       udelay(50);
+                       RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF,
+                               PHASE_CHANGE | PHASE_NOT_RESET | sample_point);
+               } else {
+                       RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK);
+                       udelay(50);
+                       RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF,
+                                       PHASE_NOT_RESET | sample_point);
+               }
+               udelay(100);
+
+               rtsx_init_cmd(chip);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE,
+                       DCMPS_CHANGE);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL,
+                       DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE);
+               retval = rtsx_send_cmd(chip, SD_CARD, 100);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, Fail);
+
+               val = *rtsx_get_cmd_data(chip);
+               if (val & DCMPS_ERROR)
+                       TRACE_GOTO(chip, Fail);
+
+               if ((val & DCMPS_CURRENT_PHASE) != sample_point)
+                       TRACE_GOTO(chip, Fail);
+
+               RTSX_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0);
+               if (ddr_rx)
+                       RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, 0);
+               else
+                       RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0);
+
+               udelay(50);
+       }
+
+       RTSX_WRITE_REG(chip, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0);
+
+       return STATUS_SUCCESS;
+
+Fail:
+#ifdef CONFIG_RTS5208_DEBUG
+       rtsx_read_register(chip, SD_VP_CTL, &val);
+       RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val);
+       rtsx_read_register(chip, SD_DCMPS_CTL, &val);
+       RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val);
+#endif
+
+       rtsx_write_register(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0);
+       rtsx_write_register(chip, SD_VP_CTL, PHASE_CHANGE, 0);
+       wait_timeout(10);
+       sd_reset_dcm(chip, tune_dir);
+       return STATUS_FAIL;
+}
+
+static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 cmd[5], buf[8];
+
+       retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
+                               SD_RSP_TYPE_R1, NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       cmd[0] = 0x40 | SEND_SCR;
+       cmd[1] = 0;
+       cmd[2] = 0;
+       cmd[3] = 0;
+       cmd[4] = 0;
+
+       retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 8, 1, bus_width,
+                       buf, 8, 250);
+       if (retval != STATUS_SUCCESS) {
+               rtsx_clear_sd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       memcpy(sd_card->raw_scr, buf, 8);
+
+       if ((buf[0] & 0x0F) == 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_query_switch_result(struct rtsx_chip *chip, u8 func_group,
+                               u8 func_to_switch, u8 *buf, int buf_len)
+{
+       u8 support_mask = 0, query_switch = 0, switch_busy = 0;
+       int support_offset = 0, query_switch_offset = 0, check_busy_offset = 0;
+
+       if (func_group == SD_FUNC_GROUP_1) {
+               support_offset = FUNCTION_GROUP1_SUPPORT_OFFSET;
+               query_switch_offset = FUNCTION_GROUP1_QUERY_SWITCH_OFFSET;
+               check_busy_offset = FUNCTION_GROUP1_CHECK_BUSY_OFFSET;
+
+               switch (func_to_switch) {
+               case HS_SUPPORT:
+                       support_mask = HS_SUPPORT_MASK;
+                       query_switch = HS_QUERY_SWITCH_OK;
+                       switch_busy = HS_SWITCH_BUSY;
+                       break;
+
+               case SDR50_SUPPORT:
+                       support_mask = SDR50_SUPPORT_MASK;
+                       query_switch = SDR50_QUERY_SWITCH_OK;
+                       switch_busy = SDR50_SWITCH_BUSY;
+                       break;
+
+               case SDR104_SUPPORT:
+                       support_mask = SDR104_SUPPORT_MASK;
+                       query_switch = SDR104_QUERY_SWITCH_OK;
+                       switch_busy = SDR104_SWITCH_BUSY;
+                       break;
+
+               case DDR50_SUPPORT:
+                       support_mask = DDR50_SUPPORT_MASK;
+                       query_switch = DDR50_QUERY_SWITCH_OK;
+                       switch_busy = DDR50_SWITCH_BUSY;
+                       break;
+
+               default:
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       } else if (func_group == SD_FUNC_GROUP_3) {
+               support_offset = FUNCTION_GROUP3_SUPPORT_OFFSET;
+               query_switch_offset = FUNCTION_GROUP3_QUERY_SWITCH_OFFSET;
+               check_busy_offset = FUNCTION_GROUP3_CHECK_BUSY_OFFSET;
+
+               switch (func_to_switch) {
+               case DRIVING_TYPE_A:
+                       support_mask = DRIVING_TYPE_A_MASK;
+                       query_switch = TYPE_A_QUERY_SWITCH_OK;
+                       switch_busy = TYPE_A_SWITCH_BUSY;
+                       break;
+
+               case DRIVING_TYPE_C:
+                       support_mask = DRIVING_TYPE_C_MASK;
+                       query_switch = TYPE_C_QUERY_SWITCH_OK;
+                       switch_busy = TYPE_C_SWITCH_BUSY;
+                       break;
+
+               case DRIVING_TYPE_D:
+                       support_mask = DRIVING_TYPE_D_MASK;
+                       query_switch = TYPE_D_QUERY_SWITCH_OK;
+                       switch_busy = TYPE_D_SWITCH_BUSY;
+                       break;
+
+               default:
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       } else if (func_group == SD_FUNC_GROUP_4) {
+               support_offset = FUNCTION_GROUP4_SUPPORT_OFFSET;
+               query_switch_offset = FUNCTION_GROUP4_QUERY_SWITCH_OFFSET;
+               check_busy_offset = FUNCTION_GROUP4_CHECK_BUSY_OFFSET;
+
+               switch (func_to_switch) {
+               case CURRENT_LIMIT_400:
+                       support_mask = CURRENT_LIMIT_400_MASK;
+                       query_switch = CURRENT_LIMIT_400_QUERY_SWITCH_OK;
+                       switch_busy = CURRENT_LIMIT_400_SWITCH_BUSY;
+                       break;
+
+               case CURRENT_LIMIT_600:
+                       support_mask = CURRENT_LIMIT_600_MASK;
+                       query_switch = CURRENT_LIMIT_600_QUERY_SWITCH_OK;
+                       switch_busy = CURRENT_LIMIT_600_SWITCH_BUSY;
+                       break;
+
+               case CURRENT_LIMIT_800:
+                       support_mask = CURRENT_LIMIT_800_MASK;
+                       query_switch = CURRENT_LIMIT_800_QUERY_SWITCH_OK;
+                       switch_busy = CURRENT_LIMIT_800_SWITCH_BUSY;
+                       break;
+
+               default:
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       } else {
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (func_group == SD_FUNC_GROUP_1) {
+               if (!(buf[support_offset] & support_mask) ||
+                       ((buf[query_switch_offset] & 0x0F) != query_switch)) {
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       /* Check 'Busy Status' */
+       if ((buf[DATA_STRUCTURE_VER_OFFSET] == 0x01) &&
+                   ((buf[check_busy_offset] & switch_busy) == switch_busy)) {
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode,
+               u8 func_group, u8 func_to_switch, u8 bus_width)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 cmd[5], buf[64];
+
+       RTSX_DEBUGP("sd_check_switch_mode (mode = %d, func_group = %d, func_to_switch = %d)\n",
+                       mode, func_group, func_to_switch);
+
+       cmd[0] = 0x40 | SWITCH;
+       cmd[1] = mode;
+
+       if (func_group == SD_FUNC_GROUP_1) {
+               cmd[2] = 0xFF;
+               cmd[3] = 0xFF;
+               cmd[4] = 0xF0 + func_to_switch;
+       } else if (func_group == SD_FUNC_GROUP_3) {
+               cmd[2] = 0xFF;
+               cmd[3] = 0xF0 + func_to_switch;
+               cmd[4] = 0xFF;
+       } else if (func_group == SD_FUNC_GROUP_4) {
+               cmd[2] = 0xFF;
+               cmd[3] = 0x0F + (func_to_switch << 4);
+               cmd[4] = 0xFF;
+       } else {
+               cmd[1] = SD_CHECK_MODE;
+               cmd[2] = 0xFF;
+               cmd[3] = 0xFF;
+               cmd[4] = 0xFF;
+       }
+
+       retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, bus_width,
+                       buf, 64, 250);
+       if (retval != STATUS_SUCCESS) {
+               rtsx_clear_sd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_DUMP(buf, 64);
+
+       if (func_group == NO_ARGUMENT) {
+               sd_card->func_group1_mask = buf[0x0D];
+               sd_card->func_group2_mask = buf[0x0B];
+               sd_card->func_group3_mask = buf[0x09];
+               sd_card->func_group4_mask = buf[0x07];
+
+               RTSX_DEBUGP("func_group1_mask = 0x%02x\n", buf[0x0D]);
+               RTSX_DEBUGP("func_group2_mask = 0x%02x\n", buf[0x0B]);
+               RTSX_DEBUGP("func_group3_mask = 0x%02x\n", buf[0x09]);
+               RTSX_DEBUGP("func_group4_mask = 0x%02x\n", buf[0x07]);
+       } else {
+               /* Maximum current consumption, check whether current is
+                * acceptable; bit[511:496] = 0x0000 means some error happened.
+                */
+               u16 cc = ((u16)buf[0] << 8) | buf[1];
+               RTSX_DEBUGP("Maximum current consumption: %dmA\n", cc);
+               if ((cc == 0) || (cc > 800))
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = sd_query_switch_result(chip, func_group,
+                                               func_to_switch, buf, 64);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if ((cc > 400) || (func_to_switch > CURRENT_LIMIT_400)) {
+                       RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK,
+                               chip->sd_800mA_ocp_thd);
+                       RTSX_WRITE_REG(chip, CARD_PWR_CTL, PMOS_STRG_MASK,
+                               PMOS_STRG_800mA);
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static u8 downgrade_switch_mode(u8 func_group, u8 func_to_switch)
+{
+       if (func_group == SD_FUNC_GROUP_1) {
+               if (func_to_switch > HS_SUPPORT)
+                       func_to_switch--;
+
+       } else if (func_group == SD_FUNC_GROUP_4) {
+               if (func_to_switch > CURRENT_LIMIT_200)
+                       func_to_switch--;
+       }
+
+       return func_to_switch;
+}
+
+static int sd_check_switch(struct rtsx_chip *chip,
+               u8 func_group, u8 func_to_switch, u8 bus_width)
+{
+       int retval;
+       int i;
+       int switch_good = 0;
+
+       for (i = 0; i < 3; i++) {
+               if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                       sd_set_err_code(chip, SD_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = sd_check_switch_mode(chip, SD_CHECK_MODE, func_group,
+                               func_to_switch, bus_width);
+               if (retval == STATUS_SUCCESS) {
+                       u8 stat;
+
+                       retval = sd_check_switch_mode(chip, SD_SWITCH_MODE,
+                                       func_group, func_to_switch, bus_width);
+                       if (retval == STATUS_SUCCESS) {
+                               switch_good = 1;
+                               break;
+                       }
+
+                       RTSX_READ_REG(chip, SD_STAT1, &stat);
+                       if (stat & SD_CRC16_ERR) {
+                               RTSX_DEBUGP("SD CRC16 error when switching mode\n");
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               func_to_switch = downgrade_switch_mode(func_group,
+                                               func_to_switch);
+
+               wait_timeout(20);
+       }
+
+       if (!switch_good)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       int i;
+       u8 func_to_switch = 0;
+
+       /* Get supported functions */
+       retval = sd_check_switch_mode(chip, SD_CHECK_MODE,
+                       NO_ARGUMENT, NO_ARGUMENT, bus_width);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail);
+
+       /* Function Group 1: Access Mode */
+       for (i = 0; i < 4; i++) {
+               switch ((u8)(chip->sd_speed_prior >> (i*8))) {
+               case SDR104_SUPPORT:
+                       if ((sd_card->func_group1_mask & SDR104_SUPPORT_MASK)
+                                       && chip->sdr104_en) {
+                               func_to_switch = SDR104_SUPPORT;
+                       }
+                       break;
+
+               case DDR50_SUPPORT:
+                       if ((sd_card->func_group1_mask & DDR50_SUPPORT_MASK)
+                                       && chip->ddr50_en) {
+                               func_to_switch = DDR50_SUPPORT;
+                       }
+                       break;
+
+               case SDR50_SUPPORT:
+                       if ((sd_card->func_group1_mask & SDR50_SUPPORT_MASK)
+                                       && chip->sdr50_en) {
+                               func_to_switch = SDR50_SUPPORT;
+                       }
+                       break;
+
+               case HS_SUPPORT:
+                       if (sd_card->func_group1_mask & HS_SUPPORT_MASK)
+                               func_to_switch = HS_SUPPORT;
+
+                       break;
+
+               default:
+                       continue;
+               }
+
+
+               if (func_to_switch)
+                       break;
+
+       }
+       RTSX_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", func_to_switch);
+
+#ifdef SUPPORT_SD_LOCK
+       if ((sd_card->sd_lock_status & SD_SDR_RST)
+                       && (DDR50_SUPPORT == func_to_switch)
+                       && (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) {
+               func_to_switch = SDR50_SUPPORT;
+               RTSX_DEBUGP("Using SDR50 instead of DDR50 for SD Lock\n");
+       }
+#endif
+
+       if (func_to_switch) {
+               retval = sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch,
+                                       bus_width);
+               if (retval != STATUS_SUCCESS) {
+                       if (func_to_switch == SDR104_SUPPORT) {
+                               sd_card->sd_switch_fail = SDR104_SUPPORT_MASK;
+                       } else if (func_to_switch == DDR50_SUPPORT) {
+                               sd_card->sd_switch_fail = SDR104_SUPPORT_MASK |
+                                       DDR50_SUPPORT_MASK;
+                       } else if (func_to_switch == SDR50_SUPPORT) {
+                               sd_card->sd_switch_fail = SDR104_SUPPORT_MASK |
+                                       DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK;
+                       }
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if (func_to_switch == SDR104_SUPPORT)
+                       SET_SD_SDR104(sd_card);
+               else if (func_to_switch == DDR50_SUPPORT)
+                       SET_SD_DDR50(sd_card);
+               else if (func_to_switch == SDR50_SUPPORT)
+                       SET_SD_SDR50(sd_card);
+               else
+                       SET_SD_HS(sd_card);
+       }
+
+       if (CHK_SD_DDR50(sd_card)) {
+               RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0x04);
+               retval = sd_set_sample_push_timing(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (!func_to_switch || (func_to_switch == HS_SUPPORT)) {
+               /* Do not try to switch current limit if the card doesn't
+                * support UHS mode or we don't want it to support UHS mode
+                */
+               return STATUS_SUCCESS;
+       }
+
+       /* Function Group 4: Current Limit */
+       func_to_switch = 0xFF;
+
+       for (i = 0; i < 4; i++) {
+               switch ((u8)(chip->sd_current_prior >> (i*8))) {
+               case CURRENT_LIMIT_800:
+                       if (sd_card->func_group4_mask & CURRENT_LIMIT_800_MASK)
+                               func_to_switch = CURRENT_LIMIT_800;
+
+                       break;
+
+               case CURRENT_LIMIT_600:
+                       if (sd_card->func_group4_mask & CURRENT_LIMIT_600_MASK)
+                               func_to_switch = CURRENT_LIMIT_600;
+
+                       break;
+
+               case CURRENT_LIMIT_400:
+                       if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK)
+                               func_to_switch = CURRENT_LIMIT_400;
+
+                       break;
+
+               case CURRENT_LIMIT_200:
+                       if (sd_card->func_group4_mask & CURRENT_LIMIT_200_MASK)
+                               func_to_switch = CURRENT_LIMIT_200;
+
+                       break;
+
+               default:
+                       continue;
+               }
+
+               if (func_to_switch != 0xFF)
+                       break;
+       }
+
+       RTSX_DEBUGP("SD_FUNC_GROUP_4: func_to_switch = 0x%02x", func_to_switch);
+
+       if (func_to_switch <= CURRENT_LIMIT_800) {
+               retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch,
+                                       bus_width);
+               if (retval != STATUS_SUCCESS) {
+                       if (sd_check_err_code(chip, SD_NO_CARD))
+                               TRACE_RET(chip, STATUS_FAIL);
+               }
+               RTSX_DEBUGP("Switch current limit finished! (%d)\n", retval);
+       }
+
+       if (CHK_SD_DDR50(sd_card))
+               RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_wait_data_idle(struct rtsx_chip *chip)
+{
+       int retval = STATUS_TIMEDOUT;
+       int i;
+       u8 val = 0;
+
+       for (i = 0; i < 100; i++) {
+               RTSX_READ_REG(chip, SD_DATA_STATE, &val);
+               if (val & SD_DATA_IDLE) {
+                       retval = STATUS_SUCCESS;
+                       break;
+               }
+               udelay(100);
+       }
+       RTSX_DEBUGP("SD_DATA_STATE: 0x%02x\n", val);
+
+       return retval;
+}
+
+static int sd_sdr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
+{
+       int retval;
+       u8 cmd[5];
+
+       retval = sd_change_phase(chip, sample_point, TUNE_RX);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       cmd[0] = 0x40 | SEND_TUNING_PATTERN;
+       cmd[1] = 0;
+       cmd[2] = 0;
+       cmd[3] = 0;
+       cmd[4] = 0;
+
+       retval = sd_read_data(chip, SD_TM_AUTO_TUNING,
+                       cmd, 5, 0x40, 1, SD_BUS_WIDTH_4, NULL, 0, 100);
+       if (retval != STATUS_SUCCESS) {
+               (void)sd_wait_data_idle(chip);
+
+               rtsx_clear_sd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 cmd[5];
+
+       retval = sd_change_phase(chip, sample_point, TUNE_RX);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_DEBUGP("sd ddr tuning rx\n");
+
+       retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
+                               SD_RSP_TYPE_R1, NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       cmd[0] = 0x40 | SD_STATUS;
+       cmd[1] = 0;
+       cmd[2] = 0;
+       cmd[3] = 0;
+       cmd[4] = 0;
+
+       retval = sd_read_data(chip, SD_TM_NORMAL_READ,
+                       cmd, 5, 64, 1, SD_BUS_WIDTH_4, NULL, 0, 100);
+       if (retval != STATUS_SUCCESS) {
+               (void)sd_wait_data_idle(chip);
+
+               rtsx_clear_sd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 cmd[5], bus_width;
+
+       if (CHK_MMC_8BIT(sd_card))
+               bus_width = SD_BUS_WIDTH_8;
+       else if (CHK_MMC_4BIT(sd_card))
+               bus_width = SD_BUS_WIDTH_4;
+       else
+               bus_width = SD_BUS_WIDTH_1;
+
+       retval = sd_change_phase(chip, sample_point, TUNE_RX);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_DEBUGP("mmc ddr tuning rx\n");
+
+       cmd[0] = 0x40 | SEND_EXT_CSD;
+       cmd[1] = 0;
+       cmd[2] = 0;
+       cmd[3] = 0;
+       cmd[4] = 0;
+
+       retval = sd_read_data(chip, SD_TM_NORMAL_READ,
+                       cmd, 5, 0x200, 1, bus_width, NULL, 0, 100);
+       if (retval != STATUS_SUCCESS) {
+               (void)sd_wait_data_idle(chip);
+
+               rtsx_clear_sd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+
+       retval = sd_change_phase(chip, sample_point, TUNE_TX);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN,
+               SD_RSP_80CLK_TIMEOUT_EN);
+
+       retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
+               SD_RSP_TYPE_R1, NULL, 0);
+       if (retval != STATUS_SUCCESS) {
+               if (sd_check_err_code(chip, SD_RSP_TIMEOUT)) {
+                       rtsx_write_register(chip, SD_CFG3,
+                                       SD_RSP_80CLK_TIMEOUT_EN, 0);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 cmd[5], bus_width;
+
+       retval = sd_change_phase(chip, sample_point, TUNE_TX);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (CHK_SD(sd_card)) {
+               bus_width = SD_BUS_WIDTH_4;
+       } else {
+               if (CHK_MMC_8BIT(sd_card))
+                       bus_width = SD_BUS_WIDTH_8;
+               else if (CHK_MMC_4BIT(sd_card))
+                       bus_width = SD_BUS_WIDTH_4;
+               else
+                       bus_width = SD_BUS_WIDTH_1;
+       }
+
+       retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN,
+               SD_RSP_80CLK_TIMEOUT_EN);
+
+       cmd[0] = 0x40 | PROGRAM_CSD;
+       cmd[1] = 0;
+       cmd[2] = 0;
+       cmd[3] = 0;
+       cmd[4] = 0;
+
+       retval = sd_write_data(chip, SD_TM_AUTO_WRITE_2,
+                       cmd, 5, 16, 1, bus_width, sd_card->raw_csd, 16, 100);
+       if (retval != STATUS_SUCCESS) {
+               rtsx_clear_sd_error(chip);
+               rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
+
+       sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1,
+                       NULL, 0);
+
+       return STATUS_SUCCESS;
+}
+
+static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map,
+                               u8 tune_dir)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       struct timing_phase_path path[MAX_PHASE + 1];
+       int i, j, cont_path_cnt;
+       int new_block, max_len, final_path_idx;
+       u8 final_phase = 0xFF;
+
+       if (phase_map == 0xFFFFFFFF) {
+               if (tune_dir == TUNE_RX)
+                       final_phase = (u8)chip->sd_default_rx_phase;
+               else
+                       final_phase = (u8)chip->sd_default_tx_phase;
+
+               goto Search_Finish;
+       }
+
+       cont_path_cnt = 0;
+       new_block = 1;
+       j = 0;
+       for (i = 0; i < MAX_PHASE + 1; i++) {
+               if (phase_map & (1 << i)) {
+                       if (new_block) {
+                               new_block = 0;
+                               j = cont_path_cnt++;
+                               path[j].start = i;
+                               path[j].end = i;
+                       } else {
+                               path[j].end = i;
+                       }
+               } else {
+                       new_block = 1;
+                       if (cont_path_cnt) {
+                               int idx = cont_path_cnt - 1;
+                               path[idx].len = path[idx].end -
+                                       path[idx].start + 1;
+                               path[idx].mid = path[idx].start +
+                                       path[idx].len / 2;
+                       }
+               }
+       }
+
+       if (cont_path_cnt == 0) {
+               RTSX_DEBUGP("No continuous phase path\n");
+               goto Search_Finish;
+       } else {
+               int idx = cont_path_cnt - 1;
+               path[idx].len = path[idx].end - path[idx].start + 1;
+               path[idx].mid = path[idx].start + path[idx].len / 2;
+       }
+
+       if ((path[0].start == 0) &&
+               (path[cont_path_cnt - 1].end == MAX_PHASE)) {
+               path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1;
+               path[0].len += path[cont_path_cnt - 1].len;
+               path[0].mid = path[0].start + path[0].len / 2;
+               if (path[0].mid < 0)
+                       path[0].mid += MAX_PHASE + 1;
+
+               cont_path_cnt--;
+       }
+
+       max_len = 0;
+       final_phase = 0;
+       final_path_idx = 0;
+       for (i = 0; i < cont_path_cnt; i++) {
+               if (path[i].len > max_len) {
+                       max_len = path[i].len;
+                       final_phase = (u8)path[i].mid;
+                       final_path_idx = i;
+               }
+
+               RTSX_DEBUGP("path[%d].start = %d\n", i, path[i].start);
+               RTSX_DEBUGP("path[%d].end = %d\n", i, path[i].end);
+               RTSX_DEBUGP("path[%d].len = %d\n", i, path[i].len);
+               RTSX_DEBUGP("path[%d].mid = %d\n", i, path[i].mid);
+               RTSX_DEBUGP("\n");
+       }
+
+       if (tune_dir == TUNE_TX) {
+               if (CHK_SD_SDR104(sd_card)) {
+                       if (max_len > 15) {
+                               int temp_mid = (max_len - 16) / 2;
+                               int temp_final_phase =
+                                       path[final_path_idx].end -
+                                       (max_len - (6 + temp_mid));
+
+                               if (temp_final_phase < 0)
+                                       final_phase = (u8)(temp_final_phase +
+                                                       MAX_PHASE + 1);
+                               else
+                                       final_phase = (u8)temp_final_phase;
+                       }
+               } else if (CHK_SD_SDR50(sd_card)) {
+                       if (max_len > 12) {
+                               int temp_mid = (max_len - 13) / 2;
+                               int temp_final_phase =
+                                       path[final_path_idx].end -
+                                       (max_len - (3 + temp_mid));
+
+                               if (temp_final_phase < 0)
+                                       final_phase = (u8)(temp_final_phase +
+                                                       MAX_PHASE + 1);
+                               else
+                                       final_phase = (u8)temp_final_phase;
+                       }
+               }
+       }
+
+Search_Finish:
+       RTSX_DEBUGP("Final chosen phase: %d\n", final_phase);
+       return final_phase;
+}
+
+static int sd_tuning_rx(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       int i, j;
+       u32 raw_phase_map[3], phase_map;
+       u8 final_phase;
+       int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point);
+
+       if (CHK_SD(sd_card)) {
+               if (CHK_SD_DDR50(sd_card))
+                       tuning_cmd = sd_ddr_tuning_rx_cmd;
+               else
+                       tuning_cmd = sd_sdr_tuning_rx_cmd;
+
+       } else {
+               if (CHK_MMC_DDR52(sd_card))
+                       tuning_cmd = mmc_ddr_tunning_rx_cmd;
+               else
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       for (i = 0; i < 3; i++) {
+               raw_phase_map[i] = 0;
+               for (j = MAX_PHASE; j >= 0; j--) {
+                       if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                               sd_set_err_code(chip, SD_NO_CARD);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       retval = tuning_cmd(chip, (u8)j);
+                       if (retval == STATUS_SUCCESS)
+                               raw_phase_map[i] |= 1 << j;
+               }
+       }
+
+       phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2];
+       for (i = 0; i < 3; i++)
+               RTSX_DEBUGP("RX raw_phase_map[%d] = 0x%08x\n", i,
+                       raw_phase_map[i]);
+
+       RTSX_DEBUGP("RX phase_map = 0x%08x\n", phase_map);
+
+       final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX);
+       if (final_phase == 0xFF)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_change_phase(chip, final_phase, TUNE_RX);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       int i;
+       u32 phase_map;
+       u8 final_phase;
+
+       RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN,
+               SD_RSP_80CLK_TIMEOUT_EN);
+
+       phase_map = 0;
+       for (i = MAX_PHASE; i >= 0; i--) {
+               if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                       sd_set_err_code(chip, SD_NO_CARD);
+                       rtsx_write_register(chip, SD_CFG3,
+                                               SD_RSP_80CLK_TIMEOUT_EN, 0);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = sd_change_phase(chip, (u8)i, TUNE_TX);
+               if (retval != STATUS_SUCCESS)
+                       continue;
+
+               retval = sd_send_cmd_get_rsp(chip, SEND_STATUS,
+                                       sd_card->sd_addr, SD_RSP_TYPE_R1, NULL,
+                                       0);
+               if ((retval == STATUS_SUCCESS) ||
+                       !sd_check_err_code(chip, SD_RSP_TIMEOUT))
+                       phase_map |= 1 << i;
+       }
+
+       RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
+
+       RTSX_DEBUGP("DDR TX pre tune phase_map = 0x%08x\n", phase_map);
+
+       final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX);
+       if (final_phase == 0xFF)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_change_phase(chip, final_phase, TUNE_TX);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_DEBUGP("DDR TX pre tune phase: %d\n", (int)final_phase);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_tuning_tx(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       int i, j;
+       u32 raw_phase_map[3], phase_map;
+       u8 final_phase;
+       int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point);
+
+       if (CHK_SD(sd_card)) {
+               if (CHK_SD_DDR50(sd_card))
+                       tuning_cmd = sd_ddr_tuning_tx_cmd;
+               else
+                       tuning_cmd = sd_sdr_tuning_tx_cmd;
+
+       } else {
+               if (CHK_MMC_DDR52(sd_card))
+                       tuning_cmd = sd_ddr_tuning_tx_cmd;
+               else
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       for (i = 0; i < 3; i++) {
+               raw_phase_map[i] = 0;
+               for (j = MAX_PHASE; j >= 0; j--) {
+                       if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                               sd_set_err_code(chip, SD_NO_CARD);
+                               rtsx_write_register(chip, SD_CFG3,
+                                                   SD_RSP_80CLK_TIMEOUT_EN, 0);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       retval = tuning_cmd(chip, (u8)j);
+                       if (retval == STATUS_SUCCESS)
+                               raw_phase_map[i] |= 1 << j;
+               }
+       }
+
+       phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2];
+       for (i = 0; i < 3; i++)
+               RTSX_DEBUGP("TX raw_phase_map[%d] = 0x%08x\n",
+                       i, raw_phase_map[i]);
+
+       RTSX_DEBUGP("TX phase_map = 0x%08x\n", phase_map);
+
+       final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX);
+       if (final_phase == 0xFF)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_change_phase(chip, final_phase, TUNE_TX);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_sdr_tuning(struct rtsx_chip *chip)
+{
+       int retval;
+
+       retval = sd_tuning_tx(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_tuning_rx(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_ddr_tuning(struct rtsx_chip *chip)
+{
+       int retval;
+
+       if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) {
+               retval = sd_ddr_pre_tuning_tx(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else {
+               retval = sd_change_phase(chip, (u8)chip->sd_ddr_tx_phase,
+                                       TUNE_TX);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = sd_tuning_rx(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) {
+               retval = sd_tuning_tx(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int mmc_ddr_tuning(struct rtsx_chip *chip)
+{
+       int retval;
+
+       if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) {
+               retval = sd_ddr_pre_tuning_tx(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else {
+               retval = sd_change_phase(chip, (u8)chip->mmc_ddr_tx_phase,
+                                       TUNE_TX);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = sd_tuning_rx(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) {
+               retval = sd_tuning_tx(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int sd_switch_clock(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       int re_tuning = 0;
+
+       retval = select_card(chip, SD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = switch_clock(chip, sd_card->sd_clock);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (re_tuning) {
+               if (CHK_SD(sd_card)) {
+                       if (CHK_SD_DDR50(sd_card))
+                               retval = sd_ddr_tuning(chip);
+                       else
+                               retval = sd_sdr_tuning(chip);
+               } else {
+                       if (CHK_MMC_DDR52(sd_card))
+                               retval = mmc_ddr_tuning(chip);
+               }
+
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_prepare_reset(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+
+       if (chip->asic_code)
+               sd_card->sd_clock = 29;
+       else
+               sd_card->sd_clock = CLK_30;
+
+       sd_card->sd_type = 0;
+       sd_card->seq_mode = 0;
+       sd_card->sd_data_buf_ready = 0;
+       sd_card->capacity = 0;
+
+#ifdef SUPPORT_SD_LOCK
+       sd_card->sd_lock_status = 0;
+       sd_card->sd_erase_status = 0;
+#endif
+
+       chip->capacity[chip->card2lun[SD_CARD]] = 0;
+       chip->sd_io = 0;
+
+       retval = sd_set_init_para(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, retval);
+
+       RTSX_WRITE_REG(chip, REG_SD_CFG1, 0xFF, 0x40);
+
+       RTSX_WRITE_REG(chip, CARD_STOP, SD_STOP | SD_CLR_ERR,
+               SD_STOP | SD_CLR_ERR);
+
+       retval = select_card(chip, SD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_pull_ctl_disable(struct rtsx_chip *chip)
+{
+       if (CHECK_PID(chip, 0x5208)) {
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF,
+                       XD_D3_PD | SD_D7_PD | SD_CLK_PD | SD_D5_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF,
+                       SD_D6_PD | SD_D0_PD | SD_D1_PD | XD_D5_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF,
+                       SD_D4_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF,
+                       XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF,
+                       MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD);
+       } else if (CHECK_PID(chip, 0x5288)) {
+               if (CHECK_BARO_PKG(chip, QFN)) {
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55);
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55);
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B);
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69);
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int sd_pull_ctl_enable(struct rtsx_chip *chip)
+{
+       int retval;
+
+       rtsx_init_cmd(chip);
+
+       if (CHECK_PID(chip, 0x5208)) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,
+                       XD_D3_PD | SD_DAT7_PU | SD_CLK_NP | SD_D5_PU);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,
+                       SD_D6_PU | SD_D0_PU | SD_D1_PU | XD_D5_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,
+                       SD_D4_PU | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,
+                       XD_RDY_PD | SD_D3_PU | SD_D2_PU | XD_ALE_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,
+                       MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF,
+                       MS_D5_PD | MS_D4_PD);
+       } else if (CHECK_PID(chip, 0x5288)) {
+               if (CHECK_BARO_PKG(chip, QFN)) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,
+                               0xA8);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,
+                               0x5A);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,
+                               0x95);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,
+                               0xAA);
+               }
+       }
+
+       retval = rtsx_send_cmd(chip, SD_CARD, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_init_power(struct rtsx_chip *chip)
+{
+       int retval;
+
+       retval = sd_power_off_card3v3(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (!chip->ft2_fast_mode)
+               wait_timeout(250);
+
+       retval = enable_card_clock(chip, SD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (chip->asic_code) {
+               retval = sd_pull_ctl_enable(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else {
+               RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20,
+                       0);
+       }
+
+       if (!chip->ft2_fast_mode) {
+               retval = card_power_on(chip, SD_CARD);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               wait_timeout(260);
+
+#ifdef SUPPORT_OCP
+               if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
+                       RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
+                               chip->ocp_stat);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+#endif
+       }
+
+       RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_dummy_clock(struct rtsx_chip *chip)
+{
+       RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0x01);
+       wait_timeout(5);
+       RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0);
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_read_lba0(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 cmd[5], bus_width;
+
+       cmd[0] = 0x40 | READ_SINGLE_BLOCK;
+       cmd[1] = 0;
+       cmd[2] = 0;
+       cmd[3] = 0;
+       cmd[4] = 0;
+
+       if (CHK_SD(sd_card)) {
+               bus_width = SD_BUS_WIDTH_4;
+       } else {
+               if (CHK_MMC_8BIT(sd_card))
+                       bus_width = SD_BUS_WIDTH_8;
+               else if (CHK_MMC_4BIT(sd_card))
+                       bus_width = SD_BUS_WIDTH_4;
+               else
+                       bus_width = SD_BUS_WIDTH_1;
+       }
+
+       retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd,
+               5, 512, 1, bus_width, NULL, 0, 100);
+       if (retval != STATUS_SUCCESS) {
+               rtsx_clear_sd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sd_check_wp_state(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u32 val;
+       u16 sd_card_type;
+       u8 cmd[5], buf[64];
+
+       retval = sd_send_cmd_get_rsp(chip, APP_CMD,
+                       sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       cmd[0] = 0x40 | SD_STATUS;
+       cmd[1] = 0;
+       cmd[2] = 0;
+       cmd[3] = 0;
+       cmd[4] = 0;
+
+       retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1,
+                       SD_BUS_WIDTH_4, buf, 64, 250);
+       if (retval != STATUS_SUCCESS) {
+               rtsx_clear_sd_error(chip);
+
+               sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
+                               SD_RSP_TYPE_R1, NULL, 0);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_DEBUGP("ACMD13:\n");
+       RTSX_DUMP(buf, 64);
+
+       sd_card_type = ((u16)buf[2] << 8) | buf[3];
+       RTSX_DEBUGP("sd_card_type = 0x%04x\n", sd_card_type);
+       if ((sd_card_type == 0x0001) || (sd_card_type == 0x0002)) {
+               /* ROM card or OTP */
+               chip->card_wp |= SD_CARD;
+       }
+
+       /* Check SD Machanical Write-Protect Switch */
+       val = rtsx_readl(chip, RTSX_BIPR);
+       if (val & SD_WRITE_PROTECT)
+               chip->card_wp |= SD_CARD;
+
+       return STATUS_SUCCESS;
+}
+
+static int reset_sd(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval, i = 0, j = 0, k = 0, hi_cap_flow = 0;
+       int sd_dont_switch = 0;
+       int support_1v8 = 0;
+       int try_sdio = 1;
+       u8 rsp[16];
+       u8 switch_bus_width;
+       u32 voltage = 0;
+       int sd20_mode = 0;
+
+       SET_SD(sd_card);
+
+Switch_Fail:
+
+       i = 0;
+       j = 0;
+       k = 0;
+       hi_cap_flow = 0;
+
+#ifdef SUPPORT_SD_LOCK
+       if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON)
+               goto SD_UNLOCK_ENTRY;
+#endif
+
+       retval = sd_prepare_reset(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_dummy_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && try_sdio) {
+               int rty_cnt = 0;
+
+               for (; rty_cnt < chip->sdio_retry_cnt; rty_cnt++) {
+                       if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                               sd_set_err_code(chip, SD_NO_CARD);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       retval = sd_send_cmd_get_rsp(chip, IO_SEND_OP_COND, 0,
+                                               SD_RSP_TYPE_R4, rsp, 5);
+                       if (retval == STATUS_SUCCESS) {
+                               int func_num = (rsp[1] >> 4) & 0x07;
+                               if (func_num) {
+                                       RTSX_DEBUGP("SD_IO card (Function number: %d)!\n", func_num);
+                                       chip->sd_io = 1;
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+
+                               break;
+                       }
+
+                       sd_init_power(chip);
+
+                       sd_dummy_clock(chip);
+               }
+
+               RTSX_DEBUGP("Normal card!\n");
+       }
+
+       /* Start Initialization Process of SD Card */
+RTY_SD_RST:
+       retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0,
+                               NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       wait_timeout(20);
+
+       retval = sd_send_cmd_get_rsp(chip, SEND_IF_COND, 0x000001AA,
+                               SD_RSP_TYPE_R7, rsp, 5);
+       if (retval == STATUS_SUCCESS) {
+               if ((rsp[4] == 0xAA) && ((rsp[3] & 0x0f) == 0x01)) {
+                       hi_cap_flow = 1;
+                       voltage = SUPPORT_VOLTAGE | 0x40000000;
+               }
+       }
+
+       if (!hi_cap_flow) {
+               voltage = SUPPORT_VOLTAGE;
+
+               retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0,
+                                       SD_RSP_TYPE_R0, NULL, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               wait_timeout(20);
+       }
+
+       do {
+               retval = sd_send_cmd_get_rsp(chip, APP_CMD, 0, SD_RSP_TYPE_R1,
+                                       NULL, 0);
+               if (retval != STATUS_SUCCESS) {
+                       if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                               sd_set_err_code(chip, SD_NO_CARD);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       j++;
+                       if (j < 3)
+                               goto RTY_SD_RST;
+                       else
+                               TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage,
+                                       SD_RSP_TYPE_R3, rsp, 5);
+               if (retval != STATUS_SUCCESS) {
+                       k++;
+                       if (k < 3)
+                               goto RTY_SD_RST;
+                       else
+                               TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               i++;
+               wait_timeout(20);
+       } while (!(rsp[1] & 0x80) && (i < 255));
+
+       if (i == 255)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (hi_cap_flow) {
+               if (rsp[1] & 0x40)
+                       SET_SD_HCXC(sd_card);
+               else
+                       CLR_SD_HCXC(sd_card);
+
+               support_1v8 = 0;
+       } else {
+               CLR_SD_HCXC(sd_card);
+               support_1v8 = 0;
+       }
+       RTSX_DEBUGP("support_1v8 = %d\n", support_1v8);
+
+       if (support_1v8) {
+               retval = sd_voltage_switch(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2,
+                               NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       for (i = 0; i < 3; i++) {
+               retval = sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0,
+                                       SD_RSP_TYPE_R6, rsp, 5);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               sd_card->sd_addr = (u32)rsp[1] << 24;
+               sd_card->sd_addr += (u32)rsp[2] << 16;
+
+               if (sd_card->sd_addr)
+                       break;
+       }
+
+       retval = sd_check_csd(chip, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_select_card(chip, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+#ifdef SUPPORT_SD_LOCK
+SD_UNLOCK_ENTRY:
+       retval = sd_update_lock_status(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (sd_card->sd_lock_status & SD_LOCKED) {
+               sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST);
+               return STATUS_SUCCESS;
+       } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) {
+               sd_card->sd_lock_status &= ~SD_PWD_EXIST;
+       }
+#endif
+
+       retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
+                               SD_RSP_TYPE_R1, NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0,
+                               SD_RSP_TYPE_R1, NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (support_1v8) {
+               retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
+                                       SD_RSP_TYPE_R1, NULL, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2,
+                                       SD_RSP_TYPE_R1, NULL, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               switch_bus_width = SD_BUS_WIDTH_4;
+       } else {
+               switch_bus_width = SD_BUS_WIDTH_1;
+       }
+
+       retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1,
+                               NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (!(sd_card->raw_csd[4] & 0x40))
+               sd_dont_switch = 1;
+
+       if (!sd_dont_switch) {
+               if (sd20_mode) {
+                       /* Set sd_switch_fail here, because we needn't
+                        * switch to UHS mode
+                        */
+                       sd_card->sd_switch_fail = SDR104_SUPPORT_MASK |
+                               DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK;
+               }
+
+               /* Check the card whether follow SD1.1 spec or higher */
+               retval = sd_check_spec(chip, switch_bus_width);
+               if (retval == STATUS_SUCCESS) {
+                       retval = sd_switch_function(chip, switch_bus_width);
+                       if (retval != STATUS_SUCCESS) {
+                               sd_init_power(chip);
+                               sd_dont_switch = 1;
+                               try_sdio = 0;
+
+                               goto Switch_Fail;
+                       }
+               } else {
+                       if (support_1v8) {
+                               sd_init_power(chip);
+                               sd_dont_switch = 1;
+                               try_sdio = 0;
+
+                               goto Switch_Fail;
+                       }
+               }
+       }
+
+       if (!support_1v8) {
+               retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
+                                       SD_RSP_TYPE_R1, NULL, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2,
+                                       SD_RSP_TYPE_R1, NULL, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+#ifdef SUPPORT_SD_LOCK
+       sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE;
+#endif
+
+       if (!sd20_mode && CHK_SD30_SPEED(sd_card)) {
+               int read_lba0 = 1;
+
+               RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07,
+                       chip->sd30_drive_sel_1v8);
+
+               retval = sd_set_init_para(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (CHK_SD_DDR50(sd_card))
+                       retval = sd_ddr_tuning(chip);
+               else
+                       retval = sd_sdr_tuning(chip);
+
+               if (retval != STATUS_SUCCESS) {
+                       if (sd20_mode) {
+                               TRACE_RET(chip, STATUS_FAIL);
+                       } else {
+                               retval = sd_init_power(chip);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                               try_sdio = 0;
+                               sd20_mode = 1;
+                               goto Switch_Fail;
+                       }
+               }
+
+               sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
+                               SD_RSP_TYPE_R1, NULL, 0);
+
+               if (CHK_SD_DDR50(sd_card)) {
+                       retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000);
+                       if (retval != STATUS_SUCCESS)
+                               read_lba0 = 0;
+               }
+
+               if (read_lba0) {
+                       retval = sd_read_lba0(chip);
+                       if (retval != STATUS_SUCCESS) {
+                               if (sd20_mode) {
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               } else {
+                                       retval = sd_init_power(chip);
+                                       if (retval != STATUS_SUCCESS)
+                                               TRACE_RET(chip, STATUS_FAIL);
+
+                                       try_sdio = 0;
+                                       sd20_mode = 1;
+                                       goto Switch_Fail;
+                               }
+                       }
+               }
+       }
+
+       retval = sd_check_wp_state(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       chip->card_bus_width[chip->card2lun[SD_CARD]] = 4;
+
+#ifdef SUPPORT_SD_LOCK
+       if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) {
+               RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02);
+               RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00);
+       }
+#endif
+
+       return STATUS_SUCCESS;
+}
+
+
+static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 buf[8] = {0}, bus_width, *ptr;
+       u16 byte_cnt;
+       int len;
+
+       retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL,
+                               0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, SWITCH_FAIL);
+
+       if (width == MMC_8BIT_BUS) {
+               buf[0] = 0x55;
+               buf[1] = 0xAA;
+               len = 8;
+               byte_cnt = 8;
+               bus_width = SD_BUS_WIDTH_8;
+       } else {
+               buf[0] = 0x5A;
+               len = 4;
+               byte_cnt = 4;
+               bus_width = SD_BUS_WIDTH_4;
+       }
+
+       retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0x02);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, SWITCH_ERR);
+
+       retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3,
+                       NULL, 0, byte_cnt, 1, bus_width, buf, len, 100);
+       if (retval != STATUS_SUCCESS) {
+               rtsx_clear_sd_error(chip);
+               rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0);
+               TRACE_RET(chip, SWITCH_ERR);
+       }
+
+       retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, SWITCH_ERR);
+
+       RTSX_DEBUGP("SD/MMC CMD %d\n", BUSTEST_R);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | BUSTEST_R);
+
+       if (width == MMC_8BIT_BUS)
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L,
+                       0xFF, 0x08);
+       else
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L,
+                       0xFF, 0x04);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
+               SD_CALCULATE_CRC7 | SD_NO_CHECK_CRC16 | SD_NO_WAIT_BUSY_END|
+               SD_CHECK_CRC7 | SD_RSP_LEN_6);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
+               PINGPONG_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+               SD_TM_NORMAL_READ | SD_TRANSFER_START);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END,
+               SD_TRANSFER_END);
+
+       rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0);
+       if (width == MMC_8BIT_BUS)
+               rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0);
+
+       retval = rtsx_send_cmd(chip, SD_CARD, 100);
+       if (retval < 0) {
+               rtsx_clear_sd_error(chip);
+               TRACE_RET(chip, SWITCH_ERR);
+       }
+
+       ptr = rtsx_get_cmd_data(chip) + 1;
+
+       if (width == MMC_8BIT_BUS) {
+               RTSX_DEBUGP("BUSTEST_R [8bits]: 0x%02x 0x%02x\n", ptr[0],
+                       ptr[1]);
+               if ((ptr[0] == 0xAA) && (ptr[1] == 0x55)) {
+                       u8 rsp[5];
+                       u32 arg;
+
+                       if (CHK_MMC_DDR52(sd_card))
+                               arg = 0x03B70600;
+                       else
+                               arg = 0x03B70200;
+
+                       retval = sd_send_cmd_get_rsp(chip, SWITCH, arg,
+                                               SD_RSP_TYPE_R1b, rsp, 5);
+                       if ((retval == STATUS_SUCCESS) &&
+                               !(rsp[4] & MMC_SWITCH_ERR))
+                               return SWITCH_SUCCESS;
+               }
+       } else {
+               RTSX_DEBUGP("BUSTEST_R [4bits]: 0x%02x\n", ptr[0]);
+               if (ptr[0] == 0xA5) {
+                       u8 rsp[5];
+                       u32 arg;
+
+                       if (CHK_MMC_DDR52(sd_card))
+                               arg = 0x03B70500;
+                       else
+                               arg = 0x03B70100;
+
+                       retval = sd_send_cmd_get_rsp(chip, SWITCH, arg,
+                                               SD_RSP_TYPE_R1b, rsp, 5);
+                       if ((retval == STATUS_SUCCESS) &&
+                               !(rsp[4] & MMC_SWITCH_ERR))
+                               return SWITCH_SUCCESS;
+               }
+       }
+
+       TRACE_RET(chip, SWITCH_FAIL);
+}
+
+
+static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+       u8 *ptr, card_type, card_type_mask = 0;
+
+       CLR_MMC_HS(sd_card);
+
+       RTSX_DEBUGP("SD/MMC CMD %d\n", SEND_EXT_CSD);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF,
+               0x40 | SEND_EXT_CSD);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, 0);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 2);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
+               SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END|
+               SD_CHECK_CRC7 | SD_RSP_LEN_6);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
+               PINGPONG_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+               SD_TM_NORMAL_READ | SD_TRANSFER_START);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END,
+               SD_TRANSFER_END);
+
+       rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 196, 0xFF, 0);
+       rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 212, 0xFF, 0);
+       rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 213, 0xFF, 0);
+       rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 214, 0xFF, 0);
+       rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 215, 0xFF, 0);
+
+       retval = rtsx_send_cmd(chip, SD_CARD, 1000);
+       if (retval < 0) {
+               if (retval == -ETIMEDOUT) {
+                       rtsx_clear_sd_error(chip);
+                       sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
+                                       SD_RSP_TYPE_R1, NULL, 0);
+               }
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       ptr = rtsx_get_cmd_data(chip);
+       if (ptr[0] & SD_TRANSFER_ERR) {
+               sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
+                               SD_RSP_TYPE_R1, NULL, 0);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (CHK_MMC_SECTOR_MODE(sd_card)) {
+               sd_card->capacity = ((u32)ptr[5] << 24) | ((u32)ptr[4] << 16) |
+                       ((u32)ptr[3] << 8) | ((u32)ptr[2]);
+       }
+
+       card_type_mask = 0x03;
+       card_type = ptr[1] & card_type_mask;
+       if (card_type) {
+               u8 rsp[5];
+
+               if (card_type & 0x04) {
+                       if (switch_ddr)
+                               SET_MMC_DDR52(sd_card);
+                       else
+                               SET_MMC_52M(sd_card);
+               } else if (card_type & 0x02) {
+                       SET_MMC_52M(sd_card);
+               } else {
+                       SET_MMC_26M(sd_card);
+               }
+
+               retval = sd_send_cmd_get_rsp(chip, SWITCH,
+                               0x03B90100, SD_RSP_TYPE_R1b, rsp, 5);
+               if ((retval != STATUS_SUCCESS) || (rsp[4] & MMC_SWITCH_ERR))
+                       CLR_MMC_HS(sd_card);
+       }
+
+       sd_choose_proper_clock(chip);
+       retval = switch_clock(chip, sd_card->sd_clock);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       /* Test Bus Procedure */
+       retval = mmc_test_switch_bus(chip, MMC_8BIT_BUS);
+       if (retval == SWITCH_SUCCESS) {
+               SET_MMC_8BIT(sd_card);
+               chip->card_bus_width[chip->card2lun[SD_CARD]] = 8;
+#ifdef SUPPORT_SD_LOCK
+               sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE;
+#endif
+       } else if (retval == SWITCH_FAIL) {
+               retval = mmc_test_switch_bus(chip, MMC_4BIT_BUS);
+               if (retval == SWITCH_SUCCESS) {
+                       SET_MMC_4BIT(sd_card);
+                       chip->card_bus_width[chip->card2lun[SD_CARD]] = 4;
+#ifdef SUPPORT_SD_LOCK
+                       sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE;
+#endif
+               } else if (retval == SWITCH_FAIL) {
+                       CLR_MMC_8BIT(sd_card);
+                       CLR_MMC_4BIT(sd_card);
+               } else {
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       } else {
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+
+static int reset_mmc(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval, i = 0, j = 0, k = 0;
+       int switch_ddr = 1;
+       u8 rsp[16];
+       u8 spec_ver = 0;
+       u32 temp;
+
+#ifdef SUPPORT_SD_LOCK
+       if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON)
+               goto MMC_UNLOCK_ENTRY;
+#endif
+
+Switch_Fail:
+       retval = sd_prepare_reset(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, retval);
+
+       SET_MMC(sd_card);
+
+RTY_MMC_RST:
+       retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0,
+                               NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       do {
+               if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                       sd_set_err_code(chip, SD_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = sd_send_cmd_get_rsp(chip, SEND_OP_COND,
+                                       (SUPPORT_VOLTAGE | 0x40000000),
+                                       SD_RSP_TYPE_R3, rsp, 5);
+               if (retval != STATUS_SUCCESS) {
+                       if (sd_check_err_code(chip, SD_BUSY) ||
+                               sd_check_err_code(chip, SD_TO_ERR)) {
+                               k++;
+                               if (k < 20) {
+                                       sd_clr_err_code(chip);
+                                       goto RTY_MMC_RST;
+                               } else {
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+                       } else {
+                               j++;
+                               if (j < 100) {
+                                       sd_clr_err_code(chip);
+                                       goto RTY_MMC_RST;
+                               } else {
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+                       }
+               }
+
+               wait_timeout(20);
+               i++;
+       } while (!(rsp[1] & 0x80) && (i < 255));
+
+       if (i == 255)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if ((rsp[1] & 0x60) == 0x40)
+               SET_MMC_SECTOR_MODE(sd_card);
+       else
+               CLR_MMC_SECTOR_MODE(sd_card);
+
+       retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2,
+                               NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       sd_card->sd_addr = 0x00100000;
+       retval = sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr,
+                               SD_RSP_TYPE_R6, rsp, 5);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_check_csd(chip, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2;
+
+       retval = sd_select_card(chip, 1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1,
+                               NULL, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+#ifdef SUPPORT_SD_LOCK
+MMC_UNLOCK_ENTRY:
+       retval = sd_update_lock_status(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+#endif
+
+       retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       chip->card_bus_width[chip->card2lun[SD_CARD]] = 1;
+
+       if (!sd_card->mmc_dont_switch_bus) {
+               if (spec_ver == 4) {
+                       /* MMC 4.x Cards */
+                       retval = mmc_switch_timing_bus(chip, switch_ddr);
+                       if (retval != STATUS_SUCCESS) {
+                               retval = sd_init_power(chip);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               sd_card->mmc_dont_switch_bus = 1;
+                               TRACE_GOTO(chip, Switch_Fail);
+                       }
+               }
+
+               if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0))
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (switch_ddr && CHK_MMC_DDR52(sd_card)) {
+                       retval = sd_set_init_para(chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       retval = mmc_ddr_tuning(chip);
+                       if (retval != STATUS_SUCCESS) {
+                               retval = sd_init_power(chip);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                               switch_ddr = 0;
+                               TRACE_GOTO(chip, Switch_Fail);
+                       }
+
+                       retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000);
+                       if (retval == STATUS_SUCCESS) {
+                               retval = sd_read_lba0(chip);
+                               if (retval != STATUS_SUCCESS) {
+                                       retval = sd_init_power(chip);
+                                       if (retval != STATUS_SUCCESS)
+                                               TRACE_RET(chip, STATUS_FAIL);
+
+                                       switch_ddr = 0;
+                                       TRACE_GOTO(chip, Switch_Fail);
+                               }
+                       }
+               }
+       }
+
+#ifdef SUPPORT_SD_LOCK
+       if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) {
+               RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02);
+               RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00);
+       }
+#endif
+
+       temp = rtsx_readl(chip, RTSX_BIPR);
+       if (temp & SD_WRITE_PROTECT)
+               chip->card_wp |= SD_CARD;
+
+       return STATUS_SUCCESS;
+}
+
+int reset_sd_card(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+
+       sd_init_reg_addr(chip);
+
+       memset(sd_card, 0, sizeof(struct sd_info));
+       chip->capacity[chip->card2lun[SD_CARD]] = 0;
+
+       retval = enable_card_clock(chip, SD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (chip->ignore_sd && CHK_SDIO_EXIST(chip) &&
+               !CHK_SDIO_IGNORED(chip)) {
+               if (chip->asic_code) {
+                       retval = sd_pull_ctl_enable(chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+               } else {
+                       retval = rtsx_write_register(chip, FPGA_PULL_CTL,
+                                               FPGA_SD_PULL_CTL_BIT | 0x20, 0);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+               }
+               retval = card_share_mode(chip, SD_CARD);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               chip->sd_io = 1;
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = sd_init_power(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (chip->sd_ctl & RESET_MMC_FIRST) {
+               retval = reset_mmc(chip);
+               if (retval != STATUS_SUCCESS) {
+                       if (sd_check_err_code(chip, SD_NO_CARD))
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       retval = reset_sd(chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+               }
+       } else {
+               retval = reset_sd(chip);
+               if (retval != STATUS_SUCCESS) {
+                       if (sd_check_err_code(chip, SD_NO_CARD))
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       if (chip->sd_io) {
+                               TRACE_RET(chip, STATUS_FAIL);
+                       } else {
+                               retval = reset_mmc(chip);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+       }
+
+       retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0);
+       RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2);
+
+       chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity;
+
+       retval = sd_set_init_para(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_DEBUGP("sd_card->sd_type = 0x%x\n", sd_card->sd_type);
+
+       return STATUS_SUCCESS;
+}
+
+static int reset_mmc_only(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+
+       sd_card->sd_type = 0;
+       sd_card->seq_mode = 0;
+       sd_card->sd_data_buf_ready = 0;
+       sd_card->capacity = 0;
+       sd_card->sd_switch_fail = 0;
+
+#ifdef SUPPORT_SD_LOCK
+       sd_card->sd_lock_status = 0;
+       sd_card->sd_erase_status = 0;
+#endif
+
+       chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0;
+
+       retval = enable_card_clock(chip, SD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_init_power(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = reset_mmc(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0);
+       RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2);
+
+       chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity;
+
+       retval = sd_set_init_para(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_DEBUGP("In reset_mmc_only, sd_card->sd_type = 0x%x\n",
+               sd_card->sd_type);
+
+       return STATUS_SUCCESS;
+}
+
+#define WAIT_DATA_READY_RTY_CNT                255
+
+static int wait_data_buf_ready(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int i, retval;
+
+       for (i = 0; i < WAIT_DATA_READY_RTY_CNT; i++) {
+               if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                       sd_set_err_code(chip, SD_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               sd_card->sd_data_buf_ready = 0;
+
+               retval = sd_send_cmd_get_rsp(chip, SEND_STATUS,
+                               sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (sd_card->sd_data_buf_ready) {
+                       return sd_send_cmd_get_rsp(chip, SEND_STATUS,
+                               sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
+               }
+       }
+
+       sd_set_err_code(chip, SD_TO_ERR);
+
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+void sd_stop_seq_mode(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+
+       if (sd_card->seq_mode) {
+               retval = sd_switch_clock(chip);
+               if (retval != STATUS_SUCCESS)
+                       return;
+
+               retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0,
+                               SD_RSP_TYPE_R1b, NULL, 0);
+               if (retval != STATUS_SUCCESS)
+                       sd_set_err_code(chip, SD_STS_ERR);
+
+               retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000);
+               if (retval != STATUS_SUCCESS)
+                       sd_set_err_code(chip, SD_STS_ERR);
+
+               sd_card->seq_mode = 0;
+
+               rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
+       }
+}
+
+static inline int sd_auto_tune_clock(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+
+       if (chip->asic_code) {
+               if (sd_card->sd_clock > 30)
+                       sd_card->sd_clock -= 20;
+       } else {
+               switch (sd_card->sd_clock) {
+               case CLK_200:
+                       sd_card->sd_clock = CLK_150;
+                       break;
+
+               case CLK_150:
+                       sd_card->sd_clock = CLK_120;
+                       break;
+
+               case CLK_120:
+                       sd_card->sd_clock = CLK_100;
+                       break;
+
+               case CLK_100:
+                       sd_card->sd_clock = CLK_80;
+                       break;
+
+               case CLK_80:
+                       sd_card->sd_clock = CLK_60;
+                       break;
+
+               case CLK_60:
+                       sd_card->sd_clock = CLK_50;
+                       break;
+
+               default:
+                       break;
+               }
+       }
+
+       retval = sd_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector,
+       u16 sector_cnt)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       u32 data_addr;
+       u8 cfg2;
+       int retval;
+
+       if (srb->sc_data_direction == DMA_FROM_DEVICE) {
+               RTSX_DEBUGP("sd_rw: Read %d %s from 0x%x\n", sector_cnt,
+                       (sector_cnt > 1) ? "sectors" : "sector", start_sector);
+       } else {
+               RTSX_DEBUGP("sd_rw: Write %d %s to 0x%x\n", sector_cnt,
+                       (sector_cnt > 1) ? "sectors" : "sector", start_sector);
+       }
+
+       sd_card->cleanup_counter = 0;
+
+       if (!(chip->card_ready & SD_CARD)) {
+               sd_card->seq_mode = 0;
+
+               retval = reset_sd_card(chip);
+               if (retval == STATUS_SUCCESS) {
+                       chip->card_ready |= SD_CARD;
+                       chip->card_fail &= ~SD_CARD;
+               } else {
+                       chip->card_ready &= ~SD_CARD;
+                       chip->card_fail |= SD_CARD;
+                       chip->capacity[chip->card2lun[SD_CARD]] = 0;
+                       chip->rw_need_retry = 1;
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card))
+               data_addr = start_sector << 9;
+       else
+               data_addr = start_sector;
+
+       sd_clr_err_code(chip);
+
+       retval = sd_switch_clock(chip);
+       if (retval != STATUS_SUCCESS) {
+               sd_set_err_code(chip, SD_IO_ERR);
+               TRACE_GOTO(chip, RW_FAIL);
+       }
+
+       if (sd_card->seq_mode &&
+               ((sd_card->pre_dir != srb->sc_data_direction) ||
+                       ((sd_card->pre_sec_addr + sd_card->pre_sec_cnt) !=
+                               start_sector))) {
+               if ((sd_card->pre_sec_cnt < 0x80)
+                               && (sd_card->pre_dir == DMA_FROM_DEVICE)
+                               && !CHK_SD30_SPEED(sd_card)
+                               && !CHK_SD_HS(sd_card)
+                               && !CHK_MMC_HS(sd_card)) {
+                       sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
+                                       SD_RSP_TYPE_R1, NULL, 0);
+               }
+
+               retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION,
+                               0, SD_RSP_TYPE_R1b, NULL, 0);
+               if (retval != STATUS_SUCCESS) {
+                       chip->rw_need_retry = 1;
+                       sd_set_err_code(chip, SD_STS_ERR);
+                       TRACE_GOTO(chip, RW_FAIL);
+               }
+
+               sd_card->seq_mode = 0;
+
+               retval = rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
+               if (retval != STATUS_SUCCESS) {
+                       sd_set_err_code(chip, SD_IO_ERR);
+                       TRACE_GOTO(chip, RW_FAIL);
+               }
+
+               if ((sd_card->pre_sec_cnt < 0x80)
+                               && !CHK_SD30_SPEED(sd_card)
+                               && !CHK_SD_HS(sd_card)
+                               && !CHK_MMC_HS(sd_card)) {
+                       sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
+                                       SD_RSP_TYPE_R1, NULL, 0);
+               }
+       }
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF,
+               (u8)sector_cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF,
+               (u8)(sector_cnt >> 8));
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
+
+       if (CHK_MMC_8BIT(sd_card))
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1,
+                       0x03, SD_BUS_WIDTH_8);
+       else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card))
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1,
+                       0x03, SD_BUS_WIDTH_4);
+       else
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1,
+                       0x03, SD_BUS_WIDTH_1);
+
+       if (sd_card->seq_mode) {
+               cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16|
+                       SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 |
+                       SD_RSP_LEN_0;
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2);
+
+               trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512,
+                               DMA_512);
+
+               if (srb->sc_data_direction == DMA_FROM_DEVICE) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+                                    SD_TM_AUTO_READ_3 | SD_TRANSFER_START);
+               } else {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+                                    SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
+               }
+
+               rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
+                       SD_TRANSFER_END, SD_TRANSFER_END);
+
+               rtsx_send_cmd_no_wait(chip);
+       } else {
+               if (srb->sc_data_direction == DMA_FROM_DEVICE) {
+                       RTSX_DEBUGP("SD/MMC CMD %d\n", READ_MULTIPLE_BLOCK);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF,
+                                    0x40 | READ_MULTIPLE_BLOCK);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF,
+                               (u8)(data_addr >> 24));
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF,
+                               (u8)(data_addr >> 16));
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF,
+                               (u8)(data_addr >> 8));
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF,
+                               (u8)data_addr);
+
+                       cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+                               SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 |
+                               SD_RSP_LEN_6;
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
+                               cfg2);
+
+                       trans_dma_enable(srb->sc_data_direction, chip,
+                                       sector_cnt * 512, DMA_512);
+
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+                                    SD_TM_AUTO_READ_2 | SD_TRANSFER_START);
+                       rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
+                                    SD_TRANSFER_END, SD_TRANSFER_END);
+
+                       rtsx_send_cmd_no_wait(chip);
+               } else {
+                       retval = rtsx_send_cmd(chip, SD_CARD, 50);
+                       if (retval < 0) {
+                               rtsx_clear_sd_error(chip);
+
+                               chip->rw_need_retry = 1;
+                               sd_set_err_code(chip, SD_TO_ERR);
+                               TRACE_GOTO(chip, RW_FAIL);
+                       }
+
+                       retval = wait_data_buf_ready(chip);
+                       if (retval != STATUS_SUCCESS) {
+                               chip->rw_need_retry = 1;
+                               sd_set_err_code(chip, SD_TO_ERR);
+                               TRACE_GOTO(chip, RW_FAIL);
+                       }
+
+                       retval = sd_send_cmd_get_rsp(chip, WRITE_MULTIPLE_BLOCK,
+                                       data_addr, SD_RSP_TYPE_R1, NULL, 0);
+                       if (retval != STATUS_SUCCESS) {
+                               chip->rw_need_retry = 1;
+                               TRACE_GOTO(chip, RW_FAIL);
+                       }
+
+                       rtsx_init_cmd(chip);
+
+                       cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+                               SD_NO_WAIT_BUSY_END |
+                               SD_NO_CHECK_CRC7 | SD_RSP_LEN_0;
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
+                               cfg2);
+
+                       trans_dma_enable(srb->sc_data_direction, chip,
+                                       sector_cnt * 512, DMA_512);
+
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+                                    SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
+                       rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
+                                    SD_TRANSFER_END, SD_TRANSFER_END);
+
+                       rtsx_send_cmd_no_wait(chip);
+               }
+
+               sd_card->seq_mode = 1;
+       }
+
+       retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb),
+                               scsi_bufflen(srb), scsi_sg_count(srb),
+                               srb->sc_data_direction, chip->sd_timeout);
+       if (retval < 0) {
+               u8 stat = 0;
+               int err;
+
+               sd_card->seq_mode = 0;
+
+               if (retval == -ETIMEDOUT)
+                       err = STATUS_TIMEDOUT;
+               else
+                       err = STATUS_FAIL;
+
+               rtsx_read_register(chip, REG_SD_STAT1, &stat);
+               rtsx_clear_sd_error(chip);
+               if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+                       chip->rw_need_retry = 0;
+                       RTSX_DEBUGP("No card exist, exit sd_rw\n");
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               chip->rw_need_retry = 1;
+
+               retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0,
+                                       SD_RSP_TYPE_R1b, NULL, 0);
+               if (retval != STATUS_SUCCESS) {
+                       sd_set_err_code(chip, SD_STS_ERR);
+                       TRACE_GOTO(chip, RW_FAIL);
+               }
+
+               if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) {
+                       RTSX_DEBUGP("SD CRC error, tune clock!\n");
+                       sd_set_err_code(chip, SD_CRC_ERR);
+                       TRACE_GOTO(chip, RW_FAIL);
+               }
+
+               if (err == STATUS_TIMEDOUT) {
+                       sd_set_err_code(chip, SD_TO_ERR);
+                       TRACE_GOTO(chip, RW_FAIL);
+               }
+
+               TRACE_RET(chip, err);
+       }
+
+       sd_card->pre_sec_addr = start_sector;
+       sd_card->pre_sec_cnt = sector_cnt;
+       sd_card->pre_dir = srb->sc_data_direction;
+
+       return STATUS_SUCCESS;
+
+RW_FAIL:
+       sd_card->seq_mode = 0;
+
+       if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
+               chip->rw_need_retry = 0;
+               RTSX_DEBUGP("No card exist, exit sd_rw\n");
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (sd_check_err_code(chip, SD_CRC_ERR)) {
+               if (CHK_MMC_4BIT(sd_card) || CHK_MMC_8BIT(sd_card)) {
+                       sd_card->mmc_dont_switch_bus = 1;
+                       reset_mmc_only(chip);
+                       sd_card->mmc_dont_switch_bus = 0;
+               } else {
+                       sd_card->need_retune = 1;
+                       sd_auto_tune_clock(chip);
+               }
+       } else if (sd_check_err_code(chip, SD_TO_ERR | SD_STS_ERR)) {
+               retval = reset_sd_card(chip);
+               if (retval != STATUS_SUCCESS) {
+                       chip->card_ready &= ~SD_CARD;
+                       chip->card_fail |= SD_CARD;
+                       chip->capacity[chip->card2lun[SD_CARD]] = 0;
+               }
+       }
+
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+#ifdef SUPPORT_CPRM
+int soft_reset_sd_card(struct rtsx_chip *chip)
+{
+       return reset_sd(chip);
+}
+
+int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx,
+               u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check)
+{
+       int retval;
+       int timeout = 100;
+       u16 reg_addr;
+       u8 *ptr;
+       int stat_idx = 0;
+       int rty_cnt = 0;
+
+       RTSX_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx);
+
+       if (rsp_type == SD_RSP_TYPE_R1b)
+               timeout = 3000;
+
+RTY_SEND_CMD:
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+                       0x01, PINGPONG_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER,
+                       0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END,
+               SD_TRANSFER_END);
+
+       if (rsp_type == SD_RSP_TYPE_R2) {
+               for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16;
+                    reg_addr++)
+                       rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
+
+               stat_idx = 17;
+       } else if (rsp_type != SD_RSP_TYPE_R0) {
+               for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4;
+                    reg_addr++)
+                       rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
+
+               stat_idx = 6;
+       }
+       rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0, 0);
+
+       rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0);
+
+       retval = rtsx_send_cmd(chip, SD_CARD, timeout);
+       if (retval < 0) {
+               if (retval == -ETIMEDOUT) {
+                       rtsx_clear_sd_error(chip);
+
+                       if (rsp_type & SD_WAIT_BUSY_END) {
+                               retval = sd_check_data0_status(chip);
+                               if (retval != STATUS_SUCCESS)
+                                       TRACE_RET(chip, retval);
+                       } else {
+                               sd_set_err_code(chip, SD_TO_ERR);
+                       }
+               }
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (rsp_type == SD_RSP_TYPE_R0)
+               return STATUS_SUCCESS;
+
+       ptr = rtsx_get_cmd_data(chip) + 1;
+
+       if ((ptr[0] & 0xC0) != 0) {
+               sd_set_err_code(chip, SD_STS_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (!(rsp_type & SD_NO_CHECK_CRC7)) {
+               if (ptr[stat_idx] & SD_CRC7_ERR) {
+                       if (cmd_idx == WRITE_MULTIPLE_BLOCK) {
+                               sd_set_err_code(chip, SD_CRC_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       if (rty_cnt < SD_MAX_RETRY_COUNT) {
+                               wait_timeout(20);
+                               rty_cnt++;
+                               goto RTY_SEND_CMD;
+                       } else {
+                               sd_set_err_code(chip, SD_CRC_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+       }
+
+       if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) ||
+               (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) {
+               if ((cmd_idx != STOP_TRANSMISSION) && (special_check == 0)) {
+                       if (ptr[1] & 0x80)
+                               TRACE_RET(chip, STATUS_FAIL);
+               }
+#ifdef SUPPORT_SD_LOCK
+               if (ptr[1] & 0x7D)
+#else
+               if (ptr[1] & 0x7F)
+#endif
+               {
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+               if (ptr[2] & 0xF8)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               if (cmd_idx == SELECT_CARD) {
+                       if (rsp_type == SD_RSP_TYPE_R2) {
+                               if ((ptr[3] & 0x1E) != 0x04)
+                                       TRACE_RET(chip, STATUS_FAIL);
+
+                       } else if (rsp_type == SD_RSP_TYPE_R0) {
+                               if ((ptr[3] & 0x1E) != 0x03)
+                                       TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+       }
+
+       if (rsp && rsp_len)
+               memcpy(rsp, ptr, rsp_len);
+
+       return STATUS_SUCCESS;
+}
+
+int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type)
+{
+       int retval, rsp_len;
+       u16 reg_addr;
+
+       if (rsp_type == SD_RSP_TYPE_R0)
+               return STATUS_SUCCESS;
+
+       rtsx_init_cmd(chip);
+
+       if (rsp_type == SD_RSP_TYPE_R2) {
+               for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16;
+                    reg_addr++)
+                       rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0);
+
+               rsp_len = 17;
+       } else if (rsp_type != SD_RSP_TYPE_R0) {
+               for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4;
+                    reg_addr++)
+                       rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0);
+
+               rsp_len = 6;
+       }
+       rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0xFF, 0);
+
+       retval = rtsx_send_cmd(chip, SD_CARD, 100);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (rsp) {
+               int min_len = (rsp_len < len) ? rsp_len : len;
+
+               memcpy(rsp, rtsx_get_cmd_data(chip), min_len);
+
+               RTSX_DEBUGP("min_len = %d\n", min_len);
+               RTSX_DEBUGP("Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n",
+                       rsp[0], rsp[1], rsp[2], rsp[3]);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int len;
+       u8 buf[18] = {
+               0x00,
+               0x00,
+               0x00,
+               0x0E,
+               0x00,
+               0x00,
+               0x00,
+               0x00,
+               0x53,
+               0x44,
+               0x20,
+               0x43,
+               0x61,
+               0x72,
+               0x64,
+               0x00,
+               0x00,
+               0x00,
+       };
+
+       sd_card->pre_cmd_err = 0;
+
+       if (!(CHK_BIT(chip->lun_mc, lun))) {
+               SET_BIT(chip->lun_mc, lun);
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) ||
+               (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) ||
+               (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) ||
+               (0x64 != srb->cmnd[8])) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       switch (srb->cmnd[1] & 0x0F) {
+       case 0:
+               sd_card->sd_pass_thru_en = 0;
+               break;
+
+       case 1:
+               sd_card->sd_pass_thru_en = 1;
+               break;
+
+       default:
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       buf[5] = (1 == CHK_SD(sd_card)) ?  0x01 : 0x02;
+       if (chip->card_wp & SD_CARD)
+               buf[5] |= 0x80;
+
+       buf[6] = (u8)(sd_card->sd_addr >> 16);
+       buf[7] = (u8)(sd_card->sd_addr >> 24);
+
+       buf[15] = chip->max_lun;
+
+       len = min_t(int, 18, scsi_bufflen(srb));
+       rtsx_stor_set_xfer_buf(buf, len, srb);
+
+       return TRANSPORT_GOOD;
+}
+
+static inline int get_rsp_type(struct scsi_cmnd *srb, u8 *rsp_type,
+                       int *rsp_len)
+{
+       if (!rsp_type || !rsp_len)
+               return STATUS_FAIL;
+
+       switch (srb->cmnd[10]) {
+       case 0x03:
+               *rsp_type = SD_RSP_TYPE_R0;
+               *rsp_len = 0;
+               break;
+
+       case 0x04:
+               *rsp_type = SD_RSP_TYPE_R1;
+               *rsp_len = 6;
+               break;
+
+       case 0x05:
+               *rsp_type = SD_RSP_TYPE_R1b;
+               *rsp_len = 6;
+               break;
+
+       case 0x06:
+               *rsp_type = SD_RSP_TYPE_R2;
+               *rsp_len = 17;
+               break;
+
+       case 0x07:
+               *rsp_type = SD_RSP_TYPE_R3;
+               *rsp_len = 6;
+               break;
+
+       default:
+               return STATUS_FAIL;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int retval, rsp_len;
+       u8 cmd_idx, rsp_type;
+       u8 standby = 0, acmd = 0;
+       u32 arg;
+
+       if (!sd_card->sd_pass_thru_en) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       retval = sd_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_FAILED);
+
+       if (sd_card->pre_cmd_err) {
+               sd_card->pre_cmd_err = 0;
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       cmd_idx = srb->cmnd[2] & 0x3F;
+       if (srb->cmnd[1] & 0x02)
+               standby = 1;
+
+       if (srb->cmnd[1] & 0x01)
+               acmd = 1;
+
+       arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) |
+               ((u32)srb->cmnd[5] << 8) | srb->cmnd[6];
+
+       retval = get_rsp_type(srb, &rsp_type, &rsp_len);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+       sd_card->last_rsp_type = rsp_type;
+
+       retval = sd_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_FAILED);
+
+#ifdef SUPPORT_SD_LOCK
+       if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) {
+               if (CHK_MMC_8BIT(sd_card)) {
+                       retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03,
+                                               SD_BUS_WIDTH_8);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+
+               } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) {
+                       retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03,
+                                               SD_BUS_WIDTH_4);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+#else
+       retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_FAILED);
+#endif
+
+       if (standby) {
+               retval = sd_select_card(chip, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
+       }
+
+       if (acmd) {
+               retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD,
+                                               sd_card->sd_addr,
+                                               SD_RSP_TYPE_R1, NULL, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
+       }
+
+       retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type,
+                       sd_card->rsp, rsp_len, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
+
+       if (standby) {
+               retval = sd_select_card(chip, 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
+       }
+
+#ifdef SUPPORT_SD_LOCK
+       retval = sd_update_lock_status(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
+#endif
+
+       scsi_set_resid(srb, 0);
+       return TRANSPORT_GOOD;
+
+SD_Execute_Cmd_Failed:
+       sd_card->pre_cmd_err = 1;
+       set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+       release_sd_card(chip);
+       do_reset_sd_card(chip);
+       if (!(chip->card_ready & SD_CARD))
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+
+       TRACE_RET(chip, TRANSPORT_FAILED);
+}
+
+int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int retval, rsp_len, i;
+       int cmd13_checkbit = 0, read_err = 0;
+       u8 cmd_idx, rsp_type, bus_width;
+       u8 send_cmd12 = 0, standby = 0, acmd = 0;
+       u32 data_len;
+
+       if (!sd_card->sd_pass_thru_en) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (sd_card->pre_cmd_err) {
+               sd_card->pre_cmd_err = 0;
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       retval = sd_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_FAILED);
+
+       cmd_idx = srb->cmnd[2] & 0x3F;
+       if (srb->cmnd[1] & 0x04)
+               send_cmd12 = 1;
+
+       if (srb->cmnd[1] & 0x02)
+               standby = 1;
+
+       if (srb->cmnd[1] & 0x01)
+               acmd = 1;
+
+       data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8]
+                                               << 8) | srb->cmnd[9];
+
+       retval = get_rsp_type(srb, &rsp_type, &rsp_len);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+       sd_card->last_rsp_type = rsp_type;
+
+       retval = sd_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_FAILED);
+
+#ifdef SUPPORT_SD_LOCK
+       if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) {
+               if (CHK_MMC_8BIT(sd_card))
+                       bus_width = SD_BUS_WIDTH_8;
+               else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card))
+                       bus_width = SD_BUS_WIDTH_4;
+               else
+                       bus_width = SD_BUS_WIDTH_1;
+       } else {
+               bus_width = SD_BUS_WIDTH_4;
+       }
+       RTSX_DEBUGP("bus_width = %d\n", bus_width);
+#else
+       bus_width = SD_BUS_WIDTH_4;
+#endif
+
+       if (data_len < 512) {
+               retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len,
+                               SD_RSP_TYPE_R1, NULL, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+       }
+
+       if (standby) {
+               retval = sd_select_card(chip, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+       }
+
+       if (acmd) {
+               retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD,
+                                               sd_card->sd_addr,
+                                               SD_RSP_TYPE_R1, NULL, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+       }
+
+       if (data_len <= 512) {
+               int min_len;
+               u8 *buf;
+               u16 byte_cnt, blk_cnt;
+               u8 cmd[5];
+
+               byte_cnt = ((u16)(srb->cmnd[8] & 0x03) << 8) | srb->cmnd[9];
+               blk_cnt = 1;
+
+               cmd[0] = 0x40 | cmd_idx;
+               cmd[1] = srb->cmnd[3];
+               cmd[2] = srb->cmnd[4];
+               cmd[3] = srb->cmnd[5];
+               cmd[4] = srb->cmnd[6];
+
+               buf = kmalloc(data_len, GFP_KERNEL);
+               if (buf == NULL)
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+
+               retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt,
+                                      blk_cnt, bus_width, buf, data_len, 2000);
+               if (retval != STATUS_SUCCESS) {
+                       read_err = 1;
+                       kfree(buf);
+                       rtsx_clear_sd_error(chip);
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+               }
+
+               min_len = min(data_len, scsi_bufflen(srb));
+               rtsx_stor_set_xfer_buf(buf, min_len, srb);
+
+               kfree(buf);
+       } else if (!(data_len & 0x1FF)) {
+               rtsx_init_cmd(chip);
+
+               trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF,
+                       0x02);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF,
+                       0x00);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H,
+                               0xFF, (srb->cmnd[7] & 0xFE) >> 1);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L,
+                               0xFF, (u8)((data_len & 0x0001FE00) >> 9));
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF,
+                       0x40 | cmd_idx);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF,
+                       srb->cmnd[3]);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF,
+                       srb->cmnd[4]);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF,
+                       srb->cmnd[5]);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF,
+                       srb->cmnd[6]);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER,
+                            0xFF, SD_TM_AUTO_READ_2 | SD_TRANSFER_START);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
+                       SD_TRANSFER_END, SD_TRANSFER_END);
+
+               rtsx_send_cmd_no_wait(chip);
+
+               retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb),
+                                       scsi_bufflen(srb), scsi_sg_count(srb),
+                                       DMA_FROM_DEVICE, 10000);
+               if (retval < 0) {
+                       read_err = 1;
+                       rtsx_clear_sd_error(chip);
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+               }
+
+       } else {
+               TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+       }
+
+       retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type);
+       if (retval != STATUS_SUCCESS)
+               TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+
+       if (standby) {
+               retval = sd_select_card(chip, 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+       }
+
+       if (send_cmd12) {
+               retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION,
+                               0, SD_RSP_TYPE_R1b, NULL, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+       }
+
+       if (data_len < 512) {
+               retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200,
+                               SD_RSP_TYPE_R1, NULL, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+
+               retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+
+               retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+       }
+
+       if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04))
+               cmd13_checkbit = 1;
+
+       for (i = 0; i < 3; i++) {
+               retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS,
+                                               sd_card->sd_addr,
+                                               SD_RSP_TYPE_R1, NULL, 0,
+                                               cmd13_checkbit);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (retval != STATUS_SUCCESS)
+               TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
+
+       scsi_set_resid(srb, 0);
+       return TRANSPORT_GOOD;
+
+SD_Execute_Read_Cmd_Failed:
+       sd_card->pre_cmd_err = 1;
+       set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+       if (read_err)
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+
+       release_sd_card(chip);
+       do_reset_sd_card(chip);
+       if (!(chip->card_ready & SD_CARD))
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+
+       TRACE_RET(chip, TRANSPORT_FAILED);
+}
+
+int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int retval, rsp_len, i;
+       int cmd13_checkbit = 0, write_err = 0;
+       u8 cmd_idx, rsp_type;
+       u8 send_cmd12 = 0, standby = 0, acmd = 0;
+       u32 data_len, arg;
+#ifdef SUPPORT_SD_LOCK
+       int lock_cmd_fail = 0;
+       u8 sd_lock_state = 0;
+       u8 lock_cmd_type = 0;
+#endif
+
+       if (!sd_card->sd_pass_thru_en) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (sd_card->pre_cmd_err) {
+               sd_card->pre_cmd_err = 0;
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       retval = sd_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_FAILED);
+
+       cmd_idx = srb->cmnd[2] & 0x3F;
+       if (srb->cmnd[1] & 0x04)
+               send_cmd12 = 1;
+
+       if (srb->cmnd[1] & 0x02)
+               standby = 1;
+
+       if (srb->cmnd[1] & 0x01)
+               acmd = 1;
+
+       data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8]
+                                               << 8) | srb->cmnd[9];
+       arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) |
+               ((u32)srb->cmnd[5] << 8) | srb->cmnd[6];
+
+#ifdef SUPPORT_SD_LOCK
+       if (cmd_idx == LOCK_UNLOCK) {
+               sd_lock_state = sd_card->sd_lock_status;
+               sd_lock_state &= SD_LOCKED;
+       }
+#endif
+
+       retval = get_rsp_type(srb, &rsp_type, &rsp_len);
+       if (retval != STATUS_SUCCESS) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+       sd_card->last_rsp_type = rsp_type;
+
+       retval = sd_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_FAILED);
+
+#ifdef SUPPORT_SD_LOCK
+       if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) {
+               if (CHK_MMC_8BIT(sd_card)) {
+                       retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03,
+                                               SD_BUS_WIDTH_8);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+
+               } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) {
+                       retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03,
+                                               SD_BUS_WIDTH_4);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+       }
+#else
+       retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, TRANSPORT_FAILED);
+#endif
+
+       if (data_len < 512) {
+               retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len,
+                               SD_RSP_TYPE_R1, NULL, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+       }
+
+       if (standby) {
+               retval = sd_select_card(chip, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+       }
+
+       if (acmd) {
+               retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD,
+                                               sd_card->sd_addr,
+                                               SD_RSP_TYPE_R1, NULL, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+       }
+
+       retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type,
+                       sd_card->rsp, rsp_len, 0);
+       if (retval != STATUS_SUCCESS)
+               TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+
+       if (data_len <= 512) {
+               u16 i;
+               u8 *buf;
+
+               buf = kmalloc(data_len, GFP_KERNEL);
+               if (buf == NULL)
+                       TRACE_RET(chip, TRANSPORT_ERROR);
+
+               rtsx_stor_get_xfer_buf(buf, data_len, srb);
+
+#ifdef SUPPORT_SD_LOCK
+               if (cmd_idx == LOCK_UNLOCK)
+                       lock_cmd_type = buf[0] & 0x0F;
+#endif
+
+               if (data_len > 256) {
+                       rtsx_init_cmd(chip);
+                       for (i = 0; i < 256; i++) {
+                               rtsx_add_cmd(chip, WRITE_REG_CMD,
+                                               PPBUF_BASE2 + i, 0xFF, buf[i]);
+                       }
+                       retval = rtsx_send_cmd(chip, 0, 250);
+                       if (retval != STATUS_SUCCESS) {
+                               kfree(buf);
+                               TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+                       }
+
+                       rtsx_init_cmd(chip);
+                       for (i = 256; i < data_len; i++) {
+                               rtsx_add_cmd(chip, WRITE_REG_CMD,
+                                               PPBUF_BASE2 + i, 0xFF, buf[i]);
+                       }
+                       retval = rtsx_send_cmd(chip, 0, 250);
+                       if (retval != STATUS_SUCCESS) {
+                               kfree(buf);
+                               TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+                       }
+               } else {
+                       rtsx_init_cmd(chip);
+                       for (i = 0; i < data_len; i++) {
+                               rtsx_add_cmd(chip, WRITE_REG_CMD,
+                                               PPBUF_BASE2 + i, 0xFF, buf[i]);
+                       }
+                       retval = rtsx_send_cmd(chip, 0, 250);
+                       if (retval != STATUS_SUCCESS) {
+                               kfree(buf);
+                               TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+                       }
+               }
+
+               kfree(buf);
+
+               rtsx_init_cmd(chip);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF,
+                       srb->cmnd[8] & 0x03);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF,
+                       srb->cmnd[9]);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF,
+                       0x00);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF,
+                       0x01);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
+                       PINGPONG_BUFFER);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+                            SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
+                       SD_TRANSFER_END, SD_TRANSFER_END);
+
+               retval = rtsx_send_cmd(chip, SD_CARD, 250);
+       } else if (!(data_len & 0x1FF)) {
+               rtsx_init_cmd(chip);
+
+               trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF,
+                       0x02);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF,
+                       0x00);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H,
+                               0xFF, (srb->cmnd[7] & 0xFE) >> 1);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L,
+                               0xFF, (u8)((data_len & 0x0001FE00) >> 9));
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
+                       SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
+                       SD_TRANSFER_END, SD_TRANSFER_END);
+
+               rtsx_send_cmd_no_wait(chip);
+
+               retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb),
+                                       scsi_bufflen(srb), scsi_sg_count(srb),
+                                       DMA_TO_DEVICE, 10000);
+
+       } else {
+               TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+       }
+
+       if (retval < 0) {
+               write_err = 1;
+               rtsx_clear_sd_error(chip);
+               TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+       }
+
+#ifdef SUPPORT_SD_LOCK
+       if (cmd_idx == LOCK_UNLOCK) {
+               if (lock_cmd_type == SD_ERASE) {
+                       sd_card->sd_erase_status = SD_UNDER_ERASING;
+                       scsi_set_resid(srb, 0);
+                       return TRANSPORT_GOOD;
+               }
+
+               rtsx_init_cmd(chip);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02);
+
+               rtsx_send_cmd(chip, SD_CARD, 250);
+
+               retval = sd_update_lock_status(chip);
+               if (retval != STATUS_SUCCESS) {
+                       RTSX_DEBUGP("Lock command fail!\n");
+                       lock_cmd_fail = 1;
+               }
+       }
+#endif /* SUPPORT_SD_LOCK */
+
+       if (standby) {
+               retval = sd_select_card(chip, 1);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+       }
+
+       if (send_cmd12) {
+               retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION,
+                               0, SD_RSP_TYPE_R1b, NULL, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+       }
+
+       if (data_len < 512) {
+               retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200,
+                               SD_RSP_TYPE_R1, NULL, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+
+               retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+
+               rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+       }
+
+       if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04))
+               cmd13_checkbit = 1;
+
+       for (i = 0; i < 3; i++) {
+               retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS,
+                                               sd_card->sd_addr,
+                                               SD_RSP_TYPE_R1, NULL, 0,
+                                               cmd13_checkbit);
+               if (retval == STATUS_SUCCESS)
+                       break;
+       }
+       if (retval != STATUS_SUCCESS)
+               TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+
+#ifdef SUPPORT_SD_LOCK
+       if (cmd_idx == LOCK_UNLOCK) {
+               if (!lock_cmd_fail) {
+                       RTSX_DEBUGP("lock_cmd_type = 0x%x\n", lock_cmd_type);
+                       if (lock_cmd_type & SD_CLR_PWD)
+                               sd_card->sd_lock_status &= ~SD_PWD_EXIST;
+
+                       if (lock_cmd_type & SD_SET_PWD)
+                               sd_card->sd_lock_status |= SD_PWD_EXIST;
+               }
+
+               RTSX_DEBUGP("sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n",
+                            sd_lock_state, sd_card->sd_lock_status);
+               if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) {
+                       sd_card->sd_lock_notify = 1;
+                       if (sd_lock_state) {
+                               if (sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) {
+                                       sd_card->sd_lock_status |= (
+                                               SD_UNLOCK_POW_ON | SD_SDR_RST);
+                                       if (CHK_SD(sd_card)) {
+                                               retval = reset_sd(chip);
+                                               if (retval != STATUS_SUCCESS) {
+                                                       sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST);
+                                                       TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
+                                               }
+                                       }
+
+                                       sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST);
+                               }
+                       }
+               }
+       }
+
+       if (lock_cmd_fail) {
+               scsi_set_resid(srb, 0);
+               set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+#endif  /* SUPPORT_SD_LOCK */
+
+       scsi_set_resid(srb, 0);
+       return TRANSPORT_GOOD;
+
+SD_Execute_Write_Cmd_Failed:
+       sd_card->pre_cmd_err = 1;
+       set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+       if (write_err)
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
+
+       release_sd_card(chip);
+       do_reset_sd_card(chip);
+       if (!(chip->card_ready & SD_CARD))
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+
+       TRACE_RET(chip, TRANSPORT_FAILED);
+}
+
+int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int count;
+       u16 data_len;
+
+       if (!sd_card->sd_pass_thru_en) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (sd_card->pre_cmd_err) {
+               sd_card->pre_cmd_err = 0;
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       data_len = ((u16)srb->cmnd[7] << 8) | srb->cmnd[8];
+
+       if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) {
+               count = (data_len < 17) ? data_len : 17;
+       } else {
+               count = (data_len < 6) ? data_len : 6;
+       }
+       rtsx_stor_set_xfer_buf(sd_card->rsp, count, srb);
+
+       RTSX_DEBUGP("Response length: %d\n", data_len);
+       RTSX_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n", sd_card->rsp[0],
+               sd_card->rsp[1], sd_card->rsp[2], sd_card->rsp[3]);
+
+       scsi_set_resid(srb, 0);
+       return TRANSPORT_GOOD;
+}
+
+int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       unsigned int lun = SCSI_LUN(srb);
+       int retval;
+
+       if (!sd_card->sd_pass_thru_en) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if (sd_card->pre_cmd_err) {
+               sd_card->pre_cmd_err = 0;
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) ||
+               (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) ||
+               (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) ||
+               (0x64 != srb->cmnd[8])) {
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       switch (srb->cmnd[1] & 0x0F) {
+       case 0:
+#ifdef SUPPORT_SD_LOCK
+               if (0x64 == srb->cmnd[9])
+                       sd_card->sd_lock_status |= SD_SDR_RST;
+#endif
+               retval = reset_sd_card(chip);
+               if (retval != STATUS_SUCCESS) {
+#ifdef SUPPORT_SD_LOCK
+                       sd_card->sd_lock_status &= ~SD_SDR_RST;
+#endif
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+                       sd_card->pre_cmd_err = 1;
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+#ifdef SUPPORT_SD_LOCK
+               sd_card->sd_lock_status &= ~SD_SDR_RST;
+#endif
+               break;
+
+       case 1:
+               retval = soft_reset_sd_card(chip);
+               if (retval != STATUS_SUCCESS) {
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+                       sd_card->pre_cmd_err = 1;
+                       TRACE_RET(chip, TRANSPORT_FAILED);
+               }
+               break;
+
+       default:
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+               TRACE_RET(chip, TRANSPORT_FAILED);
+       }
+
+       scsi_set_resid(srb, 0);
+       return TRANSPORT_GOOD;
+}
+#endif
+
+void sd_cleanup_work(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+
+       if (sd_card->seq_mode) {
+               RTSX_DEBUGP("SD: stop transmission\n");
+               sd_stop_seq_mode(chip);
+               sd_card->cleanup_counter = 0;
+       }
+}
+
+int sd_power_off_card3v3(struct rtsx_chip *chip)
+{
+       int retval;
+
+       retval = disable_card_clock(chip, SD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, 0);
+
+       if (!chip->ft2_fast_mode) {
+               retval = card_power_off(chip, SD_CARD);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               wait_timeout(50);
+       }
+
+       if (chip->asic_code) {
+               retval = sd_pull_ctl_disable(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else {
+               RTSX_WRITE_REG(chip, FPGA_PULL_CTL,
+                       FPGA_SD_PULL_CTL_BIT | 0x20, FPGA_SD_PULL_CTL_BIT);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int release_sd_card(struct rtsx_chip *chip)
+{
+       struct sd_info *sd_card = &(chip->sd_card);
+       int retval;
+
+       RTSX_DEBUGP("release_sd_card\n");
+
+       chip->card_ready &= ~SD_CARD;
+       chip->card_fail &= ~SD_CARD;
+       chip->card_wp &= ~SD_CARD;
+
+       chip->sd_io = 0;
+       chip->sd_int = 0;
+
+#ifdef SUPPORT_SD_LOCK
+       sd_card->sd_lock_status = 0;
+       sd_card->sd_erase_status = 0;
+#endif
+
+       memset(sd_card->raw_csd, 0, 16);
+       memset(sd_card->raw_scr, 0, 8);
+
+       retval = sd_power_off_card3v3(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
diff --git a/drivers/staging/rts5208/sd.h b/drivers/staging/rts5208/sd.h
new file mode 100644 (file)
index 0000000..735b2d0
--- /dev/null
@@ -0,0 +1,301 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_SD_H
+#define __REALTEK_RTSX_SD_H
+
+#include "rtsx_chip.h"
+
+#define SUPPORT_VOLTAGE        0x003C0000
+
+/* Error Code */
+#define        SD_NO_ERROR             0x0
+#define        SD_CRC_ERR              0x80
+#define        SD_TO_ERR               0x40
+#define        SD_NO_CARD              0x20
+#define SD_BUSY                        0x10
+#define        SD_STS_ERR              0x08
+#define SD_RSP_TIMEOUT         0x04
+#define SD_IO_ERR              0x02
+
+/* Return code for MMC switch bus */
+#define SWITCH_SUCCESS         0
+#define SWITCH_ERR             1
+#define SWITCH_FAIL            2
+
+/* MMC/SD Command Index */
+/* Basic command (class 0) */
+#define GO_IDLE_STATE          0
+#define        SEND_OP_COND            1
+#define        ALL_SEND_CID            2
+#define        SET_RELATIVE_ADDR       3
+#define        SEND_RELATIVE_ADDR      3
+#define        SET_DSR                 4
+#define IO_SEND_OP_COND                5
+#define        SWITCH                  6
+#define        SELECT_CARD             7
+#define        DESELECT_CARD           7
+/* CMD8 is "SEND_EXT_CSD" for MMC4.x Spec
+ * while is "SEND_IF_COND" for SD 2.0
+ */
+#define        SEND_EXT_CSD            8
+#define        SEND_IF_COND            8
+
+#define        SEND_CSD                9
+#define        SEND_CID                10
+#define        VOLTAGE_SWITCH          11
+#define        READ_DAT_UTIL_STOP      11
+#define        STOP_TRANSMISSION       12
+#define        SEND_STATUS             13
+#define        GO_INACTIVE_STATE       15
+
+#define        SET_BLOCKLEN            16
+#define        READ_SINGLE_BLOCK       17
+#define        READ_MULTIPLE_BLOCK     18
+#define        SEND_TUNING_PATTERN     19
+
+#define        BUSTEST_R               14
+#define        BUSTEST_W               19
+
+#define        WRITE_BLOCK             24
+#define        WRITE_MULTIPLE_BLOCK    25
+#define        PROGRAM_CSD             27
+
+#define        ERASE_WR_BLK_START      32
+#define        ERASE_WR_BLK_END        33
+#define        ERASE_CMD               38
+
+#define LOCK_UNLOCK            42
+#define        IO_RW_DIRECT            52
+
+#define        APP_CMD                 55
+#define        GEN_CMD                 56
+
+#define        SET_BUS_WIDTH           6
+#define        SD_STATUS               13
+#define        SEND_NUM_WR_BLOCKS      22
+#define        SET_WR_BLK_ERASE_COUNT  23
+#define        SD_APP_OP_COND          41
+#define        SET_CLR_CARD_DETECT     42
+#define        SEND_SCR                51
+
+#define        SD_READ_COMPLETE        0x00
+#define        SD_READ_TO              0x01
+#define        SD_READ_ADVENCE         0x02
+
+#define        SD_CHECK_MODE           0x00
+#define        SD_SWITCH_MODE          0x80
+#define        SD_FUNC_GROUP_1         0x01
+#define        SD_FUNC_GROUP_2         0x02
+#define        SD_FUNC_GROUP_3         0x03
+#define        SD_FUNC_GROUP_4         0x04
+#define        SD_CHECK_SPEC_V1_1      0xFF
+
+#define        NO_ARGUMENT                             0x00
+#define        CHECK_PATTERN                           0x000000AA
+#define        VOLTAGE_SUPPLY_RANGE                    0x00000100
+#define        SUPPORT_HIGH_AND_EXTENDED_CAPACITY      0x40000000
+#define        SUPPORT_MAX_POWER_PERMANCE              0x10000000
+#define        SUPPORT_1V8                             0x01000000
+
+#define        SWTICH_NO_ERR           0x00
+#define        CARD_NOT_EXIST          0x01
+#define        SPEC_NOT_SUPPORT        0x02
+#define        CHECK_MODE_ERR          0x03
+#define        CHECK_NOT_READY         0x04
+#define        SWITCH_CRC_ERR          0x05
+#define        SWITCH_MODE_ERR         0x06
+#define        SWITCH_PASS             0x07
+
+#ifdef SUPPORT_SD_LOCK
+#define SD_ERASE               0x08
+#define SD_LOCK                        0x04
+#define SD_UNLOCK              0x00
+#define SD_CLR_PWD             0x02
+#define SD_SET_PWD             0x01
+
+#define SD_PWD_LEN             0x10
+
+#define SD_LOCKED              0x80
+#define SD_LOCK_1BIT_MODE      0x40
+#define SD_PWD_EXIST           0x20
+#define SD_UNLOCK_POW_ON       0x01
+#define SD_SDR_RST             0x02
+
+#define SD_NOT_ERASE           0x00
+#define SD_UNDER_ERASING       0x01
+#define SD_COMPLETE_ERASE      0x02
+
+#define SD_RW_FORBIDDEN                0x0F
+
+#endif
+
+#define        HS_SUPPORT                      0x01
+#define        SDR50_SUPPORT                   0x02
+#define        SDR104_SUPPORT                  0x03
+#define        DDR50_SUPPORT                   0x04
+
+#define        HS_SUPPORT_MASK                 0x02
+#define        SDR50_SUPPORT_MASK              0x04
+#define        SDR104_SUPPORT_MASK             0x08
+#define        DDR50_SUPPORT_MASK              0x10
+
+#define        HS_QUERY_SWITCH_OK              0x01
+#define        SDR50_QUERY_SWITCH_OK           0x02
+#define        SDR104_QUERY_SWITCH_OK          0x03
+#define        DDR50_QUERY_SWITCH_OK           0x04
+
+#define        HS_SWITCH_BUSY                  0x02
+#define        SDR50_SWITCH_BUSY               0x04
+#define        SDR104_SWITCH_BUSY              0x08
+#define        DDR50_SWITCH_BUSY               0x10
+
+#define        FUNCTION_GROUP1_SUPPORT_OFFSET       0x0D
+#define FUNCTION_GROUP1_QUERY_SWITCH_OFFSET  0x10
+#define FUNCTION_GROUP1_CHECK_BUSY_OFFSET    0x1D
+
+#define        DRIVING_TYPE_A          0x01
+#define        DRIVING_TYPE_B              0x00
+#define        DRIVING_TYPE_C              0x02
+#define        DRIVING_TYPE_D          0x03
+
+#define        DRIVING_TYPE_A_MASK         0x02
+#define        DRIVING_TYPE_B_MASK         0x01
+#define        DRIVING_TYPE_C_MASK         0x04
+#define        DRIVING_TYPE_D_MASK         0x08
+
+#define        TYPE_A_QUERY_SWITCH_OK  0x01
+#define        TYPE_B_QUERY_SWITCH_OK  0x00
+#define        TYPE_C_QUERY_SWITCH_OK  0x02
+#define        TYPE_D_QUERY_SWITCH_OK  0x03
+
+#define        TYPE_A_SWITCH_BUSY          0x02
+#define        TYPE_B_SWITCH_BUSY          0x01
+#define        TYPE_C_SWITCH_BUSY      0x04
+#define        TYPE_D_SWITCH_BUSY      0x08
+
+#define        FUNCTION_GROUP3_SUPPORT_OFFSET       0x09
+#define FUNCTION_GROUP3_QUERY_SWITCH_OFFSET  0x0F
+#define FUNCTION_GROUP3_CHECK_BUSY_OFFSET    0x19
+
+#define        CURRENT_LIMIT_200           0x00
+#define        CURRENT_LIMIT_400           0x01
+#define        CURRENT_LIMIT_600           0x02
+#define        CURRENT_LIMIT_800           0x03
+
+#define        CURRENT_LIMIT_200_MASK  0x01
+#define        CURRENT_LIMIT_400_MASK  0x02
+#define        CURRENT_LIMIT_600_MASK  0x04
+#define        CURRENT_LIMIT_800_MASK  0x08
+
+#define        CURRENT_LIMIT_200_QUERY_SWITCH_OK    0x00
+#define        CURRENT_LIMIT_400_QUERY_SWITCH_OK    0x01
+#define        CURRENT_LIMIT_600_QUERY_SWITCH_OK    0x02
+#define        CURRENT_LIMIT_800_QUERY_SWITCH_OK    0x03
+
+#define        CURRENT_LIMIT_200_SWITCH_BUSY        0x01
+#define        CURRENT_LIMIT_400_SWITCH_BUSY        0x02
+#define        CURRENT_LIMIT_600_SWITCH_BUSY        0x04
+#define        CURRENT_LIMIT_800_SWITCH_BUSY        0x08
+
+#define        FUNCTION_GROUP4_SUPPORT_OFFSET       0x07
+#define FUNCTION_GROUP4_QUERY_SWITCH_OFFSET  0x0F
+#define FUNCTION_GROUP4_CHECK_BUSY_OFFSET    0x17
+
+#define        DATA_STRUCTURE_VER_OFFSET       0x11
+
+#define MAX_PHASE                      31
+
+#define MMC_8BIT_BUS                   0x0010
+#define MMC_4BIT_BUS                   0x0020
+
+#define MMC_SWITCH_ERR                 0x80
+
+#define SD_IO_3V3              0
+#define SD_IO_1V8              1
+
+#define TUNE_TX    0x00
+#define TUNE_RX           0x01
+
+#define CHANGE_TX  0x00
+#define CHANGE_RX  0x01
+
+#define DCM_HIGH_FREQUENCY_MODE  0x00
+#define DCM_LOW_FREQUENCY_MODE   0x01
+
+#define DCM_HIGH_FREQUENCY_MODE_SET  0x0C
+#define DCM_Low_FREQUENCY_MODE_SET   0x00
+
+#define MULTIPLY_BY_1    0x00
+#define MULTIPLY_BY_2    0x01
+#define MULTIPLY_BY_3    0x02
+#define MULTIPLY_BY_4    0x03
+#define MULTIPLY_BY_5    0x04
+#define MULTIPLY_BY_6    0x05
+#define MULTIPLY_BY_7    0x06
+#define MULTIPLY_BY_8    0x07
+#define MULTIPLY_BY_9    0x08
+#define MULTIPLY_BY_10   0x09
+
+#define DIVIDE_BY_2      0x01
+#define DIVIDE_BY_3      0x02
+#define DIVIDE_BY_4      0x03
+#define DIVIDE_BY_5      0x04
+#define DIVIDE_BY_6      0x05
+#define DIVIDE_BY_7      0x06
+#define DIVIDE_BY_8      0x07
+#define DIVIDE_BY_9      0x08
+#define DIVIDE_BY_10     0x09
+
+struct timing_phase_path {
+       int start;
+       int end;
+       int mid;
+       int len;
+};
+
+int sd_select_card(struct rtsx_chip *chip, int select);
+int sd_pull_ctl_enable(struct rtsx_chip *chip);
+int reset_sd_card(struct rtsx_chip *chip);
+int sd_switch_clock(struct rtsx_chip *chip);
+void sd_stop_seq_mode(struct rtsx_chip *chip);
+int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+       u32 start_sector, u16 sector_cnt);
+void sd_cleanup_work(struct rtsx_chip *chip);
+int sd_power_off_card3v3(struct rtsx_chip *chip);
+int release_sd_card(struct rtsx_chip *chip);
+#ifdef SUPPORT_CPRM
+int soft_reset_sd_card(struct rtsx_chip *chip);
+int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx,
+               u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check);
+int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type);
+
+int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+#endif
+
+#endif  /* __REALTEK_RTSX_SD_H */
diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c
new file mode 100644 (file)
index 0000000..312b9f9
--- /dev/null
@@ -0,0 +1,877 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+
+#include "rtsx.h"
+#include "rtsx_transport.h"
+#include "rtsx_scsi.h"
+#include "rtsx_card.h"
+#include "spi.h"
+
+static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code)
+{
+       struct spi_info *spi = &(chip->spi);
+
+       spi->err_code = err_code;
+}
+
+static int spi_init(struct rtsx_chip *chip)
+{
+       RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF,
+               CS_POLARITY_LOW | DTO_MSB_FIRST | SPI_MASTER | SPI_MODE0 |
+               SPI_AUTO);
+       RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF);
+
+       return STATUS_SUCCESS;
+}
+
+static int spi_set_init_para(struct rtsx_chip *chip)
+{
+       struct spi_info *spi = &(chip->spi);
+       int retval;
+
+       RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, (u8)(spi->clk_div >> 8));
+       RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, (u8)(spi->clk_div));
+
+       retval = switch_clock(chip, spi->spi_clock);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = select_card(chip, SPI_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN);
+       RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN);
+
+       wait_timeout(10);
+
+       retval = spi_init(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int sf_polling_status(struct rtsx_chip *chip, int msec)
+{
+       int retval;
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+               SPI_TRANSFER0_START | SPI_POLLING_MODE0);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, msec);
+       if (retval < 0) {
+               rtsx_clear_spi_error(chip);
+               spi_set_err_code(chip, SPI_BUSY_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sf_enable_write(struct rtsx_chip *chip, u8 ins)
+{
+       struct spi_info *spi = &(chip->spi);
+       int retval;
+
+       if (!spi->write_en)
+               return STATUS_SUCCESS;
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
+               SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+               SPI_TRANSFER0_START | SPI_C_MODE0);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval < 0) {
+               rtsx_clear_spi_error(chip);
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int sf_disable_write(struct rtsx_chip *chip, u8 ins)
+{
+       struct spi_info *spi = &(chip->spi);
+       int retval;
+
+       if (!spi->write_en)
+               return STATUS_SUCCESS;
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
+               SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+               SPI_TRANSFER0_START | SPI_C_MODE0);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval < 0) {
+               rtsx_clear_spi_error(chip);
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr,
+               u16 len)
+{
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
+               SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8));
+       if (addr_mode) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF,
+                       (u8)(addr >> 8));
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF,
+                       (u8)(addr >> 16));
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+                       SPI_TRANSFER0_START | SPI_CADO_MODE0);
+       } else {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+                       SPI_TRANSFER0_START | SPI_CDO_MODE0);
+       }
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+}
+
+static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr)
+{
+       int retval;
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
+               SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
+       if (addr_mode) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF,
+                       (u8)(addr >> 8));
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF,
+                       (u8)(addr >> 16));
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+                       SPI_TRANSFER0_START | SPI_CA_MODE0);
+       } else {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+                       SPI_TRANSFER0_START | SPI_C_MODE0);
+       }
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval < 0) {
+               rtsx_clear_spi_error(chip);
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int spi_init_eeprom(struct rtsx_chip *chip)
+{
+       int retval;
+       int clk;
+
+       if (chip->asic_code)
+               clk = 30;
+       else
+               clk = CLK_30;
+
+       RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00);
+       RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27);
+
+       retval = switch_clock(chip, clk);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = select_card(chip, SPI_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN);
+       RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN);
+
+       wait_timeout(10);
+
+       RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF,
+               CS_POLARITY_HIGH | SPI_EEPROM_AUTO);
+       RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF);
+
+       return STATUS_SUCCESS;
+}
+
+static int spi_eeprom_program_enable(struct rtsx_chip *chip)
+{
+       int retval;
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x86);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+               SPI_TRANSFER0_START | SPI_CA_MODE0);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+int spi_erase_eeprom_chip(struct rtsx_chip *chip)
+{
+       int retval;
+
+       retval = spi_init_eeprom(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = spi_eeprom_program_enable(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+               SPI_TRANSFER0_START | SPI_CA_MODE0);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
+
+       return STATUS_SUCCESS;
+}
+
+int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr)
+{
+       int retval;
+
+       retval = spi_init_eeprom(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = spi_eeprom_program_enable(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+               SPI_TRANSFER0_START | SPI_CA_MODE0);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
+
+       return STATUS_SUCCESS;
+}
+
+
+int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val)
+{
+       int retval;
+       u8 data;
+
+       retval = spi_init_eeprom(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+               SPI_TRANSFER0_START | SPI_CADI_MODE0);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       wait_timeout(5);
+       RTSX_READ_REG(chip, SPI_DATA, &data);
+
+       if (val)
+               *val = data;
+
+       RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
+
+       return STATUS_SUCCESS;
+}
+
+int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val)
+{
+       int retval;
+
+       retval = spi_init_eeprom(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = spi_eeprom_program_enable(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+               SPI_TRANSFER0_START | SPI_CA_MODE0);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
+
+       return STATUS_SUCCESS;
+}
+
+
+int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct spi_info *spi = &(chip->spi);
+
+       RTSX_DEBUGP("spi_get_status: err_code = 0x%x\n", spi->err_code);
+       rtsx_stor_set_xfer_buf(&(spi->err_code),
+                       min_t(int, scsi_bufflen(srb), 1), srb);
+       scsi_set_resid(srb, scsi_bufflen(srb) - 1);
+
+       return STATUS_SUCCESS;
+}
+
+int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       struct spi_info *spi = &(chip->spi);
+
+       spi_set_err_code(chip, SPI_NO_ERR);
+
+       if (chip->asic_code)
+               spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9];
+       else
+               spi->spi_clock = srb->cmnd[3];
+
+       spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
+       spi->write_en = srb->cmnd[6];
+
+       RTSX_DEBUGP("spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n",
+                    spi->spi_clock, spi->clk_div, spi->write_en);
+
+       return STATUS_SUCCESS;
+}
+
+int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       u16 len;
+       u8 *buf;
+
+       spi_set_err_code(chip, SPI_NO_ERR);
+
+       len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
+       if (len > 512) {
+               spi_set_err_code(chip, SPI_INVALID_COMMAND);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = spi_set_init_para(chip);
+       if (retval != STATUS_SUCCESS) {
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
+               PINGPONG_BUFFER);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
+               SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]);
+
+       if (len == 0) {
+               if (srb->cmnd[9]) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
+                                     0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
+               } else {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
+                                     0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
+               }
+       } else {
+               if (srb->cmnd[9]) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+                               SPI_TRANSFER0_START | SPI_CADI_MODE0);
+               } else {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+                               SPI_TRANSFER0_START | SPI_CDI_MODE0);
+               }
+       }
+
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval < 0) {
+               rtsx_clear_spi_error(chip);
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (len) {
+               buf = kmalloc(len, GFP_KERNEL);
+               if (!buf)
+                       TRACE_RET(chip, STATUS_ERROR);
+
+               retval = rtsx_read_ppbuf(chip, buf, len);
+               if (retval != STATUS_SUCCESS) {
+                       spi_set_err_code(chip, SPI_READ_ERR);
+                       kfree(buf);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
+               scsi_set_resid(srb, 0);
+
+               kfree(buf);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       unsigned int index = 0, offset = 0;
+       u8 ins, slow_read;
+       u32 addr;
+       u16 len;
+       u8 *buf;
+
+       spi_set_err_code(chip, SPI_NO_ERR);
+
+       ins = srb->cmnd[3];
+       addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5])
+                                       << 8) | srb->cmnd[6];
+       len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
+       slow_read = srb->cmnd[9];
+
+       retval = spi_set_init_para(chip);
+       if (retval != STATUS_SUCCESS) {
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
+       if (buf == NULL)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       while (len) {
+               u16 pagelen = SF_PAGE_LEN - (u8)addr;
+
+               if (pagelen > len)
+                       pagelen = len;
+
+               rtsx_init_cmd(chip);
+
+               trans_dma_enable(DMA_FROM_DEVICE, chip, 256, DMA_256);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
+
+               if (slow_read) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF,
+                               (u8)addr);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF,
+                               (u8)(addr >> 8));
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF,
+                               (u8)(addr >> 16));
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
+                               SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
+               } else {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF,
+                               (u8)addr);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF,
+                               (u8)(addr >> 8));
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF,
+                               (u8)(addr >> 16));
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
+                               SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_32);
+               }
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF,
+                       (u8)(pagelen >> 8));
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF,
+                       (u8)pagelen);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+                       SPI_TRANSFER0_START | SPI_CADI_MODE0);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0,
+                       SPI_TRANSFER0_END, SPI_TRANSFER0_END);
+
+               rtsx_send_cmd_no_wait(chip);
+
+               retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0,
+                                       DMA_FROM_DEVICE, 10000);
+               if (retval < 0) {
+                       kfree(buf);
+                       rtsx_clear_spi_error(chip);
+                       spi_set_err_code(chip, SPI_HW_ERR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset,
+                                       TO_XFER_BUF);
+
+               addr += pagelen;
+               len -= pagelen;
+       }
+
+       scsi_set_resid(srb, 0);
+       kfree(buf);
+
+       return STATUS_SUCCESS;
+}
+
+int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       u8 ins, program_mode;
+       u32 addr;
+       u16 len;
+       u8 *buf;
+       unsigned int index = 0, offset = 0;
+
+       spi_set_err_code(chip, SPI_NO_ERR);
+
+       ins = srb->cmnd[3];
+       addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5])
+                                       << 8) | srb->cmnd[6];
+       len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
+       program_mode = srb->cmnd[9];
+
+       retval = spi_set_init_para(chip);
+       if (retval != STATUS_SUCCESS) {
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (program_mode == BYTE_PROGRAM) {
+               buf = kmalloc(4, GFP_KERNEL);
+               if (!buf)
+                       TRACE_RET(chip, STATUS_ERROR);
+
+               while (len) {
+                       retval = sf_enable_write(chip, SPI_WREN);
+                       if (retval != STATUS_SUCCESS) {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset,
+                                               FROM_XFER_BUF);
+
+                       rtsx_init_cmd(chip);
+
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+                               0x01, PINGPONG_BUFFER);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF,
+                               buf[0]);
+                       sf_program(chip, ins, 1, addr, 1);
+
+                       retval = rtsx_send_cmd(chip, 0, 100);
+                       if (retval < 0) {
+                               kfree(buf);
+                               rtsx_clear_spi_error(chip);
+                               spi_set_err_code(chip, SPI_HW_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       retval = sf_polling_status(chip, 100);
+                       if (retval != STATUS_SUCCESS) {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       addr++;
+                       len--;
+               }
+
+               kfree(buf);
+
+       } else if (program_mode == AAI_PROGRAM) {
+               int first_byte = 1;
+
+               retval = sf_enable_write(chip, SPI_WREN);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               buf = kmalloc(4, GFP_KERNEL);
+               if (!buf)
+                       TRACE_RET(chip, STATUS_ERROR);
+
+               while (len) {
+                       rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset,
+                                               FROM_XFER_BUF);
+
+                       rtsx_init_cmd(chip);
+
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+                               0x01, PINGPONG_BUFFER);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF,
+                               buf[0]);
+                       if (first_byte) {
+                               sf_program(chip, ins, 1, addr, 1);
+                               first_byte = 0;
+                       } else {
+                               sf_program(chip, ins, 0, 0, 1);
+                       }
+
+                       retval = rtsx_send_cmd(chip, 0, 100);
+                       if (retval < 0) {
+                               kfree(buf);
+                               rtsx_clear_spi_error(chip);
+                               spi_set_err_code(chip, SPI_HW_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       retval = sf_polling_status(chip, 100);
+                       if (retval != STATUS_SUCCESS) {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       len--;
+               }
+
+               kfree(buf);
+
+               retval = sf_disable_write(chip, SPI_WRDI);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = sf_polling_status(chip, 100);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else if (program_mode == PAGE_PROGRAM) {
+               buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
+               if (!buf)
+                       TRACE_RET(chip, STATUS_NOMEM);
+
+               while (len) {
+                       u16 pagelen = SF_PAGE_LEN - (u8)addr;
+
+                       if (pagelen > len)
+                               pagelen = len;
+
+                       retval = sf_enable_write(chip, SPI_WREN);
+                       if (retval != STATUS_SUCCESS) {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       rtsx_init_cmd(chip);
+
+                       trans_dma_enable(DMA_TO_DEVICE, chip, 256, DMA_256);
+                       sf_program(chip, ins, 1, addr, pagelen);
+
+                       rtsx_send_cmd_no_wait(chip);
+
+                       rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index,
+                                               &offset, FROM_XFER_BUF);
+
+                       retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0,
+                                               DMA_TO_DEVICE, 100);
+                       if (retval < 0) {
+                               kfree(buf);
+                               rtsx_clear_spi_error(chip);
+                               spi_set_err_code(chip, SPI_HW_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       retval = sf_polling_status(chip, 100);
+                       if (retval != STATUS_SUCCESS) {
+                               kfree(buf);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       addr += pagelen;
+                       len -= pagelen;
+               }
+
+               kfree(buf);
+       } else {
+               spi_set_err_code(chip, SPI_INVALID_COMMAND);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       u8 ins, erase_mode;
+       u32 addr;
+
+       spi_set_err_code(chip, SPI_NO_ERR);
+
+       ins = srb->cmnd[3];
+       addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5])
+                                       << 8) | srb->cmnd[6];
+       erase_mode = srb->cmnd[9];
+
+       retval = spi_set_init_para(chip);
+       if (retval != STATUS_SUCCESS) {
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       if (erase_mode == PAGE_ERASE) {
+               retval = sf_enable_write(chip, SPI_WREN);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = sf_erase(chip, ins, 1, addr);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else if (erase_mode == CHIP_ERASE) {
+               retval = sf_enable_write(chip, SPI_WREN);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = sf_erase(chip, ins, 0, 0);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else {
+               spi_set_err_code(chip, SPI_INVALID_COMMAND);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
+{
+       int retval;
+       u8 ins, status, ewsr;
+
+       ins = srb->cmnd[3];
+       status = srb->cmnd[4];
+       ewsr = srb->cmnd[5];
+
+       retval = spi_set_init_para(chip);
+       if (retval != STATUS_SUCCESS) {
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = sf_enable_write(chip, ewsr);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
+               PINGPONG_BUFFER);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
+               SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
+               SPI_TRANSFER0_START | SPI_CDO_MODE0);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
+               SPI_TRANSFER0_END);
+
+       retval = rtsx_send_cmd(chip, 0, 100);
+       if (retval != STATUS_SUCCESS) {
+               rtsx_clear_spi_error(chip);
+               spi_set_err_code(chip, SPI_HW_ERR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
diff --git a/drivers/staging/rts5208/spi.h b/drivers/staging/rts5208/spi.h
new file mode 100644 (file)
index 0000000..fc824b5
--- /dev/null
@@ -0,0 +1,65 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_SPI_H
+#define __REALTEK_RTSX_SPI_H
+
+/* SPI operation error */
+#define SPI_NO_ERR             0x00
+#define SPI_HW_ERR             0x01
+#define SPI_INVALID_COMMAND    0x02
+#define SPI_READ_ERR           0x03
+#define SPI_WRITE_ERR          0x04
+#define SPI_ERASE_ERR          0x05
+#define SPI_BUSY_ERR           0x06
+
+/* Serial flash instruction */
+#define SPI_READ               0x03
+#define SPI_FAST_READ          0x0B
+#define SPI_WREN               0x06
+#define SPI_WRDI               0x04
+#define SPI_RDSR               0x05
+
+#define SF_PAGE_LEN            256
+
+#define BYTE_PROGRAM           0
+#define AAI_PROGRAM            1
+#define PAGE_PROGRAM           2
+
+#define PAGE_ERASE             0
+#define CHIP_ERASE             1
+
+int spi_erase_eeprom_chip(struct rtsx_chip *chip);
+int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr);
+int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val);
+int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val);
+int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip);
+
+
+#endif  /* __REALTEK_RTSX_SPI_H */
diff --git a/drivers/staging/rts5208/trace.h b/drivers/staging/rts5208/trace.h
new file mode 100644 (file)
index 0000000..0f177fb
--- /dev/null
@@ -0,0 +1,93 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_TRACE_H
+#define __REALTEK_RTSX_TRACE_H
+
+#define _MSG_TRACE
+
+#ifdef _MSG_TRACE
+static inline char *filename(char *path)
+{
+       char *ptr;
+
+       if (path == NULL)
+               return NULL;
+
+       ptr = path;
+
+       while (*ptr != '\0') {
+               if ((*ptr == '\\') || (*ptr == '/'))
+                       path = ptr + 1;
+
+               ptr++;
+       }
+
+       return path;
+}
+
+#define TRACE_RET(chip, ret)                                           \
+       do {                                                            \
+               char *_file = filename(__FILE__);                       \
+               RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \
+               (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \
+               strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \
+               strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \
+               get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \
+               (chip)->trace_msg[(chip)->msg_idx].valid = 1;           \
+               (chip)->msg_idx++;                                      \
+               if ((chip)->msg_idx >= TRACE_ITEM_CNT) {                \
+                       (chip)->msg_idx = 0;                            \
+               }                                                       \
+               return ret;                                             \
+       } while (0)
+
+#define TRACE_GOTO(chip, label)                                                \
+       do {                                                            \
+               char *_file = filename(__FILE__);                       \
+               RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \
+               (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \
+               strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \
+               strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \
+               get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \
+               (chip)->trace_msg[(chip)->msg_idx].valid = 1;           \
+               (chip)->msg_idx++;                                      \
+               if ((chip)->msg_idx >= TRACE_ITEM_CNT) {                \
+                       (chip)->msg_idx = 0;                            \
+               }                                                       \
+               goto label;                                             \
+       } while (0)
+#else
+#define TRACE_RET(chip, ret)   return ret
+#define TRACE_GOTO(chip, label)        goto label
+#endif
+
+#ifdef CONFIG_RTS5208_DEBUG
+#define RTSX_DUMP(buf, buf_len)                                        \
+       print_hex_dump(KERN_DEBUG, RTSX_STOR, DUMP_PREFIX_NONE, \
+                               16, 1, (buf), (buf_len), false)
+#else
+#define RTSX_DUMP(buf, buf_len)
+#endif
+
+#endif  /* __REALTEK_RTSX_TRACE_H */
diff --git a/drivers/staging/rts5208/xd.c b/drivers/staging/rts5208/xd.c
new file mode 100644 (file)
index 0000000..6aef53d
--- /dev/null
@@ -0,0 +1,2088 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+
+#include "rtsx.h"
+#include "rtsx_transport.h"
+#include "rtsx_scsi.h"
+#include "rtsx_card.h"
+#include "xd.h"
+
+static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no);
+static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff,
+                       u8 start_page, u8 end_page);
+
+static inline void xd_set_err_code(struct rtsx_chip *chip, u8 err_code)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+
+       xd_card->err_code = err_code;
+}
+
+static inline int xd_check_err_code(struct rtsx_chip *chip, u8 err_code)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+
+       return (xd_card->err_code == err_code);
+}
+
+static int xd_set_init_para(struct rtsx_chip *chip)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int retval;
+
+       if (chip->asic_code)
+               xd_card->xd_clock = 47;
+       else
+               xd_card->xd_clock = CLK_50;
+
+       retval = switch_clock(chip, xd_card->xd_clock);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_switch_clock(struct rtsx_chip *chip)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int retval;
+
+       retval = select_card(chip, XD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = switch_clock(chip, xd_card->xd_clock);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len)
+{
+       int retval, i;
+       u8 *ptr;
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
+               XD_TRANSFER_START | XD_READ_ID);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END,
+               XD_TRANSFER_END);
+
+       for (i = 0; i < 4; i++)
+               rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0);
+
+       retval = rtsx_send_cmd(chip, XD_CARD, 20);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ptr = rtsx_get_cmd_data(chip) + 1;
+       if (id_buf && buf_len) {
+               if (buf_len > 4)
+                       buf_len = 4;
+               memcpy(id_buf, ptr, buf_len);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static void xd_assign_phy_addr(struct rtsx_chip *chip, u32 addr, u8 mode)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+
+       switch (mode) {
+       case XD_RW_ADDR:
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)addr);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2,
+                       0xFF, (u8)(addr >> 8));
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3,
+                       0xFF, (u8)(addr >> 16));
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF,
+                       xd_card->addr_cycle | XD_CALC_ECC | XD_BA_NO_TRANSFORM);
+               break;
+
+       case XD_ERASE_ADDR:
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, (u8)addr);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1,
+                       0xFF, (u8)(addr >> 8));
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2,
+                       0xFF, (u8)(addr >> 16));
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF,
+                       (xd_card->addr_cycle - 1) | XD_CALC_ECC |
+                       XD_BA_NO_TRANSFORM);
+               break;
+
+       default:
+               break;
+       }
+}
+
+static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr,
+                       u8 *buf, int buf_len)
+{
+       int retval, i;
+
+       rtsx_init_cmd(chip);
+
+       xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,
+               0xFF, XD_TRANSFER_START | XD_READ_REDUNDANT);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+               XD_TRANSFER_END, XD_TRANSFER_END);
+
+       for (i = 0; i < 6; i++)
+               rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_PAGE_STATUS + i),
+                       0, 0);
+       for (i = 0; i < 4; i++)
+               rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_RESERVED0 + i),
+                       0, 0);
+       rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0);
+
+       retval = rtsx_send_cmd(chip, XD_CARD, 500);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (buf && buf_len) {
+               u8 *ptr = rtsx_get_cmd_data(chip) + 1;
+
+               if (buf_len > 11)
+                       buf_len = 11;
+               memcpy(buf, ptr, buf_len);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset,
+                               u8 *buf, int buf_len)
+{
+       int retval, i;
+
+       if (!buf || (buf_len < 0))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       for (i = 0; i < buf_len; i++)
+               rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i,
+                       0, 0);
+
+       retval = rtsx_send_cmd(chip, 0, 250);
+       if (retval < 0) {
+               rtsx_clear_xd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       memcpy(buf, rtsx_get_cmd_data(chip), buf_len);
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf,
+               int buf_len)
+{
+       int retval;
+       u8 reg;
+
+       if (!buf || (buf_len < 10))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
+               0x01, PINGPONG_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,
+               XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
+               XD_TRANSFER_START | XD_READ_PAGES);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END,
+               XD_TRANSFER_END);
+
+       retval = rtsx_send_cmd(chip, XD_CARD, 250);
+       if (retval == -ETIMEDOUT) {
+               rtsx_clear_xd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_READ_REG(chip, XD_PAGE_STATUS, &reg);
+       if (reg != XD_GPG) {
+               rtsx_clear_xd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       RTSX_READ_REG(chip, XD_CTL, &reg);
+       if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) {
+               retval = xd_read_data_from_ppb(chip, 0, buf, buf_len);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+               if (reg & XD_ECC1_ERROR) {
+                       u8 ecc_bit, ecc_byte;
+
+                       RTSX_READ_REG(chip, XD_ECC_BIT1, &ecc_bit);
+                       RTSX_READ_REG(chip, XD_ECC_BYTE1, &ecc_byte);
+
+                       RTSX_DEBUGP("ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n",
+                               ecc_bit, ecc_byte);
+                       if (ecc_byte < buf_len) {
+                               RTSX_DEBUGP("Before correct: 0x%x\n",
+                                       buf[ecc_byte]);
+                               buf[ecc_byte] ^= (1 << ecc_bit);
+                               RTSX_DEBUGP("After correct: 0x%x\n",
+                                       buf[ecc_byte]);
+                       }
+               }
+       } else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) {
+               rtsx_clear_xd_error(chip);
+
+               retval = xd_read_data_from_ppb(chip, 256, buf, buf_len);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+               if (reg & XD_ECC2_ERROR) {
+                       u8 ecc_bit, ecc_byte;
+
+                       RTSX_READ_REG(chip, XD_ECC_BIT2, &ecc_bit);
+                       RTSX_READ_REG(chip, XD_ECC_BYTE2, &ecc_byte);
+
+                       RTSX_DEBUGP("ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n",
+                               ecc_bit, ecc_byte);
+                       if (ecc_byte < buf_len) {
+                               RTSX_DEBUGP("Before correct: 0x%x\n",
+                                       buf[ecc_byte]);
+                               buf[ecc_byte] ^= (1 << ecc_bit);
+                               RTSX_DEBUGP("After correct: 0x%x\n",
+                                       buf[ecc_byte]);
+                       }
+               }
+       } else {
+               rtsx_clear_xd_error(chip);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static void xd_fill_pull_ctl_disable(struct rtsx_chip *chip)
+{
+       if (CHECK_PID(chip, 0x5208)) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,
+                       XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,
+                       XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,
+                       XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,
+                       XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,
+                       MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF,
+                       MS_D5_PD | MS_D4_PD);
+       } else if (CHECK_PID(chip, 0x5288)) {
+               if (CHECK_BARO_PKG(chip, QFN)) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1,
+                               0xFF, 0x55);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2,
+                               0xFF, 0x55);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3,
+                               0xFF, 0x4B);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4,
+                               0xFF, 0x69);
+               }
+       }
+}
+
+static void xd_fill_pull_ctl_stage1_barossa(struct rtsx_chip *chip)
+{
+       if (CHECK_BARO_PKG(chip, QFN)) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
+       }
+}
+
+static void xd_fill_pull_ctl_enable(struct rtsx_chip *chip)
+{
+       if (CHECK_PID(chip, 0x5208)) {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,
+                       XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,
+                       XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,
+                       XD_WP_PD | XD_CE_PU | XD_CLE_PD | XD_CD_PU);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,
+                       XD_RDY_PU | XD_WE_PU | XD_RE_PU | XD_ALE_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,
+                       MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF,
+                       MS_D5_PD | MS_D4_PD);
+       } else if (CHECK_PID(chip, 0x5288)) {
+               if (CHECK_BARO_PKG(chip, QFN)) {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1,
+                               0xFF, 0x55);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2,
+                               0xFF, 0x55);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3,
+                               0xFF, 0x53);
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4,
+                               0xFF, 0xA9);
+               }
+       }
+}
+
+static int xd_pull_ctl_disable(struct rtsx_chip *chip)
+{
+       if (CHECK_PID(chip, 0x5208)) {
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF,
+                       XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF,
+                       XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF,
+                       XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF,
+                       XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF,
+                       MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
+               RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD);
+       } else if (CHECK_PID(chip, 0x5288)) {
+               if (CHECK_BARO_PKG(chip, QFN)) {
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55);
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55);
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B);
+                       RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69);
+               }
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int reset_xd(struct rtsx_chip *chip)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int retval, i, j;
+       u8 *ptr, id_buf[4], redunt[11];
+
+       retval = select_card(chip, XD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF,
+               XD_PGSTS_NOT_FF);
+       if (chip->asic_code) {
+               if (!CHECK_PID(chip, 0x5288))
+                       xd_fill_pull_ctl_disable(chip);
+               else
+                       xd_fill_pull_ctl_stage1_barossa(chip);
+       } else {
+               rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF,
+                       (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3) | 0x20);
+       }
+
+       if (!chip->ft2_fast_mode)
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_INIT,
+                       XD_NO_AUTO_PWR_OFF, 0);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0);
+
+       retval = rtsx_send_cmd(chip, XD_CARD, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (!chip->ft2_fast_mode) {
+               retval = card_power_off(chip, XD_CARD);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               wait_timeout(250);
+
+               rtsx_init_cmd(chip);
+
+               if (chip->asic_code) {
+                       xd_fill_pull_ctl_enable(chip);
+               } else {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF,
+                               (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) |
+                               0x20);
+               }
+
+               retval = rtsx_send_cmd(chip, XD_CARD, 100);
+               if (retval < 0)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               retval = card_power_on(chip, XD_CARD);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+#ifdef SUPPORT_OCP
+               wait_timeout(50);
+               if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
+                       RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
+                               chip->ocp_stat);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+#endif
+       }
+
+       rtsx_init_cmd(chip);
+
+       if (chip->ft2_fast_mode) {
+               if (chip->asic_code) {
+                       xd_fill_pull_ctl_enable(chip);
+               } else {
+                       rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF,
+                               (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) |
+                               0x20);
+               }
+       }
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, XD_OUTPUT_EN);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN);
+
+       retval = rtsx_send_cmd(chip, XD_CARD, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if (!chip->ft2_fast_mode)
+               wait_timeout(200);
+
+       retval = xd_set_init_para(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       /* Read ID to check if the timing setting is right */
+       for (i = 0; i < 4; i++) {
+               rtsx_init_cmd(chip);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF,
+                       XD_TIME_SETUP_STEP * 3 +
+                       XD_TIME_RW_STEP * (2 + i) + XD_TIME_RWN_STEP * i);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF,
+                       XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (4 + i) +
+                       XD_TIME_RWN_STEP * (3 + i));
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
+                       XD_TRANSFER_START | XD_RESET);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+                       XD_TRANSFER_END, XD_TRANSFER_END);
+
+               rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);
+               rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0);
+
+               retval = rtsx_send_cmd(chip, XD_CARD, 100);
+               if (retval < 0)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               ptr = rtsx_get_cmd_data(chip) + 1;
+
+               RTSX_DEBUGP("XD_DAT: 0x%x, XD_CTL: 0x%x\n", ptr[0], ptr[1]);
+
+               if (((ptr[0] & READY_FLAG) != READY_STATE) ||
+                       !(ptr[1] & XD_RDY))
+                       continue;
+
+               retval = xd_read_id(chip, READ_ID, id_buf, 4);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               RTSX_DEBUGP("READ_ID: 0x%x 0x%x 0x%x 0x%x\n",
+                       id_buf[0], id_buf[1], id_buf[2], id_buf[3]);
+
+               xd_card->device_code = id_buf[1];
+
+               /* Check if the xD card is supported */
+               switch (xd_card->device_code) {
+               case XD_4M_X8_512_1:
+               case XD_4M_X8_512_2:
+                       xd_card->block_shift = 4;
+                       xd_card->page_off = 0x0F;
+                       xd_card->addr_cycle = 3;
+                       xd_card->zone_cnt = 1;
+                       xd_card->capacity = 8000;
+                       XD_SET_4MB(xd_card);
+                       break;
+               case XD_8M_X8_512:
+                       xd_card->block_shift = 4;
+                       xd_card->page_off = 0x0F;
+                       xd_card->addr_cycle = 3;
+                       xd_card->zone_cnt = 1;
+                       xd_card->capacity = 16000;
+                       break;
+               case XD_16M_X8_512:
+                       XD_PAGE_512(xd_card);
+                       xd_card->addr_cycle = 3;
+                       xd_card->zone_cnt = 1;
+                       xd_card->capacity = 32000;
+                       break;
+               case XD_32M_X8_512:
+                       XD_PAGE_512(xd_card);
+                       xd_card->addr_cycle = 3;
+                       xd_card->zone_cnt = 2;
+                       xd_card->capacity = 64000;
+                       break;
+               case XD_64M_X8_512:
+                       XD_PAGE_512(xd_card);
+                       xd_card->addr_cycle = 4;
+                       xd_card->zone_cnt = 4;
+                       xd_card->capacity = 128000;
+                       break;
+               case XD_128M_X8_512:
+                       XD_PAGE_512(xd_card);
+                       xd_card->addr_cycle = 4;
+                       xd_card->zone_cnt = 8;
+                       xd_card->capacity = 256000;
+                       break;
+               case XD_256M_X8_512:
+                       XD_PAGE_512(xd_card);
+                       xd_card->addr_cycle = 4;
+                       xd_card->zone_cnt = 16;
+                       xd_card->capacity = 512000;
+                       break;
+               case XD_512M_X8:
+                       XD_PAGE_512(xd_card);
+                       xd_card->addr_cycle = 4;
+                       xd_card->zone_cnt = 32;
+                       xd_card->capacity = 1024000;
+                       break;
+               case xD_1G_X8_512:
+                       XD_PAGE_512(xd_card);
+                       xd_card->addr_cycle = 4;
+                       xd_card->zone_cnt = 64;
+                       xd_card->capacity = 2048000;
+                       break;
+               case xD_2G_X8_512:
+                       XD_PAGE_512(xd_card);
+                       xd_card->addr_cycle = 4;
+                       xd_card->zone_cnt = 128;
+                       xd_card->capacity = 4096000;
+                       break;
+               default:
+                       continue;
+               }
+
+               /* Confirm timing setting */
+               for (j = 0; j < 10; j++) {
+                       retval = xd_read_id(chip, READ_ID, id_buf, 4);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       if (id_buf[1] != xd_card->device_code)
+                               break;
+               }
+
+               if (j == 10)
+                       break;
+       }
+
+       if (i == 4) {
+               xd_card->block_shift = 0;
+               xd_card->page_off = 0;
+               xd_card->addr_cycle = 0;
+               xd_card->capacity = 0;
+
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       retval = xd_read_id(chip, READ_xD_ID, id_buf, 4);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+       RTSX_DEBUGP("READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n",
+                       id_buf[0], id_buf[1], id_buf[2], id_buf[3]);
+       if (id_buf[2] != XD_ID_CODE)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       /* Search CIS block */
+       for (i = 0; i < 24; i++) {
+               u32 page_addr;
+
+               if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               page_addr = (u32)i << xd_card->block_shift;
+
+               for (j = 0; j < 3; j++) {
+                       retval = xd_read_redundant(chip, page_addr, redunt, 11);
+                       if (retval == STATUS_SUCCESS)
+                               break;
+               }
+               if (j == 3)
+                       continue;
+
+               if (redunt[BLOCK_STATUS] != XD_GBLK)
+                       continue;
+
+               j = 0;
+               if (redunt[PAGE_STATUS] != XD_GPG) {
+                       for (j = 1; j <= 8; j++) {
+                               retval = xd_read_redundant(chip, page_addr + j,
+                                                       redunt, 11);
+                               if (retval == STATUS_SUCCESS) {
+                                       if (redunt[PAGE_STATUS] == XD_GPG)
+                                               break;
+                               }
+                       }
+
+                       if (j == 9)
+                               break;
+               }
+
+               /* Check CIS data */
+               if ((redunt[BLOCK_STATUS] == XD_GBLK) &&
+                       (redunt[PARITY] & XD_BA1_ALL0)) {
+                       u8 buf[10];
+
+                       page_addr += j;
+
+                       retval = xd_read_cis(chip, page_addr, buf, 10);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+
+                       if ((buf[0] == 0x01) && (buf[1] == 0x03) &&
+                               (buf[2] == 0xD9)
+                                       && (buf[3] == 0x01) && (buf[4] == 0xFF)
+                                       && (buf[5] == 0x18) && (buf[6] == 0x02)
+                                       && (buf[7] == 0xDF) && (buf[8] == 0x01)
+                                       && (buf[9] == 0x20)) {
+                               xd_card->cis_block = (u16)i;
+                       }
+               }
+
+               break;
+       }
+
+       RTSX_DEBUGP("CIS block: 0x%x\n", xd_card->cis_block);
+       if (xd_card->cis_block == 0xFFFF)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity;
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_check_data_blank(u8 *redunt)
+{
+       int i;
+
+       for (i = 0; i < 6; i++) {
+               if (redunt[PAGE_STATUS + i] != 0xFF)
+                       return 0;
+       }
+
+       if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1))
+               != (XD_ECC1_ALL1 | XD_ECC2_ALL1))
+               return 0;
+
+
+       for (i = 0; i < 4; i++) {
+               if (redunt[RESERVED0 + i] != 0xFF)
+                       return 0;
+       }
+
+       return 1;
+}
+
+static u16 xd_load_log_block_addr(u8 *redunt)
+{
+       u16 addr = 0xFFFF;
+
+       if (redunt[PARITY] & XD_BA1_BA2_EQL)
+               addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) |
+                       redunt[BLOCK_ADDR1_L];
+       else if (redunt[PARITY] & XD_BA1_VALID)
+               addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) |
+                       redunt[BLOCK_ADDR1_L];
+       else if (redunt[PARITY] & XD_BA2_VALID)
+               addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) |
+                       redunt[BLOCK_ADDR2_L];
+
+       return addr;
+}
+
+static int xd_init_l2p_tbl(struct rtsx_chip *chip)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int size, i;
+
+       RTSX_DEBUGP("xd_init_l2p_tbl: zone_cnt = %d\n", xd_card->zone_cnt);
+
+       if (xd_card->zone_cnt < 1)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       size = xd_card->zone_cnt * sizeof(struct zone_entry);
+       RTSX_DEBUGP("Buffer size for l2p table is %d\n", size);
+
+       xd_card->zone = vmalloc(size);
+       if (!xd_card->zone)
+               TRACE_RET(chip, STATUS_ERROR);
+
+       for (i = 0; i < xd_card->zone_cnt; i++) {
+               xd_card->zone[i].build_flag = 0;
+               xd_card->zone[i].l2p_table = NULL;
+               xd_card->zone[i].free_table = NULL;
+               xd_card->zone[i].get_index = 0;
+               xd_card->zone[i].set_index = 0;
+               xd_card->zone[i].unused_blk_cnt = 0;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static inline void free_zone(struct zone_entry *zone)
+{
+       RTSX_DEBUGP("free_zone\n");
+
+       if (!zone)
+               return;
+
+       zone->build_flag = 0;
+       zone->set_index = 0;
+       zone->get_index = 0;
+       zone->unused_blk_cnt = 0;
+       if (zone->l2p_table) {
+               vfree(zone->l2p_table);
+               zone->l2p_table = NULL;
+       }
+       if (zone->free_table) {
+               vfree(zone->free_table);
+               zone->free_table = NULL;
+       }
+}
+
+static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       struct zone_entry *zone;
+       int zone_no;
+
+       zone_no = (int)phy_blk >> 10;
+       if (zone_no >= xd_card->zone_cnt) {
+               RTSX_DEBUGP("Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n",
+                       zone_no, xd_card->zone_cnt);
+               return;
+       }
+       zone = &(xd_card->zone[zone_no]);
+
+       if (zone->free_table == NULL) {
+               if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS)
+                       return;
+       }
+
+       if ((zone->set_index >= XD_FREE_TABLE_CNT)
+                       || (zone->set_index < 0)) {
+               free_zone(zone);
+               RTSX_DEBUGP("Set unused block fail, invalid set_index\n");
+               return;
+       }
+
+       RTSX_DEBUGP("Set unused block to index %d\n", zone->set_index);
+
+       zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff);
+       if (zone->set_index >= XD_FREE_TABLE_CNT)
+               zone->set_index = 0;
+       zone->unused_blk_cnt++;
+}
+
+static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       struct zone_entry *zone;
+       u32 phy_blk;
+
+       if (zone_no >= xd_card->zone_cnt) {
+               RTSX_DEBUGP("Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n",
+                       zone_no, xd_card->zone_cnt);
+               return BLK_NOT_FOUND;
+       }
+       zone = &(xd_card->zone[zone_no]);
+
+       if ((zone->unused_blk_cnt == 0) ||
+               (zone->set_index == zone->get_index)) {
+               free_zone(zone);
+               RTSX_DEBUGP("Get unused block fail, no unused block available\n");
+               return BLK_NOT_FOUND;
+       }
+       if ((zone->get_index >= XD_FREE_TABLE_CNT) || (zone->get_index < 0)) {
+               free_zone(zone);
+               RTSX_DEBUGP("Get unused block fail, invalid get_index\n");
+               return BLK_NOT_FOUND;
+       }
+
+       RTSX_DEBUGP("Get unused block from index %d\n", zone->get_index);
+
+       phy_blk = zone->free_table[zone->get_index];
+       zone->free_table[zone->get_index++] = 0xFFFF;
+       if (zone->get_index >= XD_FREE_TABLE_CNT)
+               zone->get_index = 0;
+       zone->unused_blk_cnt--;
+
+       phy_blk += ((u32)(zone_no) << 10);
+       return phy_blk;
+}
+
+static void xd_set_l2p_tbl(struct rtsx_chip *chip,
+                       int zone_no, u16 log_off, u16 phy_off)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       struct zone_entry *zone;
+
+       zone = &(xd_card->zone[zone_no]);
+       zone->l2p_table[log_off] = phy_off;
+}
+
+static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       struct zone_entry *zone;
+       int retval;
+
+       zone = &(xd_card->zone[zone_no]);
+       if (zone->l2p_table[log_off] == 0xFFFF) {
+               u32 phy_blk = 0;
+               int i;
+
+#ifdef XD_DELAY_WRITE
+               retval = xd_delay_write(chip);
+               if (retval != STATUS_SUCCESS) {
+                       RTSX_DEBUGP("In xd_get_l2p_tbl, delay write fail!\n");
+                       return BLK_NOT_FOUND;
+               }
+#endif
+
+               if (zone->unused_blk_cnt <= 0) {
+                       RTSX_DEBUGP("No unused block!\n");
+                       return BLK_NOT_FOUND;
+               }
+
+               for (i = 0; i < zone->unused_blk_cnt; i++) {
+                       phy_blk = xd_get_unused_block(chip, zone_no);
+                       if (phy_blk == BLK_NOT_FOUND) {
+                               RTSX_DEBUGP("No unused block available!\n");
+                               return BLK_NOT_FOUND;
+                       }
+
+                       retval = xd_init_page(chip, phy_blk, log_off,
+                                       0, xd_card->page_off + 1);
+                       if (retval == STATUS_SUCCESS)
+                               break;
+               }
+               if (i >= zone->unused_blk_cnt) {
+                       RTSX_DEBUGP("No good unused block available!\n");
+                       return BLK_NOT_FOUND;
+               }
+
+               xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(phy_blk & 0x3FF));
+               return phy_blk;
+       }
+
+       return (u32)zone->l2p_table[log_off] + ((u32)(zone_no) << 10);
+}
+
+int reset_xd_card(struct rtsx_chip *chip)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int retval;
+
+       memset(xd_card, 0, sizeof(struct xd_info));
+
+       xd_card->block_shift = 0;
+       xd_card->page_off = 0;
+       xd_card->addr_cycle = 0;
+       xd_card->capacity = 0;
+       xd_card->zone_cnt = 0;
+       xd_card->cis_block = 0xFFFF;
+       xd_card->delay_write.delay_write_flag = 0;
+
+       retval = enable_card_clock(chip, XD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = reset_xd(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       retval = xd_init_l2p_tbl(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int retval;
+       u32 page_addr;
+       u8 reg = 0;
+
+       RTSX_DEBUGP("mark block 0x%x as bad block\n", phy_blk);
+
+       if (phy_blk == BLK_NOT_FOUND)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_LATER_BBLK);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF);
+
+       page_addr = phy_blk << xd_card->block_shift;
+
+       xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF,
+               xd_card->page_off + 1);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
+               XD_TRANSFER_START | XD_WRITE_REDUNDANT);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+               XD_TRANSFER_END, XD_TRANSFER_END);
+
+       retval = rtsx_send_cmd(chip, XD_CARD, 500);
+       if (retval < 0) {
+               rtsx_clear_xd_error(chip);
+               rtsx_read_register(chip, XD_DAT, &reg);
+               if (reg & PROGRAM_ERROR)
+                       xd_set_err_code(chip, XD_PRG_ERROR);
+               else
+                       xd_set_err_code(chip, XD_TO_ERROR);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk,
+                       u16 logoff, u8 start_page, u8 end_page)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int retval;
+       u32 page_addr;
+       u8 reg = 0;
+
+       RTSX_DEBUGP("Init block 0x%x\n", phy_blk);
+
+       if (start_page > end_page)
+               TRACE_RET(chip, STATUS_FAIL);
+       if (phy_blk == BLK_NOT_FOUND)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H,
+               0xFF, (u8)(logoff >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)logoff);
+
+       page_addr = (phy_blk << xd_card->block_shift) + start_page;
+
+       xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG,
+               XD_BA_TRANSFORM, XD_BA_TRANSFORM);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT,
+               0xFF, (end_page - start_page));
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,
+               0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+               XD_TRANSFER_END, XD_TRANSFER_END);
+
+       retval = rtsx_send_cmd(chip, XD_CARD, 500);
+       if (retval < 0) {
+               rtsx_clear_xd_error(chip);
+               rtsx_read_register(chip, XD_DAT, &reg);
+               if (reg & PROGRAM_ERROR) {
+                       xd_mark_bad_block(chip, phy_blk);
+                       xd_set_err_code(chip, XD_PRG_ERROR);
+               } else {
+                       xd_set_err_code(chip, XD_TO_ERROR);
+               }
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk,
+                       u8 start_page, u8 end_page)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       u32 old_page, new_page;
+       u8 i, reg = 0;
+       int retval;
+
+       RTSX_DEBUGP("Copy page from block 0x%x to block 0x%x\n",
+               old_blk, new_blk);
+
+       if (start_page > end_page)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND))
+               TRACE_RET(chip, STATUS_FAIL);
+
+       old_page = (old_blk << xd_card->block_shift) + start_page;
+       new_page = (new_blk << xd_card->block_shift) + start_page;
+
+       XD_CLR_BAD_NEWBLK(xd_card);
+
+       RTSX_WRITE_REG(chip, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
+
+       for (i = start_page; i < end_page; i++) {
+               if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
+                       rtsx_clear_xd_error(chip);
+                       xd_set_err_code(chip, XD_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               rtsx_init_cmd(chip);
+
+               xd_assign_phy_addr(chip, old_page, XD_RW_ADDR);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,
+                       XD_AUTO_CHK_DATA_STATUS, 0);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
+                       XD_TRANSFER_START | XD_READ_PAGES);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+                       XD_TRANSFER_END, XD_TRANSFER_END);
+
+               retval = rtsx_send_cmd(chip, XD_CARD, 500);
+               if (retval < 0) {
+                       rtsx_clear_xd_error(chip);
+                       reg = 0;
+                       rtsx_read_register(chip, XD_CTL, &reg);
+                       if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) {
+                               wait_timeout(100);
+
+                               if (detect_card_cd(chip,
+                                       XD_CARD) != STATUS_SUCCESS) {
+                                       xd_set_err_code(chip, XD_NO_CARD);
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+
+                               if (((reg & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) ==
+                                               (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE))
+                                       || ((reg & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) ==
+                                               (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) {
+                                       rtsx_write_register(chip,
+                                                       XD_PAGE_STATUS, 0xFF,
+                                                       XD_BPG);
+                                       rtsx_write_register(chip,
+                                                       XD_BLOCK_STATUS, 0xFF,
+                                                       XD_GBLK);
+                                       XD_SET_BAD_OLDBLK(xd_card);
+                                       RTSX_DEBUGP("old block 0x%x ecc error\n", old_blk);
+                               }
+                       } else {
+                               xd_set_err_code(chip, XD_TO_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               if (XD_CHK_BAD_OLDBLK(xd_card))
+                       rtsx_clear_xd_error(chip);
+
+               rtsx_init_cmd(chip);
+
+               xd_assign_phy_addr(chip, new_page, XD_RW_ADDR);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
+                            XD_TRANSFER_START | XD_WRITE_PAGES);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+                       XD_TRANSFER_END, XD_TRANSFER_END);
+
+               retval = rtsx_send_cmd(chip, XD_CARD, 300);
+               if (retval < 0) {
+                       rtsx_clear_xd_error(chip);
+                       reg = 0;
+                       rtsx_read_register(chip, XD_DAT, &reg);
+                       if (reg & PROGRAM_ERROR) {
+                               xd_mark_bad_block(chip, new_blk);
+                               xd_set_err_code(chip, XD_PRG_ERROR);
+                               XD_SET_BAD_NEWBLK(xd_card);
+                       } else {
+                               xd_set_err_code(chip, XD_TO_ERROR);
+                       }
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               old_page++;
+               new_page++;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_reset_cmd(struct rtsx_chip *chip)
+{
+       int retval;
+       u8 *ptr;
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,
+               0xFF, XD_TRANSFER_START | XD_RESET);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+               XD_TRANSFER_END, XD_TRANSFER_END);
+       rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);
+       rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0);
+
+       retval = rtsx_send_cmd(chip, XD_CARD, 100);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       ptr = rtsx_get_cmd_data(chip) + 1;
+       if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY))
+               return STATUS_SUCCESS;
+
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       u32 page_addr;
+       u8 reg = 0, *ptr;
+       int i, retval;
+
+       if (phy_blk == BLK_NOT_FOUND)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       page_addr = phy_blk << xd_card->block_shift;
+
+       for (i = 0; i < 3; i++) {
+               rtsx_init_cmd(chip);
+
+               xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR);
+
+               rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
+                       XD_TRANSFER_START | XD_ERASE);
+               rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+                       XD_TRANSFER_END, XD_TRANSFER_END);
+               rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);
+
+               retval = rtsx_send_cmd(chip, XD_CARD, 250);
+               if (retval < 0) {
+                       rtsx_clear_xd_error(chip);
+                       rtsx_read_register(chip, XD_DAT, &reg);
+                       if (reg & PROGRAM_ERROR) {
+                               xd_mark_bad_block(chip, phy_blk);
+                               xd_set_err_code(chip, XD_PRG_ERROR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       } else {
+                               xd_set_err_code(chip, XD_ERASE_FAIL);
+                       }
+                       retval = xd_reset_cmd(chip);
+                       if (retval != STATUS_SUCCESS)
+                               TRACE_RET(chip, STATUS_FAIL);
+                       continue;
+               }
+
+               ptr = rtsx_get_cmd_data(chip) + 1;
+               if (*ptr & PROGRAM_ERROR) {
+                       xd_mark_bad_block(chip, phy_blk);
+                       xd_set_err_code(chip, XD_PRG_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               return STATUS_SUCCESS;
+       }
+
+       xd_mark_bad_block(chip, phy_blk);
+       xd_set_err_code(chip, XD_ERASE_FAIL);
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+
+static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       struct zone_entry *zone;
+       int retval;
+       u32 start, end, i;
+       u16 max_logoff, cur_fst_page_logoff;
+       u16 cur_lst_page_logoff, ent_lst_page_logoff;
+       u8 redunt[11];
+
+       RTSX_DEBUGP("xd_build_l2p_tbl: %d\n", zone_no);
+
+       if (xd_card->zone == NULL) {
+               retval = xd_init_l2p_tbl(chip);
+               if (retval != STATUS_SUCCESS)
+                       return retval;
+       }
+
+       if (xd_card->zone[zone_no].build_flag) {
+               RTSX_DEBUGP("l2p table of zone %d has been built\n", zone_no);
+               return STATUS_SUCCESS;
+       }
+
+       zone = &(xd_card->zone[zone_no]);
+
+       if (zone->l2p_table == NULL) {
+               zone->l2p_table = vmalloc(2000);
+               if (zone->l2p_table == NULL)
+                       TRACE_GOTO(chip, Build_Fail);
+       }
+       memset((u8 *)(zone->l2p_table), 0xff, 2000);
+
+       if (zone->free_table == NULL) {
+               zone->free_table = vmalloc(XD_FREE_TABLE_CNT * 2);
+               if (zone->free_table == NULL)
+                       TRACE_GOTO(chip, Build_Fail);
+       }
+       memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2);
+
+       if (zone_no == 0) {
+               if (xd_card->cis_block == 0xFFFF)
+                       start = 0;
+               else
+                       start = xd_card->cis_block + 1;
+               if (XD_CHK_4MB(xd_card)) {
+                       end = 0x200;
+                       max_logoff = 499;
+               } else {
+                       end = 0x400;
+                       max_logoff = 999;
+               }
+       } else {
+               start = (u32)(zone_no) << 10;
+               end = (u32)(zone_no + 1) << 10;
+               max_logoff = 999;
+       }
+
+       RTSX_DEBUGP("start block 0x%x, end block 0x%x\n", start, end);
+
+       zone->set_index = zone->get_index = 0;
+       zone->unused_blk_cnt = 0;
+
+       for (i = start; i < end; i++) {
+               u32 page_addr = i << xd_card->block_shift;
+               u32 phy_block;
+
+               retval = xd_read_redundant(chip, page_addr, redunt, 11);
+               if (retval != STATUS_SUCCESS)
+                       continue;
+
+               if (redunt[BLOCK_STATUS] != 0xFF) {
+                       RTSX_DEBUGP("bad block\n");
+                       continue;
+               }
+
+               if (xd_check_data_blank(redunt)) {
+                       RTSX_DEBUGP("blank block\n");
+                       xd_set_unused_block(chip, i);
+                       continue;
+               }
+
+               cur_fst_page_logoff = xd_load_log_block_addr(redunt);
+               if ((cur_fst_page_logoff == 0xFFFF) ||
+                       (cur_fst_page_logoff > max_logoff)) {
+                       retval = xd_erase_block(chip, i);
+                       if (retval == STATUS_SUCCESS)
+                               xd_set_unused_block(chip, i);
+                       continue;
+               }
+
+               if ((zone_no == 0) && (cur_fst_page_logoff == 0) &&
+                       (redunt[PAGE_STATUS] != XD_GPG))
+                       XD_SET_MBR_FAIL(xd_card);
+
+               if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) {
+                       zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF);
+                       continue;
+               }
+
+               phy_block = zone->l2p_table[cur_fst_page_logoff] +
+                       ((u32)((zone_no) << 10));
+
+               page_addr = ((i + 1) << xd_card->block_shift) - 1;
+
+               retval = xd_read_redundant(chip, page_addr, redunt, 11);
+               if (retval != STATUS_SUCCESS)
+                       continue;
+
+               cur_lst_page_logoff = xd_load_log_block_addr(redunt);
+               if (cur_lst_page_logoff == cur_fst_page_logoff) {
+                       int m;
+
+                       page_addr = ((phy_block + 1) <<
+                               xd_card->block_shift) - 1;
+
+                       for (m = 0; m < 3; m++) {
+                               retval = xd_read_redundant(chip, page_addr,
+                                                       redunt, 11);
+                               if (retval == STATUS_SUCCESS)
+                                       break;
+                       }
+
+                       if (m == 3) {
+                               zone->l2p_table[cur_fst_page_logoff] =
+                                       (u16)(i & 0x3FF);
+                               retval = xd_erase_block(chip, phy_block);
+                               if (retval == STATUS_SUCCESS)
+                                       xd_set_unused_block(chip, phy_block);
+                               continue;
+                       }
+
+                       ent_lst_page_logoff = xd_load_log_block_addr(redunt);
+                       if (ent_lst_page_logoff != cur_fst_page_logoff) {
+                               zone->l2p_table[cur_fst_page_logoff] =
+                                       (u16)(i & 0x3FF);
+                               retval = xd_erase_block(chip, phy_block);
+                               if (retval == STATUS_SUCCESS)
+                                       xd_set_unused_block(chip, phy_block);
+                               continue;
+                       } else {
+                               retval = xd_erase_block(chip, i);
+                               if (retval == STATUS_SUCCESS)
+                                       xd_set_unused_block(chip, i);
+                       }
+               } else {
+                       retval = xd_erase_block(chip, i);
+                       if (retval == STATUS_SUCCESS)
+                               xd_set_unused_block(chip, i);
+               }
+       }
+
+       if (XD_CHK_4MB(xd_card))
+               end = 500;
+       else
+               end = 1000;
+
+       i = 0;
+       for (start = 0; start < end; start++) {
+               if (zone->l2p_table[start] == 0xFFFF)
+                       i++;
+       }
+
+       RTSX_DEBUGP("Block count %d, invalid L2P entry %d\n", end, i);
+       RTSX_DEBUGP("Total unused block: %d\n", zone->unused_blk_cnt);
+
+       if ((zone->unused_blk_cnt - i) < 1)
+               chip->card_wp |= XD_CARD;
+
+       zone->build_flag = 1;
+
+       return STATUS_SUCCESS;
+
+Build_Fail:
+       if (zone->l2p_table) {
+               vfree(zone->l2p_table);
+               zone->l2p_table = NULL;
+       }
+       if (zone->free_table) {
+               vfree(zone->free_table);
+               zone->free_table = NULL;
+       }
+
+       return STATUS_FAIL;
+}
+
+static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd)
+{
+       int retval;
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
+               XD_TRANSFER_START | XD_SET_CMD);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+               XD_TRANSFER_END, XD_TRANSFER_END);
+
+       retval = rtsx_send_cmd(chip, XD_CARD, 200);
+       if (retval < 0)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk,
+                               u32 log_blk, u8 start_page, u8 end_page,
+                               u8 *buf, unsigned int *index,
+                               unsigned int *offset)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       u32 page_addr, new_blk;
+       u16 log_off;
+       u8 reg_val, page_cnt;
+       int zone_no, retval, i;
+
+       if (start_page > end_page)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       page_cnt = end_page - start_page;
+       zone_no = (int)(log_blk / 1000);
+       log_off = (u16)(log_blk % 1000);
+
+       if ((phy_blk & 0x3FF) == 0x3FF) {
+               for (i = 0; i < 256; i++) {
+                       page_addr = ((u32)i) << xd_card->block_shift;
+
+                       retval = xd_read_redundant(chip, page_addr, NULL, 0);
+                       if (retval == STATUS_SUCCESS)
+                               break;
+
+                       if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
+                               xd_set_err_code(chip, XD_NO_CARD);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+       }
+
+       page_addr = (phy_blk << xd_card->block_shift) + start_page;
+
+       rtsx_init_cmd(chip);
+
+       xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, XD_PPB_TO_SIE);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,
+                       XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS);
+
+       trans_dma_enable(chip->srb->sc_data_direction, chip,
+                       page_cnt * 512, DMA_512);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
+               XD_TRANSFER_START | XD_READ_PAGES);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+               XD_TRANSFER_END | XD_PPB_EMPTY, XD_TRANSFER_END | XD_PPB_EMPTY);
+
+       rtsx_send_cmd_no_wait(chip);
+
+       retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512,
+                                       scsi_sg_count(chip->srb),
+                                       index, offset, DMA_FROM_DEVICE,
+                                       chip->xd_timeout);
+       if (retval < 0) {
+               rtsx_clear_xd_error(chip);
+
+               if (retval == -ETIMEDOUT) {
+                       xd_set_err_code(chip, XD_TO_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               } else {
+                       TRACE_GOTO(chip, Fail);
+               }
+       }
+
+       return STATUS_SUCCESS;
+
+Fail:
+       RTSX_READ_REG(chip, XD_PAGE_STATUS, &reg_val);
+
+       if (reg_val !=  XD_GPG)
+               xd_set_err_code(chip, XD_PRG_ERROR);
+
+       RTSX_READ_REG(chip, XD_CTL, &reg_val);
+
+       if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE))
+                               == (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE))
+               || ((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))
+                       == (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) {
+               wait_timeout(100);
+
+               if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
+                       xd_set_err_code(chip, XD_NO_CARD);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               xd_set_err_code(chip, XD_ECC_ERROR);
+
+               new_blk = xd_get_unused_block(chip, zone_no);
+               if (new_blk == NO_NEW_BLK) {
+                       XD_CLR_BAD_OLDBLK(xd_card);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = xd_copy_page(chip, phy_blk, new_blk, 0,
+                               xd_card->page_off + 1);
+               if (retval != STATUS_SUCCESS) {
+                       if (!XD_CHK_BAD_NEWBLK(xd_card)) {
+                               retval = xd_erase_block(chip, new_blk);
+                               if (retval == STATUS_SUCCESS)
+                                       xd_set_unused_block(chip, new_blk);
+                       } else {
+                               XD_CLR_BAD_NEWBLK(xd_card);
+                       }
+                       XD_CLR_BAD_OLDBLK(xd_card);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+               xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
+               xd_erase_block(chip, phy_blk);
+               xd_mark_bad_block(chip, phy_blk);
+               XD_CLR_BAD_OLDBLK(xd_card);
+       }
+
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+static int xd_finish_write(struct rtsx_chip *chip,
+               u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int retval, zone_no;
+       u16 log_off;
+
+       RTSX_DEBUGP("xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
+                               old_blk, new_blk, log_blk);
+
+       if (page_off > xd_card->page_off)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       zone_no = (int)(log_blk / 1000);
+       log_off = (u16)(log_blk % 1000);
+
+       if (old_blk == BLK_NOT_FOUND) {
+               retval = xd_init_page(chip, new_blk, log_off,
+                               page_off, xd_card->page_off + 1);
+               if (retval != STATUS_SUCCESS) {
+                       retval = xd_erase_block(chip, new_blk);
+                       if (retval == STATUS_SUCCESS)
+                               xd_set_unused_block(chip, new_blk);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       } else {
+               retval = xd_copy_page(chip, old_blk, new_blk,
+                               page_off, xd_card->page_off + 1);
+               if (retval != STATUS_SUCCESS) {
+                       if (!XD_CHK_BAD_NEWBLK(xd_card)) {
+                               retval = xd_erase_block(chip, new_blk);
+                               if (retval == STATUS_SUCCESS)
+                                       xd_set_unused_block(chip, new_blk);
+                       }
+                       XD_CLR_BAD_NEWBLK(xd_card);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = xd_erase_block(chip, old_blk);
+               if (retval == STATUS_SUCCESS) {
+                       if (XD_CHK_BAD_OLDBLK(xd_card)) {
+                               xd_mark_bad_block(chip, old_blk);
+                               XD_CLR_BAD_OLDBLK(xd_card);
+                       } else {
+                               xd_set_unused_block(chip, old_blk);
+                       }
+               } else {
+                       xd_set_err_code(chip, XD_NO_ERROR);
+                       XD_CLR_BAD_OLDBLK(xd_card);
+               }
+       }
+
+       xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
+
+       return STATUS_SUCCESS;
+}
+
+static int xd_prepare_write(struct rtsx_chip *chip,
+               u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off)
+{
+       int retval;
+
+       RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n",
+               __func__, old_blk, new_blk, log_blk, (int)page_off);
+
+       if (page_off) {
+               retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+
+static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk,
+                               u32 new_blk, u32 log_blk, u8 start_page,
+                               u8 end_page, u8 *buf, unsigned int *index,
+                               unsigned int *offset)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       u32 page_addr;
+       int zone_no, retval;
+       u16 log_off;
+       u8 page_cnt, reg_val;
+
+       RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
+                               __func__, old_blk, new_blk, log_blk);
+
+       if (start_page > end_page)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       page_cnt = end_page - start_page;
+       zone_no = (int)(log_blk / 1000);
+       log_off = (u16)(log_blk % 1000);
+
+       page_addr = (new_blk << xd_card->block_shift) + start_page;
+
+       retval = xd_send_cmd(chip, READ1_1);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       rtsx_init_cmd(chip);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H,
+               0xFF, (u8)(log_off >> 8));
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)log_off);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG);
+
+       xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM,
+               XD_BA_TRANSFORM);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt);
+       rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
+
+       trans_dma_enable(chip->srb->sc_data_direction, chip,
+                       page_cnt * 512, DMA_512);
+
+       rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,
+               0xFF, XD_TRANSFER_START | XD_WRITE_PAGES);
+       rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
+               XD_TRANSFER_END, XD_TRANSFER_END);
+
+       rtsx_send_cmd_no_wait(chip);
+
+       retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512,
+                                       scsi_sg_count(chip->srb),
+                       index, offset, DMA_TO_DEVICE, chip->xd_timeout);
+       if (retval < 0) {
+               rtsx_clear_xd_error(chip);
+
+               if (retval == -ETIMEDOUT) {
+                       xd_set_err_code(chip, XD_TO_ERROR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               } else {
+                       TRACE_GOTO(chip, Fail);
+               }
+       }
+
+       if (end_page == (xd_card->page_off + 1)) {
+               xd_card->delay_write.delay_write_flag = 0;
+
+               if (old_blk != BLK_NOT_FOUND) {
+                       retval = xd_erase_block(chip, old_blk);
+                       if (retval == STATUS_SUCCESS) {
+                               if (XD_CHK_BAD_OLDBLK(xd_card)) {
+                                       xd_mark_bad_block(chip, old_blk);
+                                       XD_CLR_BAD_OLDBLK(xd_card);
+                               } else {
+                                       xd_set_unused_block(chip, old_blk);
+                               }
+                       } else {
+                               xd_set_err_code(chip, XD_NO_ERROR);
+                               XD_CLR_BAD_OLDBLK(xd_card);
+                       }
+               }
+               xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
+       }
+
+       return STATUS_SUCCESS;
+
+Fail:
+       RTSX_READ_REG(chip, XD_DAT, &reg_val);
+       if (reg_val & PROGRAM_ERROR) {
+               xd_set_err_code(chip, XD_PRG_ERROR);
+               xd_mark_bad_block(chip, new_blk);
+       }
+
+       TRACE_RET(chip, STATUS_FAIL);
+}
+
+#ifdef XD_DELAY_WRITE
+int xd_delay_write(struct rtsx_chip *chip)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       struct xd_delay_write_tag *delay_write = &(xd_card->delay_write);
+       int retval;
+
+       if (delay_write->delay_write_flag) {
+               RTSX_DEBUGP("xd_delay_write\n");
+               retval = xd_switch_clock(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               delay_write->delay_write_flag = 0;
+               retval = xd_finish_write(chip,
+                               delay_write->old_phyblock,
+                                       delay_write->new_phyblock,
+                               delay_write->logblock, delay_write->pageoff);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       return STATUS_SUCCESS;
+}
+#endif
+
+int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+       u32 start_sector, u16 sector_cnt)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       unsigned int lun = SCSI_LUN(srb);
+#ifdef XD_DELAY_WRITE
+       struct xd_delay_write_tag *delay_write = &(xd_card->delay_write);
+#endif
+       int retval, zone_no;
+       unsigned int index = 0, offset = 0;
+       u32 log_blk, old_blk = 0, new_blk = 0;
+       u16 log_off, total_sec_cnt = sector_cnt;
+       u8 start_page, end_page = 0, page_cnt;
+       u8 *ptr;
+
+       xd_set_err_code(chip, XD_NO_ERROR);
+
+       xd_card->cleanup_counter = 0;
+
+       RTSX_DEBUGP("xd_rw: scsi_sg_count = %d\n", scsi_sg_count(srb));
+
+       ptr = (u8 *)scsi_sglist(srb);
+
+       retval = xd_switch_clock(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+
+       if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
+               chip->card_fail |= XD_CARD;
+               set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+               TRACE_RET(chip, STATUS_FAIL);
+       }
+
+       log_blk = start_sector >> xd_card->block_shift;
+       start_page = (u8)start_sector & xd_card->page_off;
+       zone_no = (int)(log_blk / 1000);
+       log_off = (u16)(log_blk % 1000);
+
+       if (xd_card->zone[zone_no].build_flag == 0) {
+               retval = xd_build_l2p_tbl(chip, zone_no);
+               if (retval != STATUS_SUCCESS) {
+                       chip->card_fail |= XD_CARD;
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       if (srb->sc_data_direction == DMA_TO_DEVICE) {
+#ifdef XD_DELAY_WRITE
+               if (delay_write->delay_write_flag &&
+                               (delay_write->logblock == log_blk) &&
+                               (start_page > delay_write->pageoff)) {
+                       delay_write->delay_write_flag = 0;
+                       if (delay_write->old_phyblock != BLK_NOT_FOUND) {
+                               retval = xd_copy_page(chip,
+                                       delay_write->old_phyblock,
+                                       delay_write->new_phyblock,
+                                       delay_write->pageoff, start_page);
+                               if (retval != STATUS_SUCCESS) {
+                                       set_sense_type(chip, lun,
+                                               SENSE_TYPE_MEDIA_WRITE_ERR);
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+                       }
+                       old_blk = delay_write->old_phyblock;
+                       new_blk = delay_write->new_phyblock;
+               } else if (delay_write->delay_write_flag &&
+                               (delay_write->logblock == log_blk) &&
+                               (start_page == delay_write->pageoff)) {
+                       delay_write->delay_write_flag = 0;
+                       old_blk = delay_write->old_phyblock;
+                       new_blk = delay_write->new_phyblock;
+               } else {
+                       retval = xd_delay_write(chip);
+                       if (retval != STATUS_SUCCESS) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+#endif
+                       old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
+                       new_blk  = xd_get_unused_block(chip, zone_no);
+                       if ((old_blk == BLK_NOT_FOUND) ||
+                               (new_blk == BLK_NOT_FOUND)) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+
+                       retval = xd_prepare_write(chip, old_blk, new_blk,
+                                               log_blk, start_page);
+                       if (retval != STATUS_SUCCESS) {
+                               if (detect_card_cd(chip, XD_CARD) !=
+                                       STATUS_SUCCESS) {
+                                       set_sense_type(chip, lun,
+                                               SENSE_TYPE_MEDIA_NOT_PRESENT);
+                                       TRACE_RET(chip, STATUS_FAIL);
+                               }
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+#ifdef XD_DELAY_WRITE
+               }
+#endif
+       } else {
+#ifdef XD_DELAY_WRITE
+               retval = xd_delay_write(chip);
+               if (retval != STATUS_SUCCESS) {
+                       if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_NOT_PRESENT);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+#endif
+
+               old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
+               if (old_blk == BLK_NOT_FOUND) {
+                       set_sense_type(chip, lun,
+                               SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+       }
+
+       RTSX_DEBUGP("old_blk = 0x%x\n", old_blk);
+
+       while (total_sec_cnt) {
+               if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
+                       chip->card_fail |= XD_CARD;
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if ((start_page + total_sec_cnt) > (xd_card->page_off + 1))
+                       end_page = xd_card->page_off + 1;
+               else
+                       end_page = start_page + (u8)total_sec_cnt;
+
+               page_cnt = end_page - start_page;
+               if (srb->sc_data_direction == DMA_FROM_DEVICE) {
+                       retval = xd_read_multiple_pages(chip, old_blk, log_blk,
+                                       start_page, end_page, ptr,
+                                                       &index, &offset);
+                       if (retval != STATUS_SUCCESS) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               } else {
+                       retval = xd_write_multiple_pages(chip, old_blk,
+                                                       new_blk, log_blk,
+                                       start_page, end_page, ptr,
+                                                       &index, &offset);
+                       if (retval != STATUS_SUCCESS) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               total_sec_cnt -= page_cnt;
+               if (scsi_sg_count(srb) == 0)
+                       ptr += page_cnt * 512;
+
+               if (total_sec_cnt == 0)
+                       break;
+
+               log_blk++;
+               zone_no = (int)(log_blk / 1000);
+               log_off = (u16)(log_blk % 1000);
+
+               if (xd_card->zone[zone_no].build_flag == 0) {
+                       retval = xd_build_l2p_tbl(chip, zone_no);
+                       if (retval != STATUS_SUCCESS) {
+                               chip->card_fail |= XD_CARD;
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_NOT_PRESENT);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
+               if (old_blk == BLK_NOT_FOUND) {
+                       if (srb->sc_data_direction == DMA_FROM_DEVICE)
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+                       else
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               if (srb->sc_data_direction == DMA_TO_DEVICE) {
+                       new_blk = xd_get_unused_block(chip, zone_no);
+                       if (new_blk == BLK_NOT_FOUND) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_WRITE_ERR);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+               }
+
+               start_page = 0;
+       }
+
+       if ((srb->sc_data_direction == DMA_TO_DEVICE) &&
+                       (end_page != (xd_card->page_off + 1))) {
+#ifdef XD_DELAY_WRITE
+               delay_write->delay_write_flag = 1;
+               delay_write->old_phyblock = old_blk;
+               delay_write->new_phyblock = new_blk;
+               delay_write->logblock = log_blk;
+               delay_write->pageoff = end_page;
+#else
+               if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
+                       chip->card_fail |= XD_CARD;
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+
+               retval = xd_finish_write(chip, old_blk, new_blk,
+                                       log_blk, end_page);
+               if (retval != STATUS_SUCCESS) {
+                       if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
+                               set_sense_type(chip, lun,
+                                       SENSE_TYPE_MEDIA_NOT_PRESENT);
+                               TRACE_RET(chip, STATUS_FAIL);
+                       }
+                       set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
+                       TRACE_RET(chip, STATUS_FAIL);
+               }
+#endif
+       }
+
+       scsi_set_resid(srb, 0);
+
+       return STATUS_SUCCESS;
+}
+
+void xd_free_l2p_tbl(struct rtsx_chip *chip)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int i = 0;
+
+       if (xd_card->zone != NULL) {
+               for (i = 0; i < xd_card->zone_cnt; i++) {
+                       if (xd_card->zone[i].l2p_table != NULL) {
+                               vfree(xd_card->zone[i].l2p_table);
+                               xd_card->zone[i].l2p_table = NULL;
+                       }
+                       if (xd_card->zone[i].free_table != NULL) {
+                               vfree(xd_card->zone[i].free_table);
+                               xd_card->zone[i].free_table = NULL;
+                       }
+               }
+               vfree(xd_card->zone);
+               xd_card->zone = NULL;
+       }
+}
+
+void xd_cleanup_work(struct rtsx_chip *chip)
+{
+#ifdef XD_DELAY_WRITE
+       struct xd_info *xd_card = &(chip->xd_card);
+
+       if (xd_card->delay_write.delay_write_flag) {
+               RTSX_DEBUGP("xD: delay write\n");
+               xd_delay_write(chip);
+               xd_card->cleanup_counter = 0;
+       }
+#endif
+}
+
+int xd_power_off_card3v3(struct rtsx_chip *chip)
+{
+       int retval;
+
+       retval = disable_card_clock(chip, XD_CARD);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       RTSX_WRITE_REG(chip, CARD_OE, XD_OUTPUT_EN, 0);
+
+       if (!chip->ft2_fast_mode) {
+               retval = card_power_off(chip, XD_CARD);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+
+               wait_timeout(50);
+       }
+
+       if (chip->asic_code) {
+               retval = xd_pull_ctl_disable(chip);
+               if (retval != STATUS_SUCCESS)
+                       TRACE_RET(chip, STATUS_FAIL);
+       } else {
+               RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, 0xDF);
+       }
+
+       return STATUS_SUCCESS;
+}
+
+int release_xd_card(struct rtsx_chip *chip)
+{
+       struct xd_info *xd_card = &(chip->xd_card);
+       int retval;
+
+       RTSX_DEBUGP("release_xd_card\n");
+
+       chip->card_ready &= ~XD_CARD;
+       chip->card_fail &= ~XD_CARD;
+       chip->card_wp &= ~XD_CARD;
+
+       xd_card->delay_write.delay_write_flag = 0;
+
+       xd_free_l2p_tbl(chip);
+
+       retval = xd_power_off_card3v3(chip);
+       if (retval != STATUS_SUCCESS)
+               TRACE_RET(chip, STATUS_FAIL);
+
+       return STATUS_SUCCESS;
+}
diff --git a/drivers/staging/rts5208/xd.h b/drivers/staging/rts5208/xd.h
new file mode 100644 (file)
index 0000000..938138c
--- /dev/null
@@ -0,0 +1,188 @@
+/* Driver for Realtek PCI-Express card reader
+ * Header file
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG (wei_wang@realsil.com.cn)
+ *   Micky Ching (micky_ching@realsil.com.cn)
+ */
+
+#ifndef __REALTEK_RTSX_XD_H
+#define __REALTEK_RTSX_XD_H
+
+#define        XD_DELAY_WRITE
+
+/* Error Codes */
+#define        XD_NO_ERROR                     0x00
+#define        XD_NO_MEMORY                    0x80
+#define        XD_PRG_ERROR                    0x40
+#define        XD_NO_CARD                      0x20
+#define        XD_READ_FAIL                    0x10
+#define        XD_ERASE_FAIL                   0x08
+#define        XD_WRITE_FAIL                   0x04
+#define        XD_ECC_ERROR                    0x02
+#define        XD_TO_ERROR                     0x01
+
+/* XD Commands */
+#define        READ1_1                         0x00
+#define        READ1_2                         0x01
+#define        READ2                           0x50
+#define READ_ID                                0x90
+#define RESET                          0xff
+#define PAGE_PRG_1                     0x80
+#define PAGE_PRG_2                     0x10
+#define        BLK_ERASE_1                     0x60
+#define        BLK_ERASE_2                     0xD0
+#define READ_STS                       0x70
+#define READ_xD_ID                     0x9A
+#define        COPY_BACK_512                   0x8A
+#define        COPY_BACK_2K                    0x85
+#define        READ1_1_2                       0x30
+#define        READ1_1_3                       0x35
+#define        CHG_DAT_OUT_1                   0x05
+#define RDM_DAT_OUT_1                  0x05
+#define        CHG_DAT_OUT_2                   0xE0
+#define RDM_DAT_OUT_2                  0xE0
+#define        CHG_DAT_OUT_2                   0xE0
+#define        CHG_DAT_IN_1                    0x85
+#define        CACHE_PRG                       0x15
+
+/* Redundant Area Related */
+#define XD_EXTRA_SIZE                  0x10
+#define XD_2K_EXTRA_SIZE               0x40
+
+#define        NOT_WRITE_PROTECTED             0x80
+#define        READY_STATE                     0x40
+#define        PROGRAM_ERROR                   0x01
+#define        PROGRAM_ERROR_N_1               0x02
+#define        INTERNAL_READY                  0x20
+#define        READY_FLAG                      0x5F
+
+#define        XD_8M_X8_512                    0xE6
+#define        XD_16M_X8_512                   0x73
+#define        XD_32M_X8_512                   0x75
+#define        XD_64M_X8_512                   0x76
+#define        XD_128M_X8_512                  0x79
+#define        XD_256M_X8_512                  0x71
+#define        XD_128M_X8_2048                 0xF1
+#define        XD_256M_X8_2048                 0xDA
+#define        XD_512M_X8                      0xDC
+#define        XD_128M_X16_2048                0xC1
+#define        XD_4M_X8_512_1                  0xE3
+#define        XD_4M_X8_512_2                  0xE5
+#define        xD_1G_X8_512                    0xD3
+#define        xD_2G_X8_512                    0xD5
+
+#define        XD_ID_CODE                      0xB5
+
+#define        VENDOR_BLOCK                    0xEFFF
+#define        CIS_BLOCK                       0xDFFF
+
+#define        BLK_NOT_FOUND                   0xFFFFFFFF
+
+#define        NO_NEW_BLK                      0xFFFFFFFF
+
+#define        PAGE_CORRECTABLE                0x0
+#define        PAGE_NOTCORRECTABLE             0x1
+
+#define        NO_OFFSET                       0x0
+#define        WITH_OFFSET                     0x1
+
+#define        Sect_Per_Page                   4
+#define        XD_ADDR_MODE_2C                 XD_ADDR_MODE_2A
+
+#define ZONE0_BAD_BLOCK                        23
+#define NOT_ZONE0_BAD_BLOCK            24
+
+#define        XD_RW_ADDR                      0x01
+#define        XD_ERASE_ADDR                   0x02
+
+#define        XD_PAGE_512(xd_card)            \
+do {                                   \
+       (xd_card)->block_shift = 5;     \
+       (xd_card)->page_off = 0x1F;     \
+} while (0)
+
+#define        XD_SET_BAD_NEWBLK(xd_card)      ((xd_card)->multi_flag |= 0x01)
+#define        XD_CLR_BAD_NEWBLK(xd_card)      ((xd_card)->multi_flag &= ~0x01)
+#define        XD_CHK_BAD_NEWBLK(xd_card)      ((xd_card)->multi_flag & 0x01)
+
+#define        XD_SET_BAD_OLDBLK(xd_card)      ((xd_card)->multi_flag |= 0x02)
+#define        XD_CLR_BAD_OLDBLK(xd_card)      ((xd_card)->multi_flag &= ~0x02)
+#define        XD_CHK_BAD_OLDBLK(xd_card)      ((xd_card)->multi_flag & 0x02)
+
+#define        XD_SET_MBR_FAIL(xd_card)        ((xd_card)->multi_flag |= 0x04)
+#define        XD_CLR_MBR_FAIL(xd_card)        ((xd_card)->multi_flag &= ~0x04)
+#define        XD_CHK_MBR_FAIL(xd_card)        ((xd_card)->multi_flag & 0x04)
+
+#define        XD_SET_ECC_FLD_ERR(xd_card)     ((xd_card)->multi_flag |= 0x08)
+#define        XD_CLR_ECC_FLD_ERR(xd_card)     ((xd_card)->multi_flag &= ~0x08)
+#define        XD_CHK_ECC_FLD_ERR(xd_card)     ((xd_card)->multi_flag & 0x08)
+
+#define        XD_SET_4MB(xd_card)             ((xd_card)->multi_flag |= 0x10)
+#define        XD_CLR_4MB(xd_card)             ((xd_card)->multi_flag &= ~0x10)
+#define        XD_CHK_4MB(xd_card)             ((xd_card)->multi_flag & 0x10)
+
+#define        XD_SET_ECC_ERR(xd_card)         ((xd_card)->multi_flag |= 0x40)
+#define        XD_CLR_ECC_ERR(xd_card)         ((xd_card)->multi_flag &= ~0x40)
+#define        XD_CHK_ECC_ERR(xd_card)         ((xd_card)->multi_flag & 0x40)
+
+#define PAGE_STATUS            0
+#define BLOCK_STATUS           1
+#define BLOCK_ADDR1_L          2
+#define BLOCK_ADDR1_H          3
+#define BLOCK_ADDR2_L          4
+#define BLOCK_ADDR2_H          5
+#define RESERVED0              6
+#define RESERVED1              7
+#define RESERVED2              8
+#define RESERVED3              9
+#define PARITY                 10
+
+#define        CIS0_0                  0
+#define        CIS0_1                  1
+#define        CIS0_2                  2
+#define        CIS0_3                  3
+#define        CIS0_4                  4
+#define        CIS0_5                  5
+#define        CIS0_6                  6
+#define        CIS0_7                  7
+#define        CIS0_8                  8
+#define        CIS0_9                  9
+#define        CIS1_0                  256
+#define        CIS1_1                  (256 + 1)
+#define        CIS1_2                  (256 + 2)
+#define        CIS1_3                  (256 + 3)
+#define        CIS1_4                  (256 + 4)
+#define        CIS1_5                  (256 + 5)
+#define        CIS1_6                  (256 + 6)
+#define        CIS1_7                  (256 + 7)
+#define        CIS1_8                  (256 + 8)
+#define        CIS1_9                  (256 + 9)
+
+int reset_xd_card(struct rtsx_chip *chip);
+#ifdef XD_DELAY_WRITE
+int xd_delay_write(struct rtsx_chip *chip);
+#endif
+int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
+       u32 start_sector, u16 sector_cnt);
+void xd_free_l2p_tbl(struct rtsx_chip *chip);
+void xd_cleanup_work(struct rtsx_chip *chip);
+int xd_power_off_card3v3(struct rtsx_chip *chip);
+int release_xd_card(struct rtsx_chip *chip);
+
+#endif  /* __REALTEK_RTSX_XD_H */
index ba0d23a1cfbe262f028e31dac3726f04a2395d36..dda1b2a6b84b85065f83a1df83d7d0c10c2d11bc 100644 (file)
@@ -47,13 +47,13 @@ static int do_cmd(struct net_device *dev, struct ifreq *ifr, int cmd, int *data)
 {
        int ret = -1;
        struct if_bypass *bypass_cb;
-       static int (*ioctl) (struct net_device *, struct ifreq *, int);
 
        bypass_cb = (struct if_bypass *)ifr;
        bypass_cb->cmd = cmd;
        bypass_cb->data = *data;
-       if ((dev->netdev_ops) && (ioctl = dev->netdev_ops->ndo_do_ioctl)) {
-               ret = ioctl(dev, ifr, SIOCGIFBYPASS);
+
+       if (dev->netdev_ops && dev->netdev_ops->ndo_do_ioctl) {
+               ret = dev->netdev_ops->ndo_do_ioctl(dev, ifr, SIOCGIFBYPASS);
                *data = bypass_cb->data;
        }
 
@@ -480,7 +480,6 @@ static int get_bypass_info(int if_index, struct bp_info *bp_info)
                SET_BPLIB_INT_FN2(get_bypass_info, int, if_index,
                                  struct bp_info *, bp_info, ret);
        } else {
-               static int (*ioctl) (struct net_device *, struct ifreq *, int);
                struct net_device *dev;
 
                struct net_device *n;
@@ -493,9 +492,10 @@ static int get_bypass_info(int if_index, struct bp_info *bp_info)
                                bypass_cb = (struct if_bypass_info *)&ifr;
                                bypass_cb->cmd = GET_BYPASS_INFO;
 
-                               if ((dev->netdev_ops) &&
-                                   (ioctl = dev->netdev_ops->ndo_do_ioctl)) {
-                                       ret = ioctl(dev, &ifr, SIOCGIFBYPASS);
+                               if (dev->netdev_ops &&
+                                       dev->netdev_ops->ndo_do_ioctl) {
+                                       ret = dev->netdev_ops->ndo_do_ioctl(dev,
+                                               &ifr, SIOCGIFBYPASS);
                                }
 
                                else
index 47502fa5f3f60a50db71b21a90be9dc9ce9c54ba..ef5933b935906365355b7031d5a70c6c705ca9b0 100644 (file)
@@ -37,8 +37,6 @@
 #include <linux/input.h>
 #include <linux/kmod.h>
 
-#include <linux/bootmem.h>     /* for alloc_bootmem */
-
 /* speakup_*_selection */
 #include <linux/module.h>
 #include <linux/sched.h>
index 135428856d47a88487ddb679a5db7ee7341f122c..4e18fb4053446382cc30e77bc7f7c08f03af92c0 100644 (file)
@@ -6,6 +6,10 @@
 #include "spk_priv.h"
 #include "serialio.h"
 
+#ifndef SERIAL_PORT_DFNS
+#define SERIAL_PORT_DFNS
+#endif
+
 static void start_serial_interrupt(int irq);
 
 static const struct old_serial_port rs_table[] = {
index 55d68b5ad1650d18fa3cf2fb2a5fe60f2f3536e4..0a937732a190f829e930bb558ef6ebfe0fabbaca 100644 (file)
@@ -36,30 +36,4 @@ struct old_serial_port {
 
 #define spk_serial_tx_busy() ((inb(speakup_info.port_tts + UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY)
 
-/* 2.6.22 doesn't have them any more, hardcode it for now (these values should
- * be fine for 99% cases) */
-#ifndef BASE_BAUD
-#define BASE_BAUD (1843200 / 16)
-#endif
-#ifndef STD_COM_FLAGS
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
-#endif
-#endif
-#ifndef SERIAL_PORT_DFNS
-#define SERIAL_PORT_DFNS                       \
-       /* UART CLK   PORT IRQ     FLAGS        */                      \
-       { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },      /* ttyS0 */     \
-       { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },      /* ttyS1 */     \
-       { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },      /* ttyS2 */     \
-       { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },     /* ttyS3 */
-#endif
-#ifndef IRQF_SHARED
-#define IRQF_SHARED SA_SHIRQ
-#endif
-
 #endif
index 165b918b8171b6380c4d8653d576a0bc085ecb99..1b6d581c438b56a970fdf1b08e52c94846c9d793 100644 (file)
@@ -4,7 +4,7 @@
 
 menuconfig TIDSPBRIDGE
        tristate "DSP Bridge driver"
-       depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM
+       depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM && BROKEN
        select MAILBOX
        select OMAP2PLUS_MBOX
        help
index 4a800dadd7036bda258a808d0e957b5d42be39c6..f961e0ec9da81c7ca5ee3e2f628887eb94d12017 100644 (file)
@@ -359,7 +359,7 @@ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id)
  *      Return the communication memory manager object for this device.
  *      This is typically called from the client process.
  */
-int cmm_get_handle(void *hprocessor, struct cmm_object ** ph_cmm_mgr)
+int cmm_get_handle(void *hprocessor, struct cmm_object **ph_cmm_mgr)
 {
        int status = 0;
        struct dev_object *hdev_obj;
@@ -449,8 +449,7 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr,
        struct cmm_mnode *new_node;
        s32 slot_seg;
 
-       dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x "
-                       "dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n",
+       dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n",
                        __func__, dw_gpp_base_pa, ul_size, dsp_addr_offset,
                        dw_dsp_base, ul_dsp_size, gpp_base_va);
 
@@ -828,7 +827,7 @@ int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va)
  *  Purpose:
  *      Set/Get translator info.
  */
-int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 ** paddr,
+int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 **paddr,
                           u32 ul_size, u32 segm_id, bool set_info)
 {
        struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
index 41e88abe47af1f518ddf7f0ac955d8ca0812203e..996a02d27d34b06f89fcb038af16c3a04a4a8f63 100644 (file)
@@ -378,8 +378,8 @@ int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr,
                opened_doff = false;
        }
 
-       dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p psize: %p, "
-               "status 0x%x\n", __func__, lib, name, paddr, psize, status);
+       dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p psize: %p, status 0x%x\n",
+                       __func__, lib, name, paddr, psize, status);
 
        return status;
 }
@@ -705,8 +705,8 @@ func_cont:
                opened_doff = false;
        }
 
-       dev_dbg(bridge, "%s: lib: %p name: %s buf: %p size: 0x%x, "
-               "status 0x%x\n", __func__, lib, name, buf, size, status);
+       dev_dbg(bridge, "%s: lib: %p name: %s buf: %p size: 0x%x, status 0x%x\n",
+                       __func__, lib, name, buf, size, status);
        return status;
 }
 
@@ -915,10 +915,10 @@ static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this,
                        status = dbll_get_addr((struct dbll_library_obj *)lib,
                                               (char *)name, &dbll_sym);
                        if (!status) {
-                               status =
-                                   dbll_get_c_addr((struct dbll_library_obj *)
-                                                   lib, (char *)name,
-                                                   &dbll_sym);
+                               status = dbll_get_c_addr(
+                                               (struct dbll_library_obj *)
+                                               lib, (char *)name,
+                                               &dbll_sym);
                        }
                }
        }
@@ -1172,8 +1172,7 @@ func_cont:
                if (!run_addr_flag)
                        info->run_addr = info->load_addr;
                info->context = (u32) rmm_addr_obj.segid;
-               dev_dbg(bridge, "%s: %s base = 0x%x len = 0x%x, "
-                       "info->run_addr 0x%x, info->load_addr 0x%x\n",
+               dev_dbg(bridge, "%s: %s base = 0x%x len = 0x%x, info->run_addr 0x%x, info->load_addr 0x%x\n",
                        __func__, info->name, info->load_addr / DSPWORDSIZE,
                        info->size / DSPWORDSIZE, info->run_addr,
                        info->load_addr);
@@ -1399,7 +1398,7 @@ void find_symbol_callback(void *elem, void *user_data)
  * @sym_addr_output:   Symbol Output address
  * @name_output:               String with the dsp symbol
  *
- *     This function retrieves the dsp symbol from the dsp binary.
+ *     This function retrieves the dsp symbol from the dsp binary.
  */
 bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address,
                                u32 offset_range, u32 *sym_addr_output,
index 6234ffb5e8a3998275ca6c7d3b93947df706a0e9..616dc1f63070c00a5aafd9851ebe7fd51a6757da 100644 (file)
@@ -606,7 +606,7 @@ int dev_get_node_manager(struct dev_object *hdev_obj,
  *  ======== dev_get_symbol ========
  */
 int dev_get_symbol(struct dev_object *hdev_obj,
-                         const char *str_sym, u32 * pul_value)
+                         const char *str_sym, u32 *pul_value)
 {
        int status = 0;
        struct cod_manager *cod_mgr;
@@ -916,8 +916,8 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
 
        /* Local helper macro: */
 #define  STORE_FXN(cast, pfn) \
-    (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \
-    (cast)fxn_not_implemented))
+       (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \
+                          (cast)fxn_not_implemented))
 
        bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version,
                                     drv_fxns->brd_api_minor_version);
index 7c9f83916068088497694b10e98cedc7bb5cec2f..fcf564aa566d4b94ecf34d45f11cad3ea1717a5f 100644 (file)
@@ -217,8 +217,8 @@ int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size)
                status = -ENOENT;
        spin_unlock(&dmm_obj->dmm_lock);
 
-       dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, "
-               "chunk %p", __func__, dmm_mgr, addr, size, status, chunk);
+       dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, chunk %p",
+                       __func__, dmm_mgr, addr, size, status, chunk);
 
        return status;
 }
@@ -268,9 +268,9 @@ int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size,
 
        spin_unlock(&dmm_obj->dmm_lock);
 
-       dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, "
-               "rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size,
-               prsv_addr, status, rsv_addr, rsv_size);
+       dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, rsv_addr %x, rsv_size %x\n",
+                       __func__, dmm_mgr, size,
+                       prsv_addr, status, rsv_addr, rsv_size);
 
        return status;
 }
@@ -299,8 +299,8 @@ int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize)
        }
        spin_unlock(&dmm_obj->dmm_lock);
 
-       dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, "
-               "chunk %p\n", __func__, dmm_mgr, addr, psize, status, chunk);
+       dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, chunk %p\n",
+                       __func__, dmm_mgr, addr, psize, status, chunk);
 
        return status;
 }
@@ -475,11 +475,11 @@ u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr)
                }
        }
        spin_unlock(&dmm_mgr->dmm_lock);
-       printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n",
+       dev_info(bridge, "Total DSP VA FREE memory = %d Mbytes\n",
               freemem / (1024 * 1024));
-       printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n",
+       dev_info(bridge, "Total DSP VA USED memory= %d Mbytes\n",
               (((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024));
-       printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n",
+       dev_info(bridge, "DSP VA - Biggest FREE block = %d Mbytes\n",
               (bigsize * PG_SIZE4K / (1024 * 1024)));
 
        return 0;
index 70db4ff99ec6f160ebfaf3cb75e598b46c81c5a8..b7d5c8cbb2a1e026cfc65604bccc745fc828f129 100644 (file)
@@ -162,7 +162,7 @@ static u8 size_cmd[] = {
        ARRAY_SIZE(cmm_cmd),
 };
 
-static inline void _cp_fm_usr(void *to, const void __user * from,
+static inline void _cp_fm_usr(void *to, const void __user *from,
                              int *err, unsigned long bytes)
 {
        if (*err)
@@ -507,7 +507,7 @@ u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt)
 /*
  * ======== MGRWRAP_GetProcessResourceInfo ========
  */
-u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args * args,
+u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args *args,
                                                    void *pr_ctxt)
 {
        pr_err("%s: deprecated dspbridge ioctl\n", __func__);
@@ -581,7 +581,7 @@ func_end:
 /*
  * ======== procwrap_detach ========
  */
-u32 __deprecated procwrap_detach(union trapped_args * args, void *pr_ctxt)
+u32 __deprecated procwrap_detach(union trapped_args *args, void *pr_ctxt)
 {
        /* proc_detach called at bridge_release only */
        pr_err("%s: deprecated dspbridge ioctl\n", __func__);
@@ -1564,7 +1564,7 @@ u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt)
 /*
  * ======== strmwrap_get_event_handle ========
  */
-u32 __deprecated strmwrap_get_event_handle(union trapped_args * args,
+u32 __deprecated strmwrap_get_event_handle(union trapped_args *args,
                                           void *pr_ctxt)
 {
        pr_err("%s: deprecated dspbridge ioctl\n", __func__);
@@ -1793,7 +1793,7 @@ u32 strmwrap_select(union trapped_args *args, void *pr_ctxt)
 /*
  * ======== cmmwrap_calloc_buf ========
  */
-u32 __deprecated cmmwrap_calloc_buf(union trapped_args * args, void *pr_ctxt)
+u32 __deprecated cmmwrap_calloc_buf(union trapped_args *args, void *pr_ctxt)
 {
        /* This operation is done in kernel */
        pr_err("%s: deprecated dspbridge ioctl\n", __func__);
@@ -1803,7 +1803,7 @@ u32 __deprecated cmmwrap_calloc_buf(union trapped_args * args, void *pr_ctxt)
 /*
  * ======== cmmwrap_free_buf ========
  */
-u32 __deprecated cmmwrap_free_buf(union trapped_args * args, void *pr_ctxt)
+u32 __deprecated cmmwrap_free_buf(union trapped_args *args, void *pr_ctxt)
 {
        /* This operation is done in kernel */
        pr_err("%s: deprecated dspbridge ioctl\n", __func__);
index db48a789d3085a4a53aee4624eecf5692632f5b8..5d1d4a18330016b83e5abf3276b938a4e682f05a 100644 (file)
@@ -102,11 +102,13 @@ static int tweak_clear_halt_cmd(struct urb *urb)
 
        ret = usb_clear_halt(urb->dev, target_pipe);
        if (ret < 0)
-               dev_err(&urb->dev->dev, "usb_clear_halt error: devnum %d endp "
-                       "%d ret %d\n", urb->dev->devnum, target_endp, ret);
+               dev_err(&urb->dev->dev,
+                       "usb_clear_halt error: devnum %d endp %d ret %d\n",
+                       urb->dev->devnum, target_endp, ret);
        else
-               dev_info(&urb->dev->dev, "usb_clear_halt done: devnum %d endp "
-                        "%d\n", urb->dev->devnum, target_endp);
+               dev_info(&urb->dev->dev,
+                        "usb_clear_halt done: devnum %d endp %d\n",
+                        urb->dev->devnum, target_endp);
 
        return ret;
 }
@@ -127,11 +129,13 @@ static int tweak_set_interface_cmd(struct urb *urb)
 
        ret = usb_set_interface(urb->dev, interface, alternate);
        if (ret < 0)
-               dev_err(&urb->dev->dev, "usb_set_interface error: inf %u alt "
-                       "%u ret %d\n", interface, alternate, ret);
+               dev_err(&urb->dev->dev,
+                       "usb_set_interface error: inf %u alt %u ret %d\n",
+                       interface, alternate, ret);
        else
-               dev_info(&urb->dev->dev, "usb_set_interface done: inf %u alt "
-                        "%u\n", interface, alternate);
+               dev_info(&urb->dev->dev,
+                       "usb_set_interface done: inf %u alt %u\n",
+                       interface, alternate);
 
        return ret;
 }
index e3fc749c1e7e016b217d627d8a5aedeb767fcb97..4470cd321d650b469fe60e724ada16d2e543f297 100644 (file)
@@ -155,8 +155,9 @@ static void usbip_dump_usb_device(struct usb_device *udev)
 
        dev_dbg(dev, "parent %p, bus %p\n", udev->parent, udev->bus);
 
-       dev_dbg(dev, "descriptor %p, config %p, actconfig %p, "
-               "rawdescriptors %p\n", &udev->descriptor, udev->config,
+       dev_dbg(dev,
+               "descriptor %p, config %p, actconfig %p, rawdescriptors %p\n",
+               &udev->descriptor, udev->config,
                udev->actconfig, udev->rawdescriptors);
 
        dev_dbg(dev, "have_langid %d, string_langid %d\n",
index e810ad53e2acfe519a448eedc84830fcc547afae..aa22c631191c3e22d34b0ccd99f1934e5f004f0d 100644 (file)
@@ -220,8 +220,7 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc)
        memset(desc, 0, sizeof(*desc));
        desc->bDescriptorType = 0x29;
        desc->bDescLength = 9;
-       desc->wHubCharacteristics = (__force __u16)
-               (__constant_cpu_to_le16(0x0001));
+       desc->wHubCharacteristics = (__constant_cpu_to_le16(0x0001));
        desc->bNbrPorts = VHCI_NPORTS;
        desc->u.hs.DeviceRemovable[0] = 0xff;
        desc->u.hs.DeviceRemovable[1] = 0xff;
@@ -348,8 +347,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                        USB_PORT_STAT_ENABLE;
                        }
                }
-               ((u16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]);
-               ((u16 *) buf)[1] = cpu_to_le16(dum->port_status[rhport] >> 16);
+               ((__le16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]);
+               ((__le16 *) buf)[1] = cpu_to_le16(dum->port_status[rhport] >> 16);
 
                usbip_dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0],
                                  ((u16 *)buf)[1]);
@@ -537,7 +536,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
                        goto no_need_xmit;
 
                case USB_REQ_GET_DESCRIPTOR:
-                       if (ctrlreq->wValue == (USB_DT_DEVICE << 8))
+                       if (ctrlreq->wValue == cpu_to_le16(USB_DT_DEVICE << 8))
                                usbip_dbg_vhci_hc("Not yet?: "
                                                  "Get_Descriptor to device 0 "
                                                  "(get max pipe size)\n");
@@ -1108,7 +1107,7 @@ static struct platform_driver vhci_driver = {
        .suspend = vhci_hcd_suspend,
        .resume = vhci_hcd_resume,
        .driver = {
-               .name = (char *) driver_name,
+               .name = driver_name,
                .owner = THIS_MODULE,
        },
 };
@@ -1125,7 +1124,7 @@ static void the_pdev_release(struct device *dev)
 
 static struct platform_device the_pdev = {
        /* should be the same name as driver_name */
-       .name = (char *) driver_name,
+       .name = driver_name,
        .id = -1,
        .dev = {
                .release = the_pdev_release,
index 959568a1eb6a03da7260685acec030f8ccebeebf..fa14659ba43cf49a2950593813eb033e61fd646e 100644 (file)
@@ -1865,7 +1865,7 @@ BBvCalculateParameter(
                break;
 
        case RATE_5M:
-               if (bCCK == false)
+               if (!bCCK)
                        cbBitCount++;
                cbUsCount = (cbBitCount * 10) / 55;
                cbTmp = (cbUsCount * 55) / 10;
@@ -1879,7 +1879,7 @@ BBvCalculateParameter(
 
        case RATE_11M:
 
-               if (bCCK == false)
+               if (!bCCK)
                        cbBitCount++;
                cbUsCount = cbBitCount / 11;
                cbTmp = cbUsCount * 11;
index a23b591eeac3d7432a73e78990342ef0ce65c15d..d7efd0173a9a42a6ddd810c631cecebae4f23215 100644 (file)
@@ -64,7 +64,6 @@
 
 /*---------------------  Static Variables  --------------------------*/
 static int msglevel = MSG_LEVEL_INFO;
-//static int          msglevel                =MSG_LEVEL_DEBUG;
 
 const unsigned short awHWRetry0[5][5] = {
        {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
@@ -131,27 +130,26 @@ BSSpSearchBSSList(
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
                        "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID);
                if ((!is_broadcast_ether_addr(pbyDesireBSSID)) &&
-                   (memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0)) {
+                   (memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0))
                        pbyBSSID = pbyDesireBSSID;
-               }
        }
        if (pbyDesireSSID != NULL) {
-               if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) {
+               if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0)
                        pSSID = (PWLAN_IE_SSID) pbyDesireSSID;
-               }
        }
 
        if (pbyBSSID != NULL) {
-               // match BSSID first
+               /* match BSSID first */
                for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                        pCurrBSS = &(pMgmt->sBSSList[ii]);
-                       if (pDevice->bLinkPass == false) pCurrBSS->bSelected = false;
+                       if (!pDevice->bLinkPass)
+                               pCurrBSS->bSelected = false;
                        if ((pCurrBSS->bActive) &&
-                           (pCurrBSS->bSelected == false)) {
+                           (!pCurrBSS->bSelected)) {
                                if (ether_addr_equal(pCurrBSS->abyBSSID,
                                                     pbyBSSID)) {
                                        if (pSSID != NULL) {
-                                               // compare ssid
+                                               /* compare ssid */
                                                if (!memcmp(pSSID->abySSID,
                                                            ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
                                                            pSSID->len)) {
@@ -176,26 +174,26 @@ BSSpSearchBSSList(
                        }
                }
        } else {
-               // ignore BSSID
+               /* ignore BSSID */
                for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                        pCurrBSS = &(pMgmt->sBSSList[ii]);
-                       //2007-0721-01<Add>by MikeLiu
+                       /* 2007-0721-01<Add>by MikeLiu */
                        pCurrBSS->bSelected = false;
                        if (pCurrBSS->bActive) {
                                if (pSSID != NULL) {
-                                       // matched SSID
+                                       /* matched SSID */
                                        if (!!memcmp(pSSID->abySSID,
                                                     ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
                                                     pSSID->len) ||
                                            (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) {
-                                               // SSID not match skip this BSS
+                                               /* SSID not match skip this BSS */
                                                continue;
                                        }
                                }
                                if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) ||
                                    ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo))
 ) {
-                                       // Type not match skip this BSS
+                                       /* Type not match skip this BSS */
                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo);
                                        continue;
                                }
@@ -203,50 +201,23 @@ BSSpSearchBSSList(
                                if (ePhyType != PHY_TYPE_AUTO) {
                                        if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) ||
                                            ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) {
-                                               // PhyType not match skip this BSS
+                                               /* PhyType not match skip this BSS */
                                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse);
                                                continue;
                                        }
                                }
-/*
-  if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) {
-  if (pCurrBSS->bWPAValid == true) {
-  // WPA AP will reject connection of station without WPA enable.
-  continue;
-  }
-  } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
-  (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
-  if (pCurrBSS->bWPAValid == false) {
-  // station with WPA enable can't join NonWPA AP.
-  continue;
-  }
-  } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
-  (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
-  if (pCurrBSS->bWPA2Valid == false) {
-  // station with WPA2 enable can't join NonWPA2 AP.
-  continue;
-  }
-  }
-*/
+
                                if (pSelect == NULL) {
                                        pSelect = pCurrBSS;
                                } else {
-                                       // compare RSSI, select signal strong one
-                                       if (pCurrBSS->uRSSI < pSelect->uRSSI) {
+                                       /* compare RSSI, select signal strong one */
+                                       if (pCurrBSS->uRSSI < pSelect->uRSSI)
                                                pSelect = pCurrBSS;
-                                       }
                                }
                        }
                }
                if (pSelect != NULL) {
                        pSelect->bSelected = true;
-/*
-  if (pDevice->bRoaming == false)  {
-  //       Einsn Add @20070907
-  memset(pbyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-  memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-  }*/
-
                        return pSelect;
                }
        }
@@ -278,7 +249,6 @@ BSSvClearBSSList(
                        if (pMgmt->sBSSList[ii].bActive &&
                            ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
                                             pMgmt->abyCurrBSSID)) {
-                               // bKeepCurrBSSID = false;
                                continue;
                        }
                }
@@ -385,7 +355,7 @@ BSSbInsertToBSSList(
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n");
                return false;
        }
-       // save the BSS info
+       /* save the BSS info */
        pBSSList->bActive = true;
        memcpy(pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN);
        HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
@@ -416,15 +386,14 @@ BSSbInsertToBSSList(
        pBSSList->sERP.byERP = psERP->byERP;
        pBSSList->sERP.bERPExist = psERP->bERPExist;
 
-       // Check if BSS is 802.11a/b/g
+       /* check if BSS is 802.11a/b/g */
        if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
                pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
        } else {
-               if (pBSSList->sERP.bERPExist == true) {
+               if (pBSSList->sERP.bERPExist)
                        pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
-               } else {
+               else
                        pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
-               }
        }
 
        pBSSList->byRxRate = pRxPacket->byRxRate;
@@ -434,10 +403,9 @@ BSSbInsertToBSSList(
 
        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
            (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
-               // assoc with BSS
-               if (pBSSList == pMgmt->pCurrBSS) {
+               /* assoc with BSS */
+               if (pBSSList == pMgmt->pCurrBSS)
                        bParsingQuiet = true;
-               }
        }
 
        WPA_ClearRSN(pBSSList);
@@ -463,7 +431,7 @@ BSSbInsertToBSSList(
                }
        }
 
-       if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == true)) {
+       if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || pBSSList->bWPA2Valid) {
                PSKeyItem  pTransmitKey = NULL;
                bool bIs802_1x = false;
 
@@ -473,13 +441,13 @@ BSSbInsertToBSSList(
                                break;
                        }
                }
-               if ((bIs802_1x == true) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) &&
+               if (bIs802_1x && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) &&
                    (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) {
                        bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj);
 
-                       if ((pDevice->bLinkPass == true) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
-                               if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) ||
-                                   (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == true)) {
+                       if (pDevice->bLinkPass && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+                               if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) ||
+                                   KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey)) {
                                        pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList;
                                        pDevice->gsPMKIDCandidate.Version = 1;
 
@@ -490,7 +458,7 @@ BSSbInsertToBSSList(
        }
 
        if (pDevice->bUpdateBBVGA) {
-               // Moniter if RSSI is too strong.
+               /* monitor if RSSI is too strong */
                pBSSList->byRSSIStatCnt = 0;
                RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &pBSSList->ldBmMAX);
                pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX;
@@ -498,16 +466,15 @@ BSSbInsertToBSSList(
                        pBSSList->ldBmAverage[ii] = 0;
        }
 
-       if ((pIE_Country != NULL) &&
-           (pMgmt->b11hEnable == true)) {
+       if ((pIE_Country != NULL) && pMgmt->b11hEnable) {
                set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
                                 pIE_Country);
        }
 
-       if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) {
+       if (bParsingQuiet && (pIE_Quiet != NULL)) {
                if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
                    (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
-                       // valid EID
+                       /* valid EID */
                        if (pQuiet == NULL) {
                                pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
                                CARDbSetQuiet(pMgmt->pAdapter,
@@ -530,8 +497,7 @@ BSSbInsertToBSSList(
                }
        }
 
-       if ((bParsingQuiet == true) &&
-           (pQuiet != NULL)) {
+       if (bParsingQuiet && (pQuiet != NULL)) {
                CARDbStartQuiet(pMgmt->pAdapter);
        }
 
@@ -552,7 +518,7 @@ BSSbInsertToBSSList(
  *    true if success.
  *
  -*/
-// TODO: input structure modify
+/* TODO: input structure modify */
 
 bool
 BSSbUpdateToBSSList(
@@ -593,7 +559,6 @@ BSSbUpdateToBSSList(
        pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
        pBSSList->uClearCount = 0;
        pBSSList->uChannel = byCurrChannel;
-//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel);
 
        if (pSSID->len > WLAN_SSID_MAXLEN)
                pSSID->len = WLAN_SSID_MAXLEN;
@@ -602,23 +567,21 @@ BSSbUpdateToBSSList(
                memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
        memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN);
 
-       if (pExtSuppRates != NULL) {
+       if (pExtSuppRates != NULL)
                memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN);
-       } else {
+       else
                memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
-       }
        pBSSList->sERP.byERP = psERP->byERP;
        pBSSList->sERP.bERPExist = psERP->bERPExist;
 
-       // Check if BSS is 802.11a/b/g
+       /* check if BSS is 802.11a/b/g */
        if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
                pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
        } else {
-               if (pBSSList->sERP.bERPExist == true) {
+               if (pBSSList->sERP.bERPExist)
                        pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
-               } else {
+               else
                        pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
-               }
        }
 
        pBSSList->byRxRate = pRxPacket->byRxRate;
@@ -629,13 +592,12 @@ BSSbUpdateToBSSList(
 
        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
            (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
-               // assoc with BSS
-               if (pBSSList == pMgmt->pCurrBSS) {
+               /* assoc with BSS */
+               if (pBSSList == pMgmt->pCurrBSS)
                        bParsingQuiet = true;
-               }
        }
 
-       WPA_ClearRSN(pBSSList);         //mike update
+       WPA_ClearRSN(pBSSList);         /* mike update */
 
        if (pRSNWPA != NULL) {
                unsigned int uLen = pRSNWPA->len + 2;
@@ -646,7 +608,7 @@ BSSbUpdateToBSSList(
                }
        }
 
-       WPA2_ClearRSN(pBSSList);  //mike update
+       WPA2_ClearRSN(pBSSList);  /* mike update */
 
        if (pRSN != NULL) {
                unsigned int uLen = pRSN->len + 2;
@@ -659,27 +621,25 @@ BSSbUpdateToBSSList(
 
        if (pRxPacket->uRSSI != 0) {
                RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &ldBm);
-               // Moniter if RSSI is too strong.
+               /* monitor if RSSI is too strong */
                pBSSList->byRSSIStatCnt++;
                pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT;
                pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm;
                for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
-                       if (pBSSList->ldBmAverage[ii] != 0) {
+                       if (pBSSList->ldBmAverage[ii] != 0)
                                pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm);
-                       }
                }
        }
 
-       if ((pIE_Country != NULL) &&
-           (pMgmt->b11hEnable == true)) {
+       if ((pIE_Country != NULL) && pMgmt->b11hEnable) {
                set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
                                 pIE_Country);
        }
 
-       if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) {
+       if (bParsingQuiet && (pIE_Quiet != NULL)) {
                if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
                    (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
-                       // valid EID
+                       /* valid EID */
                        if (pQuiet == NULL) {
                                pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
                                CARDbSetQuiet(pMgmt->pAdapter,
@@ -702,8 +662,7 @@ BSSbUpdateToBSSList(
                }
        }
 
-       if ((bParsingQuiet == true) &&
-           (pQuiet != NULL)) {
+       if (bParsingQuiet && (pQuiet != NULL)) {
                CARDbStartQuiet(pMgmt->pAdapter);
        }
 
@@ -732,7 +691,7 @@ BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr,
        PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
        unsigned int ii;
 
-       // Index = 0 reserved for AP Node
+       /* Index = 0 reserved for AP Node */
        for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
                if (pMgmt->sNodeDBTable[ii].bActive) {
                        if (ether_addr_equal(abyDstAddr,
@@ -765,8 +724,10 @@ BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex)
        unsigned int BigestCount = 0;
        unsigned int SelectIndex;
        struct sk_buff  *skb;
-       // Index = 0 reserved for AP Node (In STA mode)
-       // Index = 0 reserved for Broadcast/MultiCast (In AP mode)
+       /*
+        * Index = 0 reserved for AP Node (In STA mode)
+        * Index = 0 reserved for Broadcast/MultiCast (In AP mode)
+        */
        SelectIndex = 1;
        for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
                if (pMgmt->sNodeDBTable[ii].bActive) {
@@ -779,11 +740,11 @@ BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex)
                }
        }
 
-       // if not found replace uInActiveCount is largest one.
+       /* if not found replace uInActiveCount is largest one */
        if (ii == (MAX_NODE_NUM + 1)) {
                *puNodeIndex = SelectIndex;
                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", SelectIndex);
-               // clear ps buffer
+               /* clear ps buffer */
                if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) {
                        while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL)
                                dev_kfree_skb(skb);
@@ -795,7 +756,7 @@ BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex)
        memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB));
        pMgmt->sNodeDBTable[*puNodeIndex].bActive = true;
        pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND;
-       // for AP mode PS queue
+       /* for AP mode PS queue */
        skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
        pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
        pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
@@ -826,9 +787,9 @@ BSSvRemoveOneNode(
 
        while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL)
                dev_kfree_skb(skb);
-       // clear context
+       /* clear context */
        memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB));
-       // clear tx bit map
+       /* clear tx bit map */
        pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &=  ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7];
 
        return;
@@ -859,9 +820,8 @@ BSSvUpdateAPNode(
        memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
 
        pMgmt->sNodeDBTable[0].bActive = true;
-       if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
+       if (pDevice->eCurrentPHYType == PHY_TYPE_11B)
                uRateLen = WLAN_RATES_MAXLEN_11B;
-       }
        pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates,
                                                (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
                                                uRateLen);
@@ -882,12 +842,10 @@ BSSvUpdateAPNode(
        pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate;
        pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo);
        pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
-#ifdef PLICE_DEBUG
-       printk("BSSvUpdateAPNode:MaxSuppRate is %d\n", pMgmt->sNodeDBTable[0].wMaxSuppRate);
-#endif
-       // Auto rate fallback function initiation.
-       // RATEbInit(pDevice);
-       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate);
+       netdev_dbg(pDevice->dev, "BSSvUpdateAPNode:MaxSuppRate is %d\n",
+                  pMgmt->sNodeDBTable[0].wMaxSuppRate);
+       /* auto rate fallback function initiation */
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->sNodeDBTable[0].wTxDataRate = %d\n", pMgmt->sNodeDBTable[0].wTxDataRate);
 };
 
 /*+
@@ -926,9 +884,9 @@ BSSvAddMulticastNode(
                          &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
 );
        pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate;
-#ifdef PLICE_DEBUG
-       printk("BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate);
-#endif
+       netdev_dbg(pDevice->dev,
+                  "BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n",
+                  pMgmt->sNodeDBTable[0].wTxDataRate);
        pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
 };
 
@@ -944,7 +902,7 @@ BSSvAddMulticastNode(
  *    none.
  *
  -*/
-//2008-4-14 <add> by chester for led issue
+/* 2008-4-14 <add> by chester for led issue */
 #ifdef FOR_LED_ON_NOTEBOOK
 bool cc = false;
 unsigned int status;
@@ -961,7 +919,7 @@ BSSvSecondCallBack(
        unsigned int uSleepySTACnt = 0;
        unsigned int uNonShortSlotSTACnt = 0;
        unsigned int uLongPreambleSTACnt = 0;
-       viawget_wpa_header *wpahdr;  //DavidWang
+       viawget_wpa_header *wpahdr;  /* DavidWang */
 
        spin_lock_irq(&pDevice->lock);
 
@@ -969,51 +927,47 @@ BSSvSecondCallBack(
 
        pDevice->byERPFlag &=
                ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
-       //2008-4-14 <add> by chester for led issue
+       /* 2008-4-14 <add> by chester for led issue */
 #ifdef FOR_LED_ON_NOTEBOOK
        MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
-       if (((!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->bHWRadioOff == false)) || ((pDevice->byGPIO & GPIO0_DATA) && (pDevice->bHWRadioOff == true))) && (cc == false)) {
+       if (((!(pDevice->byGPIO & GPIO0_DATA) && (!pDevice->bHWRadioOff)) ||
+            ((pDevice->byGPIO & GPIO0_DATA) && pDevice->bHWRadioOff)) &&
+           (!cc)) {
                cc = true;
-       } else if (cc == true) {
-               if (pDevice->bHWRadioOff == true) {
-                       if (!(pDevice->byGPIO & GPIO0_DATA))
-//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
-                       {
-                               if (status == 1) goto start;
+       } else if (cc) {
+               if (pDevice->bHWRadioOff) {
+                       if (!(pDevice->byGPIO & GPIO0_DATA)) {
+                               if (status == 1)
+                                       goto start;
                                status = 1;
                                CARDbRadioPowerOff(pDevice);
                                pMgmt->sNodeDBTable[0].bActive = false;
                                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
                                pMgmt->eCurrState = WMAC_STATE_IDLE;
-                               //netif_stop_queue(pDevice->dev);
                                pDevice->bLinkPass = false;
 
                        }
-                       if (pDevice->byGPIO & GPIO0_DATA)
-//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
-                       {
-                               if (status == 2) goto start;
+                       if (pDevice->byGPIO & GPIO0_DATA) {
+                               if (status == 2)
+                                       goto start;
                                status = 2;
                                CARDbRadioPowerOn(pDevice);
                        }
                } else {
-                       if (pDevice->byGPIO & GPIO0_DATA)
-//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
-                       {
-                               if (status == 3) goto start;
+                       if (pDevice->byGPIO & GPIO0_DATA) {
+                               if (status == 3)
+                                       goto start;
                                status = 3;
                                CARDbRadioPowerOff(pDevice);
                                pMgmt->sNodeDBTable[0].bActive = false;
                                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
                                pMgmt->eCurrState = WMAC_STATE_IDLE;
-                               //netif_stop_queue(pDevice->dev);
                                pDevice->bLinkPass = false;
 
                        }
-                       if (!(pDevice->byGPIO & GPIO0_DATA))
-//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
-                       {
-                               if (status == 4) goto start;
+                       if (!(pDevice->byGPIO & GPIO0_DATA)) {
+                               if (status == 4)
+                                       goto start;
                                status = 4;
                                CARDbRadioPowerOn(pDevice);
                        }
@@ -1025,14 +979,15 @@ start:
        if (pDevice->wUseProtectCntDown > 0) {
                pDevice->wUseProtectCntDown--;
        } else {
-               // disable protect mode
+               /* disable protect mode */
                pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
        }
 
        {
                pDevice->byReAssocCount++;
-               if ((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != true)) {  //10 sec timeout
-                       printk("Re-association timeout!!!\n");
+               /* 10 sec timeout */
+               if ((pDevice->byReAssocCount > 10) && (!pDevice->bLinkPass)) {
+                       netdev_info(pDevice->dev, "Re-association timeout!!!\n");
                        pDevice->byReAssocCount = 0;
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
                        {
@@ -1043,7 +998,7 @@ start:
                                wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
                        }
 #endif
-               } else if (pDevice->bLinkPass == true)
+               } else if (pDevice->bLinkPass)
                        pDevice->byReAssocCount = 0;
        }
 
@@ -1053,7 +1008,7 @@ start:
 
        for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
                if (pMgmt->sNodeDBTable[ii].bActive) {
-                       // Increase in-activity counter
+                       /* increase in-activity counter */
                        pMgmt->sNodeDBTable[ii].uInActiveCount++;
 
                        if (ii > 0) {
@@ -1067,7 +1022,7 @@ start:
                                if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) {
                                        pDevice->uAssocCount++;
 
-                                       // check if Non ERP exist
+                                       /* check if Non ERP exist */
                                        if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) {
                                                if (!pMgmt->sNodeDBTable[ii].bShortPreamble) {
                                                        pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
@@ -1082,43 +1037,39 @@ start:
                                        }
                                }
 
-                               // check if any STA in PS mode
+                               /* check if any STA in PS mode */
                                if (pMgmt->sNodeDBTable[ii].bPSEnable)
                                        uSleepySTACnt++;
 
                        }
 
-                       // Rate fallback check
+                       /* rate fallback check */
                        if (!pDevice->bFixRate) {
-/*
-  if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0))
-  RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii]));
-*/
                                if (ii > 0) {
-                                       // ii = 0 for multicast node (AP & Adhoc)
+                                       /* ii = 0 for multicast node (AP & Adhoc) */
                                        RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii]));
                                } else {
-                                       // ii = 0 reserved for unicast AP node (Infra STA)
+                                       /* ii = 0 reserved for unicast AP node (Infra STA) */
                                        if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)
-#ifdef PLICE_DEBUG
-                                               printk("SecondCallback:Before:TxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate);
-#endif
+                                               netdev_dbg(pDevice->dev,
+                                                          "SecondCallback:Before:TxDataRate is %d\n",
+                                                          pMgmt->sNodeDBTable[0].wTxDataRate);
                                        RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii]));
-#ifdef PLICE_DEBUG
-                                       printk("SecondCallback:After:TxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate);
-#endif
+                                       netdev_dbg(pDevice->dev,
+                                                  "SecondCallback:After:TxDataRate is %d\n",
+                                                  pMgmt->sNodeDBTable[0].wTxDataRate);
 
                                }
 
                        }
 
-                       // check if pending PS queue
+                       /* check if pending PS queue */
                        if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
-                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n",
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending\n",
                                        ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
                                if ((ii > 0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) {
                                        BSSvRemoveOneNode(pDevice, ii);
-                                       DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii);
+                                       DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove\n", ii);
                                        continue;
                                }
                        }
@@ -1127,7 +1078,7 @@ start:
        }
 
        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->eCurrentPHYType == PHY_TYPE_11G)) {
-               // on/off protect mode
+               /* on/off protect mode */
                if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
                        if (!pDevice->bProtectMode) {
                                MACvEnableProtectMD(pDevice->PortOffset);
@@ -1139,7 +1090,7 @@ start:
                                pDevice->bProtectMode = false;
                        }
                }
-               // on/off short slot time
+               /* on/off short slot time */
 
                if (uNonShortSlotSTACnt > 0) {
                        if (pDevice->bShortSlotTime) {
@@ -1155,7 +1106,7 @@ start:
                        }
                }
 
-               // on/off barker long preamble mode
+               /* on/off barker long preamble mode */
 
                if (uLongPreambleSTACnt > 0) {
                        if (!pDevice->bBarkerPreambleMd) {
@@ -1171,7 +1122,7 @@ start:
 
        }
 
-       // Check if any STA in PS mode, enable DTIM multicast deliver
+       /* check if any STA in PS mode, enable DTIM multicast deliver */
        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
                if (uSleepySTACnt > 0)
                        pMgmt->sNodeDBTable[0].bPSEnable = true;
@@ -1184,11 +1135,10 @@ start:
 
        if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
            (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
-               if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
-                       if (pDevice->bUpdateBBVGA) {
-                               // s_vCheckSensitivity((void *) pDevice);
+               /* assoc with BSS */
+               if (pMgmt->sNodeDBTable[0].bActive) {
+                       if (pDevice->bUpdateBBVGA)
                                s_vCheckPreEDThreshold((void *)pDevice);
-                       }
 
                        if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) &&
                            (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) {
@@ -1232,12 +1182,18 @@ start:
                        if (pDevice->uAutoReConnectTime < 10) {
                                pDevice->uAutoReConnectTime++;
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-                               //network manager support need not do Roaming scan???
-                               if (pDevice->bWPASuppWextEnabled == true)
+                               /*
+                                * network manager support need not do
+                                * Roaming scan???
+                                */
+                               if (pDevice->bWPASuppWextEnabled)
                                        pDevice->uAutoReConnectTime = 0;
 #endif
                        } else {
-                               //mike use old encryption status for wpa reauthen
+                               /*
+                                * mike use old encryption status
+                                * for wpa reauthentication
+                                */
                                if (pDevice->bWPADEVUp)
                                        pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus;
 
@@ -1252,7 +1208,7 @@ start:
        }
 
        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
-               // if adhoc started which essid is NULL string, rescanning.
+               /* if adhoc started which essid is NULL string, rescanning */
                if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) {
                        if (pDevice->uAutoReConnectTime < 10) {
                                pDevice->uAutoReConnectTime++;
@@ -1262,13 +1218,11 @@ start:
                                bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
                                bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
                                pDevice->uAutoReConnectTime = 0;
-                       };
+                       }
                }
                if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
-                       if (pDevice->bUpdateBBVGA) {
-                               //s_vCheckSensitivity((void *) pDevice);
+                       if (pDevice->bUpdateBBVGA)
                                s_vCheckPreEDThreshold((void *)pDevice);
-                       }
                        if (pMgmt->sNodeDBTable[0].uInActiveCount >= ADHOC_LOST_BEACON_COUNT) {
                                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
                                pMgmt->sNodeDBTable[0].uInActiveCount = 0;
@@ -1318,40 +1272,31 @@ BSSvUpdateNodeTxCounter(
        unsigned short wFallBackRate = RATE_1M;
        unsigned char byFallBack;
        unsigned int ii;
-//     unsigned int txRetryTemp;
-//PLICE_DEBUG->
-       //txRetryTemp = byTxRetry;
-//PLICE_DEBUG <-
        pTxBufHead = (PSTxBufHead) pbyBuffer;
-       if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) {
+       if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0)
                byFallBack = AUTO_FB_0;
-       } else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) {
+       else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1)
                byFallBack = AUTO_FB_1;
-       } else {
+       else
                byFallBack = AUTO_FB_NONE;
-       }
-       wRate = pTxBufHead->wReserved; //?wRate
+       wRate = pTxBufHead->wReserved;
 
-       // Only Unicast using support rates
+       /* Only Unicast using support rates */
        if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) {
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1);
                if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
                        pMgmt->sNodeDBTable[0].uTxAttempts += 1;
                        if ((byTsr1 & TSR1_TERR) == 0) {
-                               // transmit success, TxAttempts at least plus one
+                               /* transmit success, TxAttempts at least plus one */
                                pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++;
                                if ((byFallBack == AUTO_FB_NONE) ||
                                    (wRate < RATE_18M)) {
                                        wFallBackRate = wRate;
                                } else if (byFallBack == AUTO_FB_0) {
-//PLICE_DEBUG
                                        if (byTxRetry < 5)
                                                wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
-                                       //wFallBackRate = awHWRetry0[wRate-RATE_12M][byTxRetry];
-                                       //wFallBackRate = awHWRetry0[wRate-RATE_18M][txRetryTemp] +1;
                                        else
                                                wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
-                                       //wFallBackRate = awHWRetry0[wRate-RATE_12M][4];
                                } else if (byFallBack == AUTO_FB_1) {
                                        if (byTxRetry < 5)
                                                wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
@@ -1369,18 +1314,11 @@ BSSvUpdateNodeTxCounter(
                                    (wRate < RATE_18M)) {
                                        pMgmt->sNodeDBTable[0].uTxFail[wRate] += byTxRetry;
                                } else if (byFallBack == AUTO_FB_0) {
-//PLICE_DEBUG
-                                       for (ii = 0; ii < byTxRetry; ii++)
-                                               //for (ii=0;ii<txRetryTemp;ii++)
-                                       {
-                                               if (ii < 5) {
-//PLICE_DEBUG
+                                       for (ii = 0; ii < byTxRetry; ii++) {
+                                               if (ii < 5)
                                                        wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
-                                                       //wFallBackRate = awHWRetry0[wRate-RATE_12M][ii];
-                                               } else {
+                                               else
                                                        wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
-                                                       //wFallBackRate = awHWRetry0[wRate-RATE_12M][4];
-                                               }
                                                pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
                                        }
                                } else if (byFallBack == AUTO_FB_1) {
@@ -1402,7 +1340,7 @@ BSSvUpdateNodeTxCounter(
                        if (BSSDBbIsSTAInNodeDB((void *)pMgmt,  &(pMACHeader->abyAddr1[0]), &uNodeIndex)) {
                                pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1;
                                if ((byTsr1 & TSR1_TERR) == 0) {
-                                       // transmit success, TxAttempts at least plus one
+                                       /* transmit success, TxAttempts at least plus one */
                                        pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
                                        if ((byFallBack == AUTO_FB_NONE) ||
                                            (wRate < RATE_18M)) {
@@ -1485,7 +1423,7 @@ BSSvClearNodeDBTable(
 
        for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) {
                if (pMgmt->sNodeDBTable[ii].bActive) {
-                       // check if sTxPSQueue has been initial
+                       /* check if sTxPSQueue has been initial */
                        if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) {
                                while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii);
@@ -1517,7 +1455,7 @@ void s_vCheckSensitivity(
            ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
                pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
                if (pBSSList != NULL) {
-                       // Updata BB Reg if RSSI is too strong.
+                       /* Update BB Reg if RSSI is too strong */
                        long    LocalldBmAverage = 0;
                        long    uNumofdBm = 0;
                        for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
@@ -1556,9 +1494,8 @@ BSSvClearAnyBSSJoinRecord(
        PSMgmtObject    pMgmt = pDevice->pMgmt;
        unsigned int ii;
 
-       for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+       for (ii = 0; ii < MAX_BSS_NUM; ii++)
                pMgmt->sBSSList[ii].bSelected = false;
-       }
        return;
 }
 
@@ -1580,19 +1517,18 @@ void s_uCalculateLinkQual(
                pDevice->scStatistic.RxOkCnt;
        TxOkRatio = (TxCnt < 6) ? 4000 : ((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt);
        RxOkRatio = (RxCnt < 6) ? 2000 : ((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt);
-//decide link quality
-       if (pDevice->bLinkPass != true) {
+       /* decide link quality */
+       if (!pDevice->bLinkPass) {
                pDevice->scStatistic.LinkQuality = 0;
                pDevice->scStatistic.SignalStren = 0;
        } else {
                RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm);
-               if (-ldBm < 50)  {
+               if (-ldBm < 50)
                        RssiRatio = 4000;
-               } else if (-ldBm > 90) {
+               else if (-ldBm > 90)
                        RssiRatio = 0;
-               } else {
+               else
                        RssiRatio = (40-(-ldBm-50))*4000/40;
-               }
                pDevice->scStatistic.SignalStren = RssiRatio/40;
                pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100;
        }
@@ -1616,10 +1552,8 @@ void s_vCheckPreEDThreshold(
        if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
            ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
                pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
-               if (pBSSList != NULL) {
+               if (pBSSList != NULL)
                        pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1);
-                       //BBvUpdatePreEDThreshold(pDevice, false);
-               }
        }
        return;
 }
index fbf18e23e78ecb3230cbf45787f3bf91bcc6610b..db38ca05113064a8e9879b328f8ee8d272653974 100644 (file)
@@ -1053,7 +1053,7 @@ CARDbAdd_PMKID_Candidate(
        for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
                pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
                if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
-                       if ((bRSNCapExist == true) && (wRSNCap & BIT0)) {
+                       if (bRSNCapExist && (wRSNCap & BIT0)) {
                                pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
                        } else {
                                pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
@@ -1064,7 +1064,7 @@ CARDbAdd_PMKID_Candidate(
 
        // New Candidate
        pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
-       if ((bRSNCapExist == true) && (wRSNCap & BIT0)) {
+       if (bRSNCapExist && (wRSNCap & BIT0)) {
                pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
        } else {
                pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
@@ -1190,7 +1190,7 @@ CARDbStartMeasure(
                }
        } while (pDevice->uNumOfMeasureEIDs != 0);
 
-       if (bExpired == false) {
+       if (!bExpired) {
                MACvSelectPage1(pDevice->PortOffset);
                VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, LODWORD(qwStartTSF));
                VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, HIDWORD(qwStartTSF));
@@ -1280,7 +1280,7 @@ CARDbSetQuiet(
        PSDevice    pDevice = (PSDevice) pDeviceHandler;
        unsigned int ii = 0;
 
-       if (bResetQuiet == true) {
+       if (bResetQuiet) {
                MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
                for (ii = 0; ii < MAX_QUIET_COUNT; ii++) {
                        pDevice->sQuiet[ii].bEnable = false;
@@ -2013,7 +2013,7 @@ QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2)
                HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2) - 1;
        } else {
                HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2);
-       };
+       }
        return qwTSFOffset;
 }
 
index ba9481fa654f137e0b6dd54e746174ad6cc2ac70..3198a31e2ed7a3726e091e303e2ec6a2fdab1043 100644 (file)
@@ -441,8 +441,8 @@ void init_channel_table(void *pDeviceHandler)
                break;
        }
 
-       if ((pDevice->dwDiagRefCount != 0) || (pDevice->b11hEnable == true)) {
-               if (bMultiBand == true) {
+       if ((pDevice->dwDiagRefCount != 0) || pDevice->b11hEnable) {
+               if (bMultiBand) {
                        for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) {
                                sChannelTbl[ii + 1].bValid = true;
                                pDevice->abyRegPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1];
@@ -463,7 +463,7 @@ void init_channel_table(void *pDeviceHandler)
                        }
                }
        } else if (pDevice->byZoneType <= CCODE_MAX) {
-               if (bMultiBand == true) {
+               if (bMultiBand) {
                        for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) {
                                if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
                                        sChannelTbl[ii + 1].bValid = true;
@@ -531,7 +531,7 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel)
                return bResult;
        }
 
-       if (sChannelTbl[uConnectionChannel].bValid == false) {
+       if (!sChannelTbl[uConnectionChannel].bValid) {
                return false;
        }
 
@@ -557,7 +557,7 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel)
        bResult &= RFbSelectChannel(pDevice->PortOffset, pDevice->byRFType, (unsigned char)uConnectionChannel);
 
        // Init Synthesizer Table
-       if (pDevice->bEnablePSMode == true)
+       if (pDevice->bEnablePSMode)
                RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel);
 
        //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDbSetMediaChannel: %d\n", (unsigned char)uConnectionChannel);
@@ -766,7 +766,7 @@ unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType)
 
        if (ePHYType == PHY_TYPE_11A) {
                for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) {
-                       if (sChannelTbl[ii].bValid == true) {
+                       if (sChannelTbl[ii].bValid) {
                                if (byOptionChannel == 0) {
                                        byOptionChannel = (unsigned char) ii;
                                }
@@ -780,7 +780,7 @@ unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType)
        } else {
                byOptionChannel = 0;
                for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) {
-                       if (sChannelTbl[ii].bValid == true) {
+                       if (sChannelTbl[ii].bValid) {
                                if (sChannelTbl[ii].byMAP == 0) {
                                        aiWeight[ii] += 100;
                                } else if (sChannelTbl[ii].byMAP & 0x01) {
@@ -807,7 +807,7 @@ unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType)
                        }
                }
                for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) {
-                       if ((sChannelTbl[ii].bValid == true) &&
+                       if (sChannelTbl[ii].bValid &&
                            (aiWeight[ii] > aiWeight[byOptionChannel])) {
                                byOptionChannel = (unsigned char) ii;
                        }
index e7b6bc7de4ac20ffa233293e7278c815356c27fc..c9a89cd7633cfacfe6594d33e9d86cad8fff92f4 100644 (file)
@@ -218,8 +218,7 @@ RATEvParseMaxRate(
 
        for (ii = 0; ii < uRateLen; ii++) {
                byRate = (unsigned char)(pItemRates->abyRates[ii]);
-               if (WLAN_MGMT_IS_BASICRATE(byRate) &&
-                   (bUpdateBasicRate == true))  {
+               if (WLAN_MGMT_IS_BASICRATE(byRate) && bUpdateBasicRate)  {
                        // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
                        CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate));
                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
@@ -329,7 +328,7 @@ RATEvTxRateFallBack(
 
        for (ii = 0; ii < MAX_RATE; ii++) {
                if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
-                       if (bAutoRate[ii] == true) {
+                       if (bAutoRate[ii]) {
                                wIdxUpRate = (unsigned short) ii;
                        }
                } else {
@@ -354,8 +353,7 @@ RATEvTxRateFallBack(
        wIdxDownRate = psNodeDBTable->wTxDataRate;
        for (ii = psNodeDBTable->wTxDataRate; ii > 0;) {
                ii--;
-               if ((dwThroughputTbl[ii] > dwThroughput) &&
-                   (bAutoRate[ii] == true)) {
+               if ((dwThroughputTbl[ii] > dwThroughput) && bAutoRate[ii]) {
                        dwThroughput = dwThroughputTbl[ii];
                        wIdxDownRate = (unsigned short) ii;
                }
index e93fdc88d84456ed52a8cb6cdaf9c02289c695c2..68cbaee2977518670a7bf608cfe889cf18fb40e6 100644 (file)
@@ -561,7 +561,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
                        pDevice->byTxAntennaMode = ANT_B;
                        pDevice->dwTxAntennaSel = 1;
                        pDevice->dwRxAntennaSel = 1;
-                       if (pDevice->bTxRxAntInv == true)
+                       if (pDevice->bTxRxAntInv)
                                pDevice->byRxAntennaMode = ANT_A;
                        else
                                pDevice->byRxAntennaMode = ANT_B;
@@ -578,13 +578,13 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
                        pDevice->dwRxAntennaSel = 0;
                        if (byValue & EEP_ANTENNA_AUX) {
                                pDevice->byTxAntennaMode = ANT_A;
-                               if (pDevice->bTxRxAntInv == true)
+                               if (pDevice->bTxRxAntInv)
                                        pDevice->byRxAntennaMode = ANT_B;
                                else
                                        pDevice->byRxAntennaMode = ANT_A;
                        } else {
                                pDevice->byTxAntennaMode = ANT_B;
-                               if (pDevice->bTxRxAntInv == true)
+                               if (pDevice->bTxRxAntInv)
                                        pDevice->byRxAntennaMode = ANT_A;
                                else
                                        pDevice->byRxAntennaMode = ANT_B;
@@ -635,7 +635,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
                pDevice->byRFType &= RF_MASK;
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
 
-               if (pDevice->bZoneRegExist == false) {
+               if (!pDevice->bZoneRegExist) {
                        pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
                }
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
@@ -742,7 +742,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
                        if (!(pDevice->byGPIO & GPIO0_DATA)) { pDevice->bHWRadioOff = false; }
 
                }
-               if ((pDevice->bRadioControlOff == true)) {
+               if (pDevice->bRadioControlOff) {
                        CARDbRadioPowerOff(pDevice);
                } else  CARDbRadioPowerOn(pDevice);
 #else
@@ -751,7 +751,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
                        pDevice->bHWRadioOff = true;
                }
        }
-       if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) {
+       if (pDevice->bHWRadioOff || pDevice->bRadioControlOff) {
                CARDbRadioPowerOff(pDevice);
        }
 
@@ -809,7 +809,7 @@ static bool device_release_WPADEV(PSDevice pDevice)
        int ii = 0;
        // wait_queue_head_t    Set_wait;
        //send device close to wpa_supplicnat layer
-       if (pDevice->bWPADEVUp == true) {
+       if (pDevice->bWPADEVUp) {
                wpahdr = (viawget_wpa_header *)pDevice->skb->data;
                wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
                wpahdr->resp_ie_len = 0;
@@ -826,7 +826,7 @@ static bool device_release_WPADEV(PSDevice pDevice)
                //wait release WPADEV
                //    init_waitqueue_head(&Set_wait);
                //    wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ);    //1s wait
-               while ((pDevice->bWPADEVUp == true)) {
+               while (pDevice->bWPADEVUp) {
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        schedule_timeout(HZ / 20);          //wait 50ms
                        ii++;
@@ -892,7 +892,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
 #ifdef DEBUG
        printk("Before get pci_info memaddr is %x\n", pDevice->memaddr);
 #endif
-       if (device_get_pci_info(pDevice, pcid) == false) {
+       if (!device_get_pci_info(pDevice, pcid)) {
                printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device.\n");
                device_free_info(pDevice);
                return -ENODEV;
@@ -1633,7 +1633,7 @@ static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) {
                        bFull = true;
                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]);
                }
-               if (netif_queue_stopped(pDevice->dev) && (bFull == false)) {
+               if (netif_queue_stopped(pDevice->dev) && !bFull) {
                        netif_wake_queue(pDevice->dev);
                }
        }
@@ -1798,7 +1798,7 @@ static int  device_open(struct net_device *dev) {
        pDevice->byReAssocCount = 0;
        pDevice->bWPADEVUp = false;
        // Patch: if WEP key already set by iwconfig but device not yet open
-       if ((pDevice->bEncryptionEnable == true) && (pDevice->bTransmitKey == true)) {
+       if (pDevice->bEncryptionEnable && pDevice->bTransmitKey) {
                KeybSetDefaultKey(&(pDevice->sKey),
                                  (unsigned long)(pDevice->byKeyIndex | (1 << 31)),
                                  pDevice->uKeyLength,
@@ -1895,7 +1895,7 @@ static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
                return 0;
        }
 
-       if (pDevice->bStopTx0Pkt == true) {
+       if (pDevice->bStopTx0Pkt) {
                dev_kfree_skb_irq(skb);
                spin_unlock_irq(&pDevice->lock);
                return 0;
@@ -1924,7 +1924,7 @@ bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeI
        SKeyItem        STempKey;
 //    unsigned char byKeyIndex = 0;
 
-       if (pDevice->bStopTx0Pkt == true) {
+       if (pDevice->bStopTx0Pkt) {
                dev_kfree_skb_irq(skb);
                return false;
        }
@@ -1993,14 +1993,14 @@ bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeI
        } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
                byPktType = PK_TYPE_11A;
        } else {
-               if (pDevice->bProtectMode == true) {
+               if (pDevice->bProtectMode) {
                        byPktType = PK_TYPE_11GB;
                } else {
                        byPktType = PK_TYPE_11GA;
                }
        }
 
-       if (pDevice->bEncryptionEnable == true)
+       if (pDevice->bEncryptionEnable)
                bNeedEncryption = true;
 
        if (pDevice->bEnableHostWEP) {
@@ -2076,7 +2076,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
        bool bNodeExist = false;
 
        spin_lock_irq(&pDevice->lock);
-       if (pDevice->bLinkPass == false) {
+       if (!pDevice->bLinkPass) {
                dev_kfree_skb_irq(skb);
                spin_unlock_irq(&pDevice->lock);
                return 0;
@@ -2130,7 +2130,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                        }
                }
 
-               if (bNodeExist == false) {
+               if (!bNodeExist) {
                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Unknown STA not found in node DB \n");
                        dev_kfree_skb_irq(skb);
                        spin_unlock_irq(&pDevice->lock);
@@ -2149,7 +2149,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                cbFrameBodySize += 8;
        }
 
-       if (pDevice->bEncryptionEnable == true) {
+       if (pDevice->bEncryptionEnable) {
                bNeedEncryption = true;
                // get Transmit key
                do {
@@ -2196,7 +2196,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
 
        if (pDevice->bEnableHostWEP) {
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "acdma0: STA index %d\n", uNodeIndex);
-               if (pDevice->bEncryptionEnable == true) {
+               if (pDevice->bEncryptionEnable) {
                        pTransmitKey = &STempKey;
                        pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
                        pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
@@ -2286,7 +2286,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
        } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
                byPktType = PK_TYPE_11A;
        } else {
-               if (pDevice->bProtectMode == true) {
+               if (pDevice->bProtectMode) {
                        byPktType = PK_TYPE_11GB;
                } else {
                        byPktType = PK_TYPE_11GA;
@@ -2297,7 +2297,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
 //     printk("FIX RATE:CurrentRate is %d");
 //#endif
 
-       if (bNeedEncryption == true) {
+       if (bNeedEncryption) {
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
                if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
                        bNeedEncryption = false;
@@ -2306,7 +2306,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                                if (pTransmitKey == NULL) {
                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Don't Find TX KEY\n");
                                } else {
-                                       if (bTKIP_UseGTK == true) {
+                                       if (bTKIP_UseGTK) {
                                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "error: KEY is GTK!!~~\n");
                                        } else {
                                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
@@ -2493,7 +2493,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                                MACvSelectPage0(pDevice->PortOffset);
                                //xxxx
                                // WCMDbFlushCommandQueue(pDevice->pMgmt, true);
-                               if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel) == true) {
+                               if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel)) {
                                        pDevice->bMeasureInProgress = true;
                                        MACvSelectPage1(pDevice->PortOffset);
                                        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY);
@@ -2544,12 +2544,12 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                        if (pDevice->dwIsr & ISR_QUIETSTART) {
                                do {
                                        ;
-                               } while (CARDbStartQuiet(pDevice) == false);
+                               } while (!CARDbStartQuiet(pDevice));
                        }
                }
 
                if (pDevice->dwIsr & ISR_TBTT) {
-                       if (pDevice->bEnableFirstQuiet == true) {
+                       if (pDevice->bEnableFirstQuiet) {
                                pDevice->byQuietStartCount--;
                                if (pDevice->byQuietStartCount == 0) {
                                        pDevice->bEnableFirstQuiet = false;
@@ -2558,7 +2558,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                                        MACvSelectPage0(pDevice->PortOffset);
                                }
                        }
-                       if ((pDevice->bChannelSwitch == true) &&
+                       if (pDevice->bChannelSwitch &&
                            (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)) {
                                pDevice->byChannelSwitchCount--;
                                if (pDevice->byChannelSwitchCount == 0) {
@@ -2575,7 +2575,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                        if (pDevice->eOPMode == OP_MODE_ADHOC) {
                                //pDevice->bBeaconSent = false;
                        } else {
-                               if ((pDevice->bUpdateBBVGA) && (pDevice->bLinkPass == true) && (pDevice->uCurrRSSI != 0)) {
+                               if ((pDevice->bUpdateBBVGA) && pDevice->bLinkPass && (pDevice->uCurrRSSI != 0)) {
                                        long            ldBm;
 
                                        RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm);
@@ -2642,7 +2642,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                        }
                        pDevice->bBeaconSent = true;
 
-                       if (pDevice->bChannelSwitch == true) {
+                       if (pDevice->bChannelSwitch) {
                                pDevice->byChannelSwitchCount--;
                                if (pDevice->byChannelSwitchCount == 0) {
                                        pDevice->bChannelSwitch = false;
@@ -3237,7 +3237,7 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
                        netif_stop_queue(pDevice->dev);
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
                        pMgmt->eScanType = WMAC_SCAN_ACTIVE;
-                       if (pDevice->bWPASuppWextEnabled != true)
+                       if (!pDevice->bWPASuppWextEnabled)
 #endif
                                bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
                        bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
@@ -3373,7 +3373,7 @@ viawget_resume(struct pci_dev *pcid)
                spin_lock_irq(&pDevice->lock);
                MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext);
                device_init_registers(pDevice, DEVICE_INIT_DXPL);
-               if (pMgmt->sNodeDBTable[0].bActive == true) { // Assoc with BSS
+               if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
                        pMgmt->sNodeDBTable[0].bActive = false;
                        pDevice->bLinkPass = false;
                        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
index 0ff51cb4a207eeb045720a3884be0eebefc11823..0a29c901541912abb0f8975227da43e5125cc7ef 100644 (file)
@@ -169,7 +169,7 @@ s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr,
                }
        } else {
                cbHeaderSize += WLAN_HDR_ADDR3_LEN;
-       };
+       }
 
        pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize);
        if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) {
@@ -263,7 +263,7 @@ s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize,
                                psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii];
                        }
                }
-       };
+       }
        *pcbHeaderSize = cbHeaderSize;
 }
 
@@ -379,7 +379,7 @@ device_receive_frame(
 
        pMACHeader = (PS802_11Header)((unsigned char *)(skb->data) + 8);
 //PLICE_DEBUG<-
-       if (pDevice->bMeasureInProgress == true) {
+       if (pDevice->bMeasureInProgress) {
                if ((*pbyRsr & RSR_CRCOK) != 0) {
                        pDevice->byBasicMap |= 0x01;
                }
@@ -436,7 +436,7 @@ device_receive_frame(
        }
 
        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
-               if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == true) {
+               if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex)) {
                        return false;
                }
        }
@@ -592,7 +592,7 @@ device_receive_frame(
                        }
                } else {
                        // Control Frame
-               };
+               }
                return false;
        } else {
                if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
@@ -608,8 +608,7 @@ device_receive_frame(
                        }
                } else {
                        // discard DATA packet while not associate || BSSID error
-                       if ((pDevice->bLinkPass == false) ||
-                           !(*pbyRsr & RSR_BSSIDOK)) {
+                       if (!pDevice->bLinkPass || !(*pbyRsr & RSR_BSSIDOK)) {
                                if (bDeFragRx) {
                                        if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
                                                DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n",
@@ -658,7 +657,7 @@ device_receive_frame(
        // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps
        if (pDevice->bDiversityEnable && (FrameSize > 50) &&
            (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
-           (pDevice->bLinkPass == true)) {
+           pDevice->bLinkPass) {
                BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0);
        }
 
@@ -683,7 +682,7 @@ device_receive_frame(
 
        // -----------------------------------------------
 
-       if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == true)) {
+       if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnable8021x) {
                unsigned char abyMacHdr[24];
 
                // Only 802.1x packet incoming allowed
@@ -698,7 +697,7 @@ device_receive_frame(
                if (wEtherType == ETH_P_PAE) {
                        skb->dev = pDevice->apdev;
 
-                       if (bIsWEP == true) {
+                       if (bIsWEP) {
                                // strip IV header(8)
                                memcpy(&abyMacHdr[0], (skb->data + 4), 24);
                                memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24);
@@ -770,8 +769,9 @@ device_receive_frame(
                        //DBG_PRN_GRP12(("LocalL: %lx, LocalR: %lx\n", dwLocalMIC_L, dwLocalMIC_R));
                        //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwMICKey0= %lx,dwMICKey1= %lx \n", dwMICKey0, dwMICKey1);
 
-                       if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
-                           (pDevice->bRxMICFail == true)) {
+                       if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) ||
+                           (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
+                           pDevice->bRxMICFail) {
                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC comparison is fail!\n");
                                pDevice->bRxMICFail = false;
                                //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++;
@@ -894,13 +894,13 @@ device_receive_frame(
                return false;
 
        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
-               if (s_bAPModeRxData(pDevice,
+               if (!s_bAPModeRxData(pDevice,
                                    skb,
                                    FrameSize,
                                    cbHeaderOffset,
                                    iSANodeIndex,
                                    iDANodeIndex
-) == false) {
+)) {
                        if (bDeFragRx) {
                                if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
                                        DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n",
@@ -1123,7 +1123,7 @@ static bool s_bHandleRxEncryption(
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey == NULL\n");
                if (byDecMode == KEY_CTL_WEP) {
 //            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
-               } else if (pDevice->bLinkPass == true) {
+               } else if (pDevice->bLinkPass) {
 //            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
                }
                return false;
@@ -1131,7 +1131,7 @@ static bool s_bHandleRxEncryption(
        if (byDecMode != pKey->byCipherSuite) {
                if (byDecMode == KEY_CTL_WEP) {
 //            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
-               } else if (pDevice->bLinkPass == true) {
+               } else if (pDevice->bLinkPass) {
 //            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
                }
                *pKeyOut = NULL;
@@ -1234,7 +1234,7 @@ static bool s_bHostWepRxEncryption(
        if (byDecMode != pKey->byCipherSuite) {
                if (byDecMode == KEY_CTL_WEP) {
 //            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
-               } else if (pDevice->bLinkPass == true) {
+               } else if (pDevice->bLinkPass) {
 //            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
                }
                return false;
@@ -1245,7 +1245,7 @@ static bool s_bHostWepRxEncryption(
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byDecMode == KEY_CTL_WEP \n");
                if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
                    (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) ||
-                   (bOnFly == false)) {
+                   !bOnFly) {
                        // Software WEP
                        // 1. 3253A
                        // 2. WEP 256
@@ -1277,7 +1277,7 @@ static bool s_bHostWepRxEncryption(
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC0_15: %x\n", *pwRxTSC15_0);
 
                if (byDecMode == KEY_CTL_TKIP) {
-                       if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == false)) {
+                       if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || !bOnFly) {
                                // Software TKIP
                                // 1. 3253 A
                                // 2. NotOnFly
@@ -1297,7 +1297,7 @@ static bool s_bHostWepRxEncryption(
                }
 
                if (byDecMode == KEY_CTL_CCMP) {
-                       if (bOnFly == false) {
+                       if (!bOnFly) {
                                // Software CCMP
                                // NotOnFly
                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_CCMP\n");
index aab0012bba92909611659b78ef982d48aec82cfb..ca54b793f9f0273413cb7049cd656349de2cfe4b 100644 (file)
@@ -143,7 +143,8 @@ static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked)
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
                        pDevice->dev->name, pDevice->apdev->name);
        }
-       free_netdev(pDevice->apdev);
+       if (pDevice->apdev)
+               free_netdev(pDevice->apdev);
        pDevice->apdev = NULL;
        pDevice->bEnable8021x = false;
        pDevice->bEnableHostWEP = false;
@@ -494,11 +495,11 @@ static int hostap_set_encryption(PSDevice pDevice,
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg);
 
        if (param->u.crypt.alg == WPA_ALG_NONE) {
-               if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == true) {
-                       if (KeybRemoveKey(&(pDevice->sKey),
+               if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly) {
+                       if (!KeybRemoveKey(&(pDevice->sKey),
                                          param->sta_addr,
                                          pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex,
-                                         pDevice->PortOffset) == false) {
+                                         pDevice->PortOffset)) {
                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
                        }
                        pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
@@ -556,7 +557,7 @@ static int hostap_set_encryption(PSDevice pDevice,
                                       (unsigned char *)abyKey,
                                       KEY_CTL_WEP,
                                       pDevice->PortOffset,
-                                      pDevice->byLocalID) == true) {
+                                      pDevice->byLocalID)) {
                                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;
 
                        } else {
@@ -623,7 +624,7 @@ static int hostap_set_encryption(PSDevice pDevice,
                               (unsigned char *)abyKey,
                               byKeyDecMode,
                               pDevice->PortOffset,
-                              pDevice->byLocalID) == true) {
+                              pDevice->byLocalID)) {
                        pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;
 
                } else {
@@ -635,7 +636,7 @@ static int hostap_set_encryption(PSDevice pDevice,
 
        }
 
-       if (bKeyTableFull == true) {
+       if (bKeyTableFull) {
                wKeyCtl &= 0x7F00;              // clear all key control filed
                wKeyCtl |= (byKeyDecMode << 4);
                wKeyCtl |= (byKeyDecMode);
index 4bff8aa96be71689c707f858f4aed6f20d1acb17..2db4bc88e45ebc23822047956b553ee836b38041 100644 (file)
@@ -1632,7 +1632,7 @@ int iwctl_giwsens(struct net_device *dev,
                wrq->value = ldBm;
        } else {
                wrq->value = 0;
-       };
+       }
        wrq->disabled = (wrq->value == 0);
        wrq->fixed = 1;
 
index 04c1304d16e59105b9616029bc6da2a2db0f8abc..eab3b41f9e3c77b1c7d41fa18a29c56d8a17d901 100644 (file)
@@ -64,13 +64,12 @@ s_vCheckKeyTableValid(PSKeyManagement pTable, unsigned long dwIoBase)
        int i;
 
        for (i = 0; i < MAX_KEY_TABLE; i++) {
-               if ((pTable->KeyTable[i].bInUse == true) &&
-                   (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) &&
-                   (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) &&
-                   (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) &&
-                   (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) &&
-                   (pTable->KeyTable[i].GroupKey[3].bKeyValid == false)
-) {
+               if (pTable->KeyTable[i].bInUse &&
+                   !pTable->KeyTable[i].PairwiseKey.bKeyValid &&
+                   !pTable->KeyTable[i].GroupKey[0].bKeyValid &&
+                   !pTable->KeyTable[i].GroupKey[1].bKeyValid &&
+                   !pTable->KeyTable[i].GroupKey[2].bKeyValid &&
+                   !pTable->KeyTable[i].GroupKey[3].bKeyValid) {
                        pTable->KeyTable[i].bInUse = false;
                        pTable->KeyTable[i].wKeyCtl = 0;
                        pTable->KeyTable[i].bSoftWEP = false;
@@ -140,17 +139,17 @@ bool KeybGetKey(
 
        *pKey = NULL;
        for (i = 0; i < MAX_KEY_TABLE; i++) {
-               if ((pTable->KeyTable[i].bInUse == true) &&
+               if (pTable->KeyTable[i].bInUse &&
                    ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        if (dwKeyIndex == 0xFFFFFFFF) {
-                               if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
+                               if (pTable->KeyTable[i].PairwiseKey.bKeyValid) {
                                        *pKey = &(pTable->KeyTable[i].PairwiseKey);
                                        return true;
                                } else {
                                        return false;
                                }
                        } else if (dwKeyIndex < MAX_GROUP_KEY) {
-                               if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == true) {
+                               if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid) {
                                        *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]);
                                        return true;
                                } else {
@@ -202,12 +201,11 @@ bool KeybSetKey(
 
        j = (MAX_KEY_TABLE-1);
        for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {
-               if ((pTable->KeyTable[i].bInUse == false) &&
-                   (j == (MAX_KEY_TABLE-1))) {
+               if (!pTable->KeyTable[i].bInUse && (j == (MAX_KEY_TABLE-1))) {
                        // found empty table
                        j = i;
                }
-               if ((pTable->KeyTable[i].bInUse == true) &&
+               if (pTable->KeyTable[i].bInUse &&
                    ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        // found table already exist
                        if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
@@ -384,7 +382,7 @@ bool KeybRemoveKey(
        }
 
        for (i = 0; i < MAX_KEY_TABLE; i++) {
-               if ((pTable->KeyTable[i].bInUse == true) &&
+               if (pTable->KeyTable[i].bInUse &&
                    ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                                pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
@@ -428,7 +426,7 @@ bool KeybRemoveAllKey(
        int i, u;
 
        for (i = 0; i < MAX_KEY_TABLE; i++) {
-               if ((pTable->KeyTable[i].bInUse == true) &&
+               if (pTable->KeyTable[i].bInUse &&
                    ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
                        for (u = 0; u < MAX_GROUP_KEY; u++) {
@@ -461,7 +459,7 @@ void KeyvRemoveWEPKey(
 )
 {
        if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
-               if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == true) {
+               if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse) {
                        if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) {
                                pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
                                if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) {
@@ -511,10 +509,10 @@ bool KeybGetTransmitKey(
 
        *pKey = NULL;
        for (i = 0; i < MAX_KEY_TABLE; i++) {
-               if ((pTable->KeyTable[i].bInUse == true) &&
+               if (pTable->KeyTable[i].bInUse &&
                    ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        if (dwKeyType == PAIRWISE_KEY) {
-                               if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
+                               if (pTable->KeyTable[i].PairwiseKey.bKeyValid) {
                                        *pKey = &(pTable->KeyTable[i].PairwiseKey);
 
                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:");
@@ -535,7 +533,7 @@ bool KeybGetTransmitKey(
                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ERROR: dwGTKeyIndex == 0 !!!\n");
                                        return false;
                                }
-                               if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) {
+                               if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid) {
                                        *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
 
                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:");
@@ -583,8 +581,8 @@ bool KeybCheckPairewiseKey(
 
        *pKey = NULL;
        for (i = 0; i < MAX_KEY_TABLE; i++) {
-               if ((pTable->KeyTable[i].bInUse == true) &&
-                   (pTable->KeyTable[i].PairwiseKey.bKeyValid == true)) {
+               if (pTable->KeyTable[i].bInUse &&
+                   pTable->KeyTable[i].PairwiseKey.bKeyValid) {
                        *pKey = &(pTable->KeyTable[i].PairwiseKey);
                        return true;
                }
@@ -657,7 +655,7 @@ bool KeybSetDefaultKey(
                pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000;              // disable on-fly disable address match
                pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true;
        } else {
-               if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == false)
+               if (!pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP)
                        pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000;          // enable on-fly disable address match
        }
 
@@ -740,7 +738,7 @@ bool KeybSetAllGroupKey(
        }
 
        for (i = 0; i < MAX_KEY_TABLE - 1; i++) {
-               if (pTable->KeyTable[i].bInUse == true) {
+               if (pTable->KeyTable[i].bInUse) {
                        // found table already exist
                        // Group key
                        pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
index 001d15c0fa40721c7188e953a970fc1ebbd8dd39..21bd8a1126d794056f87a397d708fd0236c7e755 100644 (file)
@@ -957,13 +957,13 @@ bool MACbSafeStop(unsigned long dwIoBase)
 {
        MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX);
 
-       if (MACbSafeRxOff(dwIoBase) == false) {
+       if (!MACbSafeRxOff(dwIoBase)) {
                DBG_PORT80(0xA1);
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeRxOff == false)\n");
                MACbSafeSoftwareReset(dwIoBase);
                return false;
        }
-       if (MACbSafeTxOff(dwIoBase) == false) {
+       if (!MACbSafeTxOff(dwIoBase)) {
                DBG_PORT80(0xA2);
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeTxOff == false)\n");
                MACbSafeSoftwareReset(dwIoBase);
index 2340d2f0399b20da7db606837e53c64807986c55..4bd1ccb7951500653d20fba47e82f4b97581ef61 100644 (file)
@@ -260,7 +260,7 @@ PSvSendPSPOLL(
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
        } else {
 //        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n");
-       };
+       }
 
        return;
 }
@@ -284,16 +284,15 @@ PSbSendNullPacket(
        PSMgmtObject        pMgmt = pDevice->pMgmt;
        unsigned int uIdx;
 
-       if (pDevice->bLinkPass == false) {
+       if (!pDevice->bLinkPass) {
                return false;
        }
 #ifdef TxInSleep
-       if ((pDevice->bEnablePSMode == false) &&
-           (pDevice->fTxDataInSleep == false)) {
+       if (!pDevice->bEnablePSMode && !pDevice->fTxDataInSleep) {
                return false;
        }
 #else
-       if (pDevice->bEnablePSMode == false) {
+       if (!pDevice->bEnablePSMode) {
                return false;
        }
 #endif
index ce173cc16c192544da18dc3d0dddf09be1ed553a..edb1b2768b17353bc93aed5a82f929b91fb78499 100644 (file)
@@ -976,7 +976,7 @@ bool RFbSetPower(
        }
 
        bResult = RFbRawSetPower(pDevice, byPwr, uRATE);
-       if (bResult == true) {
+       if (bResult) {
                pDevice->byCurPwr = byPwr;
        }
        return bResult;
index 3a2661e2b27c42b8978f5ffb621d438e4b4f0725..6affd6edac0d75346ca9d1e5a8c69a00302bf223 100644 (file)
@@ -435,7 +435,7 @@ s_uGetDataDuration(
 
        switch (byDurType) {
        case DATADUR_B:    //DATADUR_B
-               if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
+               if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
                        if (bNeedAck) {
                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
                                return pDevice->uSIFS + uAckTime;
@@ -458,7 +458,7 @@ s_uGetDataDuration(
                break;
 
        case DATADUR_A:    //DATADUR_A
-               if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
+               if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
                        if (bNeedAck) {
                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
                                return pDevice->uSIFS + uAckTime;
@@ -481,7 +481,7 @@ s_uGetDataDuration(
                break;
 
        case DATADUR_A_F0:    //DATADUR_A_F0
-               if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
+               if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
                        if (bNeedAck) {
                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
                                return pDevice->uSIFS + uAckTime;
@@ -523,7 +523,7 @@ s_uGetDataDuration(
                break;
 
        case DATADUR_A_F1:    //DATADUR_A_F1
-               if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
+               if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
                        if (bNeedAck) {
                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
                                return pDevice->uSIFS + uAckTime;
@@ -2212,7 +2212,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
        else {
                bNeedACK = true;
                pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
-       };
+       }
 
        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
            (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
@@ -2686,7 +2686,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, unsigned char *pbMPDU, un
                }
                bNeedACK = true;
                pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
-       };
+       }
 
        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
            (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
index d2bdb71fe62d37a914e5d9fc0c43fff570425320..e78aedf990778088686893d6866be20d133bab5c 100644 (file)
@@ -494,7 +494,7 @@ VNTWIFIvUpdateNodeTxCounter(
                }
        }
        pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++;
-       if (bTxOk == true) {
+       if (bTxOk) {
                // transmit success, TxAttempts at least plus one
                pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
                pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++;
@@ -584,7 +584,7 @@ VNTWIFIbyGetKeyCypher(
 {
        PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
 
-       if (bGroupKey == true) {
+       if (bGroupKey) {
                return pMgmt->byCSSGK;
        } else {
                return pMgmt->byCSSPK;
@@ -731,7 +731,7 @@ VNTWIFIbMeasureReport(
                pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len);
                pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID;
        }
-       if (bEndOfReport == true) {
+       if (bEndOfReport) {
                IEEE11hbMSRRepTx(pMgmt);
        }
        //spin_unlock_irq(&pDevice->lock);
index 9c57eefe78fb12c9109a6aa2930046f3cf03c41b..72caaa203ddc3e5fb5c0a62625f27d80f12ac7ca 100644 (file)
@@ -317,7 +317,7 @@ vCommandTimer(
 
        if (pDevice->dwDiagRefCount != 0)
                return;
-       if (pDevice->bCmdRunning != true)
+       if (!pDevice->bCmdRunning)
                return;
 
        spin_lock_irq(&pDevice->lock);
@@ -326,7 +326,7 @@ vCommandTimer(
        case WLAN_CMD_SCAN_START:
 
                pDevice->byReAssocCount = 0;
-               if (pDevice->bRadioOff == true) {
+               if (pDevice->bRadioOff) {
                        s_bCommandComplete(pDevice);
                        spin_unlock_irq(&pDevice->lock);
                        return;
@@ -393,7 +393,7 @@ vCommandTimer(
 
                        vAdHocBeaconStop(pDevice);
 
-                       if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel) == true) {
+                       if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel)) {
                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SCAN Channel: %d\n", pMgmt->uScanChannel);
                        } else {
                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel);
@@ -408,7 +408,7 @@ vCommandTimer(
 
                        }
 
-                       if ((pMgmt->b11hEnable == false) ||
+                       if (!pMgmt->b11hEnable ||
                            (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
                                s_vProbeChannel(pDevice);
                                spin_unlock_irq(&pDevice->lock);
@@ -498,7 +498,7 @@ vCommandTimer(
 
        case WLAN_CMD_SSID_START:
                pDevice->byReAssocCount = 0;
-               if (pDevice->bRadioOff == true) {
+               if (pDevice->bRadioOff) {
                        s_bCommandComplete(pDevice);
                        spin_unlock_irq(&pDevice->lock);
                        return;
@@ -659,7 +659,7 @@ vCommandTimer(
                                netif_wake_queue(pDevice->dev);
                        }
 #ifdef TxInSleep
-                       if (pDevice->IsTxDataTrigger != false)   {    //TxDataTimer is not triggered at the first time
+                       if (pDevice->IsTxDataTrigger) {    //TxDataTimer is not triggered at the first time
                                del_timer(&pDevice->sTimerTxData);
                                init_timer(&pDevice->sTimerTxData);
                                pDevice->sTimerTxData.data = (unsigned long) pDevice;
@@ -694,7 +694,7 @@ vCommandTimer(
                        pMgmt->eCurrState = WMAC_STATE_IDLE;
                        pMgmt->eCurrMode = WMAC_MODE_STANDBY;
                        pDevice->bLinkPass = false;
-                       if (pDevice->bEnableHostWEP == true)
+                       if (pDevice->bEnableHostWEP)
                                BSSvClearNodeDBTable(pDevice, 1);
                        else
                                BSSvClearNodeDBTable(pDevice, 0);
@@ -776,7 +776,7 @@ vCommandTimer(
 
        case WLAN_CMD_RADIO_START:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_RADIO_START\n");
-               if (pDevice->bRadioCmd == true)
+               if (pDevice->bRadioCmd)
                        CARDbRadioPowerOn(pDevice);
                else
                        CARDbRadioPowerOff(pDevice);
@@ -948,7 +948,7 @@ bool bScheduleCommand(
        ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE);
        pDevice->cbFreeCmdQueue--;
 
-       if (pDevice->bCmdRunning == false) {
+       if (!pDevice->bCmdRunning) {
                s_bCommandComplete(pDevice);
        } else {
        }
@@ -1031,8 +1031,8 @@ BSSvSecondTxData(
 
        spin_lock_irq(&pDevice->lock);
 #if 1
-       if (((pDevice->bLinkPass == true) && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
-          (pDevice->fWPA_Authened == true)) {   //wpa linking
+       if ((pDevice->bLinkPass && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
+           pDevice->fWPA_Authened) {   //wpa linking
 #else
                if (pDevice->bLinkPass == true) {
 #endif
index f05f9f55398bf7a390068495b60ace381a978bc7..950039f6d1284fe1283bc632fc1164dbd3347be8 100644 (file)
@@ -110,7 +110,7 @@ unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader)
        unsigned int ii;
 
        for (ii = 0; ii < pDevice->cbDFCB; ii++) {
-               if ((pDevice->sRxDFCB[ii].bInUse == true) &&
+               if (pDevice->sRxDFCB[ii].bInUse &&
                    ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2,
                                     pMACHeader->abyAddr2)) {
                        //
@@ -141,7 +141,7 @@ unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader)
        if (pDevice->cbFreeDFCB == 0)
                return pDevice->cbDFCB;
        for (ii = 0; ii < pDevice->cbDFCB; ii++) {
-               if (pDevice->sRxDFCB[ii].bInUse == false) {
+               if (!pDevice->sRxDFCB[ii].bInUse) {
                        pDevice->cbFreeDFCB--;
                        pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime;
                        pDevice->sRxDFCB[ii].bInUse = true;
@@ -174,7 +174,7 @@ bool WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, unsigned i
 {
        unsigned int uHeaderSize;
 
-       if (bWEP == true) {
+       if (bWEP) {
                uHeaderSize = 28;
                if (bExtIV)
                        // ExtIV
index ed4b32b6d9cee7c4fdf8e1ca6c33ea61b06f928c..5200a2a0ecca93dc68626d6cc3434e241bdf0800 100644 (file)
@@ -468,15 +468,15 @@ vMgrAssocBeginSta(
        // ERP Phy (802.11g) should support short preamble.
        if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
-               if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) {
+               if (CARDbIsShorSlotTime(pMgmt->pAdapter)) {
                        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
                }
        } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
-               if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) {
+               if (CARDbIsShortPreamble(pMgmt->pAdapter)) {
                        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
                }
        }
-       if (pMgmt->b11hEnable == true)
+       if (pMgmt->b11hEnable)
                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
 
        /* build an assocreq frame and send it */
@@ -539,15 +539,15 @@ vMgrReAssocBeginSta(
        // ERP Phy (802.11g) should support short preamble.
        if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
-               if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) {
+               if (CARDbIsShorSlotTime(pMgmt->pAdapter)) {
                        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
                }
        } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
-               if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) {
+               if (CARDbIsShortPreamble(pMgmt->pAdapter)) {
                        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
                }
        }
-       if (pMgmt->b11hEnable == true)
+       if (pMgmt->b11hEnable)
                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
 
        pTxPacket = s_MgrMakeReAssocRequest
@@ -736,7 +736,7 @@ s_vMgrRxAssocRequest(
                        pDevice->bProtectMode = true;
                        pDevice->bNonERPPresent = true;
                }
-               if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) {
+               if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
                        pDevice->bBarkerPreambleMd = true;
                }
 
@@ -891,7 +891,7 @@ s_vMgrRxReAssocRequest(
                        pDevice->bProtectMode = true;
                        pDevice->bNonERPPresent = true;
                }
-               if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) {
+               if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
                        pDevice->bBarkerPreambleMd = true;
                }
 
@@ -1719,7 +1719,7 @@ s_vMgrRxDeauthentication(
                }
                /* else, ignore it.  TODO: IBSS authentication service
                   would be implemented here */
-       };
+       }
        return;
 }
 
@@ -1837,7 +1837,7 @@ s_vMgrRxBeacon(
                bChannelHit = true;
        }
 //2008-0730-01<Add>by MikeLiu
-       if (ChannelExceedZoneType(pDevice, byCurrChannel) == true)
+       if (ChannelExceedZoneType(pDevice, byCurrChannel))
                return;
 
        if (sFrame.pERP != NULL) {
@@ -1957,9 +1957,9 @@ s_vMgrRxBeacon(
                }
        }
 
-       if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) == true) &&
-           (bIsBSSIDEqual == true) &&
-           (bIsSSIDEqual == true) &&
+       if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) &&
+           bIsBSSIDEqual &&
+           bIsSSIDEqual &&
            (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
            (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
                // add state check to prevent reconnect fail since we'll receive Beacon
@@ -2001,7 +2001,7 @@ s_vMgrRxBeacon(
                                          &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
                                          &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
                                );
-                       if (bUpdatePhyParameter == true) {
+                       if (bUpdatePhyParameter) {
                                CARDbSetPhyParameter(pMgmt->pAdapter,
                                                     pMgmt->eCurrentPHYMode,
                                                     pMgmt->wCurrCapInfo,
@@ -2023,7 +2023,7 @@ s_vMgrRxBeacon(
                                                   sFrame.pIE_CHSW->byCount
                                        );
 
-                       } else if (bIsChannelEqual == false) {
+                       } else if (!bIsChannelEqual) {
                                set_channel(pMgmt->pAdapter, pBSSList->uChannel);
                        }
                }
@@ -2067,12 +2067,12 @@ s_vMgrRxBeacon(
        }
 
        // if infra mode
-       if (bIsAPBeacon == true) {
+       if (bIsAPBeacon) {
                // Infra mode: Local TSF always follow AP's TSF if Difference huge.
                if (bTSFLargeDiff)
                        bUpdateTSF = true;
 
-               if ((pDevice->bEnablePSMode == true) && (sFrame.pTIM != 0)) {
+               if (pDevice->bEnablePSMode && (sFrame.pTIM != 0)) {
                        // deal with DTIM, analysis TIM
                        pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false;
                        pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount;
@@ -2092,10 +2092,10 @@ s_vMgrRxBeacon(
                                        pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false;
                                } else {
                                        pMgmt->bInTIM = false;
-                               };
+                               }
                        } else {
                                pMgmt->bInTIM = false;
-                       };
+                       }
 
                        if (pMgmt->bInTIM ||
                            (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
@@ -2110,7 +2110,7 @@ s_vMgrRxBeacon(
                        } else {
                                pMgmt->bInTIMWake = false;
                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
-                               if (pDevice->bPWBitOn == false) {
+                               if (!pDevice->bPWBitOn) {
                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
                                        if (PSbSendNullPacket(pDevice))
                                                pDevice->bPWBitOn = true;
@@ -2332,10 +2332,10 @@ vMgrCreateOwnIBSS(
        }
 
        // Disable Protect Mode
-       pDevice->bProtectMode = 0;
+       pDevice->bProtectMode = false;
        MACvDisableProtectMD(pDevice->PortOffset);
 
-       pDevice->bBarkerPreambleMd = 0;
+       pDevice->bBarkerPreambleMd = false;
        MACvDisableBarkerPreambleMd(pDevice->PortOffset);
 
        // Kyle Test 2003.11.04
@@ -2480,7 +2480,7 @@ vMgrCreateOwnIBSS(
                pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
        }
 
-       if ((pMgmt->b11hEnable == true) &&
+       if (pMgmt->b11hEnable &&
            (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
        } else {
@@ -2530,7 +2530,7 @@ vMgrJoinBSSBegin(
        unsigned char byTopOFDMBasicRate = RATE_1M;
 
        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
-               if (pMgmt->sBSSList[ii].bActive == true)
+               if (pMgmt->sBSSList[ii].bActive)
                        break;
        }
 
@@ -2656,7 +2656,7 @@ vMgrJoinBSSBegin(
                        if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
                                bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate: 1(%d)\n", bResult);
-                               if (bResult == false) {
+                               if (!bResult) {
                                        vFlush_PMKID_Candidate((void *)pDevice);
                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 4\n");
                                        bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
@@ -2671,19 +2671,19 @@ vMgrJoinBSSBegin(
                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End of Join AP -- A/B/G Action\n");
                } else {
                        pMgmt->eCurrState = WMAC_STATE_IDLE;
-               };
+               }
 
        } else {
                // ad-hoc mode BSS
                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
                        if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
-                               if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) {
+                               if (!WPA_SearchRSN(0, WPA_TKIP, pCurr)) {
                                        // encryption mode error
                                        pMgmt->eCurrState = WMAC_STATE_IDLE;
                                        return;
                                }
                        } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
-                               if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) {
+                               if (!WPA_SearchRSN(0, WPA_AESCCMP, pCurr)) {
                                        // encryption mode error
                                        pMgmt->eCurrState = WMAC_STATE_IDLE;
                                        return;
@@ -2740,8 +2740,8 @@ vMgrJoinBSSBegin(
                        bMgrPrepareBeaconToSend((void *)pDevice, pMgmt);
                } else {
                        pMgmt->eCurrState = WMAC_STATE_IDLE;
-               };
-       };
+               }
+       }
        return;
 }
 
@@ -2776,10 +2776,10 @@ s_vMgrSynchBSS(
 
        *pStatus = CMD_STATUS_FAILURE;
 
-       if (s_bCipherMatch(pCurr,
+       if (!s_bCipherMatch(pCurr,
                           pDevice->eEncryptionStatus,
                           &(pMgmt->byCSSPK),
-                          &(pMgmt->byCSSGK)) == false) {
+                          &(pMgmt->byCSSGK))) {
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n");
                return;
        }
@@ -2869,18 +2869,17 @@ s_vMgrSynchBSS(
                CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_ADHOC);
        }
 
-       if (CARDbSetPhyParameter(pMgmt->pAdapter,
+       if (!CARDbSetPhyParameter(pMgmt->pAdapter,
                                 ePhyType,
                                 pCurr->wCapInfo,
                                 pCurr->sERP.byERP,
                                 pMgmt->abyCurrSuppRates,
-                                pMgmt->abyCurrExtSuppRates
-                   ) != true) {
+                                pMgmt->abyCurrExtSuppRates)) {
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType);
                return;
        }
        // set channel and clear NAV
-       if (set_channel(pMgmt->pAdapter, pCurr->uChannel) == false) {
+       if (!set_channel(pMgmt->pAdapter, pCurr->uChannel)) {
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
                return;
        }
@@ -2924,7 +2923,7 @@ static void  Encyption_Rebuild(
 
        if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||           //networkmanager 0.7.0 does not give the pairwise-key selection,
            (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {         // so we need re-select it according to real pairwise-key info.
-               if (pCurr->bWPAValid == true)  {   //WPA-PSK
+               if (pCurr->bWPAValid)  {   //WPA-PSK
                        pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
                        if (pCurr->abyPKType[0] == WPA_TKIP) {
                                pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;    //TKIP
@@ -2933,7 +2932,7 @@ static void  Encyption_Rebuild(
                                pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
                                PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
                        }
-               } else if (pCurr->bWPA2Valid == true) {  //WPA2-PSK
+               } else if (pCurr->bWPA2Valid) {  //WPA2-PSK
                        pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
                        if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
                                pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;     //TKIP
@@ -3150,8 +3149,7 @@ s_MgrMakeBeacon(
                }
        }
 
-       if ((pMgmt->b11hEnable == true) &&
-           (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
+       if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
                // Country IE
                pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
                set_country_IE(pMgmt->pAdapter, pbyBuffer);
@@ -3164,7 +3162,7 @@ s_MgrMakeBeacon(
                ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
                pbyBuffer += (1) + WLAN_IEHDR_LEN;
                uLength += (1) + WLAN_IEHDR_LEN;
-               if (pMgmt->bSwitchChannel == true) {
+               if (pMgmt->bSwitchChannel) {
                        // Channel Switch IE
                        ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
                        ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
@@ -3193,7 +3191,7 @@ s_MgrMakeBeacon(
                        pbyBuffer += (7) + WLAN_IEHDR_LEN;
                        uLength += (7) + WLAN_IEHDR_LEN;
                        for (ii = CB_MAX_CHANNEL_24G+1; ii <= CB_MAX_CHANNEL; ii++) {
-                               if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) {
+                               if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) {
                                        pbyBuffer += 2;
                                        uLength += 2;
                                        pIBSSDFS->len += 2;
@@ -3209,11 +3207,11 @@ s_MgrMakeBeacon(
                sFrame.pERP->byElementID = WLAN_EID_ERP;
                sFrame.pERP->len = 1;
                sFrame.pERP->byContext = 0;
-               if (pDevice->bProtectMode == true)
+               if (pDevice->bProtectMode)
                        sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
-               if (pDevice->bNonERPPresent == true)
+               if (pDevice->bNonERPPresent)
                        sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
-               if (pDevice->bBarkerPreambleMd == true)
+               if (pDevice->bBarkerPreambleMd)
                        sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
        }
        if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
@@ -3225,7 +3223,7 @@ s_MgrMakeBeacon(
 );
        }
        // hostapd wpa/wpa2 IE
-       if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) {
+       if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) {
                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
                        if (pMgmt->wWPAIELen != 0) {
                                sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
@@ -3338,16 +3336,15 @@ s_MgrMakeProbeResponse(
                sFrame.pERP->byElementID = WLAN_EID_ERP;
                sFrame.pERP->len = 1;
                sFrame.pERP->byContext = 0;
-               if (pDevice->bProtectMode == true)
+               if (pDevice->bProtectMode)
                        sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
-               if (pDevice->bNonERPPresent == true)
+               if (pDevice->bNonERPPresent)
                        sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
-               if (pDevice->bBarkerPreambleMd == true)
+               if (pDevice->bBarkerPreambleMd)
                        sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
        }
 
-       if ((pMgmt->b11hEnable == true) &&
-           (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
+       if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
                // Country IE
                pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
                set_country_IE(pMgmt->pAdapter, pbyBuffer);
@@ -3360,7 +3357,7 @@ s_MgrMakeProbeResponse(
                ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
                pbyBuffer += (1) + WLAN_IEHDR_LEN;
                uLength += (1) + WLAN_IEHDR_LEN;
-               if (pMgmt->bSwitchChannel == true) {
+               if (pMgmt->bSwitchChannel) {
                        // Channel Switch IE
                        ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
                        ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
@@ -3389,7 +3386,7 @@ s_MgrMakeProbeResponse(
                        pbyBuffer += (7) + WLAN_IEHDR_LEN;
                        uLength += (7) + WLAN_IEHDR_LEN;
                        for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) {
-                               if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) {
+                               if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) {
                                        pbyBuffer += 2;
                                        uLength += 2;
                                        pIBSSDFS->len += 2;
@@ -3409,7 +3406,7 @@ s_MgrMakeProbeResponse(
        }
 
        // hostapd wpa/wpa2 IE
-       if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) {
+       if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) {
                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
                        if (pMgmt->wWPAIELen != 0) {
                                sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
@@ -3507,7 +3504,7 @@ s_MgrMakeAssocRequest(
        pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
 
        // for 802.11h
-       if (pMgmt->b11hEnable == true) {
+       if (pMgmt->b11hEnable) {
                if (sFrame.pCurrPowerCap == NULL) {
                        sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len);
                        sFrame.len += (2 + WLAN_IEHDR_LEN);
@@ -3650,7 +3647,7 @@ s_MgrMakeAssocRequest(
                sFrame.pRSN->len += 6;
 
                // RSN Capabilities
-               if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) {
+               if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) {
                        memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
                } else {
                        sFrame.pRSN->abyRSN[16] = 0;
@@ -3658,7 +3655,7 @@ s_MgrMakeAssocRequest(
                }
                sFrame.pRSN->len += 2;
 
-               if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+               if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
                        // RSN PMKID
                        pbyRSN = &sFrame.pRSN->abyRSN[18];
                        pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
@@ -3896,7 +3893,7 @@ s_MgrMakeReAssocRequest(
                sFrame.pRSN->len += 6;
 
                // RSN Capabilities
-               if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) {
+               if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) {
                        memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
                } else {
                        sFrame.pRSN->abyRSN[16] = 0;
@@ -3904,7 +3901,7 @@ s_MgrMakeReAssocRequest(
                }
                sFrame.pRSN->len += 2;
 
-               if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+               if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
                        // RSN PMKID
                        pbyRSN = &sFrame.pRSN->abyRSN[18];
                        pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
@@ -4141,7 +4138,7 @@ s_vMgrRxProbeResponse(
        }
 
 //2008-0730-01<Add>by MikeLiu
-       if (ChannelExceedZoneType(pDevice, byCurrChannel) == true)
+       if (ChannelExceedZoneType(pDevice, byCurrChannel))
                return;
 
        if (sFrame.pERP != NULL) {
@@ -4578,7 +4575,7 @@ bAdd_PMKID_Candidate(
        for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
                pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
                if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
-                       if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) {
+                       if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) {
                                pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
                        } else {
                                pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
@@ -4589,7 +4586,7 @@ bAdd_PMKID_Candidate(
 
        // New Candidate
        pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
-       if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) {
+       if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) {
                pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
        } else {
                pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
@@ -4650,7 +4647,7 @@ s_bCipherMatch(
        }
 
        if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
-           (pBSSNode->bWPA2Valid == true) &&
+           pBSSNode->bWPA2Valid &&
            //20080123-01,<Add> by Einsn Liu
            ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
                //WPA2
@@ -4684,7 +4681,7 @@ s_bCipherMatch(
                }
 
        } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
-                  (pBSSNode->bWPAValid == true) &&
+                  pBSSNode->bWPAValid &&
                   ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
                //WPA
                // check Group Key Cipher
index b697fa6c3b16af995f1af746529b478c6e0df7bf..990ea0f9e9fbfd07930c681d0e2da14c94d18d86 100644 (file)
@@ -241,7 +241,7 @@ WPA_SearchRSN(
        int ii;
        unsigned char byPKType = WPA_NONE;
 
-       if (pBSSList->bWPAValid == false)
+       if (!pBSSList->bWPAValid)
                return false;
 
        switch (byCmd) {
index 089788dfba633001b0682b99f6f27d68e266b2f6..2013122e92b26ca38e04054fc53a41d2e282e7f1 100644 (file)
@@ -42,14 +42,14 @@ static int msglevel = MSG_LEVEL_INFO;
 
 /*---------------------  Static Variables  --------------------------*/
 
-const unsigned char abyOUIGK[4]      = { 0x00, 0x0F, 0xAC, 0x00 };
-const unsigned char abyOUIWEP40[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
-const unsigned char abyOUIWEP104[4]  = { 0x00, 0x0F, 0xAC, 0x05 };
-const unsigned char abyOUITKIP[4]    = { 0x00, 0x0F, 0xAC, 0x02 };
-const unsigned char abyOUICCMP[4]    = { 0x00, 0x0F, 0xAC, 0x04 };
+static const unsigned char abyOUIGK[4]      = { 0x00, 0x0F, 0xAC, 0x00 };
+static const unsigned char abyOUIWEP40[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+static const unsigned char abyOUIWEP104[4]  = { 0x00, 0x0F, 0xAC, 0x05 };
+static const unsigned char abyOUITKIP[4]    = { 0x00, 0x0F, 0xAC, 0x02 };
+static const unsigned char abyOUICCMP[4]    = { 0x00, 0x0F, 0xAC, 0x04 };
 
-const unsigned char abyOUI8021X[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
-const unsigned char abyOUIPSK[4]     = { 0x00, 0x0F, 0xAC, 0x02 };
+static const unsigned char abyOUI8021X[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+static const unsigned char abyOUIPSK[4]     = { 0x00, 0x0F, 0xAC, 0x02 };
 
 /*---------------------  Static Functions  --------------------------*/
 
@@ -192,7 +192,7 @@ WPA2vParseRSN(
                                        break;
                        } //for
 
-                       if (bUseGK == true) {
+                       if (bUseGK) {
                                if (j != 1) {
                                        // invalid CSS, This should be only PK CSS.
                                        return;
@@ -335,7 +335,7 @@ WPA2uSetIEs(
                pRSNIEs->len += 2;
 
                if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) &&
-                   (pMgmt->bRoaming == true) &&
+                   pMgmt->bRoaming &&
                    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
                        // RSN PMKID
                        pwPMKID = (unsigned short *)(&pRSNIEs->abyRSN[18]);  // Point to PMKID count
index 044368a46c53f332d45f9387722563143139c468..ee83704e440139d2c0d713512ef3e864584eec20 100644 (file)
@@ -341,22 +341,22 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel)
                // If is_broadcast_ether_addr, set the key as every key entry's group key.
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
 
-               if ((KeybSetAllGroupKey(&(pDevice->sKey),
+               if (KeybSetAllGroupKey(&(pDevice->sKey),
                                        dwKeyIndex,
                                        param->u.wpa_key.key_len,
                                        (PQWORD) &(KeyRSC),
                                        (unsigned char *)abyKey,
                                        byKeyDecMode,
                                        pDevice->PortOffset,
-                                       pDevice->byLocalID) == true) &&
-                   (KeybSetDefaultKey(&(pDevice->sKey),
+                                       pDevice->byLocalID) &&
+                   KeybSetDefaultKey(&(pDevice->sKey),
                                       dwKeyIndex,
                                       param->u.wpa_key.key_len,
                                       (PQWORD) &(KeyRSC),
                                       (unsigned char *)abyKey,
                                       byKeyDecMode,
                                       pDevice->PortOffset,
-                                      pDevice->byLocalID) == true)) {
+                                      pDevice->byLocalID)) {
                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
 
                } else {
@@ -389,7 +389,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel)
                               (unsigned char *)abyKey,
                               byKeyDecMode,
                               pDevice->PortOffset,
-                              pDevice->byLocalID) == true) {
+                              pDevice->byLocalID)) {
                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
 
                } else {
@@ -804,7 +804,7 @@ static int wpa_set_associate(PSDevice pDevice,
        else
                pDevice->bEncryptionEnable = false;
        if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
-             ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled == true))))  //DavidWang  //20080717-06,<Modify> by chester//Not to initial WEP
+             ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && bWepEnabled)))  //DavidWang  //20080717-06,<Modify> by chester//Not to initial WEP
                KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
        spin_lock_irq(&pDevice->lock);
        pDevice->bLinkPass = false;
index 6c7693911cd614d829fd1ffaa5176e43b104750f..61b9f7bdb85844908fa009a32190069de77f635d 100644 (file)
@@ -37,7 +37,7 @@
  * SBOX Table
  */
 
-u8 sbox_table[256] = {
+static u8 sbox_table[256] = {
        0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
        0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
        0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
@@ -56,7 +56,7 @@ u8 sbox_table[256] = {
        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
 };
 
-u8 dot2_table[256] = {
+static u8 dot2_table[256] = {
        0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
        0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
        0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
@@ -75,7 +75,7 @@ u8 dot2_table[256] = {
        0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
 };
 
-u8 dot3_table[256] = {
+static u8 dot3_table[256] = {
        0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
        0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
        0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
@@ -115,7 +115,7 @@ static void xor_32(u8 *a, u8 *b, u8 *out)
        (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
 }
 
-void AddRoundKey(u8 *key, int round)
+static void AddRoundKey(u8 *key, int round)
 {
        u8 sbox_key[4];
        u8 rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
@@ -133,7 +133,7 @@ void AddRoundKey(u8 *key, int round)
        xor_32(&key[12], &key[8], &key[12]);
 }
 
-void SubBytes(u8 *in, u8 *out)
+static void SubBytes(u8 *in, u8 *out)
 {
        int i;
 
@@ -141,7 +141,7 @@ void SubBytes(u8 *in, u8 *out)
                out[i] = sbox_table[in[i]];
 }
 
-void ShiftRows(u8 *in, u8 *out)
+static void ShiftRows(u8 *in, u8 *out)
 {
        out[0]  = in[0];
        out[1]  = in[5];
@@ -161,7 +161,7 @@ void ShiftRows(u8 *in, u8 *out)
        out[15] = in[11];
 }
 
-void MixColumns(u8 *in, u8 *out)
+static void MixColumns(u8 *in, u8 *out)
 {
 
        out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
@@ -170,7 +170,7 @@ void MixColumns(u8 *in, u8 *out)
        out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
 }
 
-void AESv128(u8 *key, u8 *data, u8 *ciphertext)
+static void AESv128(u8 *key, u8 *data, u8 *ciphertext)
 {
        int  i;
        int  round;
index 1e8b8412e67e4b6663161c977f2334a154b65e0a..468f455e0d26f5698e3b12ba6994c893409067c0 100644 (file)
@@ -48,7 +48,7 @@
 static int          msglevel                =MSG_LEVEL_INFO;
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 
-u8 abyVT3184_AGC[] = {
+static u8 abyVT3184_AGC[] = {
     0x00,   //0
     0x00,   //1
     0x02,   //2
@@ -115,7 +115,7 @@ u8 abyVT3184_AGC[] = {
     0x3E    //3F
 };
 
-u8 abyVT3184_AL2230[] = {
+static u8 abyVT3184_AL2230[] = {
         0x31,//00
         0x00,
         0x00,
@@ -375,7 +375,7 @@ u8 abyVT3184_AL2230[] = {
 };
 
 //{{RobertYu:20060515, new BB setting for VT3226D0
-u8 abyVT3184_VT3226D0[] = {
+static u8 abyVT3184_VT3226D0[] = {
         0x31,//00
         0x00,
         0x00,
@@ -634,7 +634,7 @@ u8 abyVT3184_VT3226D0[] = {
         0x00,
 };
 
-const u16 awcFrameTime[MAX_RATE] =
+static const u16 awcFrameTime[MAX_RATE] =
 {10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216};
 
 /*
@@ -939,6 +939,7 @@ int BBbVT3184Init(struct vnt_private *pDevice)
     u8 *                   pbyAgc;
     u16                    wLengthAgc;
     u8                    abyArray[256];
+       u8 data;
 
     ntStatus = CONTROLnsRequestIn(pDevice,
                                   MESSAGE_TYPE_READ,
@@ -1104,6 +1105,16 @@ else {
     ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x0D,0x01);
 
     RFbRFTableDownload(pDevice);
+
+       /* Fix for TX USB resets from vendors driver */
+       CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ, USB_REG4,
+               MESSAGE_REQUEST_MEM, sizeof(data), &data);
+
+       data |= 0x2;
+
+       CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, USB_REG4,
+               MESSAGE_REQUEST_MEM, sizeof(data), &data);
+
     return true;//ntStatus;
 }
 
index dad3f8c78e21d196540c62741af4fbbbe305819b..1c3cbc54ce18a2aeef0d2891ab404fafb6515510 100644 (file)
 static int          msglevel                =MSG_LEVEL_INFO;
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 
-const u16             awHWRetry0[5][5] = {
+static const u16             awHWRetry0[5][5] = {
                                             {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
                                             {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
                                             {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
                                             {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
                                             {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
                                            };
-const u16             awHWRetry1[5][5] = {
+static const u16             awHWRetry1[5][5] = {
                                             {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
                                             {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
                                             {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
index 19d3cf451b880c736c82cce806fdfb14d98b6379..662cfea7527e2ef321c53c538c972513a7fd00d7 100644 (file)
@@ -66,7 +66,7 @@ static int          msglevel                =MSG_LEVEL_INFO;
 //const u16 cwRXBCNTSFOff[MAX_RATE] =
 //{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
 
-const u16 cwRXBCNTSFOff[MAX_RATE] =
+static const u16 cwRXBCNTSFOff[MAX_RATE] =
 {192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
 
 /*
@@ -205,7 +205,7 @@ static u16 swGetOFDMControlRate(struct vnt_private *pDevice, u16 wRateIdx)
  * Return Value: none
  *
  */
-void
+static void
 CARDvCalculateOFDMRParameter (
       u16 wRate,
       u8 byBBType,
index e430b35463b6b3595aa52a7fa8bb4962c9aff0f0..5a4fa0e2581b14355422957ff46ce2b59700b638 100644 (file)
@@ -423,8 +423,7 @@ void CHvInitChannelTable(struct vnt_private *pDevice)
             break;
     }
 
-    if ((pDevice->dwDiagRefCount != 0) ||
-        (pDevice->b11hEable == true)) {
+    if (pDevice->b11hEable == true) {
         if (bMultiBand == true) {
                for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
                        sChannelTbl[ii+1].bValid = true;
index af9eab0c00a317d0513b84f52e5ba98cc995d083..547db6f0c53f65e1301b80aef34d1bf59053bc08 100644 (file)
@@ -45,7 +45,7 @@
 
 /* static int msglevel = MSG_LEVEL_DEBUG; */
 static int msglevel = MSG_LEVEL_INFO;
-const u8 acbyIERate[MAX_RATE] = {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18,
+static const u8 acbyIERate[MAX_RATE] = {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18,
        0x24, 0x30, 0x48, 0x60, 0x6C};
 
 #define AUTORATE_TXOK_CNT       0x0400
index afe7074c3037e37614121f12077b277fa86cecde..7c6dd5f52295608e170ab31028c71002575b9c2e 100644 (file)
 /*
  * TX FIFO header
  */
-
-typedef struct tagSTxShortBufHead {
-    u16    wFIFOCtl;
-    u16    wTimeStamp;
-} __attribute__ ((__packed__))
-STxShortBufHead, *PSTxShortBufHead;
-typedef const STxShortBufHead *PCSTxShortBufHead;
-
 typedef struct tagSBEACONCtl {
        u32 BufReady:1;
        u32 TSF:15;
index 62b7de19b371d2cc7635de9fa339b2b7b78a0143..82e1e6d695d1a79be5cc941e4a950acdf64d8dda 100644 (file)
@@ -44,6 +44,7 @@
 #include <net/cfg80211.h>
 #include <linux/timer.h>
 #include <linux/usb.h>
+#include <linux/crc32.h>
 
 #ifdef SIOCETHTOOL
 #define DEVICE_ETHTOOL_IOCTL_SUPPORT
@@ -75,6 +76,7 @@
 #include "desc.h"
 #include "key.h"
 #include "card.h"
+#include "rndis.h"
 
 #define VNT_USB_VENDOR_ID                     0x160a
 #define VNT_USB_PRODUCT_ID                    0x3184
@@ -149,11 +151,9 @@ typedef enum __device_msg_level {
        MSG_LEVEL_DEBUG = 4           /* Only for debug purpose. */
 } DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL;
 
-typedef enum __device_init_type {
-       DEVICE_INIT_COLD = 0,       /* cold init */
-       DEVICE_INIT_RESET,          /* reset init or Dx to D0 power remain */
-       DEVICE_INIT_DXPL            /* Dx to D0 power lost init */
-} DEVICE_INIT_TYPE, *PDEVICE_INIT_TYPE;
+#define DEVICE_INIT_COLD       0x0 /* cold init */
+#define DEVICE_INIT_RESET      0x1 /* reset init or Dx to D0 power remain */
+#define DEVICE_INIT_DXPL       0x2 /* Dx to D0 power lost init */
 
 /* USB */
 
@@ -467,6 +467,8 @@ struct vnt_private {
        u8 byOriginalZonetype;
 
        int bLinkPass; /* link status: OK or fail */
+       struct vnt_cmd_card_init init_command;
+       struct vnt_rsp_card_init init_response;
        u8 abyCurrentNetAddr[ETH_ALEN];
        u8 abyPermanentNetAddr[ETH_ALEN];
 
@@ -596,7 +598,6 @@ struct vnt_private {
 
        int bCCK;
        int bEncryptionEnable;
-       int bLongHeader;
        int bShortSlotTime;
        int bProtectMode;
        int bNonERPPresent;
@@ -666,8 +667,6 @@ struct vnt_private {
        u8 abyPRNG[WLAN_WEPMAX_KEYLEN+3];
        u8 byKeyIndex;
 
-       int bAES;
-
        u32 uKeyLength;
        u8 abyKey[WLAN_WEP232_KEYLEN];
 
@@ -695,7 +694,6 @@ struct vnt_private {
        u8 byBBPreEDIndex;
 
        int bRadioCmd;
-       u32 dwDiagRefCount;
 
        /* For FOE Tuning */
        u8  byFOETuning;
index 75dc92d64056a3c30ef25698196fa1c3e4ce326f..2bed31b741c082425462e7699198e81503570409 100644 (file)
@@ -59,7 +59,7 @@
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 static int          msglevel                =MSG_LEVEL_INFO;
 
-const u8 acbyRxRate[MAX_RATE] =
+static const u8 acbyRxRate[MAX_RATE] =
 {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
 
 static u8 s_byGetRateIdx(u8 byRate);
index ae1676d190c5b318fcaa43466f58539d39fed095..67ba48b9a8d906d7c8e1091a7ccfdddebf9b9ee5 100644 (file)
@@ -133,7 +133,8 @@ static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked)
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
                       pDevice->dev->name, pDevice->apdev->name);
        }
-       free_netdev(pDevice->apdev);
+       if (pDevice->apdev)
+               free_netdev(pDevice->apdev);
        pDevice->apdev = NULL;
     pDevice->bEnable8021x = false;
     pDevice->bEnableHostWEP = false;
index aae228c533effe3a0a7f0f0460ec9ab8c9cb90e5..4cb7aa737a999bc0f0da70de0f1522795decc382 100644 (file)
@@ -67,7 +67,6 @@
 #include "datarate.h"
 #include "rf.h"
 #include "firmware.h"
-#include "rndis.h"
 #include "control.h"
 #include "channel.h"
 #include "int.h"
@@ -215,8 +214,7 @@ static void device_set_multi(struct net_device *dev);
 static int  device_close(struct net_device *dev);
 static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 
-static int device_init_registers(struct vnt_private *pDevice,
-       DEVICE_INIT_TYPE InitType);
+static int device_init_registers(struct vnt_private *pDevice);
 static bool device_init_defrag_cb(struct vnt_private *pDevice);
 static void device_init_diversity_timer(struct vnt_private *pDevice);
 static int  device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
@@ -296,343 +294,352 @@ static void device_init_diversity_timer(struct vnt_private *pDevice)
 /*
  * initialization of MAC & BBP registers
  */
-
-static int device_init_registers(struct vnt_private *pDevice,
-       DEVICE_INIT_TYPE InitType)
+static int device_init_registers(struct vnt_private *pDevice)
 {
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+       struct vnt_cmd_card_init *init_cmd = &pDevice->init_command;
+       struct vnt_rsp_card_init *init_rsp = &pDevice->init_response;
        u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
        u8 abySNAP_RFC1042[ETH_ALEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
        u8 abySNAP_Bridgetunnel[ETH_ALEN]
                = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
        u8 byAntenna;
        int ii;
-       CMD_CARD_INIT sInitCmd;
        int ntStatus = STATUS_SUCCESS;
-       RSP_CARD_INIT   sInitRsp;
        u8 byTmp;
        u8 byCalibTXIQ = 0, byCalibTXDC = 0, byCalibRXIQ = 0;
 
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n", InitType, pDevice->byPacketType);
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n",
+                               DEVICE_INIT_COLD, pDevice->byPacketType);
+
        spin_lock_irq(&pDevice->lock);
-       if (InitType == DEVICE_INIT_COLD) {
-               memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
-               memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
-               memcpy(pDevice->abySNAP_Bridgetunnel,
-                      abySNAP_Bridgetunnel,
-                      ETH_ALEN);
-
-        if ( !FIRMWAREbCheckVersion(pDevice) ) {
-            if (FIRMWAREbDownload(pDevice) == true) {
-                if (FIRMWAREbBrach2Sram(pDevice) == false) {
-                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbBrach2Sram fail \n");
-                       spin_unlock_irq(&pDevice->lock);
-                    return false;
-                }
-            } else {
-
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbDownload fail \n");
-                spin_unlock_irq(&pDevice->lock);
-                return false;
-            }
-        }
 
-        if ( !BBbVT3184Init(pDevice) ) {
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail \n");
-            spin_unlock_irq(&pDevice->lock);
-            return false;
-        }
-    }
+       memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
+       memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
+       memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
+
+       if (!FIRMWAREbCheckVersion(pDevice)) {
+               if (FIRMWAREbDownload(pDevice) == true) {
+                       if (FIRMWAREbBrach2Sram(pDevice) == false) {
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+                                       " FIRMWAREbBrach2Sram fail\n");
+                               spin_unlock_irq(&pDevice->lock);
+                               return false;
+                       }
+               } else {
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+                               " FIRMWAREbDownload fail\n");
+                       spin_unlock_irq(&pDevice->lock);
+                       return false;
+               }
+       }
 
-    sInitCmd.byInitClass = (u8)InitType;
-    sInitCmd.bExistSWNetAddr = (u8) pDevice->bExistSWNetAddr;
-    for (ii = 0; ii < 6; ii++)
-       sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii];
-    sInitCmd.byShortRetryLimit = pDevice->byShortRetryLimit;
-    sInitCmd.byLongRetryLimit = pDevice->byLongRetryLimit;
-
-    /* issue card_init command to device */
-    ntStatus = CONTROLnsRequestOut(pDevice,
-                                    MESSAGE_TYPE_CARDINIT,
-                                    0,
-                                    0,
-                                    sizeof(CMD_CARD_INIT),
-                                    (u8 *) &(sInitCmd));
-
-    if ( ntStatus != STATUS_SUCCESS ) {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail \n");
-        spin_unlock_irq(&pDevice->lock);
-        return false;
-    }
-    if (InitType == DEVICE_INIT_COLD) {
+       if (!BBbVT3184Init(pDevice)) {
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail\n");
+               spin_unlock_irq(&pDevice->lock);
+               return false;
+       }
 
-        ntStatus = CONTROLnsRequestIn(pDevice,MESSAGE_TYPE_INIT_RSP,0,0,sizeof(RSP_CARD_INIT), (u8 *) &(sInitRsp));
+       init_cmd->init_class = DEVICE_INIT_COLD;
+       init_cmd->exist_sw_net_addr = (u8) pDevice->bExistSWNetAddr;
+       for (ii = 0; ii < 6; ii++)
+               init_cmd->sw_net_addr[ii] = pDevice->abyCurrentNetAddr[ii];
+       init_cmd->short_retry_limit = pDevice->byShortRetryLimit;
+       init_cmd->long_retry_limit = pDevice->byLongRetryLimit;
+
+       /* issue card_init command to device */
+       ntStatus = CONTROLnsRequestOut(pDevice,
+               MESSAGE_TYPE_CARDINIT, 0, 0,
+               sizeof(struct vnt_cmd_card_init), (u8 *)init_cmd);
+       if (ntStatus != STATUS_SUCCESS) {
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail\n");
+               spin_unlock_irq(&pDevice->lock);
+               return false;
+       }
 
-        if (ntStatus != STATUS_SUCCESS) {
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Cardinit request in status fail!\n");
-            spin_unlock_irq(&pDevice->lock);
-            return false;
-        }
+       ntStatus = CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_INIT_RSP, 0, 0,
+               sizeof(struct vnt_rsp_card_init), (u8 *)init_rsp);
+       if (ntStatus != STATUS_SUCCESS) {
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+                       "Cardinit request in status fail!\n");
+               spin_unlock_irq(&pDevice->lock);
+               return false;
+       }
 
        /* local ID for AES functions */
-        ntStatus = CONTROLnsRequestIn(pDevice,
-                                    MESSAGE_TYPE_READ,
-                                    MAC_REG_LOCALID,
-                                    MESSAGE_REQUEST_MACREG,
-                                    1,
-                                    &pDevice->byLocalID);
-
-        if ( ntStatus != STATUS_SUCCESS ) {
-            spin_unlock_irq(&pDevice->lock);
-            return false;
-        }
+       ntStatus = CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ,
+               MAC_REG_LOCALID, MESSAGE_REQUEST_MACREG, 1,
+                       &pDevice->byLocalID);
+       if (ntStatus != STATUS_SUCCESS) {
+               spin_unlock_irq(&pDevice->lock);
+               return false;
+       }
 
        /* do MACbSoftwareReset in MACvInitialize */
 
        /* force CCK */
-        pDevice->bCCK = true;
+       pDevice->bCCK = true;
        pDevice->bProtectMode = false;
        /* only used in 11g type, sync with ERP IE */
-        pDevice->bNonERPPresent = false;
-        pDevice->bBarkerPreambleMd = false;
-        if ( pDevice->bFixRate ) {
-            pDevice->wCurrentRate = (u16) pDevice->uConnectionRate;
-        } else {
-            if ( pDevice->byBBType == BB_TYPE_11B )
-                pDevice->wCurrentRate = RATE_11M;
-            else
-                pDevice->wCurrentRate = RATE_54M;
-        }
+       pDevice->bNonERPPresent = false;
+       pDevice->bBarkerPreambleMd = false;
+       if (pDevice->bFixRate) {
+               pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
+       } else {
+               if (pDevice->byBBType == BB_TYPE_11B)
+                       pDevice->wCurrentRate = RATE_11M;
+               else
+                       pDevice->wCurrentRate = RATE_54M;
+       }
 
-        CHvInitChannelTable(pDevice);
+       CHvInitChannelTable(pDevice);
 
-        pDevice->byTopOFDMBasicRate = RATE_24M;
-        pDevice->byTopCCKBasicRate = RATE_1M;
+       pDevice->byTopOFDMBasicRate = RATE_24M;
+       pDevice->byTopCCKBasicRate = RATE_1M;
        pDevice->byRevId = 0;
        /* target to IF pin while programming to RF chip */
-        pDevice->byCurPwr = 0xFF;
+       pDevice->byCurPwr = 0xFF;
 
-        pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK];
-        pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG];
+       pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK];
+       pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG];
        /* load power table */
        for (ii = 0; ii < 14; ii++) {
-            pDevice->abyCCKPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL];
-            if (pDevice->abyCCKPwrTbl[ii] == 0)
-                pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr;
-            pDevice->abyOFDMPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL];
-            if (pDevice->abyOFDMPwrTbl[ii] == 0)
-                pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG;
-        }
+               pDevice->abyCCKPwrTbl[ii] =
+                       pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL];
+
+               if (pDevice->abyCCKPwrTbl[ii] == 0)
+                       pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr;
+                       pDevice->abyOFDMPwrTbl[ii] =
+                               pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL];
+               if (pDevice->abyOFDMPwrTbl[ii] == 0)
+                       pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG;
+       }
 
        /*
         * original zonetype is USA, but custom zonetype is Europe,
         * then need to recover 12, 13, 14 channels with 11 channel
         */
-          if(((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
-               (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe))&&
-            (pDevice->byOriginalZonetype == ZoneType_USA)) {
+       if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
+               (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) &&
+               (pDevice->byOriginalZonetype == ZoneType_USA)) {
                for (ii = 11; ii < 14; ii++) {
                        pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
                        pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
                }
-         }
+       }
 
-         pDevice->byOFDMPwrA = 0x34; /* same as RFbMA2829SelectChannel */
+       pDevice->byOFDMPwrA = 0x34; /* same as RFbMA2829SelectChannel */
 
-         /* load OFDM A power table */
-         for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) {
-            pDevice->abyOFDMAPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL];
-            if (pDevice->abyOFDMAPwrTbl[ii] == 0)
-                pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA;
-        }
+       /* load OFDM A power table */
+       for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) {
+               pDevice->abyOFDMAPwrTbl[ii] =
+                       pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL];
+
+               if (pDevice->abyOFDMAPwrTbl[ii] == 0)
+                       pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA;
+       }
 
-        byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA];
-        if (byAntenna & EEP_ANTINV)
-            pDevice->bTxRxAntInv = true;
-        else
-            pDevice->bTxRxAntInv = false;
+       byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA];
 
-        byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+       if (byAntenna & EEP_ANTINV)
+               pDevice->bTxRxAntInv = true;
+       else
+               pDevice->bTxRxAntInv = false;
+
+       byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
 
        if (byAntenna == 0) /* if not set default is both */
-            byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
-
-        if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
-            pDevice->byAntennaCount = 2;
-            pDevice->byTxAntennaMode = ANT_B;
-            pDevice->dwTxAntennaSel = 1;
-            pDevice->dwRxAntennaSel = 1;
-            if (pDevice->bTxRxAntInv == true)
-                pDevice->byRxAntennaMode = ANT_A;
-            else
-                pDevice->byRxAntennaMode = ANT_B;
-
-            if (pDevice->bDiversityRegCtlON)
-                pDevice->bDiversityEnable = true;
-            else
-                pDevice->bDiversityEnable = false;
-        } else  {
-            pDevice->bDiversityEnable = false;
-            pDevice->byAntennaCount = 1;
-            pDevice->dwTxAntennaSel = 0;
-            pDevice->dwRxAntennaSel = 0;
-            if (byAntenna & EEP_ANTENNA_AUX) {
-                pDevice->byTxAntennaMode = ANT_A;
-                if (pDevice->bTxRxAntInv == true)
-                    pDevice->byRxAntennaMode = ANT_B;
-                else
-                    pDevice->byRxAntennaMode = ANT_A;
-            } else {
-                pDevice->byTxAntennaMode = ANT_B;
-                if (pDevice->bTxRxAntInv == true)
-                    pDevice->byRxAntennaMode = ANT_A;
-                else
-                    pDevice->byRxAntennaMode = ANT_B;
-            }
-        }
-        pDevice->ulDiversityNValue = 100*255;
-        pDevice->ulDiversityMValue = 100*16;
-        pDevice->byTMax = 1;
-        pDevice->byTMax2 = 4;
-        pDevice->ulSQ3TH = 0;
-        pDevice->byTMax3 = 64;
+               byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+
+       if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
+               pDevice->byAntennaCount = 2;
+               pDevice->byTxAntennaMode = ANT_B;
+               pDevice->dwTxAntennaSel = 1;
+               pDevice->dwRxAntennaSel = 1;
+
+               if (pDevice->bTxRxAntInv == true)
+                       pDevice->byRxAntennaMode = ANT_A;
+               else
+                       pDevice->byRxAntennaMode = ANT_B;
+
+               if (pDevice->bDiversityRegCtlON)
+                       pDevice->bDiversityEnable = true;
+               else
+                       pDevice->bDiversityEnable = false;
+       } else  {
+               pDevice->bDiversityEnable = false;
+               pDevice->byAntennaCount = 1;
+               pDevice->dwTxAntennaSel = 0;
+               pDevice->dwRxAntennaSel = 0;
+
+               if (byAntenna & EEP_ANTENNA_AUX) {
+                       pDevice->byTxAntennaMode = ANT_A;
+
+                       if (pDevice->bTxRxAntInv == true)
+                               pDevice->byRxAntennaMode = ANT_B;
+                       else
+                               pDevice->byRxAntennaMode = ANT_A;
+               } else {
+                       pDevice->byTxAntennaMode = ANT_B;
+
+               if (pDevice->bTxRxAntInv == true)
+                       pDevice->byRxAntennaMode = ANT_A;
+               else
+                       pDevice->byRxAntennaMode = ANT_B;
+               }
+       }
+
+       pDevice->ulDiversityNValue = 100 * 255;
+       pDevice->ulDiversityMValue = 100 * 16;
+       pDevice->byTMax = 1;
+       pDevice->byTMax2 = 4;
+       pDevice->ulSQ3TH = 0;
+       pDevice->byTMax3 = 64;
 
        /* get Auto Fall Back type */
-        pDevice->byAutoFBCtrl = AUTO_FB_0;
+       pDevice->byAutoFBCtrl = AUTO_FB_0;
 
        /* set SCAN Time */
-        pDevice->uScanTime = WLAN_SCAN_MINITIME;
+       pDevice->uScanTime = WLAN_SCAN_MINITIME;
 
        /* default Auto Mode */
        /* pDevice->NetworkType = Ndis802_11Automode; */
-        pDevice->eConfigPHYMode = PHY_TYPE_AUTO;
-        pDevice->byBBType = BB_TYPE_11G;
+       pDevice->eConfigPHYMode = PHY_TYPE_AUTO;
+       pDevice->byBBType = BB_TYPE_11G;
 
        /* initialize BBP registers */
-        pDevice->ulTxPower = 25;
+       pDevice->ulTxPower = 25;
 
        /* get channel range */
-        pDevice->byMinChannel = 1;
-        pDevice->byMaxChannel = CB_MAX_CHANNEL;
+       pDevice->byMinChannel = 1;
+       pDevice->byMaxChannel = CB_MAX_CHANNEL;
 
        /* get RFType */
-        pDevice->byRFType = sInitRsp.byRFType;
+       pDevice->byRFType = init_rsp->rf_type;
 
-        if ((pDevice->byRFType & RF_EMU) != 0) {
+       if ((pDevice->byRFType & RF_EMU) != 0) {
                /* force change RevID for VT3253 emu */
                pDevice->byRevId = 0x80;
-        }
+       }
 
        /* load vt3266 calibration parameters in EEPROM */
-        if (pDevice->byRFType == RF_VT3226D0) {
-            if((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) &&
-                (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) {
-                byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ];
-                byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC];
-                byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ];
-                if( (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) ) {
+       if (pDevice->byRFType == RF_VT3226D0) {
+               if ((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) &&
+                       (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) {
+
+                       byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ];
+                       byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC];
+                       byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ];
+                       if (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) {
                        /* CR255, enable TX/RX IQ and DC compensation mode */
-                       ControlvWriteByte(pDevice,
-                                         MESSAGE_REQUEST_BBREG,
-                                         0xFF,
-                                         0x03);
+                               ControlvWriteByte(pDevice,
+                                       MESSAGE_REQUEST_BBREG,
+                                       0xff,
+                                       0x03);
                        /* CR251, TX I/Q Imbalance Calibration */
-                       ControlvWriteByte(pDevice,
-                                         MESSAGE_REQUEST_BBREG,
-                                         0xFB,
-                                         byCalibTXIQ);
+                               ControlvWriteByte(pDevice,
+                                       MESSAGE_REQUEST_BBREG,
+                                       0xfb,
+                                       byCalibTXIQ);
                        /* CR252, TX DC-Offset Calibration */
-                       ControlvWriteByte(pDevice,
-                                         MESSAGE_REQUEST_BBREG,
-                                         0xFC,
-                                         byCalibTXDC);
+                               ControlvWriteByte(pDevice,
+                                       MESSAGE_REQUEST_BBREG,
+                                       0xfC,
+                                       byCalibTXDC);
                        /* CR253, RX I/Q Imbalance Calibration */
-                       ControlvWriteByte(pDevice,
-                                         MESSAGE_REQUEST_BBREG,
-                                         0xFD,
-                                         byCalibRXIQ);
-                } else {
+                               ControlvWriteByte(pDevice,
+                                       MESSAGE_REQUEST_BBREG,
+                                       0xfd,
+                                       byCalibRXIQ);
+                       } else {
                        /* CR255, turn off BB Calibration compensation */
-                       ControlvWriteByte(pDevice,
-                                         MESSAGE_REQUEST_BBREG,
-                                         0xFF,
-                                         0x0);
-                }
-            }
-        }
-        pMgmt->eScanType = WMAC_SCAN_PASSIVE;
-        pMgmt->uCurrChannel = pDevice->uChannel;
-        pMgmt->uIBSSChannel = pDevice->uChannel;
-        CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
+                               ControlvWriteByte(pDevice,
+                                       MESSAGE_REQUEST_BBREG,
+                                       0xff,
+                                       0x0);
+                       }
+               }
+       }
+
+       pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+       pMgmt->uCurrChannel = pDevice->uChannel;
+       pMgmt->uIBSSChannel = pDevice->uChannel;
+       CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
 
        /* get permanent network address */
-        memcpy(pDevice->abyPermanentNetAddr,&(sInitRsp.byNetAddr[0]),6);
+       memcpy(pDevice->abyPermanentNetAddr, init_rsp->net_addr, 6);
        memcpy(pDevice->abyCurrentNetAddr,
-              pDevice->abyPermanentNetAddr,
-              ETH_ALEN);
+                               pDevice->abyPermanentNetAddr, ETH_ALEN);
 
        /* if exist SW network address, use it */
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %pM\n",
                pDevice->abyCurrentNetAddr);
-    }
 
-    /*
-     * set BB and packet type at the same time
-     * set Short Slot Time, xIFS, and RSPINF
-     */
-    if (pDevice->byBBType == BB_TYPE_11A) {
-        CARDbAddBasicRate(pDevice, RATE_6M);
-        pDevice->bShortSlotTime = true;
-    } else {
-        CARDbAddBasicRate(pDevice, RATE_1M);
-        pDevice->bShortSlotTime = false;
-    }
-    BBvSetShortSlotTime(pDevice);
-    CARDvSetBSSMode(pDevice);
+       /*
+       * set BB and packet type at the same time
+       * set Short Slot Time, xIFS, and RSPINF
+       */
+       if (pDevice->byBBType == BB_TYPE_11A) {
+               CARDbAddBasicRate(pDevice, RATE_6M);
+               pDevice->bShortSlotTime = true;
+       } else {
+               CARDbAddBasicRate(pDevice, RATE_1M);
+               pDevice->bShortSlotTime = false;
+       }
 
-    if (pDevice->bUpdateBBVGA) {
-        pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
-        pDevice->byBBVGANew = pDevice->byBBVGACurrent;
-        BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
-    }
+       BBvSetShortSlotTime(pDevice);
+       CARDvSetBSSMode(pDevice);
 
-    pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
-    pDevice->bHWRadioOff = false;
-    if ( (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0 ) {
-        ntStatus = CONTROLnsRequestIn(pDevice,
-                                    MESSAGE_TYPE_READ,
-                                    MAC_REG_GPIOCTL1,
-                                    MESSAGE_REQUEST_MACREG,
-                                    1,
-                                    &byTmp);
-
-        if ( ntStatus != STATUS_SUCCESS ) {
-            spin_unlock_irq(&pDevice->lock);
-            return false;
-        }
-        if ( (byTmp & GPIO3_DATA) == 0 ) {
-            pDevice->bHWRadioOff = true;
-            MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
-        } else {
-            MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
-            pDevice->bHWRadioOff = false;
-        }
+       if (pDevice->bUpdateBBVGA) {
+               pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
+               pDevice->byBBVGANew = pDevice->byBBVGACurrent;
 
-    }
+               BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+       }
 
-    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_TMLEN,0x38);
-    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
-    MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL0,0x01);
+       pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
+       pDevice->bHWRadioOff = false;
 
-    if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) {
-        CARDbRadioPowerOff(pDevice);
-    } else {
-        CARDbRadioPowerOn(pDevice);
-    }
+       if ((pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0) {
+               ntStatus = CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ,
+                       MAC_REG_GPIOCTL1, MESSAGE_REQUEST_MACREG, 1, &byTmp);
 
-    spin_unlock_irq(&pDevice->lock);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
-    return true;
+               if (ntStatus != STATUS_SUCCESS) {
+                       spin_unlock_irq(&pDevice->lock);
+                       return false;
+               }
+
+               if ((byTmp & GPIO3_DATA) == 0) {
+                       pDevice->bHWRadioOff = true;
+                       MACvRegBitsOn(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD);
+               } else {
+                       MACvRegBitsOff(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD);
+                       pDevice->bHWRadioOff = false;
+               }
+
+       }
+
+       ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG,
+                               MAC_REG_PAPEDELAY, LEDSTS_TMLEN, 0x38);
+
+       ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG,
+                               MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW);
+
+       MACvRegBitsOn(pDevice, MAC_REG_GPIOCTL0, 0x01);
+
+       if ((pDevice->bHWRadioOff == true) ||
+                               (pDevice->bRadioControlOff == true)) {
+               CARDbRadioPowerOff(pDevice);
+       } else {
+               CARDbRadioPowerOn(pDevice);
+       }
+
+
+       spin_unlock_irq(&pDevice->lock);
+
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
+
+       return true;
 }
 
 #ifdef CONFIG_PM       /* Minimal support for suspend and resume */
@@ -962,10 +969,10 @@ static int  device_open(struct net_device *dev)
     /* read config file */
     Read_config_file(pDevice);
 
-    if (device_init_registers(pDevice, DEVICE_INIT_COLD) == false) {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
-        goto free_all;
-    }
+       if (device_init_registers(pDevice) == false) {
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
+               goto free_all;
+       }
 
     device_set_multi(pDevice->dev);
 
@@ -1187,22 +1194,6 @@ out:
        return NETDEV_TX_OK;
 }
 
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
-    int crc = -1;
-
-    while(--length >= 0) {
-        unsigned char current_octet = *data++;
-        int bit;
-        for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
-            crc = (crc << 1) ^
-                ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
-        }
-    }
-    return crc;
-}
-
 /* find out the start position of str2 from str1 */
 static unsigned char *kstrstr(const unsigned char *str1,
                              const unsigned char *str2) {
index d27fa434550da50181f34a519aa3e2545a291d68..1e8f64bff03c665046c8b51b72bb1cf5809e3aa3 100644 (file)
@@ -419,7 +419,7 @@ static u8 vt3226_channel_table1[CB_MAX_CHANNEL_24G][3] = {
 ///}}RobertYu
 
 //{{RobertYu:20060502, TWIF 1.14, LO Current for 11b mode
-const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = {
+static const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = {
     0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
     0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
     0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
@@ -597,7 +597,7 @@ static u8 vt3342_channel_table1[CB_MAX_CHANNEL][3] = {
  *
 -*/
 
-const u32 al2230_power_table[AL2230_PWR_IDX_LEN] = {
+static const u32 al2230_power_table[AL2230_PWR_IDX_LEN] = {
     0x04040900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
     0x04041900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
     0x04042900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
@@ -740,9 +740,6 @@ int RFbSetPower(struct vnt_private *priv, u32 rate, u32 channel)
        int ret = true;
        u8 power = priv->byCCKPwr;
 
-       if (priv->dwDiagRefCount)
-               return true;
-
        if (channel == 0)
                return -EINVAL;
 
index 5e073062017a2e657e1f0b33ebddcaa1d2fa21c4..3661f82766e076babbaf17349ec923ca5f5a345e 100644 (file)
@@ -66,6 +66,8 @@
 
 #define VIAUSB20_PACKET_HEADER          0x04
 
+#define USB_REG4       0x604
+
 typedef struct _CMD_MESSAGE
 {
     u8        byData[256];
@@ -77,23 +79,23 @@ typedef struct _CMD_WRITE_MASK
     u8        byMask;
 } CMD_WRITE_MASK, *PCMD_WRITE_MASK;
 
-typedef struct _CMD_CARD_INIT
+struct vnt_cmd_card_init
 {
-    u8        byInitClass;
-    u8        bExistSWNetAddr;
-    u8        bySWNetAddr[6];
-    u8        byShortRetryLimit;
-    u8        byLongRetryLimit;
-} CMD_CARD_INIT, *PCMD_CARD_INIT;
-
-typedef struct _RSP_CARD_INIT
+       u8 init_class;
+       u8 exist_sw_net_addr;
+       u8 sw_net_addr[6];
+       u8 short_retry_limit;
+       u8 long_retry_limit;
+};
+
+struct vnt_rsp_card_init
 {
-    u8        byStatus;
-    u8        byNetAddr[6];
-    u8        byRFType;
-    u8        byMinChannel;
-    u8        byMaxChannel;
-} RSP_CARD_INIT, *PRSP_CARD_INIT;
+       u8 status;
+       u8 net_addr[6];
+       u8 rf_type;
+       u8 min_channel;
+       u8 max_channel;
+};
 
 typedef struct _CMD_SET_KEY
 {
index 35a3ddb41a6a2f4ac7ee36ad55a55549ee7569e0..cc2302900989c4827f02489f5b5ba18be4a320b6 100644 (file)
 
 static int          msglevel                = MSG_LEVEL_INFO;
 
-const u16 wTimeStampOff[2][MAX_RATE] = {
+static const u16 wTimeStampOff[2][MAX_RATE] = {
         {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
         {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
     };
 
-const u16 wFB_Opt0[2][5] = {
+static const u16 wFB_Opt0[2][5] = {
         {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
         {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
     };
-const u16 wFB_Opt1[2][5] = {
+static const u16 wFB_Opt1[2][5] = {
         {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
         {RATE_6M , RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
     };
@@ -278,7 +278,7 @@ static void s_vFillTxKey(struct vnt_private *pDevice,
                mic_hdr->tsc_15_0 = cpu_to_be16(pTransmitKey->wTSC15_0);
 
                /* MICHDR1 */
-               if (pDevice->bLongHeader)
+               if (ieee80211_has_a4(pMACHeader->frame_control))
                        mic_hdr->hlen = cpu_to_be16(28);
                else
                        mic_hdr->hlen = cpu_to_be16(22);
@@ -292,7 +292,7 @@ static void s_vFillTxKey(struct vnt_private *pDevice,
                                                                & 0xc78f);
                mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->seq_ctrl & 0xf);
 
-               if (pDevice->bLongHeader)
+               if (ieee80211_has_a4(pMACHeader->frame_control))
                        memcpy(mic_hdr->addr4, pMACHeader->addr4, ETH_ALEN);
        }
 }
@@ -790,7 +790,6 @@ static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
 {
        struct vnt_tx_fifo_head *pFifoHead = &tx_buffer->fifo_head;
        union vnt_tx_data_head *head = NULL;
-       u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
        u16 wFifoCtl;
        u8 byFBOption = AUTO_FB_NONE;
 
@@ -805,9 +804,6 @@ static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
        if (!pFifoHead)
                return 0;
 
-       if (pDevice->bLongHeader)
-               cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
-
        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
                if (need_rts) {
                        struct vnt_rrv_time_rts *pBuf =
@@ -978,28 +974,19 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
                        bSoftWEP = true; /* WEP 256 */
        }
 
-    // Get pkt type
-    if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
-        if (pDevice->dwDiagRefCount == 0) {
-            cb802_1_H_len = 8;
-        } else {
-            cb802_1_H_len = 2;
-        }
-    } else {
-        cb802_1_H_len = 0;
-    }
+       /* Get pkt type */
+       if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN)
+               cb802_1_H_len = 8;
+       else
+               cb802_1_H_len = 0;
 
     cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len;
 
     //Set packet type
     pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8);
 
-    if (pDevice->dwDiagRefCount != 0) {
-        bNeedACK = false;
-        pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
-    } else { //if (pDevice->dwDiagRefCount != 0) {
        if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
-           (pDevice->eOPMode == OP_MODE_AP)) {
+                       (pDevice->eOPMode == OP_MODE_AP)) {
                if (is_multicast_ether_addr(psEthHeader->h_dest)) {
                        bNeedACK = false;
                        pTxBufHead->wFIFOCtl =
@@ -1008,26 +995,17 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
                        bNeedACK = true;
                        pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
                }
-        }
-        else {
-            // MSDUs in Infra mode always need ACK
-            bNeedACK = true;
-            pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
-        }
-    } //if (pDevice->dwDiagRefCount != 0) {
+       } else {
+               /* MSDUs in Infra mode always need ACK */
+               bNeedACK = true;
+               pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+       }
 
     pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
 
-    //Set FIFOCTL_LHEAD
-    if (pDevice->bLongHeader)
-        pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
-
     //Set FRAGCTL_MACHDCNT
-    if (pDevice->bLongHeader) {
-        cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
-    } else {
-        cbMACHdLen = WLAN_HDR_ADDR3_LEN;
-    }
+       cbMACHdLen = WLAN_HDR_ADDR3_LEN;
+
     pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10);
 
     //Set FIFOCTL_GrpAckPolicy
@@ -1183,24 +1161,19 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
         }
     }
 
-    // 802.1H
-    if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
-       if (pDevice->dwDiagRefCount == 0) {
+       /* 802.1H */
+       if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
                if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) ||
-                   (psEthHeader->h_proto == cpu_to_le16(0xF380))) {
+                       (psEthHeader->h_proto == cpu_to_le16(0xF380)))
                        memcpy((u8 *) (pbyPayloadHead),
-                              abySNAP_Bridgetunnel, 6);
-            } else {
-                memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
-            }
-            pbyType = (u8 *) (pbyPayloadHead + 6);
-            memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16));
-        } else {
-            memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->h_proto), sizeof(u16));
+                                       abySNAP_Bridgetunnel, 6);
+               else
+                       memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
 
-        }
+               pbyType = (u8 *) (pbyPayloadHead + 6);
 
-    }
+               memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16));
+       }
 
     if (pPacket != NULL) {
         // Copy the Packet into a tx Buffer
@@ -1352,11 +1325,6 @@ static void s_vGenerateMACHeader(struct vnt_private *pDevice,
 
     pMACHeader->duration_id = cpu_to_le16(wDuration);
 
-    if (pDevice->bLongHeader) {
-        PWLAN_80211HDR_A4 pMACA4Header  = (PWLAN_80211HDR_A4) pbyBufferAddr;
-        pMACHeader->frame_control |= (FC_TODS | FC_FROMDS);
-        memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
-    }
     pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
 
     //Set FragNumber in Sequence Control
@@ -1494,7 +1462,6 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
     // Notes:
     // Although spec says MMPDU can be fragmented; In most case,
     // no one will send a MMPDU under fragmentation. With RTS may occur.
-    pDevice->bAES = false;  //Set FRAGCTL_WEPTYP
 
     if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
         if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
@@ -1515,7 +1482,6 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
             cbIVlen = 8;//RSN Header
             cbICVlen = 8;//MIC
             pTxBufHead->wFragCtl |= FRAGCTL_AES;
-            pDevice->bAES = true;
         }
         //MAC Header should be padding 0 to DW alignment.
         uPadding = 4 - (cbMacHdLen%4);
@@ -1659,16 +1625,13 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
        struct vnt_tx_mgmt *pPacket)
 {
        struct vnt_beacon_buffer *pTX_Buffer;
+       struct vnt_tx_short_buf_head *short_head;
        u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
        u32 cbHeaderSize = 0;
-       u16 wTxBufSize = sizeof(STxShortBufHead);
-       PSTxShortBufHead pTxBufHead;
        struct ieee80211_hdr *pMACHeader;
-       struct vnt_tx_datahead_ab *pTxDataHead;
        u16 wCurrentRate;
        u32 cbFrameBodySize;
        u32 cbReqCount;
-       u8 *pbyTxBufferAddr;
        struct vnt_usb_send_context *pContext;
        CMD_STATUS status;
 
@@ -1680,49 +1643,50 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
     }
 
        pTX_Buffer = (struct vnt_beacon_buffer *)&pContext->Data[0];
-    pbyTxBufferAddr = (u8 *)&(pTX_Buffer->wFIFOCtl);
+       short_head = &pTX_Buffer->short_head;
 
     cbFrameBodySize = pPacket->cbPayloadLen;
 
-    pTxBufHead = (PSTxShortBufHead) pbyTxBufferAddr;
-    wTxBufSize = sizeof(STxShortBufHead);
+       cbHeaderSize = sizeof(struct vnt_tx_short_buf_head);
 
-    if (pDevice->byBBType == BB_TYPE_11A) {
-        wCurrentRate = RATE_6M;
-       pTxDataHead = (struct vnt_tx_datahead_ab *)
-                       (pbyTxBufferAddr + wTxBufSize);
-        //Get SignalField,ServiceField,Length
-       BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A,
-                                                       &pTxDataHead->ab);
-        //Get Duration and TimeStampOff
-       pTxDataHead->wDuration = s_uGetDataDuration(pDevice,
-                                               PK_TYPE_11A, false);
-       pTxDataHead->wTimeStampOff = vnt_time_stamp_off(pDevice, wCurrentRate);
-       cbHeaderSize = wTxBufSize + sizeof(struct vnt_tx_datahead_ab);
-    } else {
-        wCurrentRate = RATE_1M;
-        pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
-       pTxDataHead = (struct vnt_tx_datahead_ab *)
-                               (pbyTxBufferAddr + wTxBufSize);
-        //Get SignalField,ServiceField,Length
-       BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B,
-                                                       &pTxDataHead->ab);
-        //Get Duration and TimeStampOff
-       pTxDataHead->wDuration = s_uGetDataDuration(pDevice,
+       if (pDevice->byBBType == BB_TYPE_11A) {
+               wCurrentRate = RATE_6M;
+
+               /* Get SignalField,ServiceField,Length */
+               BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate,
+                       PK_TYPE_11A, &short_head->ab);
+
+               /* Get Duration and TimeStampOff */
+               short_head->duration = s_uGetDataDuration(pDevice,
+                                                       PK_TYPE_11A, false);
+               short_head->time_stamp_off =
+                               vnt_time_stamp_off(pDevice, wCurrentRate);
+       } else {
+               wCurrentRate = RATE_1M;
+               short_head->fifo_ctl |= FIFOCTL_11B;
+
+               /* Get SignalField,ServiceField,Length */
+               BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate,
+                                       PK_TYPE_11B, &short_head->ab);
+
+               /* Get Duration and TimeStampOff */
+               short_head->duration = s_uGetDataDuration(pDevice,
                                                PK_TYPE_11B, false);
-       pTxDataHead->wTimeStampOff = vnt_time_stamp_off(pDevice, wCurrentRate);
-       cbHeaderSize = wTxBufSize + sizeof(struct vnt_tx_datahead_ab);
-    }
+               short_head->time_stamp_off =
+                       vnt_time_stamp_off(pDevice, wCurrentRate);
+       }
 
-    //Generate Beacon Header
-    pMACHeader = (struct ieee80211_hdr *)(pbyTxBufferAddr + cbHeaderSize);
-    memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
 
-    pMACHeader->duration_id = 0;
-    pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
-    pDevice->wSeqCounter++ ;
-    if (pDevice->wSeqCounter > 0x0fff)
-        pDevice->wSeqCounter = 0;
+       /* Generate Beacon Header */
+       pMACHeader = &pTX_Buffer->hdr;
+
+       memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
+
+       pMACHeader->duration_id = 0;
+       pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
+       pDevice->wSeqCounter++;
+       if (pDevice->wSeqCounter > 0x0fff)
+               pDevice->wSeqCounter = 0;
 
     cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
 
@@ -1892,7 +1856,6 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     // Notes:
     // Although spec says MMPDU can be fragmented; In most case,
     // no one will send a MMPDU under fragmentation. With RTS may occur.
-    pDevice->bAES = false;  //Set FRAGCTL_WEPTYP
 
     if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
         if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
@@ -1914,7 +1877,6 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
             cbICVlen = 8;//MIC
            cbMICHDR = sizeof(struct vnt_mic_hdr);
             pTxBufHead->wFragCtl |= FRAGCTL_AES;
-            pDevice->bAES = true;
         }
         //MAC Header should be padding 0 to DW alignment.
         uPadding = 4 - (cbMacHdLen%4);
index eecbe890027e50976461925022ac87e8dac9dfc8..b3ee6d01aa88a2af793b73754849592fe85f3ba9 100644 (file)
@@ -230,12 +230,20 @@ struct vnt_tx_buffer {
        union vnt_tx_head tx_head;
 } __packed;
 
+struct vnt_tx_short_buf_head {
+       u16 fifo_ctl;
+       u16 time_stamp;
+       struct vnt_phy_field ab;
+       u16 duration;
+       u16 time_stamp_off;
+} __packed;
+
 struct vnt_beacon_buffer {
        u8 byType;
        u8 byPKTNO;
        u16 wTxByteCount;
-       u16 wFIFOCtl;
-       u16 wTimeStamp;
+       struct vnt_tx_short_buf_head short_head;
+       struct ieee80211_hdr hdr;
 } __packed;
 
 void vDMA0_tx_80211(struct vnt_private *, struct sk_buff *skb);
index 9d643e449ac3c1ce97ecb84bd031820510c88415..28282f345901cc49cc55a46b297b91c64a19eb07 100644 (file)
@@ -39,7 +39,7 @@
 /* The 2nd table is the same as the 1st but with the upper and lower   */
 /* bytes swapped. To allow an endian tolerant implementation, the byte */
 /* halves have been expressed independently here.                      */
-const u8 TKIP_Sbox_Lower[256] = {
+static const u8 TKIP_Sbox_Lower[256] = {
     0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
     0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
     0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
@@ -74,7 +74,7 @@ const u8 TKIP_Sbox_Lower[256] = {
     0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
 };
 
-const u8 TKIP_Sbox_Upper[256] = {
+static const u8 TKIP_Sbox_Upper[256] = {
     0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
     0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
     0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
index 2f8e2a87533182a8f9bfa4fd3f62857067d8a731..6b9522914634fa3a7db5b69e89483db648ea8823 100644 (file)
@@ -55,8 +55,8 @@
 #include "channel.h"
 #include "iowpa.h"
 
-static int          msglevel                =MSG_LEVEL_INFO;
-//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int msglevel = MSG_LEVEL_INFO;
+//static int msglevel = MSG_LEVEL_DEBUG;
 
 static void s_vProbeChannel(struct vnt_private *);
 
@@ -87,38 +87,33 @@ static void vAdHocBeaconStop(struct vnt_private *pDevice)
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        int bStop;
 
-    /*
-     * temporarily stop Beacon packet for AdHoc Server
-     * if all of the following coditions are met:
-     *  (1) STA is in AdHoc mode
-     *  (2) VT3253 is programmed as automatic Beacon Transmitting
-     *  (3) One of the following conditions is met
-     *      (3.1) AdHoc channel is in B/G band and the
-     *      current scan channel is in A band
-     *      or
-     *      (3.2) AdHoc channel is in A mode
-     */
-    bStop = false;
-    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
-    (pMgmt->eCurrState >= WMAC_STATE_STARTED))
-    {
-        if ((pMgmt->uIBSSChannel <=  CB_MAX_CHANNEL_24G) &&
-             (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G))
-        {
-            bStop = true;
-        }
-        if (pMgmt->uIBSSChannel >  CB_MAX_CHANNEL_24G)
-        {
-            bStop = true;
-        }
-    }
-
-    if (bStop)
-    {
-        //PMESG(("STOP_BEACON: IBSSChannel = %u, ScanChannel = %u\n",
-        //        pMgmt->uIBSSChannel, pMgmt->uScanChannel));
-        MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
-    }
+       /*
+        * temporarily stop Beacon packet for AdHoc Server
+        * if all of the following coditions are met:
+        *  (1) STA is in AdHoc mode
+        *  (2) VT3253 is programmed as automatic Beacon Transmitting
+        *  (3) One of the following conditions is met
+        *      (3.1) AdHoc channel is in B/G band and the
+        *      current scan channel is in A band
+        *      or
+        *      (3.2) AdHoc channel is in A mode
+        */
+       bStop = false;
+       if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
+           (pMgmt->eCurrState >= WMAC_STATE_STARTED)) {
+               if ((pMgmt->uIBSSChannel <=  CB_MAX_CHANNEL_24G) &&
+                   (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) {
+                       bStop = true;
+               }
+               if (pMgmt->uIBSSChannel >  CB_MAX_CHANNEL_24G)
+                       bStop = true;
+       }
+
+       if (bStop) {
+               //PMESG(("STOP_BEACON: IBSSChannel = %u, ScanChannel = %u\n",
+               //        pMgmt->uIBSSChannel, pMgmt->uScanChannel));
+               MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+       }
 
 } /* vAdHocBeaconStop */
 
@@ -145,12 +140,11 @@ static void vAdHocBeaconRestart(struct vnt_private *pDevice)
      *  (1) STA is in AdHoc mode
      *  (2) VT3253 is programmed as automatic Beacon Transmitting
      */
-    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
-    (pMgmt->eCurrState >= WMAC_STATE_STARTED))
-    {
-        //PMESG(("RESTART_BEACON\n"));
-        MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
-    }
+       if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
+           (pMgmt->eCurrState >= WMAC_STATE_STARTED)) {
+               //PMESG(("RESTART_BEACON\n"));
+               MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+       }
 
 }
 
@@ -182,34 +176,33 @@ static void s_vProbeChannel(struct vnt_private *pDevice)
        u8 *pbyRate;
        int ii;
 
-    if (pDevice->byBBType == BB_TYPE_11A) {
-        pbyRate = &abyCurrSuppRatesA[0];
-    } else if (pDevice->byBBType == BB_TYPE_11B) {
-        pbyRate = &abyCurrSuppRatesB[0];
-    } else {
-        pbyRate = &abyCurrSuppRatesG[0];
-    }
-    // build an assocreq frame and send it
-    pTxPacket = s_MgrMakeProbeRequest
-                (
-                  pDevice,
-                  pMgmt,
-                  pMgmt->abyScanBSSID,
-                  (PWLAN_IE_SSID)pMgmt->abyScanSSID,
-                  (PWLAN_IE_SUPP_RATES)pbyRate,
-                  (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG
-                );
-
-    if (pTxPacket != NULL ){
-        for (ii = 0; ii < 1 ; ii++) {
-            if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n");
-            }
-            else {
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n");
-            }
-        }
-    }
+       if (pDevice->byBBType == BB_TYPE_11A)
+               pbyRate = &abyCurrSuppRatesA[0];
+       else if (pDevice->byBBType == BB_TYPE_11B)
+               pbyRate = &abyCurrSuppRatesB[0];
+       else
+               pbyRate = &abyCurrSuppRatesG[0];
+
+       // build an assocreq frame and send it
+       pTxPacket = s_MgrMakeProbeRequest
+                   (
+                    pDevice,
+                    pMgmt,
+                    pMgmt->abyScanBSSID,
+                    (PWLAN_IE_SSID)pMgmt->abyScanSSID,
+                    (PWLAN_IE_SUPP_RATES)pbyRate,
+                    (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG
+                    );
+
+       if (pTxPacket != NULL) {
+               for (ii = 0; ii < 1; ii++) {
+                       if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail..\n");
+                       } else {
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending..\n");
+                       }
+               }
+       }
 
 }
 
@@ -224,7 +217,7 @@ static void s_vProbeChannel(struct vnt_private *pDevice)
  *
 -*/
 
-struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice,
+static struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice,
        struct vnt_manager *pMgmt, u8 *pScanBSSID, PWLAN_IE_SSID pSSID,
        PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
 {
@@ -236,37 +229,38 @@ struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice,
                + WLAN_PROBEREQ_FR_MAXLEN);
        pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
                + sizeof(struct vnt_tx_mgmt));
-    sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
-    sFrame.len = WLAN_PROBEREQ_FR_MAXLEN;
-    vMgrEncodeProbeRequest(&sFrame);
-    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
-        (
-        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
-        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ)
-        ));
-    memcpy( sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN);
-    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
-    memcpy( sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN);
-    // Copy the SSID, pSSID->len=0 indicate broadcast SSID
-    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
-    sFrame.len += pSSID->len + WLAN_IEHDR_LEN;
-    memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
-    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
-    sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
-    memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
-    // Copy the extension rate set
-    if (pDevice->byBBType == BB_TYPE_11G) {
-        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
-        sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
-        memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
-    }
-    pTxPacket->cbMPDULen = sFrame.len;
-    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
-
-    return pTxPacket;
+       sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
+       sFrame.len = WLAN_PROBEREQ_FR_MAXLEN;
+       vMgrEncodeProbeRequest(&sFrame);
+       sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+               (
+                WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+                WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ)
+                ));
+       memcpy(sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN);
+       memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+       memcpy(sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN);
+       // Copy the SSID, pSSID->len=0 indicate broadcast SSID
+       sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+       sFrame.len += pSSID->len + WLAN_IEHDR_LEN;
+       memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
+       sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+       sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
+       memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+       // Copy the extension rate set
+       if (pDevice->byBBType == BB_TYPE_11G) {
+               sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+               sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
+               memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
+       }
+       pTxPacket->cbMPDULen = sFrame.len;
+       pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+       return pTxPacket;
 }
 
-void vCommandTimerWait(struct vnt_private *pDevice, unsigned long MSecond)
+static void
+vCommandTimerWait(struct vnt_private *pDevice, unsigned long MSecond)
 {
        schedule_delayed_work(&pDevice->run_command_work,
                                                msecs_to_jiffies(MSecond));
@@ -289,661 +283,639 @@ void vRunCommand(struct work_struct *work)
        if (pDevice->Flags & fMP_DISCONNECTED)
                return;
 
-    if (pDevice->dwDiagRefCount != 0)
-        return;
-    if (pDevice->bCmdRunning != true)
-        return;
+       if (pDevice->bCmdRunning != true)
+               return;
 
-    spin_lock_irq(&pDevice->lock);
+       spin_lock_irq(&pDevice->lock);
 
-    switch ( pDevice->eCommandState ) {
+       switch (pDevice->eCommandState) {
 
-        case WLAN_CMD_SCAN_START:
+       case WLAN_CMD_SCAN_START:
 
                pDevice->byReAssocCount = 0;
-            if (pDevice->bRadioOff == true) {
-                s_bCommandComplete(pDevice);
-                spin_unlock_irq(&pDevice->lock);
-                return;
-            }
-
-            if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
-                s_bCommandComplete(pDevice);
-                spin_unlock_irq(&pDevice->lock);
-                return;
-            }
-
-            pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID;
-
-            if (pMgmt->uScanChannel == 0 ) {
-                pMgmt->uScanChannel = pDevice->byMinChannel;
-            }
-            if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
-               pDevice->eCommandState = WLAN_CMD_SCAN_END;
-                s_bCommandComplete(pDevice);
-                spin_unlock_irq(&pDevice->lock);
-                return;
-
-            } else {
-                if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) {
-                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel);
+               if (pDevice->bRadioOff == true) {
+                       s_bCommandComplete(pDevice);
+                       spin_unlock_irq(&pDevice->lock);
+                       return;
+               }
+
+               if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+                       s_bCommandComplete(pDevice);
+                       spin_unlock_irq(&pDevice->lock);
+                       return;
+               }
+
+               pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID;
+
+               if (pMgmt->uScanChannel == 0)
+                       pMgmt->uScanChannel = pDevice->byMinChannel;
+               if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
+                       pDevice->eCommandState = WLAN_CMD_SCAN_END;
+                       s_bCommandComplete(pDevice);
+                       spin_unlock_irq(&pDevice->lock);
+                       return;
+               } else {
+                       if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) {
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d\n", pMgmt->uScanChannel);
+                               pMgmt->uScanChannel++;
+                               s_bCommandComplete(pDevice);
+                               spin_unlock_irq(&pDevice->lock);
+                               return;
+                       }
+                       if (pMgmt->uScanChannel == pDevice->byMinChannel) {
+                               // pMgmt->eScanType = WMAC_SCAN_ACTIVE;          //mike mark
+                               pMgmt->abyScanBSSID[0] = 0xFF;
+                               pMgmt->abyScanBSSID[1] = 0xFF;
+                               pMgmt->abyScanBSSID[2] = 0xFF;
+                               pMgmt->abyScanBSSID[3] = 0xFF;
+                               pMgmt->abyScanBSSID[4] = 0xFF;
+                               pMgmt->abyScanBSSID[5] = 0xFF;
+                               pItemSSID->byElementID = WLAN_EID_SSID;
+                               // clear bssid list
+                               /* BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); */
+                               pMgmt->eScanState = WMAC_IS_SCANNING;
+                               pDevice->byScanBBType = pDevice->byBBType;  //lucas
+                               pDevice->bStopDataPkt = true;
+                               // Turn off RCR_BSSID filter every time
+                               MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_BSSID);
+                               pDevice->byRxMode &= ~RCR_BSSID;
+                       }
+                       //lucas
+                       vAdHocBeaconStop(pDevice);
+                       if ((pDevice->byBBType != BB_TYPE_11A) &&
+                           (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) {
+                               pDevice->byBBType = BB_TYPE_11A;
+                               CARDvSetBSSMode(pDevice);
+                       } else if ((pDevice->byBBType == BB_TYPE_11A) &&
+                                  (pMgmt->uScanChannel <= CB_MAX_CHANNEL_24G)) {
+                               pDevice->byBBType = BB_TYPE_11G;
+                               CARDvSetBSSMode(pDevice);
+                       }
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning....  channel: [%d]\n", pMgmt->uScanChannel);
+                       // Set channel
+                       CARDbSetMediaChannel(pDevice, pMgmt->uScanChannel);
+                       // Set Baseband to be more sensitive.
+
+                       if (pDevice->bUpdateBBVGA) {
+                               BBvSetShortSlotTime(pDevice);
+                               BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+                               BBvUpdatePreEDThreshold(pDevice, true);
+                       }
                        pMgmt->uScanChannel++;
-                    s_bCommandComplete(pDevice);
-                    spin_unlock_irq(&pDevice->lock);
-                    return;
-                }
-                if (pMgmt->uScanChannel == pDevice->byMinChannel) {
-                   // pMgmt->eScanType = WMAC_SCAN_ACTIVE;          //mike mark
-                    pMgmt->abyScanBSSID[0] = 0xFF;
-                    pMgmt->abyScanBSSID[1] = 0xFF;
-                    pMgmt->abyScanBSSID[2] = 0xFF;
-                    pMgmt->abyScanBSSID[3] = 0xFF;
-                    pMgmt->abyScanBSSID[4] = 0xFF;
-                    pMgmt->abyScanBSSID[5] = 0xFF;
-                    pItemSSID->byElementID = WLAN_EID_SSID;
-                    // clear bssid list
-                   /* BSSvClearBSSList((void *) pDevice,
-                      pDevice->bLinkPass); */
-                    pMgmt->eScanState = WMAC_IS_SCANNING;
-                    pDevice->byScanBBType = pDevice->byBBType;  //lucas
-                    pDevice->bStopDataPkt = true;
-                    // Turn off RCR_BSSID filter every time
-                    MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_BSSID);
-                    pDevice->byRxMode &= ~RCR_BSSID;
-
-                }
-                //lucas
-                vAdHocBeaconStop(pDevice);
-                if ((pDevice->byBBType != BB_TYPE_11A) && (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) {
-                    pDevice->byBBType = BB_TYPE_11A;
-                    CARDvSetBSSMode(pDevice);
-                }
-                else if ((pDevice->byBBType == BB_TYPE_11A) && (pMgmt->uScanChannel <= CB_MAX_CHANNEL_24G)) {
-                    pDevice->byBBType = BB_TYPE_11G;
-                    CARDvSetBSSMode(pDevice);
-                }
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning....  channel: [%d]\n", pMgmt->uScanChannel);
-                // Set channel
-                CARDbSetMediaChannel(pDevice, pMgmt->uScanChannel);
-                // Set Baseband to be more sensitive.
-
-                if (pDevice->bUpdateBBVGA) {
-                    BBvSetShortSlotTime(pDevice);
-                    BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
-                    BBvUpdatePreEDThreshold(pDevice, true);
-                }
-                pMgmt->uScanChannel++;
-
-                while (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel) &&
-                        pMgmt->uScanChannel <= pDevice->byMaxChannel ){
-                    pMgmt->uScanChannel++;
-                }
-
-                if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
-                    // Set Baseband to be not sensitive and rescan
-                    pDevice->eCommandState = WLAN_CMD_SCAN_END;
-
-                }
-                if ((pMgmt->b11hEnable == false) ||
-                    (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
-                    s_vProbeChannel(pDevice);
-                    spin_unlock_irq(&pDevice->lock);
-                    vCommandTimerWait((void *) pDevice, 100);
-                    return;
-                } else {
-                    spin_unlock_irq(&pDevice->lock);
-                   vCommandTimerWait((void *) pDevice, WCMD_PASSIVE_SCAN_TIME);
-                    return;
-                }
-
-            }
-
-            break;
-
-        case WLAN_CMD_SCAN_END:
-
-            // Set Baseband's sensitivity back.
-            if (pDevice->byBBType != pDevice->byScanBBType) {
-                pDevice->byBBType = pDevice->byScanBBType;
-                CARDvSetBSSMode(pDevice);
-            }
-
-            if (pDevice->bUpdateBBVGA) {
-                BBvSetShortSlotTime(pDevice);
-                BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
-                BBvUpdatePreEDThreshold(pDevice, false);
-            }
-
-            // Set channel back
-            vAdHocBeaconRestart(pDevice);
-            // Set channel back
-            CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
-            // Set Filter
-            if (pMgmt->bCurrBSSIDFilterOn) {
-                MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
-                pDevice->byRxMode |= RCR_BSSID;
-            }
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
+
+                       while (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel) &&
+                               pMgmt->uScanChannel <= pDevice->byMaxChannel){
+                               pMgmt->uScanChannel++;
+                       }
+
+                       if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
+                               // Set Baseband to be not sensitive and rescan
+                               pDevice->eCommandState = WLAN_CMD_SCAN_END;
+                       }
+                       if ((pMgmt->b11hEnable == false) ||
+                           (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
+                               s_vProbeChannel(pDevice);
+                               spin_unlock_irq(&pDevice->lock);
+                               vCommandTimerWait((void *) pDevice, 100);
+                               return;
+                       } else {
+                               spin_unlock_irq(&pDevice->lock);
+                               vCommandTimerWait((void *) pDevice, WCMD_PASSIVE_SCAN_TIME);
+                               return;
+                       }
+               }
+
+               break;
+
+       case WLAN_CMD_SCAN_END:
+
+               // Set Baseband's sensitivity back.
+               if (pDevice->byBBType != pDevice->byScanBBType) {
+                       pDevice->byBBType = pDevice->byScanBBType;
+                       CARDvSetBSSMode(pDevice);
+               }
+
+               if (pDevice->bUpdateBBVGA) {
+                       BBvSetShortSlotTime(pDevice);
+                       BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+                       BBvUpdatePreEDThreshold(pDevice, false);
+               }
+
+               // Set channel back
+               vAdHocBeaconRestart(pDevice);
+               // Set channel back
+               CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
+               // Set Filter
+               if (pMgmt->bCurrBSSIDFilterOn) {
+                       MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+                       pDevice->byRxMode |= RCR_BSSID;
+               }
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
                pMgmt->uScanChannel = 0;
-            pMgmt->eScanState = WMAC_NO_SCANNING;
-            pDevice->bStopDataPkt = false;
+               pMgmt->eScanState = WMAC_NO_SCANNING;
+               pDevice->bStopDataPkt = false;
 
                /*send scan event to wpa_Supplicant*/
                PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
                memset(&wrqu, 0, sizeof(wrqu));
                wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
 
-            s_bCommandComplete(pDevice);
-            break;
+               s_bCommandComplete(pDevice);
+               break;
 
-        case WLAN_CMD_DISASSOCIATE_START :
+       case WLAN_CMD_DISASSOCIATE_START:
                pDevice->byReAssocCount = 0;
-            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
-                (pMgmt->eCurrState != WMAC_STATE_ASSOC)) {
-                s_bCommandComplete(pDevice);
-                spin_unlock_irq(&pDevice->lock);
-                return;
-            } else {
-
-                     pDevice->bwextstep0 = false;
-                        pDevice->bwextstep1 = false;
-                        pDevice->bwextstep2 = false;
-                        pDevice->bwextstep3 = false;
-                  pDevice->bWPASuppWextEnabled = false;
-                   pDevice->fWPA_Authened = false;
-
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
-                // reason = 8 : disassoc because sta has left
-               vMgrDisassocBeginSta((void *) pDevice,
-                                    pMgmt,
-                                    pMgmt->abyCurrBSSID,
-                                    (8),
-                                    &Status);
-                pDevice->bLinkPass = false;
-                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
-                // unlock command busy
-                pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
-                pItemSSID->len = 0;
-                memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
-                pMgmt->eCurrState = WMAC_STATE_IDLE;
-                pMgmt->sNodeDBTable[0].bActive = false;
-//                pDevice->bBeaconBufReady = false;
-            }
-            netif_stop_queue(pDevice->dev);
-            if (pDevice->bNeedRadioOFF == true)
-                CARDbRadioPowerOff(pDevice);
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_SSID_START:
+               if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+                   (pMgmt->eCurrState != WMAC_STATE_ASSOC)) {
+                       s_bCommandComplete(pDevice);
+                       spin_unlock_irq(&pDevice->lock);
+                       return;
+               } else {
+                       pDevice->bwextstep0 = false;
+                       pDevice->bwextstep1 = false;
+                       pDevice->bwextstep2 = false;
+                       pDevice->bwextstep3 = false;
+                       pDevice->bWPASuppWextEnabled = false;
+                       pDevice->fWPA_Authened = false;
+
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
+                       // reason = 8 : disassoc because sta has left
+                       vMgrDisassocBeginSta((void *) pDevice,
+                                            pMgmt,
+                                            pMgmt->abyCurrBSSID,
+                                            (8),
+                                            &Status);
+                       pDevice->bLinkPass = false;
+                       ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW);
+                       // unlock command busy
+                       pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+                       pItemSSID->len = 0;
+                       memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
+                       pMgmt->eCurrState = WMAC_STATE_IDLE;
+                       pMgmt->sNodeDBTable[0].bActive = false;
+//                     pDevice->bBeaconBufReady = false;
+               }
+               netif_stop_queue(pDevice->dev);
+               if (pDevice->bNeedRadioOFF == true)
+                       CARDbRadioPowerOff(pDevice);
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_SSID_START:
 
                pDevice->byReAssocCount = 0;
-            if (pDevice->bRadioOff == true) {
-                s_bCommandComplete(pDevice);
-                spin_unlock_irq(&pDevice->lock);
-                return;
-            }
-
-            memcpy(pMgmt->abyAdHocSSID,pMgmt->abyDesireSSID,
-                              ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN);
-
-            pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
-            pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID);
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);
-
-            if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n",pItemSSID->len);
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n",pItemSSIDCurr->len);
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID);
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID);
-            }
-
-            if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
-                ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)&& (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
-
-                if (pItemSSID->len == pItemSSIDCurr->len) {
-                    if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) {
-                        s_bCommandComplete(pDevice);
-                        spin_unlock_irq(&pDevice->lock);
-                        return;
-                    }
-                }
-                netif_stop_queue(pDevice->dev);
-                pDevice->bLinkPass = false;
-                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
-            }
-            // set initial state
-            pMgmt->eCurrState = WMAC_STATE_IDLE;
-            pMgmt->eCurrMode = WMAC_MODE_STANDBY;
-           PSvDisablePowerSaving((void *) pDevice);
-            BSSvClearNodeDBTable(pDevice, 0);
-           vMgrJoinBSSBegin((void *) pDevice, &Status);
-            // if Infra mode
-            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) {
-                // Call mgr to begin the deauthentication
-                // reason = (3) because sta has left ESS
-             if (pMgmt->eCurrState >= WMAC_STATE_AUTH) {
-               vMgrDeAuthenBeginSta((void *)pDevice,
-                                    pMgmt,
-                                    pMgmt->abyCurrBSSID,
-                                    (3),
-                                    &Status);
-             }
-                // Call mgr to begin the authentication
-               vMgrAuthenBeginSta((void *) pDevice, pMgmt, &Status);
-                if (Status == CMD_STATUS_SUCCESS) {
-                  pDevice->byLinkWaitCount = 0;
-                    pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT;
-                   vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT);
-                    spin_unlock_irq(&pDevice->lock);
-                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
-                    return;
-                }
-            }
-            // if Adhoc mode
-            else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
-                if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
-                    if (netif_queue_stopped(pDevice->dev)){
-                        netif_wake_queue(pDevice->dev);
-                    }
-                    pDevice->bLinkPass = true;
-                    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
-                    pMgmt->sNodeDBTable[0].bActive = true;
-                    pMgmt->sNodeDBTable[0].uInActiveCount = 0;
-                }
-                else {
-                    // start own IBSS
-                   DBG_PRT(MSG_LEVEL_DEBUG,
-                           KERN_INFO "CreateOwn IBSS by CurrMode = IBSS_STA\n");
-                   vMgrCreateOwnIBSS((void *) pDevice, &Status);
-                    if (Status != CMD_STATUS_SUCCESS){
-                       DBG_PRT(MSG_LEVEL_DEBUG,
-                               KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
-                    }
-                    BSSvAddMulticastNode(pDevice);
-                }
-                s_bClearBSSID_SCAN(pDevice);
-            }
-            // if SSID not found
-            else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) {
-                if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA ||
-                    pMgmt->eConfigMode == WMAC_CONFIG_AUTO) {
-                    // start own IBSS
-                       DBG_PRT(MSG_LEVEL_DEBUG,
-                               KERN_INFO "CreateOwn IBSS by CurrMode = STANDBY\n");
-                   vMgrCreateOwnIBSS((void *) pDevice, &Status);
-                    if (Status != CMD_STATUS_SUCCESS){
-                       DBG_PRT(MSG_LEVEL_DEBUG,
-                               KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
-                    }
-                    BSSvAddMulticastNode(pDevice);
-                    s_bClearBSSID_SCAN(pDevice);
+               if (pDevice->bRadioOff == true) {
+                       s_bCommandComplete(pDevice);
+                       spin_unlock_irq(&pDevice->lock);
+                       return;
+               }
+
+               memcpy(pMgmt->abyAdHocSSID, pMgmt->abyDesireSSID,
+                      ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN);
+
+               pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+               pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID);
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);
+
+               if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n", pItemSSID->len);
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n", pItemSSIDCurr->len);
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID);
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID);
+               }
+
+               if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
+                   ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
+                       if (pItemSSID->len == pItemSSIDCurr->len) {
+                               if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) {
+                                       s_bCommandComplete(pDevice);
+                                       spin_unlock_irq(&pDevice->lock);
+                                       return;
+                               }
+                       }
+                       netif_stop_queue(pDevice->dev);
+                       pDevice->bLinkPass = false;
+                       ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW);
+               }
+               // set initial state
+               pMgmt->eCurrState = WMAC_STATE_IDLE;
+               pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+               PSvDisablePowerSaving((void *) pDevice);
+               BSSvClearNodeDBTable(pDevice, 0);
+               vMgrJoinBSSBegin((void *) pDevice, &Status);
+               // if Infra mode
+               if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) {
+                       // Call mgr to begin the deauthentication
+                       // reason = (3) because sta has left ESS
+                       if (pMgmt->eCurrState >= WMAC_STATE_AUTH) {
+                               vMgrDeAuthenBeginSta((void *)pDevice,
+                                                    pMgmt,
+                                                    pMgmt->abyCurrBSSID,
+                                                    (3),
+                                                    &Status);
+                       }
+                       // Call mgr to begin the authentication
+                       vMgrAuthenBeginSta((void *) pDevice, pMgmt, &Status);
+                       if (Status == CMD_STATUS_SUCCESS) {
+                               pDevice->byLinkWaitCount = 0;
+                               pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT;
+                               vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT);
+                               spin_unlock_irq(&pDevice->lock);
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
+                               return;
+                       }
+               }
+               // if Adhoc mode
+               else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+                       if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
+                               if (netif_queue_stopped(pDevice->dev))
+                                       netif_wake_queue(pDevice->dev);
+                               pDevice->bLinkPass = true;
+                               ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_INTER);
+                               pMgmt->sNodeDBTable[0].bActive = true;
+                               pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+                       } else {
+                               // start own IBSS
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CreateOwn IBSS by CurrMode = IBSS_STA\n");
+                               vMgrCreateOwnIBSS((void *) pDevice, &Status);
+                               if (Status != CMD_STATUS_SUCCESS) {
+                                       DBG_PRT(MSG_LEVEL_DEBUG,
+                                               KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
+                               }
+                               BSSvAddMulticastNode(pDevice);
+                       }
+                       s_bClearBSSID_SCAN(pDevice);
+               }
+               // if SSID not found
+               else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) {
+                       if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA ||
+                           pMgmt->eConfigMode == WMAC_CONFIG_AUTO) {
+                               // start own IBSS
+                               DBG_PRT(MSG_LEVEL_DEBUG,
+                                       KERN_INFO "CreateOwn IBSS by CurrMode = STANDBY\n");
+                               vMgrCreateOwnIBSS((void *) pDevice, &Status);
+                               if (Status != CMD_STATUS_SUCCESS) {
+                                       DBG_PRT(MSG_LEVEL_DEBUG,
+                                               KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
+                               }
+                               BSSvAddMulticastNode(pDevice);
+                               s_bClearBSSID_SCAN(pDevice);
 /*
-                    pDevice->bLinkPass = true;
-                    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
-                    if (netif_queue_stopped(pDevice->dev)){
-                        netif_wake_queue(pDevice->dev);
-                    }
-                    s_bClearBSSID_SCAN(pDevice);
+                               pDevice->bLinkPass = true;
+                               ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+                               if (netif_queue_stopped(pDevice->dev)){
+                                       netif_wake_queue(pDevice->dev);
+                               }
+                               s_bClearBSSID_SCAN(pDevice);
 */
-                }
-                else {
-                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
-                    // if(pDevice->bWPASuppWextEnabled == true)
-                        {
-                       union iwreq_data  wrqu;
-                       memset(&wrqu, 0, sizeof (wrqu));
-                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-                       PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
-                       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
-                       }
-                }
-            }
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_AUTHENTICATE_WAIT :
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n");
-            if (pMgmt->eCurrState == WMAC_STATE_AUTH) {
+                       } else {
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
+                               // if(pDevice->bWPASuppWextEnabled == true)
+                               {
+                                       union iwreq_data  wrqu;
+                                       memset(&wrqu, 0, sizeof(wrqu));
+                                       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                                       PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
+                                       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                               }
+                       }
+               }
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_AUTHENTICATE_WAIT:
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n");
+               if (pMgmt->eCurrState == WMAC_STATE_AUTH) {
+                       pDevice->byLinkWaitCount = 0;
+                       // Call mgr to begin the association
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n");
+                       vMgrAssocBeginSta((void *) pDevice, pMgmt, &Status);
+                       if (Status == CMD_STATUS_SUCCESS) {
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n");
+                               pDevice->byLinkWaitCount = 0;
+                               pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
+                               vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT);
+                               spin_unlock_irq(&pDevice->lock);
+                               return;
+                       }
+               } else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) {
+                       printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
+               } else if (pDevice->byLinkWaitCount <= 4) {
+                       //mike add:wait another 2 sec if authenticated_frame delay!
+                       pDevice->byLinkWaitCount++;
+                       printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
+                       spin_unlock_irq(&pDevice->lock);
+                       vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT/2);
+                       return;
+               }
                pDevice->byLinkWaitCount = 0;
-                // Call mgr to begin the association
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n");
-               vMgrAssocBeginSta((void *) pDevice, pMgmt, &Status);
-                if (Status == CMD_STATUS_SUCCESS) {
-                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n");
-                 pDevice->byLinkWaitCount = 0;
-                    pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
-                   vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT);
-                    spin_unlock_irq(&pDevice->lock);
-                    return;
-                }
-            }
-          else if(pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) {
-               printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
-          }
-          else  if(pDevice->byLinkWaitCount <= 4){    //mike add:wait another 2 sec if authenticated_frame delay!
-                pDevice->byLinkWaitCount ++;
-              printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount);
-              spin_unlock_irq(&pDevice->lock);
-              vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT/2);
-              return;
-          }
-                 pDevice->byLinkWaitCount = 0;
-
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_ASSOCIATE_WAIT :
-            if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n");
-                if (pDevice->ePSMode != WMAC_POWER_CAM) {
-                       PSvEnablePowerSaving((void *) pDevice,
-                                            pMgmt->wListenInterval);
-                }
+
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_ASSOCIATE_WAIT:
+               if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n");
+                       if (pDevice->ePSMode != WMAC_POWER_CAM) {
+                               PSvEnablePowerSaving((void *) pDevice,
+                                               pMgmt->wListenInterval);
+                       }
 /*
-                if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) {
-                    KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
-                }
+                       if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) {
+                               KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
+                       }
 */
-                pDevice->byLinkWaitCount = 0;
-                pDevice->byReAssocCount = 0;
-                pDevice->bLinkPass = true;
-                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
-                s_bClearBSSID_SCAN(pDevice);
-
-                if (netif_queue_stopped(pDevice->dev)){
-                    netif_wake_queue(pDevice->dev);
-                }
-
-            }
-          else if(pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
-               printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
-          }
-          else  if(pDevice->byLinkWaitCount <= 4){    //mike add:wait another 2 sec if associated_frame delay!
-                pDevice->byLinkWaitCount ++;
-              printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount);
-              spin_unlock_irq(&pDevice->lock);
-              vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT/2);
-              return;
-          }
-
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_AP_MODE_START :
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n");
-
-            if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
-               cancel_delayed_work_sync(&pDevice->second_callback_work);
-                pMgmt->eCurrState = WMAC_STATE_IDLE;
-                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
-                pDevice->bLinkPass = false;
-                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
-                if (pDevice->bEnableHostWEP == true)
-                    BSSvClearNodeDBTable(pDevice, 1);
-                else
-                    BSSvClearNodeDBTable(pDevice, 0);
-                pDevice->uAssocCount = 0;
-                pMgmt->eCurrState = WMAC_STATE_IDLE;
-                pDevice->bFixRate = false;
-
-               vMgrCreateOwnIBSS((void *) pDevice, &Status);
-               if (Status != CMD_STATUS_SUCCESS) {
-                       DBG_PRT(MSG_LEVEL_DEBUG,
-                               KERN_INFO "vMgrCreateOwnIBSS fail!\n");
-                }
-                // always turn off unicast bit
-                MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST);
-                pDevice->byRxMode &= ~RCR_UNICAST;
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode );
-                BSSvAddMulticastNode(pDevice);
-                if (netif_queue_stopped(pDevice->dev)){
-                    netif_wake_queue(pDevice->dev);
-                }
-                pDevice->bLinkPass = true;
-                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
-               schedule_delayed_work(&pDevice->second_callback_work, HZ);
-            }
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_TX_PSPACKET_START :
-            // DTIM Multicast tx
-            if (pMgmt->sNodeDBTable[0].bRxPSPoll) {
-                while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) {
-                    if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) {
-                        pMgmt->abyPSTxMap[0] &= ~byMask[0];
-                        pDevice->bMoreData = false;
-                    }
-                    else {
-                        pDevice->bMoreData = true;
-                    }
-
-                    if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) {
-                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n");
-                    }
-
-                    pMgmt->sNodeDBTable[0].wEnQueueCnt--;
-                }
-            }
-
-            // PS nodes tx
-            for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
-                if (pMgmt->sNodeDBTable[ii].bActive &&
-                    pMgmt->sNodeDBTable[ii].bRxPSPoll) {
-                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n",
-                               ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
-                    while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
-                        if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
-                            // clear tx map
-                            pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
-                                    ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
-                            pDevice->bMoreData = false;
-                        }
-                        else {
-                            pDevice->bMoreData = true;
-                        }
-
-                        if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) {
-                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n");
-                        }
-
-                        pMgmt->sNodeDBTable[ii].wEnQueueCnt--;
-                        // check if sta ps enable, wait next pspoll
-                        // if sta ps disable, send all pending buffers.
-                        if (pMgmt->sNodeDBTable[ii].bPSEnable)
-                            break;
-                    }
-                    if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
-                        // clear tx map
-                        pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
-                                    ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
-                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii);
-                    }
-                    pMgmt->sNodeDBTable[ii].bRxPSPoll = false;
-                }
-            }
-
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_RADIO_START:
-
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n");
-       //     if (pDevice->bRadioCmd == true)
-       //         CARDbRadioPowerOn(pDevice);
-       //     else
-       //         CARDbRadioPowerOff(pDevice);
-
-       {
-              int ntStatus = STATUS_SUCCESS;
-        u8            byTmp;
-
-        ntStatus = CONTROLnsRequestIn(pDevice,
-                                    MESSAGE_TYPE_READ,
-                                    MAC_REG_GPIOCTL1,
-                                    MESSAGE_REQUEST_MACREG,
-                                    1,
-                                    &byTmp);
-
-        if ( ntStatus != STATUS_SUCCESS ) {
-                s_bCommandComplete(pDevice);
-                spin_unlock_irq(&pDevice->lock);
-                return;
-        }
-        if ( (byTmp & GPIO3_DATA) == 0 ) {
-           DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_OFF........................\n");
-                // Old commands are useless.
-                // empty command Q
-              pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
-                pDevice->uCmdDequeueIdx = 0;
-                pDevice->uCmdEnqueueIdx = 0;
-                //0415pDevice->bCmdRunning = false;
-                pDevice->bCmdClear = true;
-                pDevice->bStopTx0Pkt = false;
-                pDevice->bStopDataPkt = true;
-
-                pDevice->byKeyIndex = 0;
-                pDevice->bTransmitKey = false;
-           spin_unlock_irq(&pDevice->lock);
-           KeyvInitTable(pDevice,&pDevice->sKey);
-           spin_lock_irq(&pDevice->lock);
-              pMgmt->byCSSPK = KEY_CTL_NONE;
-                pMgmt->byCSSGK = KEY_CTL_NONE;
-
-         if (pDevice->bLinkPass == true) {
-                // reason = 8 : disassoc because sta has left
-               vMgrDisassocBeginSta((void *) pDevice,
-                                    pMgmt,
-                                    pMgmt->abyCurrBSSID,
-                                    (8),
-                                    &Status);
-                       pDevice->bLinkPass = false;
-                // unlock command busy
-                        pMgmt->eCurrState = WMAC_STATE_IDLE;
-                        pMgmt->sNodeDBTable[0].bActive = false;
-                    // if(pDevice->bWPASuppWextEnabled == true)
-                        {
-                       union iwreq_data  wrqu;
-                       memset(&wrqu, 0, sizeof (wrqu));
-                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-                       PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
-                       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
-                       }
-               }
-                      pDevice->bwextstep0 = false;
-                        pDevice->bwextstep1 = false;
-                        pDevice->bwextstep2 = false;
-                        pDevice->bwextstep3 = false;
-                     pDevice->bWPASuppWextEnabled = false;
-                         //clear current SSID
-                  pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
-                  pItemSSID->len = 0;
-                  memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
-                //clear desired SSID
-                pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
-                pItemSSID->len = 0;
-                memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
-
-           netif_stop_queue(pDevice->dev);
-           CARDbRadioPowerOff(pDevice);
-             MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
-           ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_OFF);
-           pDevice->bHWRadioOff = true;
-        } else {
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_ON........................\n");
-            pDevice->bHWRadioOff = false;
-                CARDbRadioPowerOn(pDevice);
-            MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
-            ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_ON);
-        }
-      }
-
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_CHANGE_BBSENSITIVITY_START:
-
-            pDevice->bStopDataPkt = true;
-            pDevice->byBBVGACurrent = pDevice->byBBVGANew;
-            BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change sensitivity pDevice->byBBVGACurrent = %x\n", pDevice->byBBVGACurrent);
-            pDevice->bStopDataPkt = false;
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_TBTT_WAKEUP_START:
-            PSbIsNextTBTTWakeUp(pDevice);
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_BECON_SEND_START:
-            bMgrPrepareBeaconToSend(pDevice, pMgmt);
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_SETPOWER_START:
-
-            RFbSetPower(pDevice, pDevice->wCurrentRate, pMgmt->uCurrChannel);
-
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_CHANGE_ANTENNA_START:
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change from Antenna%d to", (int)pDevice->dwRxAntennaSel);
-            if ( pDevice->dwRxAntennaSel == 0) {
-                pDevice->dwRxAntennaSel=1;
-                if (pDevice->bTxRxAntInv == true)
-                    BBvSetAntennaMode(pDevice, ANT_RXA);
-                else
-                    BBvSetAntennaMode(pDevice, ANT_RXB);
-            } else {
-                pDevice->dwRxAntennaSel=0;
-                if (pDevice->bTxRxAntInv == true)
-                    BBvSetAntennaMode(pDevice, ANT_RXB);
-                else
-                    BBvSetAntennaMode(pDevice, ANT_RXA);
-            }
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_REMOVE_ALLKEY_START:
-            KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_MAC_DISPOWERSAVING_START:
-            ControlvReadByte (pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData);
-            if ( (byData & PSCTL_PS) != 0 ) {
-                // disable power saving hw function
-                CONTROLnsRequestOut(pDevice,
-                                MESSAGE_TYPE_DISABLE_PS,
-                                0,
-                                0,
-                                0,
-                                NULL
-                                );
-            }
-            s_bCommandComplete(pDevice);
-            break;
-
-        case WLAN_CMD_11H_CHSW_START:
-            CARDbSetMediaChannel(pDevice, pDevice->byNewChannel);
-            pDevice->bChannelSwitch = false;
-            pMgmt->uCurrChannel = pDevice->byNewChannel;
-            pDevice->bStopDataPkt = false;
-            s_bCommandComplete(pDevice);
-            break;
-
-        default:
-            s_bCommandComplete(pDevice);
-            break;
-    } //switch
-
-    spin_unlock_irq(&pDevice->lock);
-    return;
+                       pDevice->byLinkWaitCount = 0;
+                       pDevice->byReAssocCount = 0;
+                       pDevice->bLinkPass = true;
+                       ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_INTER);
+                       s_bClearBSSID_SCAN(pDevice);
+
+                       if (netif_queue_stopped(pDevice->dev))
+                               netif_wake_queue(pDevice->dev);
+
+               } else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
+                       printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
+               } else if (pDevice->byLinkWaitCount <= 4) {
+                       //mike add:wait another 2 sec if associated_frame delay!
+                       pDevice->byLinkWaitCount++;
+                       printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
+                       spin_unlock_irq(&pDevice->lock);
+                       vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT/2);
+                       return;
+               }
+
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_AP_MODE_START:
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n");
+
+               if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+                       cancel_delayed_work_sync(&pDevice->second_callback_work);
+                       pMgmt->eCurrState = WMAC_STATE_IDLE;
+                       pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                       pDevice->bLinkPass = false;
+                       ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW);
+                       if (pDevice->bEnableHostWEP == true)
+                               BSSvClearNodeDBTable(pDevice, 1);
+                       else
+                               BSSvClearNodeDBTable(pDevice, 0);
+                       pDevice->uAssocCount = 0;
+                       pMgmt->eCurrState = WMAC_STATE_IDLE;
+                       pDevice->bFixRate = false;
+
+                       vMgrCreateOwnIBSS((void *) pDevice, &Status);
+                       if (Status != CMD_STATUS_SUCCESS) {
+                               DBG_PRT(MSG_LEVEL_DEBUG,
+                                       KERN_INFO "vMgrCreateOwnIBSS fail!\n");
+                       }
+                       // always turn off unicast bit
+                       MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST);
+                       pDevice->byRxMode &= ~RCR_UNICAST;
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode);
+                       BSSvAddMulticastNode(pDevice);
+                       if (netif_queue_stopped(pDevice->dev))
+                               netif_wake_queue(pDevice->dev);
+                       pDevice->bLinkPass = true;
+                       ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_INTER);
+                       schedule_delayed_work(&pDevice->second_callback_work, HZ);
+               }
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_TX_PSPACKET_START:
+               // DTIM Multicast tx
+               if (pMgmt->sNodeDBTable[0].bRxPSPoll) {
+                       while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) {
+                               if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) {
+                                       pMgmt->abyPSTxMap[0] &= ~byMask[0];
+                                       pDevice->bMoreData = false;
+                               } else {
+                                       pDevice->bMoreData = true;
+                               }
+
+                               if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0)
+                                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail\n");
+
+                               pMgmt->sNodeDBTable[0].wEnQueueCnt--;
+                       }
+               }
+
+               // PS nodes tx
+               for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
+                       if (pMgmt->sNodeDBTable[ii].bActive &&
+                           pMgmt->sNodeDBTable[ii].bRxPSPoll) {
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n",
+                                               ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
+                               while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
+                                       if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
+                                               // clear tx map
+                                               pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
+                                                                       ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
+                                               pDevice->bMoreData = false;
+                                       } else {
+                                               pDevice->bMoreData = true;
+                                       }
+
+                                       if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0)
+                                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail\n");
+
+                                       pMgmt->sNodeDBTable[ii].wEnQueueCnt--;
+                                       // check if sta ps enable, wait next pspoll
+                                       // if sta ps disable, send all pending buffers.
+                                       if (pMgmt->sNodeDBTable[ii].bPSEnable)
+                                               break;
+                               }
+                               if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
+                                       // clear tx map
+                                       pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
+                                                       ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
+                                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear\n", ii);
+                               }
+                               pMgmt->sNodeDBTable[ii].bRxPSPoll = false;
+                       }
+               }
+
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_RADIO_START:
+
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n");
+//             if (pDevice->bRadioCmd == true)
+//                     CARDbRadioPowerOn(pDevice);
+//             else
+//                     CARDbRadioPowerOff(pDevice);
+               {
+                       int ntStatus = STATUS_SUCCESS;
+                       u8            byTmp;
+
+                       ntStatus = CONTROLnsRequestIn(pDevice,
+                                       MESSAGE_TYPE_READ,
+                                       MAC_REG_GPIOCTL1,
+                                       MESSAGE_REQUEST_MACREG,
+                                       1,
+                                       &byTmp);
+
+                       if (ntStatus != STATUS_SUCCESS) {
+                               s_bCommandComplete(pDevice);
+                               spin_unlock_irq(&pDevice->lock);
+                               return;
+                       }
+                       if ((byTmp & GPIO3_DATA) == 0) {
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_OFF........................\n");
+                               // Old commands are useless.
+                               // empty command Q
+                               pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
+                               pDevice->uCmdDequeueIdx = 0;
+                               pDevice->uCmdEnqueueIdx = 0;
+                               //0415pDevice->bCmdRunning = false;
+                               pDevice->bCmdClear = true;
+                               pDevice->bStopTx0Pkt = false;
+                               pDevice->bStopDataPkt = true;
+
+                               pDevice->byKeyIndex = 0;
+                               pDevice->bTransmitKey = false;
+                               spin_unlock_irq(&pDevice->lock);
+                               KeyvInitTable(pDevice, &pDevice->sKey);
+                               spin_lock_irq(&pDevice->lock);
+                               pMgmt->byCSSPK = KEY_CTL_NONE;
+                               pMgmt->byCSSGK = KEY_CTL_NONE;
+
+                               if (pDevice->bLinkPass == true) {
+                                       // reason = 8 : disassoc because sta has left
+                                       vMgrDisassocBeginSta((void *) pDevice,
+                                                       pMgmt,
+                                                       pMgmt->abyCurrBSSID,
+                                                       (8),
+                                                       &Status);
+                                       pDevice->bLinkPass = false;
+                                       // unlock command busy
+                                       pMgmt->eCurrState = WMAC_STATE_IDLE;
+                                       pMgmt->sNodeDBTable[0].bActive = false;
+                                       // if(pDevice->bWPASuppWextEnabled == true)
+                                       {
+                                               union iwreq_data  wrqu;
+                                               memset(&wrqu, 0, sizeof(wrqu));
+                                               wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                                               PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+                                               wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                                       }
+                               }
+                               pDevice->bwextstep0 = false;
+                               pDevice->bwextstep1 = false;
+                               pDevice->bwextstep2 = false;
+                               pDevice->bwextstep3 = false;
+                               pDevice->bWPASuppWextEnabled = false;
+                               //clear current SSID
+                               pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+                               pItemSSID->len = 0;
+                               memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
+                               //clear desired SSID
+                               pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+                               pItemSSID->len = 0;
+                               memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
+
+                               netif_stop_queue(pDevice->dev);
+                               CARDbRadioPowerOff(pDevice);
+                               MACvRegBitsOn(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD);
+                               ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_OFF);
+                               pDevice->bHWRadioOff = true;
+                       } else {
+                               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_ON........................\n");
+                               pDevice->bHWRadioOff = false;
+                               CARDbRadioPowerOn(pDevice);
+                               MACvRegBitsOff(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD);
+                               ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_ON);
+                       }
+               }
+
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_CHANGE_BBSENSITIVITY_START:
+
+               pDevice->bStopDataPkt = true;
+               pDevice->byBBVGACurrent = pDevice->byBBVGANew;
+               BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change sensitivity pDevice->byBBVGACurrent = %x\n", pDevice->byBBVGACurrent);
+               pDevice->bStopDataPkt = false;
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_TBTT_WAKEUP_START:
+               PSbIsNextTBTTWakeUp(pDevice);
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_BECON_SEND_START:
+               bMgrPrepareBeaconToSend(pDevice, pMgmt);
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_SETPOWER_START:
+
+               RFbSetPower(pDevice, pDevice->wCurrentRate, pMgmt->uCurrChannel);
+
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_CHANGE_ANTENNA_START:
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change from Antenna%d to", (int)pDevice->dwRxAntennaSel);
+               if (pDevice->dwRxAntennaSel == 0) {
+                       pDevice->dwRxAntennaSel = 1;
+                       if (pDevice->bTxRxAntInv == true)
+                               BBvSetAntennaMode(pDevice, ANT_RXA);
+                       else
+                               BBvSetAntennaMode(pDevice, ANT_RXB);
+               } else {
+                       pDevice->dwRxAntennaSel = 0;
+                       if (pDevice->bTxRxAntInv == true)
+                               BBvSetAntennaMode(pDevice, ANT_RXB);
+                       else
+                               BBvSetAntennaMode(pDevice, ANT_RXA);
+               }
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_REMOVE_ALLKEY_START:
+               KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_MAC_DISPOWERSAVING_START:
+               ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData);
+               if ((byData & PSCTL_PS) != 0) {
+                       // disable power saving hw function
+                       CONTROLnsRequestOut(pDevice,
+                                       MESSAGE_TYPE_DISABLE_PS,
+                                       0,
+                                       0,
+                                       0,
+                                       NULL
+                                       );
+               }
+               s_bCommandComplete(pDevice);
+               break;
+
+       case WLAN_CMD_11H_CHSW_START:
+               CARDbSetMediaChannel(pDevice, pDevice->byNewChannel);
+               pDevice->bChannelSwitch = false;
+               pMgmt->uCurrChannel = pDevice->byNewChannel;
+               pDevice->bStopDataPkt = false;
+               s_bCommandComplete(pDevice);
+               break;
+
+       default:
+               s_bCommandComplete(pDevice);
+               break;
+       } //switch
+
+       spin_unlock_irq(&pDevice->lock);
+       return;
 }
 
 static int s_bCommandComplete(struct vnt_private *pDevice)
@@ -953,152 +925,146 @@ static int s_bCommandComplete(struct vnt_private *pDevice)
        int bRadioCmd = false;
        int bForceSCAN = true;
 
-    pDevice->eCommandState = WLAN_CMD_IDLE;
-    if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) {
-        //Command Queue Empty
-        pDevice->bCmdRunning = false;
-        return true;
-    }
-    else {
-        pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd;
-        pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID;
-        bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd;
-        bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN;
-        ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE);
-        pDevice->cbFreeCmdQueue++;
-        pDevice->bCmdRunning = true;
-        switch ( pDevice->eCommand ) {
-            case WLAN_CMD_BSSID_SCAN:
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n");
-                pDevice->eCommandState = WLAN_CMD_SCAN_START;
-                pMgmt->uScanChannel = 0;
-                if (pSSID->len != 0) {
-                    memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-                } else {
-                    memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-                }
+       pDevice->eCommandState = WLAN_CMD_IDLE;
+       if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) {
+               //Command Queue Empty
+               pDevice->bCmdRunning = false;
+               return true;
+       } else {
+               pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd;
+               pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID;
+               bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd;
+               bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN;
+               ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE);
+               pDevice->cbFreeCmdQueue++;
+               pDevice->bCmdRunning = true;
+               switch (pDevice->eCommand) {
+               case WLAN_CMD_BSSID_SCAN:
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n");
+                       pDevice->eCommandState = WLAN_CMD_SCAN_START;
+                       pMgmt->uScanChannel = 0;
+                       if (pSSID->len != 0)
+                               memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                       else
+                               memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
 /*
-                if ((bForceSCAN == false) && (pDevice->bLinkPass == true)) {
-                    if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) &&
-                        ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) {
-                        pDevice->eCommandState = WLAN_CMD_IDLE;
-                    }
-                }
+                       if ((bForceSCAN == false) && (pDevice->bLinkPass == true)) {
+                               if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) &&
+                                   ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) {
+                                       pDevice->eCommandState = WLAN_CMD_IDLE;
+                               }
+                       }
 */
-                break;
-            case WLAN_CMD_SSID:
-                pDevice->eCommandState = WLAN_CMD_SSID_START;
-                if (pSSID->len > WLAN_SSID_MAXLEN)
-                    pSSID->len = WLAN_SSID_MAXLEN;
-                if (pSSID->len != 0)
-                    memcpy(pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n");
-                break;
-            case WLAN_CMD_DISASSOCIATE:
-                pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START;
-                break;
-            case WLAN_CMD_RX_PSPOLL:
-                pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START;
-                break;
-            case WLAN_CMD_RUN_AP:
-                pDevice->eCommandState = WLAN_CMD_AP_MODE_START;
-                break;
-            case WLAN_CMD_RADIO:
-                pDevice->eCommandState = WLAN_CMD_RADIO_START;
-                pDevice->bRadioCmd = bRadioCmd;
-                break;
-            case WLAN_CMD_CHANGE_BBSENSITIVITY:
-                pDevice->eCommandState = WLAN_CMD_CHANGE_BBSENSITIVITY_START;
-                break;
-
-            case WLAN_CMD_TBTT_WAKEUP:
-                pDevice->eCommandState = WLAN_CMD_TBTT_WAKEUP_START;
-                break;
-
-            case WLAN_CMD_BECON_SEND:
-                pDevice->eCommandState = WLAN_CMD_BECON_SEND_START;
-                break;
-
-            case WLAN_CMD_SETPOWER:
-                pDevice->eCommandState = WLAN_CMD_SETPOWER_START;
-                break;
-
-            case WLAN_CMD_CHANGE_ANTENNA:
-                pDevice->eCommandState = WLAN_CMD_CHANGE_ANTENNA_START;
-                break;
-
-            case WLAN_CMD_REMOVE_ALLKEY:
-                pDevice->eCommandState = WLAN_CMD_REMOVE_ALLKEY_START;
-                break;
-
-            case WLAN_CMD_MAC_DISPOWERSAVING:
-                pDevice->eCommandState = WLAN_CMD_MAC_DISPOWERSAVING_START;
-                break;
-
-            case WLAN_CMD_11H_CHSW:
-                pDevice->eCommandState = WLAN_CMD_11H_CHSW_START;
-                break;
-
-            default:
-                break;
-
-        }
-       vCommandTimerWait(pDevice, 0);
-    }
-
-    return true;
+                       break;
+               case WLAN_CMD_SSID:
+                       pDevice->eCommandState = WLAN_CMD_SSID_START;
+                       if (pSSID->len > WLAN_SSID_MAXLEN)
+                               pSSID->len = WLAN_SSID_MAXLEN;
+                       if (pSSID->len != 0)
+                               memcpy(pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n");
+                       break;
+               case WLAN_CMD_DISASSOCIATE:
+                       pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START;
+                       break;
+               case WLAN_CMD_RX_PSPOLL:
+                       pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START;
+                       break;
+               case WLAN_CMD_RUN_AP:
+                       pDevice->eCommandState = WLAN_CMD_AP_MODE_START;
+                       break;
+               case WLAN_CMD_RADIO:
+                       pDevice->eCommandState = WLAN_CMD_RADIO_START;
+                       pDevice->bRadioCmd = bRadioCmd;
+                       break;
+               case WLAN_CMD_CHANGE_BBSENSITIVITY:
+                       pDevice->eCommandState = WLAN_CMD_CHANGE_BBSENSITIVITY_START;
+                       break;
+
+               case WLAN_CMD_TBTT_WAKEUP:
+                       pDevice->eCommandState = WLAN_CMD_TBTT_WAKEUP_START;
+                       break;
+
+               case WLAN_CMD_BECON_SEND:
+                       pDevice->eCommandState = WLAN_CMD_BECON_SEND_START;
+                       break;
+
+               case WLAN_CMD_SETPOWER:
+                       pDevice->eCommandState = WLAN_CMD_SETPOWER_START;
+                       break;
+
+               case WLAN_CMD_CHANGE_ANTENNA:
+                       pDevice->eCommandState = WLAN_CMD_CHANGE_ANTENNA_START;
+                       break;
+
+               case WLAN_CMD_REMOVE_ALLKEY:
+                       pDevice->eCommandState = WLAN_CMD_REMOVE_ALLKEY_START;
+                       break;
+
+               case WLAN_CMD_MAC_DISPOWERSAVING:
+                       pDevice->eCommandState = WLAN_CMD_MAC_DISPOWERSAVING_START;
+                       break;
+
+               case WLAN_CMD_11H_CHSW:
+                       pDevice->eCommandState = WLAN_CMD_11H_CHSW_START;
+                       break;
+
+               default:
+                       break;
+               }
+               vCommandTimerWait(pDevice, 0);
+       }
+
+       return true;
 }
 
 int bScheduleCommand(struct vnt_private *pDevice,
                CMD_CODE eCommand, u8 *pbyItem0)
 {
 
-    if (pDevice->cbFreeCmdQueue == 0) {
-        return (false);
-    }
-    pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand;
-    pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true;
-    memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-    if (pbyItem0 != NULL) {
-        switch (eCommand) {
-            case WLAN_CMD_BSSID_SCAN:
-                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false;
-                memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
-                         pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-                break;
-
-            case WLAN_CMD_SSID:
-                memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
-                         pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-                break;
-
-            case WLAN_CMD_DISASSOCIATE:
-                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0);
-                break;
+       if (pDevice->cbFreeCmdQueue == 0)
+               return false;
+       pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand;
+       pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true;
+       memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+       if (pbyItem0 != NULL) {
+               switch (eCommand) {
+               case WLAN_CMD_BSSID_SCAN:
+                       pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false;
+                       memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+                               pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                       break;
+
+               case WLAN_CMD_SSID:
+                       memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+                               pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                       break;
+
+               case WLAN_CMD_DISASSOCIATE:
+                       pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0);
+                       break;
 /*
-            case WLAN_CMD_DEAUTH:
-                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((u16 *)pbyItem0);
-                break;
+               case WLAN_CMD_DEAUTH:
+                       pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((u16 *)pbyItem0);
+                       break;
 */
 
-            case WLAN_CMD_RADIO:
-                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0);
-                break;
+               case WLAN_CMD_RADIO:
+                       pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0);
+                       break;
+
+               default:
+                       break;
+               }
+       }
 
-            default:
-                break;
-        }
-    }
+       ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE);
+       pDevice->cbFreeCmdQueue--;
 
-    ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE);
-    pDevice->cbFreeCmdQueue--;
+       if (pDevice->bCmdRunning == false)
+               s_bCommandComplete(pDevice);
 
-    if (pDevice->bCmdRunning == false) {
-        s_bCommandComplete(pDevice);
-    }
-    else {
-    }
-    return (true);
+       return true;
 
 }
 
@@ -1121,16 +1087,16 @@ static int s_bClearBSSID_SCAN(struct vnt_private *pDevice)
        unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx;
        unsigned int ii;
 
-    if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) {
-        for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii ++) {
-            if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN)
-                pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE;
-            ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE);
-            if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx)
-                break;
-        }
-    }
-    return true;
+       if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) {
+               for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii++) {
+                       if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN)
+                               pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE;
+                       ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE);
+                       if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx)
+                               break;
+               }
+       }
+       return true;
 }
 
 //mike add:reset command timer
index e26c41519b156dbc04bef2d3ae6e91b0cf0bc017..d74b0e7cb171963a91db5e961a36f890bd675c5b 100644 (file)
@@ -2961,7 +2961,7 @@ static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice,
  *
 -*/
 
-struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice,
+static struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice,
        struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod,
        u32 uCurrChannel, u16 wCurrATIMWinodw, u8 *pDstAddr,
        PWLAN_IE_SSID pCurrSSID, u8 *pCurrBSSID,
@@ -3081,7 +3081,7 @@ struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice,
  *
 -*/
 
-struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice,
+static struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice,
        struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
        u16 wListenInterval,
        PWLAN_IE_SSID pCurrSSID,
@@ -3329,7 +3329,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice,
  *
 -*/
 
-struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice,
+static struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice,
        struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
        u16 wListenInterval, PWLAN_IE_SSID pCurrSSID,
        PWLAN_IE_SUPP_RATES pCurrRates,
@@ -3576,7 +3576,7 @@ struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice,
  *
 -*/
 
-struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice,
+static struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice,
        struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
        u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
        PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
@@ -3642,7 +3642,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice,
  *
 -*/
 
-struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *pDevice,
+static struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *pDevice,
        struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
        u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
        PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
index 01db4e7154da9b39f29ef399a7f012bc799620e5..403c295cc02c19f4cac7088a9ac98521300b1be7 100644 (file)
 
 static int          msglevel                =MSG_LEVEL_INFO;
 
-const u8 abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
-const u8 abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
-const u8 abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
-const u8 abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
-const u8 abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
-const u8 abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
+static const u8 abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
+static const u8 abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
+static const u8 abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
+static const u8 abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
+static const u8 abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
+static const u8 abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
 
 /*+
  *
index aa2216184345192dabe1e524c2779d809f6038d6..df5541794e0ff50fb584d9e8bf66393ac92adbfa 100644 (file)
 static int          msglevel                =MSG_LEVEL_INFO;
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 
-const u8 abyOUIGK[4]      = { 0x00, 0x0F, 0xAC, 0x00 };
-const u8 abyOUIWEP40[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
-const u8 abyOUIWEP104[4]  = { 0x00, 0x0F, 0xAC, 0x05 };
-const u8 abyOUITKIP[4]    = { 0x00, 0x0F, 0xAC, 0x02 };
-const u8 abyOUICCMP[4]    = { 0x00, 0x0F, 0xAC, 0x04 };
-
-const u8 abyOUI8021X[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
-const u8 abyOUIPSK[4]     = { 0x00, 0x0F, 0xAC, 0x02 };
+static const u8 abyOUIGK[4]      = { 0x00, 0x0F, 0xAC, 0x00 };
+static const u8 abyOUIWEP40[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+static const u8 abyOUIWEP104[4]  = { 0x00, 0x0F, 0xAC, 0x05 };
+static const u8 abyOUITKIP[4]    = { 0x00, 0x0F, 0xAC, 0x02 };
+static const u8 abyOUICCMP[4]    = { 0x00, 0x0F, 0xAC, 0x04 };
+
+static const u8 abyOUI8021X[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+static const u8 abyOUIPSK[4]     = { 0x00, 0x0F, 0xAC, 0x02 };
 
 /*+
  *
index cac7720bef2b26922039606ef993c33b24e6e4c8..aef0855f4c689d8479d2570d83ec48c3b489a015 100644 (file)
@@ -56,7 +56,8 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter,
                        RTS_on = true; /* Using RTS */
                else {
                        if (pT01->T01_modulation_type) { /* Is using OFDM */
-                               if (CURRENT_PROTECT_MECHANISM) /* Is using protect */
+                               /* Is using protect */
+                               if (CURRENT_PROTECT_MECHANISM)
                                        CTS_on = true; /* Using CTS */
                        }
                }
@@ -69,9 +70,9 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter,
                         *  ACK Rate : 24 Mega bps
                         *  ACK frame length = 14 bytes */
                        Duration = 2*DEFAULT_SIFSTIME +
-                                          2*PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
-                                          ((BodyLen*8 + 22 + Rate*4 - 1)/(Rate*4))*Tsym +
-                                          ((112 + 22 + 95)/96)*Tsym;
+                               2*PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
+                               ((BodyLen*8 + 22 + Rate*4 - 1)/(Rate*4))*Tsym +
+                               ((112 + 22 + 95)/96)*Tsym;
                } else  { /* DSSS */
                        /* CTS duration
                         *  2 SIFS + DATA transmit time + 1 ACK
@@ -92,13 +93,15 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter,
                                 * CTS Rate : 24 Mega bps
                                 * CTS frame length = 14 bytes */
                                Duration += (DEFAULT_SIFSTIME +
-                                           PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
-                                           ((112 + 22 + 95)/96)*Tsym);
+                                       PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
+                                       ((112 + 22 + 95)/96)*Tsym);
                        } else {
                                /* CTS + 1 SIFS + CTS duration
                                 * CTS Rate : ?? Mega bps
-                                * CTS frame length = 14 bytes */
-                               if (pT01->T01_plcp_header_length) /* long preamble */
+                                * CTS frame length = 14 bytes
+                                */
+                               /* long preamble */
+                               if (pT01->T01_plcp_header_length)
                                        Duration += LONG_PREAMBLE_PLUS_PLCPHEADER_TIME;
                                else
                                        Duration += SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME;
@@ -149,8 +152,8 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter,
                                             + Rate-1) / Rate +
                                            DEFAULT_SIFSTIME*3);
                        }
-
-                       ((u16 *)buffer)[5] = cpu_to_le16(Duration); /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */
+                       /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */
+                       ((u16 *)buffer)[5] = cpu_to_le16(Duration);
 
                        /* ----20061009 add by anson's endian */
                        pNextT00->value = cpu_to_le32(pNextT00->value);
@@ -159,7 +162,8 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter,
 
                        buffer += OffsetSize;
                        pT01 = (struct T01_descriptor *)(buffer+4);
-                       if (i != 1)     /* The last fragment will not have the next fragment */
+                       /* The last fragment will not have the next fragment */
+                       if (i != 1)
                                pNextT00 = (struct T00_descriptor *)(buffer+OffsetSize);
                }
 
@@ -189,7 +193,8 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter,
                }
        }
 
-       ((u16 *)buffer)[5] = cpu_to_le16(Duration); /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */
+       /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */
+       ((u16 *)buffer)[5] = cpu_to_le16(Duration);
        pT00->value = cpu_to_le32(pT00->value);
        pT01->value = cpu_to_le32(pT01->value);
        /* --end 20061009 add */
@@ -221,9 +226,10 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter,
                CopySize = SizeLeft;
                if (SizeLeft > pDes->FragmentThreshold) {
                        CopySize = pDes->FragmentThreshold;
-                       pT00->T00_frame_length = 24 + CopySize; /* Set USB length */
-               } else
-                       pT00->T00_frame_length = 24 + SizeLeft; /* Set USB length */
+                       /* Set USB length */
+                       pT00->T00_frame_length = 24 + CopySize;
+               } else  /* Set USB length */
+                       pT00->T00_frame_length = 24 + SizeLeft;
 
                SizeLeft -= CopySize;
 
@@ -267,21 +273,27 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter,
                /* 931130.5.n */
                if (pMds->MicAdd) {
                        if (!SizeLeft) {
-                               pMds->MicWriteAddress[pMds->MicWriteIndex] = buffer - pMds->MicAdd;
-                               pMds->MicWriteSize[pMds->MicWriteIndex] = pMds->MicAdd;
+                               pMds->MicWriteAddress[pMds->MicWriteIndex] =
+                                       buffer - pMds->MicAdd;
+                               pMds->MicWriteSize[pMds->MicWriteIndex] =
+                                       pMds->MicAdd;
                                pMds->MicAdd = 0;
                        } else if (SizeLeft < 8) { /* 931130.5.p */
                                pMds->MicAdd = SizeLeft;
-                               pMds->MicWriteAddress[pMds->MicWriteIndex] = buffer - (8 - SizeLeft);
-                               pMds->MicWriteSize[pMds->MicWriteIndex] = 8 - SizeLeft;
+                               pMds->MicWriteAddress[pMds->MicWriteIndex] =
+                                       buffer - (8 - SizeLeft);
+                               pMds->MicWriteSize[pMds->MicWriteIndex] =
+                                       8 - SizeLeft;
                                pMds->MicWriteIndex++;
                        }
                }
 
                /* Does it need to generate the new header for next mpdu? */
                if (SizeLeft) {
-                       buffer = TargetBuffer + Size; /* Get the next 4n start address */
-                       memcpy(buffer, TargetBuffer, 32); /* Copy 8B USB +24B 802.11 */
+                       /* Get the next 4n start address */
+                       buffer = TargetBuffer + Size;
+                       /* Copy 8B USB +24B 802.11 */
+                       memcpy(buffer, TargetBuffer, 32);
                        pT00 = (struct T00_descriptor *)buffer;
                        pT00->T00_first_mpdu = 0;
                }
@@ -293,7 +305,8 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter,
        pT00->T00_IsLastMpdu = 1;
        buffer = (u8 *)pT00 + 8; /* +8 for USB hdr */
        buffer[1] &= ~0x04; /* Clear more frag bit of 802.11 frame control */
-       pDes->FragmentCount = FragmentCount; /* Update the correct fragment number */
+       /* Update the correct fragment number */
+       pDes->FragmentCount = FragmentCount;
        return Size;
 }
 
@@ -330,7 +343,8 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter,
 
        FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; /* Do not fragment */
        /* Copy full data, the 1'st buffer contain all the data 931130.5.j */
-       memcpy(TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE); /* Copy header */
+       /* Copy header */
+       memcpy(TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE);
        pDes->buffer_address[0] = src_buffer + DOT_11_MAC_HEADER_SIZE;
        pDes->buffer_total_size -= DOT_11_MAC_HEADER_SIZE;
        pDes->buffer_size[0] = pDes->buffer_total_size;
@@ -358,8 +372,8 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter,
        for (i = 0; i < 2; i++) {
                if (i == 1)
                        ctmp1 = ctmpf;
-
-               pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1; /* backup the ta rate and fall back rate */
+               /* backup the ta rate and fall back rate */
+               pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1;
 
                if (ctmp1 == 108)
                        ctmp2 = 7;
@@ -395,7 +409,8 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter,
        /*
         * Set preamble type
         */
-       if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0)) /* RATE_1M */
+       /* RATE_1M */
+       if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0))
                pDes->PreambleMode =  WLAN_PREAMBLE_TYPE_LONG;
        else
                pDes->PreambleMode =  CURRENT_PREAMBLE_MODE;
@@ -468,12 +483,14 @@ Mds_Tx(struct wbsoft_priv *adapter)
        /* Start to fill the data */
        do {
                FillIndex = pMds->TxFillIndex;
-               if (pMds->TxOwner[FillIndex]) { /* Is owned by software 0:Yes 1:No */
+               /* Is owned by software 0:Yes 1:No */
+               if (pMds->TxOwner[FillIndex]) {
                        pr_debug("[Mds_Tx] Tx Owner is H/W.\n");
                        break;
                }
 
-               XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex); /* Get buffer */
+               /* Get buffer */
+               XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex);
                XmitBufSize = 0;
                FillCount = 0;
                do {
@@ -485,7 +502,8 @@ Mds_Tx(struct wbsoft_priv *adapter)
                        FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD;
                        /* 931130.5.b */
                        FragmentCount = PacketSize/FragmentThreshold + 1;
-                       stmp = PacketSize + FragmentCount*32 + 8; /* 931130.5.c 8:MIC */
+                       /* 931130.5.c 8:MIC */
+                       stmp = PacketSize + FragmentCount*32 + 8;
                        if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER)
                                break; /* buffer is not enough */
 
@@ -499,18 +517,23 @@ Mds_Tx(struct wbsoft_priv *adapter)
 
                        TxDesIndex = pMds->TxDesIndex; /* Get the current ID */
                        pTxDes->Descriptor_ID = TxDesIndex;
-                       pMds->TxDesFrom[TxDesIndex] = 2; /* Storing the information of source coming from */
+                       /* Storing the information of source coming from */
+                       pMds->TxDesFrom[TxDesIndex] = 2;
                        pMds->TxDesIndex++;
                        pMds->TxDesIndex %= MAX_USB_TX_DESCRIPTOR;
 
                        MLME_GetNextPacket(adapter, pTxDes);
 
-                       /* Copy header. 8byte USB + 24byte 802.11Hdr. Set TxRate, Preamble type */
+                       /*
+                        * Copy header. 8byte USB + 24byte 802.11Hdr.
+                        * Set TxRate, Preamble type
+                       */
                        Mds_HeaderCopy(adapter, pTxDes, XmitBufAddress);
 
                        /* For speed up Key setting */
                        if (pTxDes->EapFix) {
-                               pr_debug("35: EPA 4th frame detected. Size = %d\n", PacketSize);
+                               pr_debug("35: EPA 4th frame detected. Size = %d\n",
+                                                PacketSize);
                                pHwData->IsKeyPreSet = 1;
                        }
 
@@ -524,7 +547,9 @@ Mds_Tx(struct wbsoft_priv *adapter)
                        XmitBufSize += CurrentSize;
                        XmitBufAddress += CurrentSize;
 
-                       /* Get packet to transmit completed, 1:TESTSTA 2:MLME 3: Ndis data */
+                       /* Get packet to transmit completed,
+                        * 1:TESTSTA 2:MLME 3: Ndis data
+                       */
                        MLME_SendComplete(adapter, 0, true);
 
                        /* Software TSC count 20060214 */
@@ -533,7 +558,12 @@ Mds_Tx(struct wbsoft_priv *adapter)
                                pMds->TxTsc_2++;
 
                        FillCount++; /* 20060928 */
-               } while (HAL_USB_MODE_BURST(pHwData)); /* End of multiple MSDU copy loop. false = single true = multiple sending  */
+               /*
+                * End of multiple MSDU copy loop.
+                * false = single
+                * true = multiple sending
+                */
+               } while (HAL_USB_MODE_BURST(pHwData));
 
                /* Move to the next one, if necessary */
                if (BufferFilled) {
@@ -594,7 +624,8 @@ Mds_SendComplete(struct wbsoft_priv *adapter, struct T02_descriptor *pT02)
                                        pHwData->tx_retry_count[RetryCount] += RetryCount;
                                else
                                        pHwData->tx_retry_count[7] += RetryCount;
-                               pr_debug("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count);
+                               pr_debug("dto_tx_retry_count =%d\n",
+                                               pHwData->dto_tx_retry_count);
                                MTO_SetTxCount(adapter, TxRate, RetryCount);
                        }
                        pHwData->dto_tx_frag_count += (RetryCount+1);
index 5b6f670d8ef2217b44db95754920c376cdc9cc0a..eccd780ef135ff96c089ad2206e420722700611c 100644 (file)
@@ -5211,7 +5211,7 @@ static const CFG_PROG_STRCT fw_image_code[] = {
                0000,
        0x000F429B,                                     // Start execution address
        },
-       { 0000, 0000, 0000, 0000, 00000000, 0000, 00000000}
+       { 0000, 0000, 0000, 0000, 00000000, 0000, NULL}
 };
 
 static const CFG_RANGE20_STRCT fw_image_infocompat[] = {
@@ -5247,8 +5247,8 @@ memimage fw_image = {
        "FUPU7D37dhfwci\001C",                  //signature, <format number>, C/Bin type
        (CFG_PROG_STRCT *) fw_image_code,
        0x000F429B,
-       00000000,                                       //(dummy) pdaplug
-       00000000,                                       //(dummy) priplug
+       NULL,                                   //(dummy) pdaplug
+       NULL,                                   //(dummy) priplug
        (CFG_RANGE20_STRCT *) fw_image_infocompat,
        (CFG_IDENTITY_STRCT *) fw_image_infoidentity,
 };
index a4fd5c4717a880d7c68eefaf939062eabbb4c02a..a7d24c95191d15826ac808b226c26ae71e12ac98 100644 (file)
@@ -73,7 +73,8 @@ static int prism2_result2err(int prism2_result)
 static int prism2_domibset_uint32(wlandevice_t *wlandev, u32 did, u32 data)
 {
        struct p80211msg_dot11req_mibset msg;
-       p80211item_uint32_t *mibitem = (p80211item_uint32_t *) &msg.mibattribute.data;
+       p80211item_uint32_t *mibitem =
+                       (p80211item_uint32_t *) &msg.mibattribute.data;
 
        msg.msgcode = DIDmsg_dot11req_mibset;
        mibitem->did = did;
@@ -86,7 +87,8 @@ static int prism2_domibset_pstr32(wlandevice_t *wlandev,
                                  u32 did, u8 len, u8 *data)
 {
        struct p80211msg_dot11req_mibset msg;
-       p80211item_pstr32_t *mibitem = (p80211item_pstr32_t *) &msg.mibattribute.data;
+       p80211item_pstr32_t *mibitem =
+                       (p80211item_pstr32_t *) &msg.mibattribute.data;
 
        msg.msgcode = DIDmsg_dot11req_mibset;
        mibitem->did = did;
@@ -182,7 +184,8 @@ static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
                        goto exit;
                }
 
-               result = prism2_domibset_pstr32(wlandev, did, params->key_len, params->key);
+               result = prism2_domibset_pstr32(wlandev, did,
+                                               params->key_len, params->key);
                if (result)
                        goto exit;
                break;
@@ -328,7 +331,8 @@ static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
        return result;
 }
 
-static int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
+static int prism2_scan(struct wiphy *wiphy,
+                      struct cfg80211_scan_request *request)
 {
        struct net_device *dev;
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
@@ -380,7 +384,8 @@ static int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *reques
                (i < request->n_channels) && i < ARRAY_SIZE(prism2_channels);
                i++)
                msg1.channellist.data.data[i] =
-                       ieee80211_frequency_to_channel(request->channels[i]->center_freq);
+                       ieee80211_frequency_to_channel(
+                               request->channels[i]->center_freq);
        msg1.channellist.data.len = request->n_channels;
 
        msg1.maxchanneltime.data = 250;
@@ -410,7 +415,8 @@ static int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *reques
                ie_len = ie_buf[1] + 2;
                memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len);
                bss = cfg80211_inform_bss(wiphy,
-                       ieee80211_get_channel(wiphy, ieee80211_dsss_chan_to_freq(msg2.dschannel.data)),
+                       ieee80211_get_channel(wiphy,
+                             ieee80211_dsss_chan_to_freq(msg2.dschannel.data)),
                        (const u8 *) &(msg2.bssid.data.data),
                        msg2.timestamp.data, msg2.capinfo.data,
                        msg2.beaconperiod.data,
index 3dfa85ccc50408bdccbc1129670472427ec2f04f..333a2f693e49682720d396fd2e24baeb049279e8 100644 (file)
@@ -350,10 +350,10 @@ PD Record codes
 
 /*-------------------------------------------------------------*/
 /* Commonly used basic types */
-typedef struct hfa384x_bytestr {
+struct hfa384x_bytestr {
        u16 len;
        u8 data[0];
-} __packed hfa384x_bytestr_t;
+} __packed;
 
 typedef struct hfa384x_bytestr32 {
        u16 len;
index d22db43e803199f122696f7ae7ec3c16ee2d6171..a9909f6b000114245052f4e3ba995154797143a8 100644 (file)
@@ -525,7 +525,7 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
 
        p80211pstrd_t *pstr;
        u8 bytebuf[80];
-       hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf;
+       struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *) bytebuf;
        u16 word;
 
        wlandev->macmode = WLAN_MACMODE_NONE;
@@ -1019,7 +1019,7 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
        struct p80211msg_lnxreq_autojoin *msg = msgp;
        p80211pstrd_t *pstr;
        u8 bytebuf[256];
-       hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf;
+       struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *) bytebuf;
 
        wlandev->macmode = WLAN_MACMODE_NONE;
 
index 07eecebeb6ccb476c3759aea3e87037512c0b45a..190d390c8490ac0c77a06cab7358da0d37fe4601 100644 (file)
@@ -92,8 +92,10 @@ void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr);
 void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len);
 
 /* byte string conversion functions*/
-void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
-void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
+void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr,
+                            p80211pstrd_t *pstr);
+void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr,
+                            p80211pstrd_t *pstr);
 
 /* functions to convert Group Addresses */
 void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv);
index d3a06fa0b4f6ad934b3025b94d9be2c631b0f41d..9b5f3b72d3cac36552903062297c8a0956fbe025 100644 (file)
@@ -763,7 +763,8 @@ static int prism2mib_priv(struct mibrec *mib,
 *
 ----------------------------------------------------------------*/
 
-void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
+void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr,
+                            p80211pstrd_t *pstr)
 {
        bytestr->len = cpu_to_le16((u16) (pstr->len));
        memcpy(bytestr->data, pstr->data, pstr->len);
@@ -804,7 +805,8 @@ void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr)
 *
 ----------------------------------------------------------------*/
 
-void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
+void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr,
+                            p80211pstrd_t *pstr)
 {
        pstr->len = (u8) (le16_to_cpu((u16) (bytestr->len)));
        memcpy(pstr->data, bytestr->data, pstr->len);
index 76374b2202285b201981fd6c618c7fc744e72ff0..46f9491d10d3ce92252665615d35ec747e5db37d 100644 (file)
@@ -1279,7 +1279,7 @@ void prism2sta_processing_defer(struct work_struct *data)
                                     HFA384x_RID_CURRENTSSID, result);
                                return;
                        }
-                       prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
+                       prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid,
                                                (p80211pstrd_t *) &
                                                wlandev->ssid);
 
@@ -1361,7 +1361,7 @@ void prism2sta_processing_defer(struct work_struct *data)
                                 HFA384x_RID_CURRENTSSID, result);
                        return;
                }
-               prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
+               prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid,
                                        (p80211pstrd_t *) &wlandev->ssid);
 
                hw->link_status = HFA384x_LINK_CONNECTED;
@@ -2037,7 +2037,7 @@ void prism2sta_commsqual_defer(struct work_struct *data)
                         HFA384x_RID_CURRENTSSID, result);
                return;
        }
-       prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
+       prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid,
                                (p80211pstrd_t *) &wlandev->ssid);
 
        /* Reschedule timer */
index 79ce363b2ea9d1dd2cb0b79362b607659ca37345..108f2733106d77c00b73003e106febe6aa8998cc 100644 (file)
@@ -171,13 +171,14 @@ static inline int valid_io_request(struct zram *zram, struct bio *bio)
        u64 start, end, bound;
 
        /* unaligned request */
-       if (unlikely(bio->bi_sector & (ZRAM_SECTOR_PER_LOGICAL_BLOCK - 1)))
+       if (unlikely(bio->bi_iter.bi_sector &
+                    (ZRAM_SECTOR_PER_LOGICAL_BLOCK - 1)))
                return 0;
-       if (unlikely(bio->bi_size & (ZRAM_LOGICAL_BLOCK_SIZE - 1)))
+       if (unlikely(bio->bi_iter.bi_size & (ZRAM_LOGICAL_BLOCK_SIZE - 1)))
                return 0;
 
-       start = bio->bi_sector;
-       end = start + (bio->bi_size >> SECTOR_SHIFT);
+       start = bio->bi_iter.bi_sector;
+       end = start + (bio->bi_iter.bi_size >> SECTOR_SHIFT);
        bound = zram->disksize >> SECTOR_SHIFT;
        /* out of range range */
        if (unlikely(start >= bound || end > bound || start > end))
@@ -652,28 +653,38 @@ static ssize_t reset_store(struct device *dev,
                return -ENOMEM;
 
        /* Do not reset an active device! */
-       if (bdev->bd_holders)
-               return -EBUSY;
+       if (bdev->bd_holders) {
+               ret = -EBUSY;
+               goto out;
+       }
 
        ret = kstrtou16(buf, 10, &do_reset);
        if (ret)
-               return ret;
+               goto out;
 
-       if (!do_reset)
-               return -EINVAL;
+       if (!do_reset) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        /* Make sure all pending I/O is finished */
        fsync_bdev(bdev);
+       bdput(bdev);
 
        zram_reset_device(zram, true);
        return len;
+
+out:
+       bdput(bdev);
+       return ret;
 }
 
 static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
 {
-       int i, offset;
+       int offset;
        u32 index;
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
 
        switch (rw) {
        case READ:
@@ -684,36 +695,37 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
                break;
        }
 
-       index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
-       offset = (bio->bi_sector & (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
+       index = bio->bi_iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
+       offset = (bio->bi_iter.bi_sector &
+                 (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
 
-       bio_for_each_segment(bvec, bio, i) {
+       bio_for_each_segment(bvec, bio, iter) {
                int max_transfer_size = PAGE_SIZE - offset;
 
-               if (bvec->bv_len > max_transfer_size) {
+               if (bvec.bv_len > max_transfer_size) {
                        /*
                         * zram_bvec_rw() can only make operation on a single
                         * zram page. Split the bio vector.
                         */
                        struct bio_vec bv;
 
-                       bv.bv_page = bvec->bv_page;
+                       bv.bv_page = bvec.bv_page;
                        bv.bv_len = max_transfer_size;
-                       bv.bv_offset = bvec->bv_offset;
+                       bv.bv_offset = bvec.bv_offset;
 
                        if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
                                goto out;
 
-                       bv.bv_len = bvec->bv_len - max_transfer_size;
+                       bv.bv_len = bvec.bv_len - max_transfer_size;
                        bv.bv_offset += max_transfer_size;
                        if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
                                goto out;
                } else
-                       if (zram_bvec_rw(zram, bvec, index, offset, bio, rw)
+                       if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
                            < 0)
                                goto out;
 
-               update_position(&index, &offset, bvec);
+               update_position(&index, &offset, &bvec);
        }
 
        set_bit(BIO_UPTODATE, &bio->bi_flags);
index 1a67537dbc5654be28e7d640f89d3fe3fd903e30..3b950e5a918f8c1a252aabc7da049e2732e2e15d 100644 (file)
@@ -430,7 +430,12 @@ static struct page *get_next_page(struct page *page)
        return next;
 }
 
-/* Encode <page, obj_idx> as a single handle value */
+/*
+ * Encode <page, obj_idx> as a single handle value.
+ * On hardware platforms with physical memory starting at 0x0 the pfn
+ * could be 0 so we ensure that the handle will never be 0 by adjusting the
+ * encoded obj_idx value before encoding.
+ */
 static void *obj_location_to_handle(struct page *page, unsigned long obj_idx)
 {
        unsigned long handle;
@@ -441,17 +446,21 @@ static void *obj_location_to_handle(struct page *page, unsigned long obj_idx)
        }
 
        handle = page_to_pfn(page) << OBJ_INDEX_BITS;
-       handle |= (obj_idx & OBJ_INDEX_MASK);
+       handle |= ((obj_idx + 1) & OBJ_INDEX_MASK);
 
        return (void *)handle;
 }
 
-/* Decode <page, obj_idx> pair from the given object handle */
+/*
+ * Decode <page, obj_idx> pair from the given object handle. We adjust the
+ * decoded obj_idx back to its original value since it was adjusted in
+ * obj_location_to_handle().
+ */
 static void obj_handle_to_location(unsigned long handle, struct page **page,
                                unsigned long *obj_idx)
 {
        *page = pfn_to_page(handle >> OBJ_INDEX_BITS);
-       *obj_idx = handle & OBJ_INDEX_MASK;
+       *obj_idx = (handle & OBJ_INDEX_MASK) - 1;
 }
 
 static unsigned long obj_idx_to_offset(struct page *page,
index c87959f12760462ca76740737e7cc839bdd4fc58..2d29356d0c85a076e90db99bbda9f1a428f9c336 100644 (file)
@@ -319,7 +319,7 @@ iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num)
        bio->bi_bdev = ib_dev->ibd_bd;
        bio->bi_private = cmd;
        bio->bi_end_io = &iblock_bio_done;
-       bio->bi_sector = lba;
+       bio->bi_iter.bi_sector = lba;
 
        return bio;
 }
index 2b86f8e0fb58f965f637c82e3206f3e4d83c6e51..71630a2af42ccf5f2eb48ea79793cadca86ab5c6 100644 (file)
@@ -1855,6 +1855,9 @@ static struct console sercons = {
  */
 static int __init amiserial_console_init(void)
 {
+       if (!MACH_IS_AMIGA)
+               return -ENODEV;
+
        register_console(&sercons);
        return 0;
 }
index 7cdd1eb9406c11ccb4870560490f0c6036f92032..268b62768f2b41eab5f7db4d4c5c8b9111f248b6 100644 (file)
@@ -768,7 +768,7 @@ static size_t __process_echoes(struct tty_struct *tty)
         * data at the tail to prevent a subsequent overrun */
        while (ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) {
                if (echo_buf(ldata, tail) == ECHO_OP_START) {
-                       if (echo_buf(ldata, tail) == ECHO_OP_ERASE_TAB)
+                       if (echo_buf(ldata, tail + 1) == ECHO_OP_ERASE_TAB)
                                tail += 3;
                        else
                                tail += 2;
@@ -810,7 +810,8 @@ static void process_echoes(struct tty_struct *tty)
        struct n_tty_data *ldata = tty->disc_data;
        size_t echoed;
 
-       if (!L_ECHO(tty) || ldata->echo_commit == ldata->echo_tail)
+       if ((!L_ECHO(tty) && !L_ECHONL(tty)) ||
+           ldata->echo_commit == ldata->echo_tail)
                return;
 
        mutex_lock(&ldata->output_lock);
@@ -825,7 +826,8 @@ static void flush_echoes(struct tty_struct *tty)
 {
        struct n_tty_data *ldata = tty->disc_data;
 
-       if (!L_ECHO(tty) || ldata->echo_commit == ldata->echo_head)
+       if ((!L_ECHO(tty) && !L_ECHONL(tty)) ||
+           ldata->echo_commit == ldata->echo_head)
                return;
 
        mutex_lock(&ldata->output_lock);
@@ -1998,7 +2000,10 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
                found = 1;
 
        size = N_TTY_BUF_SIZE - tail;
-       n = (found + eol + size) & (N_TTY_BUF_SIZE - 1);
+       n = eol - tail;
+       if (n > 4096)
+               n += 4096;
+       n += found;
        c = n;
 
        if (found && read_buf(ldata, eol) == __DISABLED_CHAR) {
@@ -2243,18 +2248,19 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
                if (time)
                        timeout = time;
        }
-       mutex_unlock(&ldata->atomic_read_lock);
-       remove_wait_queue(&tty->read_wait, &wait);
+       n_tty_set_room(tty);
+       up_read(&tty->termios_rwsem);
 
+       remove_wait_queue(&tty->read_wait, &wait);
        if (!waitqueue_active(&tty->read_wait))
                ldata->minimum_to_wake = minimum;
 
+       mutex_unlock(&ldata->atomic_read_lock);
+
        __set_current_state(TASK_RUNNING);
        if (b - buf)
                retval = b - buf;
 
-       n_tty_set_room(tty);
-       up_read(&tty->termios_rwsem);
        return retval;
 }
 
index f3b306efaa591d518b1b894253e0714ea3cba5c6..23329918f2292b088eac724156d743784460866c 100644 (file)
@@ -41,7 +41,7 @@ config SERIAL_8250_DEPRECATED_OPTIONS
          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
+         keep the 8250_core.* options around until they revert the changes
          they already did.
 
          If 8250 is built as a module, this adds 8250_core alias instead. 
index 481b781b26e370e23fea8d2088311562c15cde87..e9d420ff39310741212eb77e194c13fca2662b18 100644 (file)
@@ -2052,6 +2052,9 @@ static int __init pmz_console_init(void)
        /* Probe ports */
        pmz_probe();
 
+       if (pmz_ports_count == 0)
+               return -ENODEV;
+
        /* TODO: Autoprobe console based on OF */
        /* pmz_console.index = i; */
        register_console(&pmz_console);
index 7d8103cd3e2ec56eacbb5a5d3f3f332597e190ff..e7e9cabb21fd2a4a6613f075632e6f16f3432a33 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
 
 #ifdef CONFIG_SUPERH
 #include <asm/sh_bios.h>
@@ -2437,6 +2438,112 @@ static int sci_remove(struct platform_device *dev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id of_sci_match[] = {
+       { .compatible = "renesas,sci-SCI-uart",
+               .data = (void *)PORT_SCI },
+       { .compatible = "renesas,sci-SCIF-uart",
+               .data = (void *)PORT_SCIF },
+       { .compatible = "renesas,sci-IRDA-uart",
+               .data = (void *)PORT_IRDA },
+       { .compatible = "renesas,sci-SCIFA-uart",
+               .data = (void *)PORT_SCIFA },
+       { .compatible = "renesas,sci-SCIFB-uart",
+               .data = (void *)PORT_SCIFB },
+       {},
+};
+MODULE_DEVICE_TABLE(of, of_sci_match);
+
+static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
+                                                               int *dev_id)
+{
+       struct plat_sci_port *p;
+       struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *match;
+       struct resource *res;
+       const __be32 *prop;
+       int i, irq, val;
+
+       match = of_match_node(of_sci_match, pdev->dev.of_node);
+       if (!match || !match->data) {
+               dev_err(&pdev->dev, "OF match error\n");
+               return NULL;
+       }
+
+       p = devm_kzalloc(&pdev->dev, sizeof(struct plat_sci_port), GFP_KERNEL);
+       if (!p) {
+               dev_err(&pdev->dev, "failed to allocate DT config data\n");
+               return NULL;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "failed to get I/O memory\n");
+               return NULL;
+       }
+       p->mapbase = res->start;
+
+       for (i = 0; i < SCIx_NR_IRQS; i++) {
+               irq = platform_get_irq(pdev, i);
+               if (irq < 0) {
+                       dev_err(&pdev->dev, "failed to get irq data %d\n", i);
+                       return NULL;
+               }
+               p->irqs[i] = irq;
+       }
+
+       prop = of_get_property(np, "cell-index", NULL);
+       if (!prop) {
+               dev_err(&pdev->dev, "required DT prop cell-index missing\n");
+               return NULL;
+       }
+       *dev_id = be32_to_cpup(prop);
+
+       prop = of_get_property(np, "renesas,scscr", NULL);
+       if (!prop) {
+               dev_err(&pdev->dev, "required DT prop scscr missing\n");
+               return NULL;
+       }
+       p->scscr = be32_to_cpup(prop);
+
+       prop = of_get_property(np, "renesas,scbrr-algo-id", NULL);
+       if (!prop) {
+               dev_err(&pdev->dev, "required DT prop scbrr-algo-id missing\n");
+               return NULL;
+       }
+       val = be32_to_cpup(prop);
+       if (val <= SCBRR_ALGO_INVALID || val >= SCBRR_NR_ALGOS) {
+               dev_err(&pdev->dev, "DT prop scbrr-algo-id out of range\n");
+               return NULL;
+       }
+       p->scbrr_algo_id = val;
+
+       p->flags = UPF_IOREMAP;
+       if (of_get_property(np, "renesas,autoconf", NULL))
+               p->flags |= UPF_BOOT_AUTOCONF;
+
+       prop = of_get_property(np, "renesas,regtype", NULL);
+       if (prop) {
+               val = be32_to_cpup(prop);
+               if (val < SCIx_PROBE_REGTYPE || val >= SCIx_NR_REGTYPES) {
+                       dev_err(&pdev->dev, "DT prop regtype out of range\n");
+                       return NULL;
+               }
+               p->regtype = val;
+       }
+
+       p->type = (unsigned int)match->data;
+
+       return p;
+}
+#else
+static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
+                                                               int *dev_id)
+{
+       return NULL;
+}
+#endif /* CONFIG_OF */
+
 static int sci_probe_single(struct platform_device *dev,
                                      unsigned int index,
                                      struct plat_sci_port *p,
@@ -2469,9 +2576,9 @@ static int sci_probe_single(struct platform_device *dev,
 
 static int sci_probe(struct platform_device *dev)
 {
-       struct plat_sci_port *p = dev_get_platdata(&dev->dev);
-       struct sci_port *sp = &sci_ports[dev->id];
-       int ret;
+       struct plat_sci_port *p;
+       struct sci_port *sp;
+       int ret, dev_id = dev->id;
 
        /*
         * If we've come here via earlyprintk initialization, head off to
@@ -2481,9 +2588,20 @@ static int sci_probe(struct platform_device *dev)
        if (is_early_platform_device(dev))
                return sci_probe_earlyprintk(dev);
 
+       if (dev->dev.of_node)
+               p = sci_parse_dt(dev, &dev_id);
+       else
+               p = dev_get_platdata(&dev->dev);
+
+       if (!p) {
+               dev_err(&dev->dev, "no setup data supplied\n");
+               return -EINVAL;
+       }
+
+       sp = &sci_ports[dev_id];
        platform_set_drvdata(dev, sp);
 
-       ret = sci_probe_single(dev, dev->id, p, sp);
+       ret = sci_probe_single(dev, dev_id, p, sp);
        if (ret)
                return ret;
 
@@ -2535,6 +2653,7 @@ static struct platform_driver sci_driver = {
                .name   = "sh-sci",
                .owner  = THIS_MODULE,
                .pm     = &sci_dev_pm_ops,
+               .of_match_table = of_match_ptr(of_sci_match),
        },
 };
 
index 3a1a01af9a805b38b05f1833eefa80400072f4f4..c74a00ad7add80254ddf98dbaf88ed0725a540e0 100644 (file)
@@ -2086,6 +2086,7 @@ retry_open:
                        filp->f_op = &tty_fops;
                goto retry_open;
        }
+       clear_bit(TTY_HUPPED, &tty->flags);
        tty_unlock(tty);
 
 
index 4e243c37f17f50ab197582a3ee5d4662e933d368..f0155a39aaa3b686f1b392c7d59781a8f76fda5d 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <linux/usb/hcd.h>
-#include <acpi/acpi_bus.h>
 
 #include "usb.h"
 
@@ -127,7 +126,7 @@ out:
        return ret;
 }
 
-static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
+static struct acpi_device *usb_acpi_find_companion(struct device *dev)
 {
        struct usb_device *udev;
        acpi_handle *parent_handle;
@@ -169,16 +168,15 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
                                break;
                        }
 
-                       return -ENODEV;
+                       return NULL;
                }
 
                /* root hub's parent is the usb hcd. */
-               parent_handle = ACPI_HANDLE(dev->parent);
-               *handle = acpi_get_child(parent_handle, udev->portnum);
-               if (!*handle)
-                       return -ENODEV;
-               return 0;
+               return acpi_find_child_device(ACPI_COMPANION(dev->parent),
+                                             udev->portnum, false);
        } else if (is_usb_port(dev)) {
+               struct acpi_device *adev = NULL;
+
                sscanf(dev_name(dev), "port%d", &port_num);
                /* Get the struct usb_device point of port's hub */
                udev = to_usb_device(dev->parent->parent);
@@ -194,26 +192,27 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
 
                        raw_port_num = usb_hcd_find_raw_port_number(hcd,
                                port_num);
-                       *handle = acpi_get_child(ACPI_HANDLE(&udev->dev),
-                               raw_port_num);
-                       if (!*handle)
-                               return -ENODEV;
+                       adev = acpi_find_child_device(ACPI_COMPANION(&udev->dev),
+                                                     raw_port_num, false);
+                       if (!adev)
+                               return NULL;
                } else {
                        parent_handle =
                                usb_get_hub_port_acpi_handle(udev->parent,
                                udev->portnum);
                        if (!parent_handle)
-                               return -ENODEV;
+                               return NULL;
 
-                       *handle = acpi_get_child(parent_handle, port_num);
-                       if (!*handle)
-                               return -ENODEV;
+                       acpi_bus_get_device(parent_handle, &adev);
+                       adev = acpi_find_child_device(adev, port_num, false);
+                       if (!adev)
+                               return NULL;
                }
-               usb_acpi_check_port_connect_type(udev, *handle, port_num);
-       } else
-               return -ENODEV;
+               usb_acpi_check_port_connect_type(udev, adev->handle, port_num);
+               return adev;
+       }
 
-       return 0;
+       return NULL;
 }
 
 static bool usb_acpi_bus_match(struct device *dev)
@@ -224,7 +223,7 @@ static bool usb_acpi_bus_match(struct device *dev)
 static struct acpi_bus_type usb_acpi_bus = {
        .name = "USB",
        .match = usb_acpi_bus_match,
-       .find_device = usb_acpi_find_device,
+       .find_companion = usb_acpi_find_companion,
 };
 
 int usb_acpi_register(void)
index 95f7649c71a78745692a63bafd1527daacda52e3..21a352079bc25fdd0fe33ddba1a3191b29b812f0 100644 (file)
@@ -459,6 +459,8 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
                        dep = dwc3_wIndex_to_dep(dwc, wIndex);
                        if (!dep)
                                return -EINVAL;
+                       if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
+                               break;
                        ret = __dwc3_gadget_ep_set_halt(dep, set);
                        if (ret)
                                return -EINVAL;
index 5452c0fce36074d4238e3553bb00d879d8df9ac3..02e44fcaf205e3eaf4a69e706c41d6e081c6c1e5 100644 (file)
@@ -1200,9 +1200,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value)
                else
                        dep->flags |= DWC3_EP_STALL;
        } else {
-               if (dep->flags & DWC3_EP_WEDGE)
-                       return 0;
-
                ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
                        DWC3_DEPCMD_CLEARSTALL, &params);
                if (ret)
@@ -1210,7 +1207,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value)
                                        value ? "set" : "clear",
                                        dep->name);
                else
-                       dep->flags &= ~DWC3_EP_STALL;
+                       dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE);
        }
 
        return ret;
index a91e6422f93021f912042298a99cdde36362b09b..f66d96ad1f51eb96d1806187dbb564675a02b8f0 100644 (file)
@@ -682,6 +682,7 @@ config USB_CONFIGFS_PHONET
 config USB_CONFIGFS_MASS_STORAGE
        boolean "Mass storage"
        depends on USB_CONFIGFS
+       depends on BLOCK
        select USB_F_MASS_STORAGE
        help
          The Mass Storage Gadget acts as a USB Mass Storage disk drive.
index 3e7ae707f691c4b0cf4b701024d8df0af4a5bb69..2018ba1a2172d4bb26faea20c34e44653070e91f 100644 (file)
@@ -593,6 +593,7 @@ static void reset_config(struct usb_composite_dev *cdev)
                bitmap_zero(f->endpoints, 32);
        }
        cdev->config = NULL;
+       cdev->delayed_status = 0;
 }
 
 static int set_config(struct usb_composite_dev *cdev,
index 774e8b89cdb593bf951b5c82e97c169f921a6130..241fc873ffa4569fcc98a3a93ff98e3f07339d72 100644 (file)
@@ -1304,7 +1304,7 @@ static struct ffs_data *ffs_data_new(void)
 {
        struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL);
        if (unlikely(!ffs))
-               return 0;
+               return NULL;
 
        ENTER();
 
index a03ba2c83589ee15f9c1880d17f1aa133eb47f29..b963939088606e7e9252ec1f55d42ff9fdd1dcd3 100644 (file)
@@ -523,7 +523,7 @@ static int fsg_setup(struct usb_function *f,
                 */
                DBG(fsg, "bulk reset request\n");
                raise_exception(fsg->common, FSG_STATE_RESET);
-               return DELAYED_STATUS;
+               return USB_GADGET_DELAYED_STATUS;
 
        case US_BULK_GET_MAX_LUN:
                if (ctrl->bRequestType !=
@@ -602,13 +602,14 @@ static bool start_out_transfer(struct fsg_common *common, struct fsg_buffhd *bh)
        return true;
 }
 
-static int sleep_thread(struct fsg_common *common)
+static int sleep_thread(struct fsg_common *common, bool can_freeze)
 {
        int     rc = 0;
 
        /* Wait until a signal arrives or we are woken up */
        for (;;) {
-               try_to_freeze();
+               if (can_freeze)
+                       try_to_freeze();
                set_current_state(TASK_INTERRUPTIBLE);
                if (signal_pending(current)) {
                        rc = -EINTR;
@@ -682,7 +683,7 @@ static int do_read(struct fsg_common *common)
                /* Wait for the next buffer to become available */
                bh = common->next_buffhd_to_fill;
                while (bh->state != BUF_STATE_EMPTY) {
-                       rc = sleep_thread(common);
+                       rc = sleep_thread(common, false);
                        if (rc)
                                return rc;
                }
@@ -937,7 +938,7 @@ static int do_write(struct fsg_common *common)
                }
 
                /* Wait for something to happen */
-               rc = sleep_thread(common);
+               rc = sleep_thread(common, false);
                if (rc)
                        return rc;
        }
@@ -1504,7 +1505,7 @@ static int throw_away_data(struct fsg_common *common)
                }
 
                /* Otherwise wait for something to happen */
-               rc = sleep_thread(common);
+               rc = sleep_thread(common, true);
                if (rc)
                        return rc;
        }
@@ -1625,7 +1626,7 @@ static int send_status(struct fsg_common *common)
        /* Wait for the next buffer to become available */
        bh = common->next_buffhd_to_fill;
        while (bh->state != BUF_STATE_EMPTY) {
-               rc = sleep_thread(common);
+               rc = sleep_thread(common, true);
                if (rc)
                        return rc;
        }
@@ -1828,7 +1829,7 @@ static int do_scsi_command(struct fsg_common *common)
        bh = common->next_buffhd_to_fill;
        common->next_buffhd_to_drain = bh;
        while (bh->state != BUF_STATE_EMPTY) {
-               rc = sleep_thread(common);
+               rc = sleep_thread(common, true);
                if (rc)
                        return rc;
        }
@@ -2174,7 +2175,7 @@ static int get_next_command(struct fsg_common *common)
        /* Wait for the next buffer to become available */
        bh = common->next_buffhd_to_fill;
        while (bh->state != BUF_STATE_EMPTY) {
-               rc = sleep_thread(common);
+               rc = sleep_thread(common, true);
                if (rc)
                        return rc;
        }
@@ -2193,7 +2194,7 @@ static int get_next_command(struct fsg_common *common)
 
        /* Wait for the CBW to arrive */
        while (bh->state != BUF_STATE_FULL) {
-               rc = sleep_thread(common);
+               rc = sleep_thread(common, true);
                if (rc)
                        return rc;
        }
@@ -2379,7 +2380,7 @@ static void handle_exception(struct fsg_common *common)
                        }
                        if (num_active == 0)
                                break;
-                       if (sleep_thread(common))
+                       if (sleep_thread(common, true))
                                return;
                }
 
@@ -2516,7 +2517,7 @@ static int fsg_main_thread(void *common_)
                }
 
                if (!common->running) {
-                       sleep_thread(common);
+                       sleep_thread(common, true);
                        continue;
                }
 
@@ -3111,7 +3112,7 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
                                          fsg->common->can_stall);
                if (ret)
                        return ret;
-               fsg_common_set_inquiry_string(fsg->common, 0, 0);
+               fsg_common_set_inquiry_string(fsg->common, NULL, NULL);
                ret = fsg_common_run_thread(fsg->common);
                if (ret)
                        return ret;
index 0ac6064aa3b86b6cd2376324ac9996f8ece1c0a0..409a3c45a36af1ec596ad4d9bf2c117c9f493444 100644 (file)
@@ -54,6 +54,7 @@
  */
 #ifdef CONFIG_ARCH_PXA
 #include <mach/pxa25x-udc.h>
+#include <mach/hardware.h>
 #endif
 
 #ifdef CONFIG_ARCH_LUBBOCK
index 68be48d3340411c9e91632e19dd15ec4fd3cbfe1..47287518bff3d9dfe3d666d46a66dfc2fa82ffb3 100644 (file)
@@ -1833,7 +1833,7 @@ static int __exit r8a66597_remove(struct platform_device *pdev)
        r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
 
        if (r8a66597->pdata->on_chip) {
-               clk_disable(r8a66597->clk);
+               clk_disable_unprepare(r8a66597->clk);
                clk_put(r8a66597->clk);
        }
 
@@ -1931,7 +1931,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
                        ret = PTR_ERR(r8a66597->clk);
                        goto clean_up;
                }
-               clk_enable(r8a66597->clk);
+               clk_prepare_enable(r8a66597->clk);
        }
 
        if (r8a66597->pdata->sudmac) {
@@ -1996,7 +1996,7 @@ clean_up3:
        free_irq(irq, r8a66597);
 clean_up2:
        if (r8a66597->pdata->on_chip) {
-               clk_disable(r8a66597->clk);
+               clk_disable_unprepare(r8a66597->clk);
                clk_put(r8a66597->clk);
        }
 clean_up:
index 9875d9c0823f7c554744a40acb0a70897dde0bc6..e20bc109fdd70f43eec9e1572d3fa8f75e6ba423 100644 (file)
@@ -1180,6 +1180,7 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
 }
 
 static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg);
+static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg);
 
 /**
  * s3c_hsotg_process_control - process a control request
@@ -1221,6 +1222,7 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg,
        if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
                switch (ctrl->bRequest) {
                case USB_REQ_SET_ADDRESS:
+                       s3c_hsotg_disconnect(hsotg);
                        dcfg = readl(hsotg->regs + DCFG);
                        dcfg &= ~DCFG_DevAddr_MASK;
                        dcfg |= ctrl->wValue << DCFG_DevAddr_SHIFT;
@@ -1245,7 +1247,9 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg,
        /* as a fallback, try delivering it to the driver to deal with */
 
        if (ret == 0 && hsotg->driver) {
+               spin_unlock(&hsotg->lock);
                ret = hsotg->driver->setup(&hsotg->gadget, ctrl);
+               spin_lock(&hsotg->lock);
                if (ret < 0)
                        dev_dbg(hsotg->dev, "driver->setup() ret %d\n", ret);
        }
@@ -1308,10 +1312,12 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep,
                return;
        }
 
+       spin_lock(&hsotg->lock);
        if (req->actual == 0)
                s3c_hsotg_enqueue_setup(hsotg);
        else
                s3c_hsotg_process_control(hsotg, req->buf);
+       spin_unlock(&hsotg->lock);
 }
 
 /**
@@ -2533,7 +2539,6 @@ irq_retry:
                writel(GINTSTS_USBSusp, hsotg->regs + GINTSTS);
 
                call_gadget(hsotg, suspend);
-               s3c_hsotg_disconnect(hsotg);
        }
 
        if (gintsts & GINTSTS_WkUpInt) {
index c74c2fdbd56eda5683a13995a96b6221711c30ef..70c891469f574ebd1d7719fc05bcf838d1d6e3cb 100644 (file)
@@ -119,10 +119,6 @@ static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
        return curlun->filp != NULL;
 }
 
-/* Big enough to hold our biggest descriptor */
-#define EP0_BUFSIZE    256
-#define DELAYED_STATUS (EP0_BUFSIZE + 999)     /* An impossibly large value */
-
 /* Default size of buffer length. */
 #define FSG_BUFLEN     ((u32)16384)
 
index 6c3d7950d2a9e56d5231938493127c0964f04221..0f8aad78b54f7095a26b6e413a22ff5ae1e016df 100644 (file)
@@ -370,7 +370,7 @@ err:
        return -ENOMEM;
 }
 
-void bot_cleanup_old_alt(struct f_uas *fu)
+static void bot_cleanup_old_alt(struct f_uas *fu)
 {
        if (!(fu->flags & USBG_ENABLED))
                return;
index 0dd07ae1555ddf066312e0ff4e8182a02f27a3d6..f49b0b61ecc8163941447e8ba5b719982951531e 100644 (file)
@@ -91,17 +91,17 @@ static struct usb_zero_options gzero_options = {
  * functional coverage for the "USBCV" test harness from USB-IF.
  * It's always set if OTG mode is enabled.
  */
-unsigned autoresume = DEFAULT_AUTORESUME;
+static unsigned autoresume = DEFAULT_AUTORESUME;
 module_param(autoresume, uint, S_IRUGO);
 MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
 
 /* Maximum Autoresume time */
-unsigned max_autoresume;
+static unsigned max_autoresume;
 module_param(max_autoresume, uint, S_IRUGO);
 MODULE_PARM_DESC(max_autoresume, "maximum seconds before remote wakeup");
 
 /* Interval between two remote wakeups */
-unsigned autoresume_interval_ms;
+static unsigned autoresume_interval_ms;
 module_param(autoresume_interval_ms, uint, S_IRUGO);
 MODULE_PARM_DESC(autoresume_interval_ms,
                "milliseconds to increase successive wakeup delays");
index 0a43329569d178de72a5c8ee619e7206c360c51c..4d4499b8044971a8db410579f7965e9b6d862c38 100644 (file)
@@ -1809,7 +1809,6 @@ static void musb_free(struct musb *musb)
                        disable_irq_wake(musb->nIrq);
                free_irq(musb->nIrq, musb);
        }
-       cancel_work_sync(&musb->irq_work);
 
        musb_host_free(musb);
 }
@@ -1896,6 +1895,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        musb_platform_disable(musb);
        musb_generic_disable(musb);
 
+       /* Init IRQ workqueue before request_irq */
+       INIT_WORK(&musb->irq_work, musb_irq_work);
+
        /* setup musb parts of the core (especially endpoints) */
        status = musb_core_init(plat->config->multipoint
                        ? MUSB_CONTROLLER_MHDRC
@@ -1905,9 +1907,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 
        setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
 
-       /* Init IRQ workqueue before request_irq */
-       INIT_WORK(&musb->irq_work, musb_irq_work);
-
        /* attach to the IRQ */
        if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) {
                dev_err(dev, "request_irq %d failed!\n", nIrq);
@@ -1981,6 +1980,7 @@ fail4:
        musb_host_cleanup(musb);
 
 fail3:
+       cancel_work_sync(&musb->irq_work);
        if (musb->dma_controller)
                dma_controller_destroy(musb->dma_controller);
 fail2_5:
@@ -2043,6 +2043,7 @@ static int musb_remove(struct platform_device *pdev)
        if (musb->dma_controller)
                dma_controller_destroy(musb->dma_controller);
 
+       cancel_work_sync(&musb->irq_work);
        musb_free(musb);
        device_init_wakeup(dev, 0);
        return 0;
index ff9d6de2b7465c949d54ae4801108a3800f4be3f..a12bd30401e076fe0e502789e300c05ecc770bb1 100644 (file)
@@ -38,6 +38,7 @@ struct cppi41_dma_channel {
        u32 prog_len;
        u32 transferred;
        u32 packet_sz;
+       struct list_head tx_check;
 };
 
 #define MUSB_DMA_NUM_CHANNELS 15
@@ -47,6 +48,8 @@ struct cppi41_dma_controller {
        struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS];
        struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS];
        struct musb *musb;
+       struct hrtimer early_tx;
+       struct list_head early_tx_list;
        u32 rx_mode;
        u32 tx_mode;
        u32 auto_req;
@@ -96,31 +99,27 @@ static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
        cppi41_channel->usb_toggle = toggle;
 }
 
-static void cppi41_dma_callback(void *private_data)
+static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep)
 {
-       struct dma_channel *channel = private_data;
-       struct cppi41_dma_channel *cppi41_channel = channel->private_data;
-       struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
-       struct musb *musb = hw_ep->musb;
-       unsigned long flags;
-       struct dma_tx_state txstate;
-       u32 transferred;
+       u8              epnum = hw_ep->epnum;
+       struct musb     *musb = hw_ep->musb;
+       void __iomem    *epio = musb->endpoints[epnum].regs;
+       u16             csr;
 
-       spin_lock_irqsave(&musb->lock, flags);
+       csr = musb_readw(epio, MUSB_TXCSR);
+       if (csr & MUSB_TXCSR_TXPKTRDY)
+               return false;
+       return true;
+}
 
-       dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
-                       &txstate);
-       transferred = cppi41_channel->prog_len - txstate.residue;
-       cppi41_channel->transferred += transferred;
+static void cppi41_dma_callback(void *private_data);
 
-       dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n",
-               hw_ep->epnum, cppi41_channel->transferred,
-               cppi41_channel->total_len);
+static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
+{
+       struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
+       struct musb *musb = hw_ep->musb;
 
-       update_rx_toggle(cppi41_channel);
-
-       if (cppi41_channel->transferred == cppi41_channel->total_len ||
-                       transferred < cppi41_channel->packet_sz) {
+       if (!cppi41_channel->prog_len) {
 
                /* done, complete */
                cppi41_channel->channel.actual_len =
@@ -150,13 +149,11 @@ static void cppi41_dma_callback(void *private_data)
                                remain_bytes,
                                direction,
                                DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-               if (WARN_ON(!dma_desc)) {
-                       spin_unlock_irqrestore(&musb->lock, flags);
+               if (WARN_ON(!dma_desc))
                        return;
-               }
 
                dma_desc->callback = cppi41_dma_callback;
-               dma_desc->callback_param = channel;
+               dma_desc->callback_param = &cppi41_channel->channel;
                cppi41_channel->cookie = dma_desc->tx_submit(dma_desc);
                dma_async_issue_pending(dc);
 
@@ -166,6 +163,117 @@ static void cppi41_dma_callback(void *private_data)
                        musb_writew(epio, MUSB_RXCSR, csr);
                }
        }
+}
+
+static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer)
+{
+       struct cppi41_dma_controller *controller;
+       struct cppi41_dma_channel *cppi41_channel, *n;
+       struct musb *musb;
+       unsigned long flags;
+       enum hrtimer_restart ret = HRTIMER_NORESTART;
+
+       controller = container_of(timer, struct cppi41_dma_controller,
+                       early_tx);
+       musb = controller->musb;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       list_for_each_entry_safe(cppi41_channel, n, &controller->early_tx_list,
+                       tx_check) {
+               bool empty;
+               struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
+
+               empty = musb_is_tx_fifo_empty(hw_ep);
+               if (empty) {
+                       list_del_init(&cppi41_channel->tx_check);
+                       cppi41_trans_done(cppi41_channel);
+               }
+       }
+
+       if (!list_empty(&controller->early_tx_list)) {
+               ret = HRTIMER_RESTART;
+               hrtimer_forward_now(&controller->early_tx,
+                               ktime_set(0, 150 * NSEC_PER_USEC));
+       }
+
+       spin_unlock_irqrestore(&musb->lock, flags);
+       return ret;
+}
+
+static void cppi41_dma_callback(void *private_data)
+{
+       struct dma_channel *channel = private_data;
+       struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+       struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
+       struct musb *musb = hw_ep->musb;
+       unsigned long flags;
+       struct dma_tx_state txstate;
+       u32 transferred;
+       bool empty;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
+                       &txstate);
+       transferred = cppi41_channel->prog_len - txstate.residue;
+       cppi41_channel->transferred += transferred;
+
+       dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n",
+               hw_ep->epnum, cppi41_channel->transferred,
+               cppi41_channel->total_len);
+
+       update_rx_toggle(cppi41_channel);
+
+       if (cppi41_channel->transferred == cppi41_channel->total_len ||
+                       transferred < cppi41_channel->packet_sz)
+               cppi41_channel->prog_len = 0;
+
+       empty = musb_is_tx_fifo_empty(hw_ep);
+       if (empty) {
+               cppi41_trans_done(cppi41_channel);
+       } else {
+               struct cppi41_dma_controller *controller;
+               /*
+                * On AM335x it has been observed that the TX interrupt fires
+                * too early that means the TXFIFO is not yet empty but the DMA
+                * engine says that it is done with the transfer. We don't
+                * receive a FIFO empty interrupt so the only thing we can do is
+                * to poll for the bit. On HS it usually takes 2us, on FS around
+                * 110us - 150us depending on the transfer size.
+                * We spin on HS (no longer than than 25us and setup a timer on
+                * FS to check for the bit and complete the transfer.
+                */
+               controller = cppi41_channel->controller;
+
+               if (musb->g.speed == USB_SPEED_HIGH) {
+                       unsigned wait = 25;
+
+                       do {
+                               empty = musb_is_tx_fifo_empty(hw_ep);
+                               if (empty)
+                                       break;
+                               wait--;
+                               if (!wait)
+                                       break;
+                               udelay(1);
+                       } while (1);
+
+                       empty = musb_is_tx_fifo_empty(hw_ep);
+                       if (empty) {
+                               cppi41_trans_done(cppi41_channel);
+                               goto out;
+                       }
+               }
+               list_add_tail(&cppi41_channel->tx_check,
+                               &controller->early_tx_list);
+               if (!hrtimer_active(&controller->early_tx)) {
+                       hrtimer_start_range_ns(&controller->early_tx,
+                               ktime_set(0, 140 * NSEC_PER_USEC),
+                               40 * NSEC_PER_USEC,
+                               HRTIMER_MODE_REL);
+               }
+       }
+out:
        spin_unlock_irqrestore(&musb->lock, flags);
 }
 
@@ -364,6 +472,8 @@ static int cppi41_is_compatible(struct dma_channel *channel, u16 maxpacket,
                WARN_ON(1);
                return 1;
        }
+       if (cppi41_channel->hw_ep->ep_in.type != USB_ENDPOINT_XFER_BULK)
+               return 0;
        if (cppi41_channel->is_tx)
                return 1;
        /* AM335x Advisory 1.0.13. No workaround for device RX mode */
@@ -388,6 +498,7 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel)
        if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)
                return 0;
 
+       list_del_init(&cppi41_channel->tx_check);
        if (is_tx) {
                csr = musb_readw(epio, MUSB_TXCSR);
                csr &= ~MUSB_TXCSR_DMAENAB;
@@ -495,6 +606,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
                cppi41_channel->controller = controller;
                cppi41_channel->port_num = port;
                cppi41_channel->is_tx = is_tx;
+               INIT_LIST_HEAD(&cppi41_channel->tx_check);
 
                musb_dma = &cppi41_channel->channel;
                musb_dma->private_data = cppi41_channel;
@@ -520,6 +632,7 @@ void dma_controller_destroy(struct dma_controller *c)
        struct cppi41_dma_controller *controller = container_of(c,
                        struct cppi41_dma_controller, controller);
 
+       hrtimer_cancel(&controller->early_tx);
        cppi41_dma_controller_stop(controller);
        kfree(controller);
 }
@@ -539,6 +652,9 @@ struct dma_controller *dma_controller_create(struct musb *musb,
        if (!controller)
                goto kzalloc_fail;
 
+       hrtimer_init(&controller->early_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       controller->early_tx.function = cppi41_recheck_tx_req;
+       INIT_LIST_HEAD(&controller->early_tx_list);
        controller->musb = musb;
 
        controller->controller.channel_alloc = cppi41_dma_channel_allocate;
index d2d3a173b31503b54f9071e9af48f4878567856f..32fb057c03f58e25f401bdb49755e2cdc2637e86 100644 (file)
@@ -1796,7 +1796,11 @@ int musb_gadget_setup(struct musb *musb)
 
        /* this "gadget" abstracts/virtualizes the controller */
        musb->g.name = musb_driver_name;
+#if IS_ENABLED(CONFIG_USB_MUSB_DUAL_ROLE)
        musb->g.is_otg = 1;
+#elif IS_ENABLED(CONFIG_USB_MUSB_GADGET)
+       musb->g.is_otg = 0;
+#endif
 
        musb_g_init_endpoints(musb);
 
index 6370e50649d7f732c640fd65879c26d82ec5f994..0e3c60cb669a63c7a1d1bb7bd673f212f854c425 100644 (file)
@@ -52,8 +52,7 @@ static int am335x_phy_probe(struct platform_device *pdev)
                return am_phy->id;
        }
 
-       ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen,
-                       USB_PHY_TYPE_USB2, 0, false);
+       ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, NULL);
        if (ret)
                return ret;
 
@@ -66,8 +65,6 @@ static int am335x_phy_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, am_phy);
 
        return 0;
-
-       return ret;
 }
 
 static int am335x_phy_remove(struct platform_device *pdev)
index fce3a9e9bb5d282ff6b1a64492ad6a55c90e654f..aa6d37b3378ad65ff26e336031173a9ae52d2287 100644 (file)
@@ -48,8 +48,9 @@ void usb_nop_xceiv_register(void)
        if (pd)
                return;
        pd = platform_device_register_simple("usb_phy_gen_xceiv", -1, NULL, 0);
-       if (!pd) {
+       if (IS_ERR(pd)) {
                pr_err("Unable to register generic usb transceiver\n");
+               pd = NULL;
                return;
        }
 }
@@ -150,10 +151,40 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
 }
 
 int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
-               enum usb_phy_type type, u32 clk_rate, bool needs_vcc)
+               struct usb_phy_gen_xceiv_platform_data *pdata)
 {
+       enum usb_phy_type type = USB_PHY_TYPE_USB2;
        int err;
 
+       u32 clk_rate = 0;
+       bool needs_vcc = false;
+
+       nop->reset_active_low = true;   /* default behaviour */
+
+       if (dev->of_node) {
+               struct device_node *node = dev->of_node;
+               enum of_gpio_flags flags = 0;
+
+               if (of_property_read_u32(node, "clock-frequency", &clk_rate))
+                       clk_rate = 0;
+
+               needs_vcc = of_property_read_bool(node, "vcc-supply");
+               nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios",
+                                                               0, &flags);
+               if (nop->gpio_reset == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+
+               nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+       } else if (pdata) {
+               type = pdata->type;
+               clk_rate = pdata->clk_rate;
+               needs_vcc = pdata->needs_vcc;
+               nop->gpio_reset = pdata->gpio_reset;
+       } else {
+               nop->gpio_reset = -1;
+       }
+
        nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg),
                        GFP_KERNEL);
        if (!nop->phy.otg)
@@ -218,43 +249,14 @@ EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy);
 static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct usb_phy_gen_xceiv_platform_data *pdata =
-                       dev_get_platdata(&pdev->dev);
        struct usb_phy_gen_xceiv        *nop;
-       enum usb_phy_type       type = USB_PHY_TYPE_USB2;
        int err;
-       u32 clk_rate = 0;
-       bool needs_vcc = false;
 
        nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL);
        if (!nop)
                return -ENOMEM;
 
-       nop->reset_active_low = true;   /* default behaviour */
-
-       if (dev->of_node) {
-               struct device_node *node = dev->of_node;
-               enum of_gpio_flags flags;
-
-               if (of_property_read_u32(node, "clock-frequency", &clk_rate))
-                       clk_rate = 0;
-
-               needs_vcc = of_property_read_bool(node, "vcc-supply");
-               nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios",
-                                                               0, &flags);
-               if (nop->gpio_reset == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
-
-               nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
-
-       } else if (pdata) {
-               type = pdata->type;
-               clk_rate = pdata->clk_rate;
-               needs_vcc = pdata->needs_vcc;
-               nop->gpio_reset = pdata->gpio_reset;
-       }
-
-       err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc);
+       err = usb_phy_gen_create_phy(dev, nop, dev_get_platdata(&pdev->dev));
        if (err)
                return err;
 
@@ -271,8 +273,6 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, nop);
 
        return 0;
-
-       return err;
 }
 
 static int usb_phy_gen_xceiv_remove(struct platform_device *pdev)
index d2a220d81734ad5be296f56c3b416aa321bfb63e..38a81f307b8220bc5dfc81487a9fb420e397ccd1 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _PHY_GENERIC_H_
 #define _PHY_GENERIC_H_
 
+#include <linux/usb/usb_phy_gen_xceiv.h>
+
 struct usb_phy_gen_xceiv {
        struct usb_phy phy;
        struct device *dev;
@@ -14,6 +16,6 @@ int usb_gen_phy_init(struct usb_phy *phy);
 void usb_gen_phy_shutdown(struct usb_phy *phy);
 
 int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
-               enum usb_phy_type type, u32 clk_rate, bool needs_vcc);
+               struct usb_phy_gen_xceiv_platform_data *pdata);
 
 #endif
index fdd33b44dbd31b929eb13a2c0bd138570ccebc37..545844b7e7962f809f33812d9167f039b5fbc8d1 100644 (file)
@@ -164,7 +164,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
 
        mxs_phy->clk = clk;
 
-       platform_set_drvdata(pdev, &mxs_phy->phy);
+       platform_set_drvdata(pdev, mxs_phy);
 
        ret = usb_add_phy_dev(&mxs_phy->phy);
        if (ret)
index a99a6953f11cc1988272b9ae2d4e917073eb458f..db3ab34cddb4cbc6be6df4e66596b11186235477 100644 (file)
@@ -107,10 +107,10 @@ static void __rcar_gen2_usb_phy_init(struct rcar_gen2_usb_phy_priv *priv)
        clk_prepare_enable(priv->clk);
 
        /* Set USB channels in the USBHS UGCTRL2 register */
-       val = ioread32(priv->base);
+       val = ioread32(priv->base + USBHS_UGCTRL2_REG);
        val &= ~(USBHS_UGCTRL2_USB0_HS | USBHS_UGCTRL2_USB2_SS);
        val |= priv->ugctrl2;
-       iowrite32(val, priv->base);
+       iowrite32(val, priv->base + USBHS_UGCTRL2_REG);
 }
 
 /* Shutdown USB channels */
index 2b01ec8651c296e3f016bf2421040da6f1bbbc98..b63ce023f96f1ab7284e218ca68219da5f952440 100644 (file)
@@ -173,16 +173,8 @@ retry:
                clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags);
                return result;
        }
-       /*
-        * Try sending off another urb, unless called from completion handler
-        * (in which case there will be no free urb or no data).
-        */
-       if (mem_flags != GFP_ATOMIC)
-               goto retry;
 
-       clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags);
-
-       return 0;
+       goto retry;     /* try sending off another urb */
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_write_start);
 
@@ -208,7 +200,7 @@ int usb_serial_generic_write(struct tty_struct *tty,
                return 0;
 
        count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock);
-       result = usb_serial_generic_write_start(port, GFP_KERNEL);
+       result = usb_serial_generic_write_start(port, GFP_ATOMIC);
        if (result)
                return result;
 
index 0dac36ce09d6d74b7b33af1c15a70faffa72e792..518f790ef88a6d319e4d7fd806557c61741363dd 100644 (file)
@@ -3710,7 +3710,7 @@ default_chipset:
        if (!videomemory) {
                dev_warn(&pdev->dev,
                         "Unable to map videomem cached writethrough\n");
-               info->screen_base = (char *)ZTWO_VADDR(info->fix.smem_start);
+               info->screen_base = ZTWO_VADDR(info->fix.smem_start);
        } else
                info->screen_base = (char *)videomemory;
 
index 5aab9b9dc2109be565005d77cbfed962046434b3..d992aa5eb3f0dc6557b23b4ec3e4868301c5ede8 100644 (file)
@@ -2256,7 +2256,7 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
 
        info->fix.mmio_start = regbase;
        cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
-                                           : (caddr_t)ZTWO_VADDR(regbase);
+                                           : ZTWO_VADDR(regbase);
        if (!cinfo->regbase) {
                dev_err(info->device, "Cannot map registers\n");
                error = -EIO;
@@ -2266,7 +2266,7 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
        info->fix.smem_start = rambase;
        info->screen_size = ramsize;
        info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
-                                              : (caddr_t)ZTWO_VADDR(rambase);
+                                              : ZTWO_VADDR(rambase);
        if (!info->screen_base) {
                dev_err(info->device, "Cannot map video RAM\n");
                error = -EIO;
index 5bd2eb8d4f394b2122bf42bb1a1c42a71f440efe..cda7587cbc86ec0e2a6fa8a2ca90038ff71e155b 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/fb.h>
 
 #include <asm/setup.h>
-#include <asm/bootinfo.h>
 #include <asm/macintosh.h>
 #include <asm/io.h>
 
index e287ebc47817da5e8dccd66ce40d028d92bb6c73..97cb9bd1d1ddb75f48abe8546c555f6160b7a0b1 100644 (file)
@@ -56,7 +56,6 @@
 #include <linux/cuda.h>
 #include <asm/io.h>
 #ifdef CONFIG_MAC
-#include <asm/bootinfo.h>
 #include <asm/macintosh.h>
 #else
 #include <asm/prom.h>
index be37dde4f864448c13643ee4535e5b6a830be34c..9bd089ebb70fe8c4f32550338db633d2c5a41bdf 100644 (file)
 
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
 #include <linux/jiffies.h>
 #include <linux/bitops.h>
 #include <linux/uaccess.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 
 #include "at91sam9_wdt.h"
 
 #define DRV_NAME "AT91SAM9 Watchdog"
 
-#define wdt_read(field) \
-       __raw_readl(at91wdt_private.base + field)
-#define wdt_write(field, val) \
-       __raw_writel((val), at91wdt_private.base + field)
+#define wdt_read(wdt, field) \
+       __raw_readl((wdt)->base + (field))
+#define wdt_write(wtd, field, val) \
+       __raw_writel((val), (wdt)->base + (field))
 
 /* AT91SAM9 watchdog runs a 12bit counter @ 256Hz,
  * use this to convert a watchdog
  * value from/to milliseconds.
  */
-#define ms_to_ticks(t) (((t << 8) / 1000) - 1)
-#define ticks_to_ms(t) (((t + 1) * 1000) >> 8)
+#define ticks_to_hz_rounddown(t)       ((((t) + 1) * HZ) >> 8)
+#define ticks_to_hz_roundup(t)         (((((t) + 1) * HZ) + 255) >> 8)
+#define ticks_to_secs(t)               (((t) + 1) >> 8)
+#define secs_to_ticks(s)               (((s) << 8) - 1)
+
+#define WDT_MR_RESET   0x3FFF2FFF
+
+/* Watchdog max counter value in ticks */
+#define WDT_COUNTER_MAX_TICKS  0xFFF
+
+/* Watchdog max delta/value in secs */
+#define WDT_COUNTER_MAX_SECS   ticks_to_secs(WDT_COUNTER_MAX_TICKS)
 
 /* Hardware timeout in seconds */
 #define WDT_HW_TIMEOUT 2
@@ -66,23 +79,40 @@ module_param(nowayout, bool, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
        "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
-static struct watchdog_device at91_wdt_dev;
-static void at91_ping(unsigned long data);
-
-static struct {
+#define to_wdt(wdd) container_of(wdd, struct at91wdt, wdd)
+struct at91wdt {
+       struct watchdog_device wdd;
        void __iomem *base;
        unsigned long next_heartbeat;   /* the next_heartbeat for the timer */
        struct timer_list timer;        /* The timer that pings the watchdog */
-} at91wdt_private;
+       u32 mr;
+       u32 mr_mask;
+       unsigned long heartbeat;        /* WDT heartbeat in jiffies */
+       bool nowayout;
+       unsigned int irq;
+};
 
 /* ......................................................................... */
 
+static irqreturn_t wdt_interrupt(int irq, void *dev_id)
+{
+       struct at91wdt *wdt = (struct at91wdt *)dev_id;
+
+       if (wdt_read(wdt, AT91_WDT_SR)) {
+               pr_crit("at91sam9 WDT software reset\n");
+               emergency_restart();
+               pr_crit("Reboot didn't ?????\n");
+       }
+
+       return IRQ_HANDLED;
+}
+
 /*
  * Reload the watchdog timer.  (ie, pat the watchdog)
  */
-static inline void at91_wdt_reset(void)
+static inline void at91_wdt_reset(struct at91wdt *wdt)
 {
-       wdt_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
+       wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
 }
 
 /*
@@ -90,26 +120,21 @@ static inline void at91_wdt_reset(void)
  */
 static void at91_ping(unsigned long data)
 {
-       if (time_before(jiffies, at91wdt_private.next_heartbeat) ||
-           (!watchdog_active(&at91_wdt_dev))) {
-               at91_wdt_reset();
-               mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
-       } else
+       struct at91wdt *wdt = (struct at91wdt *)data;
+       if (time_before(jiffies, wdt->next_heartbeat) ||
+           !watchdog_active(&wdt->wdd)) {
+               at91_wdt_reset(wdt);
+               mod_timer(&wdt->timer, jiffies + wdt->heartbeat);
+       } else {
                pr_crit("I will reset your machine !\n");
-}
-
-static int at91_wdt_ping(struct watchdog_device *wdd)
-{
-       /* calculate when the next userspace timeout will be */
-       at91wdt_private.next_heartbeat = jiffies + wdd->timeout * HZ;
-       return 0;
+       }
 }
 
 static int at91_wdt_start(struct watchdog_device *wdd)
 {
-       /* calculate the next userspace timeout and modify the timer */
-       at91_wdt_ping(wdd);
-       mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
+       struct at91wdt *wdt = to_wdt(wdd);
+       /* calculate when the next userspace timeout will be */
+       wdt->next_heartbeat = jiffies + wdd->timeout * HZ;
        return 0;
 }
 
@@ -122,39 +147,89 @@ static int at91_wdt_stop(struct watchdog_device *wdd)
 static int at91_wdt_set_timeout(struct watchdog_device *wdd, unsigned int new_timeout)
 {
        wdd->timeout = new_timeout;
-       return 0;
+       return at91_wdt_start(wdd);
 }
 
-/*
- * Set the watchdog time interval in 1/256Hz (write-once)
- * Counter is 12 bit.
- */
-static int at91_wdt_settimeout(unsigned int timeout)
+static int at91_wdt_init(struct platform_device *pdev, struct at91wdt *wdt)
 {
-       unsigned int reg;
-       unsigned int mr;
-
-       /* Check if disabled */
-       mr = wdt_read(AT91_WDT_MR);
-       if (mr & AT91_WDT_WDDIS) {
-               pr_err("sorry, watchdog is disabled\n");
-               return -EIO;
+       u32 tmp;
+       u32 delta;
+       u32 value;
+       int err;
+       u32 mask = wdt->mr_mask;
+       unsigned long min_heartbeat = 1;
+       struct device *dev = &pdev->dev;
+
+       tmp = wdt_read(wdt, AT91_WDT_MR);
+       if ((tmp & mask) != (wdt->mr & mask)) {
+               if (tmp == WDT_MR_RESET) {
+                       wdt_write(wdt, AT91_WDT_MR, wdt->mr);
+                       tmp = wdt_read(wdt, AT91_WDT_MR);
+               }
+       }
+
+       if (tmp & AT91_WDT_WDDIS) {
+               if (wdt->mr & AT91_WDT_WDDIS)
+                       return 0;
+               dev_err(dev, "watchdog is disabled\n");
+               return -EINVAL;
+       }
+
+       value = tmp & AT91_WDT_WDV;
+       delta = (tmp & AT91_WDT_WDD) >> 16;
+
+       if (delta < value)
+               min_heartbeat = ticks_to_hz_roundup(value - delta);
+
+       wdt->heartbeat = ticks_to_hz_rounddown(value);
+       if (!wdt->heartbeat) {
+               dev_err(dev,
+                       "heartbeat is too small for the system to handle it correctly\n");
+               return -EINVAL;
+       }
+
+       if (wdt->heartbeat < min_heartbeat + 4) {
+               wdt->heartbeat = min_heartbeat;
+               dev_warn(dev,
+                        "min heartbeat and max heartbeat might be too close for the system to handle it correctly\n");
+               if (wdt->heartbeat < 4)
+                       dev_warn(dev,
+                                "heartbeat might be too small for the system to handle it correctly\n");
+       } else {
+               wdt->heartbeat -= 4;
        }
 
-       /*
-        * All counting occurs at SLOW_CLOCK / 128 = 256 Hz
-        *
-        * Since WDV is a 12-bit counter, the maximum period is
-        * 4096 / 256 = 16 seconds.
-        */
-       reg = AT91_WDT_WDRSTEN  /* causes watchdog reset */
-               /* | AT91_WDT_WDRPROC   causes processor reset only */
-               | AT91_WDT_WDDBGHLT     /* disabled in debug mode */
-               | AT91_WDT_WDD          /* restart at any time */
-               | (timeout & AT91_WDT_WDV);  /* timer value */
-       wdt_write(AT91_WDT_MR, reg);
+       if ((tmp & AT91_WDT_WDFIEN) && wdt->irq) {
+               err = request_irq(wdt->irq, wdt_interrupt,
+                                 IRQF_SHARED | IRQF_IRQPOLL,
+                                 pdev->name, wdt);
+               if (err)
+                       return err;
+       }
+
+       if ((tmp & wdt->mr_mask) != (wdt->mr & wdt->mr_mask))
+               dev_warn(dev,
+                        "watchdog already configured differently (mr = %x expecting %x)\n",
+                        tmp & wdt->mr_mask, wdt->mr & wdt->mr_mask);
+
+       setup_timer(&wdt->timer, at91_ping, (unsigned long)wdt);
+       mod_timer(&wdt->timer, jiffies + wdt->heartbeat);
+
+       /* Try to set timeout from device tree first */
+       if (watchdog_init_timeout(&wdt->wdd, 0, dev))
+               watchdog_init_timeout(&wdt->wdd, heartbeat, dev);
+       watchdog_set_nowayout(&wdt->wdd, wdt->nowayout);
+       err = watchdog_register_device(&wdt->wdd);
+       if (err)
+               goto out_stop_timer;
+
+       wdt->next_heartbeat = jiffies + wdt->wdd.timeout * HZ;
 
        return 0;
+
+out_stop_timer:
+       del_timer(&wdt->timer);
+       return err;
 }
 
 /* ......................................................................... */
@@ -169,61 +244,123 @@ static const struct watchdog_ops at91_wdt_ops = {
        .owner =        THIS_MODULE,
        .start =        at91_wdt_start,
        .stop =         at91_wdt_stop,
-       .ping =         at91_wdt_ping,
        .set_timeout =  at91_wdt_set_timeout,
 };
 
-static struct watchdog_device at91_wdt_dev = {
-       .info =         &at91_wdt_info,
-       .ops =          &at91_wdt_ops,
-       .timeout =      WDT_HEARTBEAT,
-       .min_timeout =  1,
-       .max_timeout =  0xFFFF,
-};
+#if defined(CONFIG_OF)
+static int of_at91wdt_init(struct device_node *np, struct at91wdt *wdt)
+{
+       u32 min = 0;
+       u32 max = WDT_COUNTER_MAX_SECS;
+       const char *tmp;
+
+       /* Get the interrupts property */
+       wdt->irq = irq_of_parse_and_map(np, 0);
+       if (!wdt->irq)
+               dev_warn(wdt->wdd.parent, "failed to get IRQ from DT\n");
+
+       if (!of_property_read_u32_index(np, "atmel,max-heartbeat-sec", 0,
+                                       &max)) {
+               if (!max || max > WDT_COUNTER_MAX_SECS)
+                       max = WDT_COUNTER_MAX_SECS;
+
+               if (!of_property_read_u32_index(np, "atmel,min-heartbeat-sec",
+                                               0, &min)) {
+                       if (min >= max)
+                               min = max - 1;
+               }
+       }
+
+       min = secs_to_ticks(min);
+       max = secs_to_ticks(max);
+
+       wdt->mr_mask = 0x3FFFFFFF;
+       wdt->mr = 0;
+       if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
+           !strcmp(tmp, "software")) {
+               wdt->mr |= AT91_WDT_WDFIEN;
+               wdt->mr_mask &= ~AT91_WDT_WDRPROC;
+       } else {
+               wdt->mr |= AT91_WDT_WDRSTEN;
+       }
+
+       if (!of_property_read_string(np, "atmel,reset-type", &tmp) &&
+           !strcmp(tmp, "proc"))
+               wdt->mr |= AT91_WDT_WDRPROC;
+
+       if (of_property_read_bool(np, "atmel,disable")) {
+               wdt->mr |= AT91_WDT_WDDIS;
+               wdt->mr_mask &= AT91_WDT_WDDIS;
+       }
+
+       if (of_property_read_bool(np, "atmel,idle-halt"))
+               wdt->mr |= AT91_WDT_WDIDLEHLT;
+
+       if (of_property_read_bool(np, "atmel,dbg-halt"))
+               wdt->mr |= AT91_WDT_WDDBGHLT;
+
+       wdt->mr |= max | ((max - min) << 16);
+
+       return 0;
+}
+#else
+static inline int of_at91wdt_init(struct device_node *np, struct at91wdt *wdt)
+{
+       return 0;
+}
+#endif
 
 static int __init at91wdt_probe(struct platform_device *pdev)
 {
        struct resource *r;
-       int res;
+       int err;
+       struct at91wdt *wdt;
 
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!r)
-               return -ENODEV;
-       at91wdt_private.base = ioremap(r->start, resource_size(r));
-       if (!at91wdt_private.base) {
-               dev_err(&pdev->dev, "failed to map registers, aborting.\n");
+       wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+       if (!wdt)
                return -ENOMEM;
-       }
 
-       at91_wdt_dev.parent = &pdev->dev;
-       watchdog_init_timeout(&at91_wdt_dev, heartbeat, &pdev->dev);
-       watchdog_set_nowayout(&at91_wdt_dev, nowayout);
+       wdt->mr = (WDT_HW_TIMEOUT * 256) | AT91_WDT_WDRSTEN | AT91_WDT_WDD |
+                 AT91_WDT_WDDBGHLT | AT91_WDT_WDIDLEHLT;
+       wdt->mr_mask = 0x3FFFFFFF;
+       wdt->nowayout = nowayout;
+       wdt->wdd.parent = &pdev->dev;
+       wdt->wdd.info = &at91_wdt_info;
+       wdt->wdd.ops = &at91_wdt_ops;
+       wdt->wdd.timeout = WDT_HEARTBEAT;
+       wdt->wdd.min_timeout = 1;
+       wdt->wdd.max_timeout = 0xFFFF;
 
-       /* Set watchdog */
-       res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000));
-       if (res)
-               return res;
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       wdt->base = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(wdt->base))
+               return PTR_ERR(wdt->base);
+
+       if (pdev->dev.of_node) {
+               err = of_at91wdt_init(pdev->dev.of_node, wdt);
+               if (err)
+                       return err;
+       }
 
-       res = watchdog_register_device(&at91_wdt_dev);
-       if (res)
-               return res;
+       err = at91_wdt_init(pdev, wdt);
+       if (err)
+               return err;
 
-       at91wdt_private.next_heartbeat = jiffies + at91_wdt_dev.timeout * HZ;
-       setup_timer(&at91wdt_private.timer, at91_ping, 0);
-       mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
+       platform_set_drvdata(pdev, wdt);
 
        pr_info("enabled (heartbeat=%d sec, nowayout=%d)\n",
-               at91_wdt_dev.timeout, nowayout);
+               wdt->wdd.timeout, wdt->nowayout);
 
        return 0;
 }
 
 static int __exit at91wdt_remove(struct platform_device *pdev)
 {
-       watchdog_unregister_device(&at91_wdt_dev);
+       struct at91wdt *wdt = platform_get_drvdata(pdev);
+       watchdog_unregister_device(&wdt->wdd);
 
        pr_warn("I quit now, hardware will probably reboot!\n");
-       del_timer(&at91wdt_private.timer);
+       del_timer(&wdt->timer);
 
        return 0;
 }
index a6a2cebb25879242b8408b1537838a67d932b2b3..cafa973c43be7af984fb9d39456b1d36b8913ea8 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/watchdog.h>
 #include <linux/platform_device.h>
 #include <linux/of_address.h>
-#include <linux/miscdevice.h>
 
 #define PM_RSTC                                0x1c
 #define PM_WDOG                                0x24
index 833e813118489216a8a27901f749f0765bd03e8f..d1d07f2f69df7cf61cd838feaa89650c22908098 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <linux/platform_device.h>
 #include <linux/module.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/timer.h>
 #include <linux/io.h>
index 70a240297c6d22f2a7d170a731f70320512f478a..07f88f54e5c03008159a5a276056340e65058086 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
-#include <linux/miscdevice.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
index 2de486a7eea18a058808cbb33a0ec0fa5f3a650b..3aa50cfa335fda1576950451a492a92336da41cd 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index a1a3638c579c857c382ec9c253e5f69424e1dbbb..20dc73844737a99cf30aa6852f6bfceb06d04984 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/miscdevice.h>
 #include <linux/uaccess.h>
 #include <linux/watchdog.h>
 #include <linux/platform_device.h>
index 6d4f3998e1f6c08e7158fdf1068b3a94c3bad448..bdb3f4a5b27c760b5c7509f957213037e234e2be 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
index 44edca66d564195a8e20b54f20c8b4cc389eca2c..f7722a42467632030b4d36dc608e1af7cf497002 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/miscdevice.h>
 #include <linux/platform_device.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
index 1bdcc313e1d9f713dc24c8b4cf7e2f7e9c312574..5bec20f5dc2db29ec5294bbdf03ee7b8106cb21a 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index 53d37fea183e1b5be5f2f18093a1c4021e632bc9..d92c2d5859ce9f67c4af0f2c61fcbe6c8c396e74 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/watchdog.h>
-#include <linux/miscdevice.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
 
index f9b8e06f355808e763ca7a1f7f2e4511fe33c88f..af3528f84d65469196d2a409dbcfc531a09e57c6 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/pm_runtime.h>
 #include <linux/fs.h>
index ef2638fee4a8f7037c1f7c342ec1be1347ee3957..c04a1aa158e25762fcbe2b161052beaf56897d7f 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/timer.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
index d667f6b51d35f93aba02547f82653f3dbb189aa4..bb64ae3f47da58079ac816bde0d5c9abac5f0bff 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/platform_device.h>
 #include <linux/stmp3xxx_rtc_wdt.h>
index 0fd0e8ae62a833b462b29bd09f8f5e7666e437bf..6a447e321dd0c3cf076169d7eac3c7b887a4b96b 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/types.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index e029b5768f2c1379279f034dc24c892b52fc0ec3..5aed9d7ad47e6ee81e96b4f16b15aa653a6a9482 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
-#include <linux/miscdevice.h>
 #include <linux/err.h>
 #include <linux/uaccess.h>
 #include <linux/watchdog.h>
index 62ccf5424ba857e0fe11bb22187bb7dd5d3dad6c..028387192b608b04a9fd9483a9916404cb861f76 100644 (file)
@@ -930,9 +930,10 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
                ret = m2p_add_override(mfn, pages[i], kmap_ops ?
                                       &kmap_ops[i] : NULL);
                if (ret)
-                       return ret;
+                       goto out;
        }
 
+ out:
        if (lazy)
                arch_leave_lazy_mmu_mode();
 
@@ -969,9 +970,10 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
                ret = m2p_remove_override(pages[i], kmap_ops ?
                                       &kmap_ops[i] : NULL);
                if (ret)
-                       return ret;
+                       goto out;
        }
 
+ out:
        if (lazy)
                arch_leave_lazy_mmu_mode();
 
index a224bc74b6b9d34fa5c45f41408a3ed1138098f4..1eac0731c349f2067b42dea6e01f292453096d4b 100644 (file)
@@ -555,6 +555,11 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
                                sg_dma_len(sgl) = 0;
                                return 0;
                        }
+                       xen_dma_map_page(hwdev, pfn_to_page(map >> PAGE_SHIFT),
+                                               map & ~PAGE_MASK,
+                                               sg->length,
+                                               dir,
+                                               attrs);
                        sg->dma_address = xen_phys_to_bus(map);
                } else {
                        /* we are not interested in the dma_addr returned by
index 8dae6c13063af5df3846d0c3a700876fe23eefe0..80875fb770ed931681c75db5aa4209c15acfc7a7 100644 (file)
 #include <linux/cpu.h>
 #include <linux/acpi.h>
 #include <linux/uaccess.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 #include <acpi/processor.h>
-
 #include <xen/acpi.h>
 #include <xen/interface/platform.h>
 #include <asm/xen/hypercall.h>
@@ -269,7 +266,8 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
                if (!is_processor_present(handle))
                        break;
 
-               if (!acpi_bus_get_device(handle, &device))
+               acpi_bus_get_device(handle, &device);
+               if (acpi_device_enumerated(device))
                        break;
 
                result = acpi_bus_scan(handle);
@@ -277,8 +275,9 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
                        pr_err(PREFIX "Unable to add the device\n");
                        break;
                }
-               result = acpi_bus_get_device(handle, &device);
-               if (result) {
+               device = NULL;
+               acpi_bus_get_device(handle, &device);
+               if (!acpi_device_enumerated(device)) {
                        pr_err(PREFIX "Missing device object\n");
                        break;
                }
index 9083f1e474f801c07c1531551fa971b5e0e21b38..f8d18626969a48819ae5810f1d424dc4eacf3f31 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_drivers.h>
 #include <xen/acpi.h>
 #include <xen/interface/platform.h>
 #include <asm/xen/hypercall.h>
@@ -169,7 +168,7 @@ static int acpi_memory_get_device(acpi_handle handle,
        acpi_scan_lock_acquire();
 
        acpi_bus_get_device(handle, &device);
-       if (device)
+       if (acpi_device_enumerated(device))
                goto end;
 
        /*
@@ -182,8 +181,9 @@ static int acpi_memory_get_device(acpi_handle handle,
                result = -EINVAL;
                goto out;
        }
-       result = acpi_bus_get_device(handle, &device);
-       if (result) {
+       device = NULL;
+       acpi_bus_get_device(handle, &device);
+       if (!acpi_device_enumerated(device)) {
                pr_warn(PREFIX "Missing device object\n");
                result = -EINVAL;
                goto out;
index 59708fdd068bdfed83976dab53a823115efeda29..40c4bc06b5fa0929af0b9b8ffddd9d59e6bcbc36 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-#include <asm/xen/hypercall.h>
+#include <linux/acpi.h>
 #include <xen/interface/version.h>
 #include <xen/xen-ops.h>
+#include <asm/xen/hypercall.h>
 
 #define ACPI_PROCESSOR_AGGREGATOR_CLASS        "acpi_pad"
 #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
index 13bc6c31c060bfc9821eb23eb467873b720c6f13..7231859119f1f126ac89e606ecc7c96c1a6a55c3 100644 (file)
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/syscore_ops.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
 #include <acpi/processor.h>
-
 #include <xen/xen.h>
 #include <xen/interface/platform.h>
 #include <asm/xen/hypercall.h>
index f62172603215ed433a32f7945603c95bf05783c2..7dc5332ff9842bfe1f119f4ff003056430959ec3 100644 (file)
@@ -2,8 +2,9 @@
 # Makefile for the Zorro bus specific drivers.
 #
 
-obj-$(CONFIG_ZORRO)    += zorro.o zorro-driver.o zorro-sysfs.o names.o
+obj-$(CONFIG_ZORRO)    += zorro.o zorro-driver.o zorro-sysfs.o
 obj-$(CONFIG_PROC_FS)  += proc.o
+obj-$(CONFIG_ZORRO_NAMES) +=  names.o
 
 hostprogs-y            := gen-devlist
 
index e8517c3d8e82df3d9b34f9049a29bdedd0a61b0e..6f3fd9903ac387f8d354c843ae88950b45bcfcfb 100644 (file)
@@ -15,8 +15,6 @@
 #include <linux/zorro.h>
 
 
-#ifdef CONFIG_ZORRO_NAMES
-
 struct zorro_prod_info {
        __u16 prod;
        unsigned short seen;
@@ -69,7 +67,6 @@ void __init zorro_name_device(struct zorro_dev *dev)
        } while (--i);
 
        /* Couldn't find either the manufacturer nor the product */
-       sprintf(name, "Zorro device %08x", dev->id);
        return;
 
        match_manuf: {
@@ -98,11 +95,3 @@ void __init zorro_name_device(struct zorro_dev *dev)
                }
        }
 }
-
-#else
-
-void __init zorro_name_device(struct zorro_dev *dev)
-{
-}
-
-#endif
index ea1ce822a8e0437120184a8e559bd0495860c7b7..6ac2579da0ebb1355450474204807701e47e2e08 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/export.h>
+
+#include <asm/byteorder.h>
 #include <asm/uaccess.h>
 #include <asm/amigahw.h>
 #include <asm/setup.h>
@@ -41,10 +43,10 @@ proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *
        /* Construct a ConfigDev */
        memset(&cd, 0, sizeof(cd));
        cd.cd_Rom = z->rom;
-       cd.cd_SlotAddr = z->slotaddr;
-       cd.cd_SlotSize = z->slotsize;
-       cd.cd_BoardAddr = (void *)zorro_resource_start(z);
-       cd.cd_BoardSize = zorro_resource_len(z);
+       cd.cd_SlotAddr = cpu_to_be16(z->slotaddr);
+       cd.cd_SlotSize = cpu_to_be16(z->slotsize);
+       cd.cd_BoardAddr = cpu_to_be32(zorro_resource_start(z));
+       cd.cd_BoardSize = cpu_to_be32(zorro_resource_len(z));
 
        if (copy_to_user(buf, (void *)&cd + pos, nbytes))
                return -EFAULT;
index ac1db7f1bcab7731e9366cfc4bce832c4258cd35..eacae1434b73fd7472e2d81b5b86ebc214f3e6af 100644 (file)
@@ -161,11 +161,12 @@ static int zorro_uevent(struct device *dev, struct kobj_uevent_env *env)
 }
 
 struct bus_type zorro_bus_type = {
-       .name   = "zorro",
-       .match  = zorro_bus_match,
-       .uevent = zorro_uevent,
-       .probe  = zorro_device_probe,
-       .remove = zorro_device_remove,
+       .name     = "zorro",
+       .dev_name = "zorro",
+       .match    = zorro_bus_match,
+       .uevent   = zorro_uevent,
+       .probe    = zorro_device_probe,
+       .remove   = zorro_device_remove,
 };
 EXPORT_SYMBOL(zorro_bus_type);
 
index 26f7184ef9e1a19cb47890bcbfaa124c6c34912b..36b210f9b6b29621fa9e410db063d3df53d7fb75 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 
+#include <asm/byteorder.h>
+
 #include "zorro.h"
 
 
@@ -33,10 +35,20 @@ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
 
 zorro_config_attr(id, id, "0x%08x\n");
 zorro_config_attr(type, rom.er_Type, "0x%02x\n");
-zorro_config_attr(serial, rom.er_SerialNumber, "0x%08x\n");
 zorro_config_attr(slotaddr, slotaddr, "0x%04x\n");
 zorro_config_attr(slotsize, slotsize, "0x%04x\n");
 
+static ssize_t
+show_serial(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct zorro_dev *z;
+
+       z = to_zorro_dev(dev);
+       return sprintf(buf, "0x%08x\n", be32_to_cpu(z->rom.er_SerialNumber));
+}
+
+static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL);
+
 static ssize_t zorro_show_resource(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct zorro_dev *z = to_zorro_dev(dev);
@@ -60,10 +72,10 @@ static ssize_t zorro_read_config(struct file *filp, struct kobject *kobj,
        /* Construct a ConfigDev */
        memset(&cd, 0, sizeof(cd));
        cd.cd_Rom = z->rom;
-       cd.cd_SlotAddr = z->slotaddr;
-       cd.cd_SlotSize = z->slotsize;
-       cd.cd_BoardAddr = (void *)zorro_resource_start(z);
-       cd.cd_BoardSize = zorro_resource_len(z);
+       cd.cd_SlotAddr = cpu_to_be16(z->slotaddr);
+       cd.cd_SlotSize = cpu_to_be16(z->slotsize);
+       cd.cd_BoardAddr = cpu_to_be32(zorro_resource_start(z));
+       cd.cd_BoardSize = cpu_to_be32(zorro_resource_len(z));
 
        return memory_read_from_buffer(buf, count, &off, &cd, sizeof(cd));
 }
index 858c9714b2f390a26e1a1450f196d7abf6e14340..707c1a5a031703ba1b7e8de9f87e71103d217a18 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
+#include <asm/byteorder.h>
 #include <asm/setup.h>
 #include <asm/amigahw.h>
 
@@ -29,7 +30,8 @@
      */
 
 unsigned int zorro_num_autocon;
-struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
+struct zorro_dev_init zorro_autocon_init[ZORRO_NUM_AUTO] __initdata;
+struct zorro_dev *zorro_autocon;
 
 
     /*
@@ -38,6 +40,7 @@ struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
 
 struct zorro_bus {
        struct device dev;
+       struct zorro_dev devices[0];
 };
 
 
@@ -125,18 +128,22 @@ static struct resource __init *zorro_find_parent_resource(
 static int __init amiga_zorro_probe(struct platform_device *pdev)
 {
        struct zorro_bus *bus;
+       struct zorro_dev_init *zi;
        struct zorro_dev *z;
        struct resource *r;
        unsigned int i;
        int error;
 
        /* Initialize the Zorro bus */
-       bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+       bus = kzalloc(sizeof(*bus) +
+                     zorro_num_autocon * sizeof(bus->devices[0]),
+                     GFP_KERNEL);
        if (!bus)
                return -ENOMEM;
 
+       zorro_autocon = bus->devices;
        bus->dev.parent = &pdev->dev;
-       dev_set_name(&bus->dev, "zorro");
+       dev_set_name(&bus->dev, zorro_bus_type.name);
        error = device_register(&bus->dev);
        if (error) {
                pr_err("Zorro: Error registering zorro_bus\n");
@@ -151,15 +158,23 @@ static int __init amiga_zorro_probe(struct platform_device *pdev)
 
        /* First identify all devices ... */
        for (i = 0; i < zorro_num_autocon; i++) {
+               zi = &zorro_autocon_init[i];
                z = &zorro_autocon[i];
-               z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
+
+               z->rom = zi->rom;
+               z->id = (be16_to_cpu(z->rom.er_Manufacturer) << 16) |
+                       (z->rom.er_Product << 8);
                if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
                        /* GVP quirk */
-                       unsigned long magic = zorro_resource_start(z)+0x8000;
+                       unsigned long magic = zi->boardaddr + 0x8000;
                        z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
                }
+               z->slotaddr = zi->slotaddr;
+               z->slotsize = zi->slotsize;
                sprintf(z->name, "Zorro device %08x", z->id);
                zorro_name_device(z);
+               z->resource.start = zi->boardaddr;
+               z->resource.end = zi->boardaddr + zi->boardsize - 1;
                z->resource.name = z->name;
                r = zorro_find_parent_resource(pdev, z);
                error = request_resource(r, &z->resource);
@@ -167,9 +182,9 @@ static int __init amiga_zorro_probe(struct platform_device *pdev)
                        dev_err(&bus->dev,
                                "Address space collision on device %s %pR\n",
                                z->name, &z->resource);
-               dev_set_name(&z->dev, "%02x", i);
                z->dev.parent = &bus->dev;
                z->dev.bus = &zorro_bus_type;
+               z->dev.id = i;
        }
 
        /* ... then register them */
index b682d5ccd63f74b1be7aae6db188270318891f14..34119fb4e5601603edbd139563f539b3548963c9 100644 (file)
@@ -1,4 +1,9 @@
 
+#ifdef CONFIG_ZORRO_NAMES
 extern void zorro_name_device(struct zorro_dev *z);
+#else
+static inline void zorro_name_device(struct zorro_dev *dev) { }
+#endif
+
 extern int zorro_create_sysfs_dev_files(struct zorro_dev *z);
 
index 2b7a032c37bc7b087e0fdb3129436c0b735ba809..a69260f27555df85894618dc1647422971914dc4 100644 (file)
@@ -239,13 +239,12 @@ void v9fs_cache_inode_flush_cookie(struct inode *inode)
 void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp)
 {
        struct v9fs_inode *v9inode = V9FS_I(inode);
-       struct p9_fid *fid;
 
        if (!v9inode->fscache)
                return;
 
        spin_lock(&v9inode->fscache_lock);
-       fid = filp->private_data;
+
        if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
                v9fs_cache_inode_flush_cookie(inode);
        else
index a0df3e73c2b128e01ede3519b1c2aae2d8b09f28..27782bb7f4f9090c7c6330a1c071356b9c4baaf1 100644 (file)
@@ -461,14 +461,12 @@ v9fs_file_write_internal(struct inode *inode, struct p9_fid *fid,
        int n;
        loff_t i_size;
        size_t total = 0;
-       struct p9_client *clnt;
        loff_t origin = *offset;
        unsigned long pg_start, pg_end;
 
        p9_debug(P9_DEBUG_VFS, "data %p count %d offset %x\n",
                 data, (int)count, (int)*offset);
 
-       clnt = fid->clnt;
        do {
                n = p9_client_write(fid, NULL, data+total, origin+total, count);
                if (n <= 0)
index 4e65aa903345da5a7e63f5e49fb53f1204ee579e..af7d531bdecdedcc4e7cef7a99dc36347b1c1163 100644 (file)
@@ -779,7 +779,6 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
                                      unsigned int flags)
 {
        struct dentry *res;
-       struct super_block *sb;
        struct v9fs_session_info *v9ses;
        struct p9_fid *dfid, *fid;
        struct inode *inode;
@@ -791,7 +790,6 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
        if (dentry->d_name.len > NAME_MAX)
                return ERR_PTR(-ENAMETOOLONG);
 
-       sb = dir->i_sb;
        v9ses = v9fs_inode2v9ses(dir);
        /* We can walk d_parent because we hold the dir->i_mutex */
        dfid = v9fs_fid_lookup(dentry->d_parent);
@@ -863,7 +861,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
                return finish_no_open(file, res);
 
        err = 0;
-       fid = NULL;
+
        v9ses = v9fs_inode2v9ses(dir);
        perm = unixmode2p9mode(v9ses, mode);
        fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
index 4c10edec26a04a5796f417da7151f3b5ae2b77fb..98013068f35bffa2e347b0ddb1b7ce44b366deb7 100644 (file)
@@ -473,13 +473,11 @@ static int
 v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
                 struct kstat *stat)
 {
-       int err;
        struct v9fs_session_info *v9ses;
        struct p9_fid *fid;
        struct p9_stat_dotl *st;
 
        p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
-       err = -EPERM;
        v9ses = v9fs_dentry2v9ses(dentry);
        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
                generic_fillattr(dentry->d_inode, stat);
@@ -556,7 +554,6 @@ static int v9fs_mapped_iattr_valid(int iattr_valid)
 int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
 {
        int retval;
-       struct v9fs_session_info *v9ses;
        struct p9_fid *fid;
        struct p9_iattr_dotl p9attr;
        struct inode *inode = dentry->d_inode;
@@ -577,8 +574,6 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
        p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
        p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
 
-       retval = -EPERM;
-       v9ses = v9fs_dentry2v9ses(dentry);
        fid = v9fs_fid_lookup(dentry);
        if (IS_ERR(fid))
                return PTR_ERR(fid);
@@ -768,7 +763,6 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
                struct dentry *dentry)
 {
        int err;
-       char *name;
        struct dentry *dir_dentry;
        struct p9_fid *dfid, *oldfid;
        struct v9fs_session_info *v9ses;
@@ -786,8 +780,6 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
        if (IS_ERR(oldfid))
                return PTR_ERR(oldfid);
 
-       name = (char *) dentry->d_name.name;
-
        err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
 
        if (err < 0) {
index 3c28cdfb8c477b65269c1a26957cb4942d10344f..04133a1fd9cbea42585f530b56bb73f93b1bd1dc 100644 (file)
@@ -138,8 +138,7 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
        if (retval < 0) {
                p9_debug(P9_DEBUG_VFS, "p9_client_xattrcreate failed %d\n",
                         retval);
-               p9_client_clunk(fid);
-               return retval;
+               goto err;
        }
        msize = fid->clnt->msize;
        while (value_len) {
@@ -152,12 +151,15 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
                if (write_count < 0) {
                        /* error in xattr write */
                        retval = write_count;
-                       break;
+                       goto err;
                }
                offset += write_count;
                value_len -= write_count;
        }
-       return p9_client_clunk(fid);
+       retval = offset;
+err:
+       p9_client_clunk(fid);
+       return retval;
 }
 
 ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
index 4fe6df3ec28fe5392b680e853b0fbfef6313179a..39a824f44e7c17c807988ca970a2eefbe2113ece 100644 (file)
@@ -53,7 +53,7 @@ obj-$(CONFIG_FHANDLE)         += fhandle.o
 obj-y                          += quota/
 
 obj-$(CONFIG_PROC_FS)          += proc/
-obj-$(CONFIG_SYSFS)            += sysfs/
+obj-$(CONFIG_SYSFS)            += sysfs/ kernfs/
 obj-$(CONFIG_CONFIGFS_FS)      += configfs/
 obj-y                          += devpts/
 
index a29409c1ffe066b00684db073aa365997371e80f..b41c2c9792ff0dc9a68529219af40967421f797e 100644 (file)
@@ -91,7 +91,7 @@ more 2.4 fixes: [Roman Zippel]
 Version 3.11
 ------------
 
-- Converted to use 2.3.x page cache [Dave Jones <dave@powertweak.com>]
+- Converted to use 2.3.x page cache [Dave Jones]
 - Corruption in truncate() bugfix [Ken Tyler <kent@werple.net.au>]
 
 Version 3.10
index fc60b31453eefbbdcc234c7df78c5504da655980..80d972d739e5d32236b0df186d6312dcab028f3f 100644 (file)
@@ -134,8 +134,7 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
                return 0;
        }
 
-       iv = bip_vec_idx(bip, bip->bip_vcnt);
-       BUG_ON(iv == NULL);
+       iv = bip->bip_vec + bip->bip_vcnt;
 
        iv->bv_page = page;
        iv->bv_len = len;
@@ -203,6 +202,12 @@ static inline unsigned int bio_integrity_hw_sectors(struct blk_integrity *bi,
        return sectors;
 }
 
+static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
+                                              unsigned int sectors)
+{
+       return bio_integrity_hw_sectors(bi, sectors) * bi->tuple_size;
+}
+
 /**
  * bio_integrity_tag_size - Retrieve integrity tag space
  * @bio:       bio to inspect
@@ -215,9 +220,9 @@ unsigned int bio_integrity_tag_size(struct bio *bio)
 {
        struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
 
-       BUG_ON(bio->bi_size == 0);
+       BUG_ON(bio->bi_iter.bi_size == 0);
 
-       return bi->tag_size * (bio->bi_size / bi->sector_size);
+       return bi->tag_size * (bio->bi_iter.bi_size / bi->sector_size);
 }
 EXPORT_SYMBOL(bio_integrity_tag_size);
 
@@ -235,9 +240,9 @@ int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len, int set)
        nr_sectors = bio_integrity_hw_sectors(bi,
                                        DIV_ROUND_UP(len, bi->tag_size));
 
-       if (nr_sectors * bi->tuple_size > bip->bip_size) {
-               printk(KERN_ERR "%s: tag too big for bio: %u > %u\n",
-                      __func__, nr_sectors * bi->tuple_size, bip->bip_size);
+       if (nr_sectors * bi->tuple_size > bip->bip_iter.bi_size) {
+               printk(KERN_ERR "%s: tag too big for bio: %u > %u\n", __func__,
+                      nr_sectors * bi->tuple_size, bip->bip_iter.bi_size);
                return -1;
        }
 
@@ -299,29 +304,30 @@ static void bio_integrity_generate(struct bio *bio)
 {
        struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
        struct blk_integrity_exchg bix;
-       struct bio_vec *bv;
-       sector_t sector = bio->bi_sector;
-       unsigned int i, sectors, total;
+       struct bio_vec bv;
+       struct bvec_iter iter;
+       sector_t sector = bio->bi_iter.bi_sector;
+       unsigned int sectors, total;
        void *prot_buf = bio->bi_integrity->bip_buf;
 
        total = 0;
        bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
        bix.sector_size = bi->sector_size;
 
-       bio_for_each_segment(bv, bio, i) {
-               void *kaddr = kmap_atomic(bv->bv_page);
-               bix.data_buf = kaddr + bv->bv_offset;
-               bix.data_size = bv->bv_len;
+       bio_for_each_segment(bv, bio, iter) {
+               void *kaddr = kmap_atomic(bv.bv_page);
+               bix.data_buf = kaddr + bv.bv_offset;
+               bix.data_size = bv.bv_len;
                bix.prot_buf = prot_buf;
                bix.sector = sector;
 
                bi->generate_fn(&bix);
 
-               sectors = bv->bv_len / bi->sector_size;
+               sectors = bv.bv_len / bi->sector_size;
                sector += sectors;
                prot_buf += sectors * bi->tuple_size;
                total += sectors * bi->tuple_size;
-               BUG_ON(total > bio->bi_integrity->bip_size);
+               BUG_ON(total > bio->bi_integrity->bip_iter.bi_size);
 
                kunmap_atomic(kaddr);
        }
@@ -386,8 +392,8 @@ int bio_integrity_prep(struct bio *bio)
 
        bip->bip_owns_buf = 1;
        bip->bip_buf = buf;
-       bip->bip_size = len;
-       bip->bip_sector = bio->bi_sector;
+       bip->bip_iter.bi_size = len;
+       bip->bip_iter.bi_sector = bio->bi_iter.bi_sector;
 
        /* Map it */
        offset = offset_in_page(buf);
@@ -441,19 +447,20 @@ static int bio_integrity_verify(struct bio *bio)
 {
        struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
        struct blk_integrity_exchg bix;
-       struct bio_vec *bv;
-       sector_t sector = bio->bi_integrity->bip_sector;
-       unsigned int i, sectors, total, ret;
+       struct bio_vec bv;
+       struct bvec_iter iter;
+       sector_t sector = bio->bi_integrity->bip_iter.bi_sector;
+       unsigned int sectors, total, ret;
        void *prot_buf = bio->bi_integrity->bip_buf;
 
        ret = total = 0;
        bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
        bix.sector_size = bi->sector_size;
 
-       bio_for_each_segment(bv, bio, i) {
-               void *kaddr = kmap_atomic(bv->bv_page);
-               bix.data_buf = kaddr + bv->bv_offset;
-               bix.data_size = bv->bv_len;
+       bio_for_each_segment(bv, bio, iter) {
+               void *kaddr = kmap_atomic(bv.bv_page);
+               bix.data_buf = kaddr + bv.bv_offset;
+               bix.data_size = bv.bv_len;
                bix.prot_buf = prot_buf;
                bix.sector = sector;
 
@@ -464,11 +471,11 @@ static int bio_integrity_verify(struct bio *bio)
                        return ret;
                }
 
-               sectors = bv->bv_len / bi->sector_size;
+               sectors = bv.bv_len / bi->sector_size;
                sector += sectors;
                prot_buf += sectors * bi->tuple_size;
                total += sectors * bi->tuple_size;
-               BUG_ON(total > bio->bi_integrity->bip_size);
+               BUG_ON(total > bio->bi_integrity->bip_iter.bi_size);
 
                kunmap_atomic(kaddr);
        }
@@ -495,7 +502,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
 
        /* Restore original bio completion handler */
        bio->bi_end_io = bip->bip_end_io;
-       bio_endio(bio, error);
+       bio_endio_nodec(bio, error);
 }
 
 /**
@@ -532,56 +539,6 @@ void bio_integrity_endio(struct bio *bio, int error)
 }
 EXPORT_SYMBOL(bio_integrity_endio);
 
-/**
- * bio_integrity_mark_head - Advance bip_vec skip bytes
- * @bip:       Integrity vector to advance
- * @skip:      Number of bytes to advance it
- */
-void bio_integrity_mark_head(struct bio_integrity_payload *bip,
-                            unsigned int skip)
-{
-       struct bio_vec *iv;
-       unsigned int i;
-
-       bip_for_each_vec(iv, bip, i) {
-               if (skip == 0) {
-                       bip->bip_idx = i;
-                       return;
-               } else if (skip >= iv->bv_len) {
-                       skip -= iv->bv_len;
-               } else { /* skip < iv->bv_len) */
-                       iv->bv_offset += skip;
-                       iv->bv_len -= skip;
-                       bip->bip_idx = i;
-                       return;
-               }
-       }
-}
-
-/**
- * bio_integrity_mark_tail - Truncate bip_vec to be len bytes long
- * @bip:       Integrity vector to truncate
- * @len:       New length of integrity vector
- */
-void bio_integrity_mark_tail(struct bio_integrity_payload *bip,
-                            unsigned int len)
-{
-       struct bio_vec *iv;
-       unsigned int i;
-
-       bip_for_each_vec(iv, bip, i) {
-               if (len == 0) {
-                       bip->bip_vcnt = i;
-                       return;
-               } else if (len >= iv->bv_len) {
-                       len -= iv->bv_len;
-               } else { /* len < iv->bv_len) */
-                       iv->bv_len = len;
-                       len = 0;
-               }
-       }
-}
-
 /**
  * bio_integrity_advance - Advance integrity vector
  * @bio:       bio whose integrity vector to update
@@ -595,13 +552,9 @@ void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
 {
        struct bio_integrity_payload *bip = bio->bi_integrity;
        struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
-       unsigned int nr_sectors;
-
-       BUG_ON(bip == NULL);
-       BUG_ON(bi == NULL);
+       unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
 
-       nr_sectors = bio_integrity_hw_sectors(bi, bytes_done >> 9);
-       bio_integrity_mark_head(bip, nr_sectors * bi->tuple_size);
+       bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes);
 }
 EXPORT_SYMBOL(bio_integrity_advance);
 
@@ -621,63 +574,12 @@ void bio_integrity_trim(struct bio *bio, unsigned int offset,
 {
        struct bio_integrity_payload *bip = bio->bi_integrity;
        struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
-       unsigned int nr_sectors;
 
-       BUG_ON(bip == NULL);
-       BUG_ON(bi == NULL);
-       BUG_ON(!bio_flagged(bio, BIO_CLONED));
-
-       nr_sectors = bio_integrity_hw_sectors(bi, sectors);
-       bip->bip_sector = bip->bip_sector + offset;
-       bio_integrity_mark_head(bip, offset * bi->tuple_size);
-       bio_integrity_mark_tail(bip, sectors * bi->tuple_size);
+       bio_integrity_advance(bio, offset << 9);
+       bip->bip_iter.bi_size = bio_integrity_bytes(bi, sectors);
 }
 EXPORT_SYMBOL(bio_integrity_trim);
 
-/**
- * bio_integrity_split - Split integrity metadata
- * @bio:       Protected bio
- * @bp:                Resulting bio_pair
- * @sectors:   Offset
- *
- * Description: Splits an integrity page into a bio_pair.
- */
-void bio_integrity_split(struct bio *bio, struct bio_pair *bp, int sectors)
-{
-       struct blk_integrity *bi;
-       struct bio_integrity_payload *bip = bio->bi_integrity;
-       unsigned int nr_sectors;
-
-       if (bio_integrity(bio) == 0)
-               return;
-
-       bi = bdev_get_integrity(bio->bi_bdev);
-       BUG_ON(bi == NULL);
-       BUG_ON(bip->bip_vcnt != 1);
-
-       nr_sectors = bio_integrity_hw_sectors(bi, sectors);
-
-       bp->bio1.bi_integrity = &bp->bip1;
-       bp->bio2.bi_integrity = &bp->bip2;
-
-       bp->iv1 = bip->bip_vec[bip->bip_idx];
-       bp->iv2 = bip->bip_vec[bip->bip_idx];
-
-       bp->bip1.bip_vec = &bp->iv1;
-       bp->bip2.bip_vec = &bp->iv2;
-
-       bp->iv1.bv_len = sectors * bi->tuple_size;
-       bp->iv2.bv_offset += sectors * bi->tuple_size;
-       bp->iv2.bv_len -= sectors * bi->tuple_size;
-
-       bp->bip1.bip_sector = bio->bi_integrity->bip_sector;
-       bp->bip2.bip_sector = bio->bi_integrity->bip_sector + nr_sectors;
-
-       bp->bip1.bip_vcnt = bp->bip2.bip_vcnt = 1;
-       bp->bip1.bip_idx = bp->bip2.bip_idx = 0;
-}
-EXPORT_SYMBOL(bio_integrity_split);
-
 /**
  * bio_integrity_clone - Callback for cloning bios with integrity metadata
  * @bio:       New bio
@@ -702,9 +604,8 @@ int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
        memcpy(bip->bip_vec, bip_src->bip_vec,
               bip_src->bip_vcnt * sizeof(struct bio_vec));
 
-       bip->bip_sector = bip_src->bip_sector;
        bip->bip_vcnt = bip_src->bip_vcnt;
-       bip->bip_idx = bip_src->bip_idx;
+       bip->bip_iter = bip_src->bip_iter;
 
        return 0;
 }
index 33d79a4eb92d6e623aa90e2291af39b2b2689d83..75c49a38223969c1f7256868cb3b09fc7d3bd286 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -38,8 +38,6 @@
  */
 #define BIO_INLINE_VECS                4
 
-static mempool_t *bio_split_pool __read_mostly;
-
 /*
  * if you change this list, also change bvec_alloc or things will
  * break badly! cannot be bigger than what you can fit into an
@@ -273,6 +271,7 @@ void bio_init(struct bio *bio)
 {
        memset(bio, 0, sizeof(*bio));
        bio->bi_flags = 1 << BIO_UPTODATE;
+       atomic_set(&bio->bi_remaining, 1);
        atomic_set(&bio->bi_cnt, 1);
 }
 EXPORT_SYMBOL(bio_init);
@@ -295,9 +294,35 @@ void bio_reset(struct bio *bio)
 
        memset(bio, 0, BIO_RESET_BYTES);
        bio->bi_flags = flags|(1 << BIO_UPTODATE);
+       atomic_set(&bio->bi_remaining, 1);
 }
 EXPORT_SYMBOL(bio_reset);
 
+static void bio_chain_endio(struct bio *bio, int error)
+{
+       bio_endio(bio->bi_private, error);
+       bio_put(bio);
+}
+
+/**
+ * bio_chain - chain bio completions
+ *
+ * The caller won't have a bi_end_io called when @bio completes - instead,
+ * @parent's bi_end_io won't be called until both @parent and @bio have
+ * completed; the chained bio will also be freed when it completes.
+ *
+ * The caller must not set bi_private or bi_end_io in @bio.
+ */
+void bio_chain(struct bio *bio, struct bio *parent)
+{
+       BUG_ON(bio->bi_private || bio->bi_end_io);
+
+       bio->bi_private = parent;
+       bio->bi_end_io  = bio_chain_endio;
+       atomic_inc(&parent->bi_remaining);
+}
+EXPORT_SYMBOL(bio_chain);
+
 static void bio_alloc_rescue(struct work_struct *work)
 {
        struct bio_set *bs = container_of(work, struct bio_set, rescue_work);
@@ -473,13 +498,13 @@ EXPORT_SYMBOL(bio_alloc_bioset);
 void zero_fill_bio(struct bio *bio)
 {
        unsigned long flags;
-       struct bio_vec *bv;
-       int i;
+       struct bio_vec bv;
+       struct bvec_iter iter;
 
-       bio_for_each_segment(bv, bio, i) {
-               char *data = bvec_kmap_irq(bv, &flags);
-               memset(data, 0, bv->bv_len);
-               flush_dcache_page(bv->bv_page);
+       bio_for_each_segment(bv, bio, iter) {
+               char *data = bvec_kmap_irq(&bv, &flags);
+               memset(data, 0, bv.bv_len);
+               flush_dcache_page(bv.bv_page);
                bvec_kunmap_irq(data, &flags);
        }
 }
@@ -515,51 +540,49 @@ inline int bio_phys_segments(struct request_queue *q, struct bio *bio)
 EXPORT_SYMBOL(bio_phys_segments);
 
 /**
- *     __bio_clone     -       clone a bio
+ *     __bio_clone_fast - clone a bio that shares the original bio's biovec
  *     @bio: destination bio
  *     @bio_src: bio to clone
  *
  *     Clone a &bio. Caller will own the returned bio, but not
  *     the actual data it points to. Reference count of returned
  *     bio will be one.
+ *
+ *     Caller must ensure that @bio_src is not freed before @bio.
  */
-void __bio_clone(struct bio *bio, struct bio *bio_src)
+void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
 {
-       memcpy(bio->bi_io_vec, bio_src->bi_io_vec,
-               bio_src->bi_max_vecs * sizeof(struct bio_vec));
+       BUG_ON(bio->bi_pool && BIO_POOL_IDX(bio) != BIO_POOL_NONE);
 
        /*
         * most users will be overriding ->bi_bdev with a new target,
         * so we don't set nor calculate new physical/hw segment counts here
         */
-       bio->bi_sector = bio_src->bi_sector;
        bio->bi_bdev = bio_src->bi_bdev;
        bio->bi_flags |= 1 << BIO_CLONED;
        bio->bi_rw = bio_src->bi_rw;
-       bio->bi_vcnt = bio_src->bi_vcnt;
-       bio->bi_size = bio_src->bi_size;
-       bio->bi_idx = bio_src->bi_idx;
+       bio->bi_iter = bio_src->bi_iter;
+       bio->bi_io_vec = bio_src->bi_io_vec;
 }
-EXPORT_SYMBOL(__bio_clone);
+EXPORT_SYMBOL(__bio_clone_fast);
 
 /**
- *     bio_clone_bioset -      clone a bio
+ *     bio_clone_fast - clone a bio that shares the original bio's biovec
  *     @bio: bio to clone
  *     @gfp_mask: allocation priority
  *     @bs: bio_set to allocate from
  *
- *     Like __bio_clone, only also allocates the returned bio
+ *     Like __bio_clone_fast, only also allocates the returned bio
  */
-struct bio *bio_clone_bioset(struct bio *bio, gfp_t gfp_mask,
-                            struct bio_set *bs)
+struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs)
 {
        struct bio *b;
 
-       b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, bs);
+       b = bio_alloc_bioset(gfp_mask, 0, bs);
        if (!b)
                return NULL;
 
-       __bio_clone(b, bio);
+       __bio_clone_fast(b, bio);
 
        if (bio_integrity(bio)) {
                int ret;
@@ -574,6 +597,74 @@ struct bio *bio_clone_bioset(struct bio *bio, gfp_t gfp_mask,
 
        return b;
 }
+EXPORT_SYMBOL(bio_clone_fast);
+
+/**
+ *     bio_clone_bioset - clone a bio
+ *     @bio_src: bio to clone
+ *     @gfp_mask: allocation priority
+ *     @bs: bio_set to allocate from
+ *
+ *     Clone bio. Caller will own the returned bio, but not the actual data it
+ *     points to. Reference count of returned bio will be one.
+ */
+struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
+                            struct bio_set *bs)
+{
+       unsigned nr_iovecs = 0;
+       struct bvec_iter iter;
+       struct bio_vec bv;
+       struct bio *bio;
+
+       /*
+        * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
+        * bio_src->bi_io_vec to bio->bi_io_vec.
+        *
+        * We can't do that anymore, because:
+        *
+        *  - The point of cloning the biovec is to produce a bio with a biovec
+        *    the caller can modify: bi_idx and bi_bvec_done should be 0.
+        *
+        *  - The original bio could've had more than BIO_MAX_PAGES biovecs; if
+        *    we tried to clone the whole thing bio_alloc_bioset() would fail.
+        *    But the clone should succeed as long as the number of biovecs we
+        *    actually need to allocate is fewer than BIO_MAX_PAGES.
+        *
+        *  - Lastly, bi_vcnt should not be looked at or relied upon by code
+        *    that does not own the bio - reason being drivers don't use it for
+        *    iterating over the biovec anymore, so expecting it to be kept up
+        *    to date (i.e. for clones that share the parent biovec) is just
+        *    asking for trouble and would force extra work on
+        *    __bio_clone_fast() anyways.
+        */
+
+       bio_for_each_segment(bv, bio_src, iter)
+               nr_iovecs++;
+
+       bio = bio_alloc_bioset(gfp_mask, nr_iovecs, bs);
+       if (!bio)
+               return NULL;
+
+       bio->bi_bdev            = bio_src->bi_bdev;
+       bio->bi_rw              = bio_src->bi_rw;
+       bio->bi_iter.bi_sector  = bio_src->bi_iter.bi_sector;
+       bio->bi_iter.bi_size    = bio_src->bi_iter.bi_size;
+
+       bio_for_each_segment(bv, bio_src, iter)
+               bio->bi_io_vec[bio->bi_vcnt++] = bv;
+
+       if (bio_integrity(bio_src)) {
+               int ret;
+
+               ret = bio_integrity_clone(bio, bio_src, gfp_mask);
+               if (ret < 0) {
+                       bio_put(bio);
+                       return NULL;
+               }
+       }
+
+       return bio;
+}
 EXPORT_SYMBOL(bio_clone_bioset);
 
 /**
@@ -612,7 +703,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
        if (unlikely(bio_flagged(bio, BIO_CLONED)))
                return 0;
 
-       if (((bio->bi_size + len) >> 9) > max_sectors)
+       if (((bio->bi_iter.bi_size + len) >> 9) > max_sectors)
                return 0;
 
        /*
@@ -635,8 +726,9 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
                                           simulate merging updated prev_bvec
                                           as new bvec. */
                                        .bi_bdev = bio->bi_bdev,
-                                       .bi_sector = bio->bi_sector,
-                                       .bi_size = bio->bi_size - prev_bv_len,
+                                       .bi_sector = bio->bi_iter.bi_sector,
+                                       .bi_size = bio->bi_iter.bi_size -
+                                               prev_bv_len,
                                        .bi_rw = bio->bi_rw,
                                };
 
@@ -684,8 +776,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
        if (q->merge_bvec_fn) {
                struct bvec_merge_data bvm = {
                        .bi_bdev = bio->bi_bdev,
-                       .bi_sector = bio->bi_sector,
-                       .bi_size = bio->bi_size,
+                       .bi_sector = bio->bi_iter.bi_sector,
+                       .bi_size = bio->bi_iter.bi_size,
                        .bi_rw = bio->bi_rw,
                };
 
@@ -708,7 +800,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
        bio->bi_vcnt++;
        bio->bi_phys_segments++;
  done:
-       bio->bi_size += len;
+       bio->bi_iter.bi_size += len;
        return len;
 }
 
@@ -807,28 +899,7 @@ void bio_advance(struct bio *bio, unsigned bytes)
        if (bio_integrity(bio))
                bio_integrity_advance(bio, bytes);
 
-       bio->bi_sector += bytes >> 9;
-       bio->bi_size -= bytes;
-
-       if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
-               return;
-
-       while (bytes) {
-               if (unlikely(bio->bi_idx >= bio->bi_vcnt)) {
-                       WARN_ONCE(1, "bio idx %d >= vcnt %d\n",
-                                 bio->bi_idx, bio->bi_vcnt);
-                       break;
-               }
-
-               if (bytes >= bio_iovec(bio)->bv_len) {
-                       bytes -= bio_iovec(bio)->bv_len;
-                       bio->bi_idx++;
-               } else {
-                       bio_iovec(bio)->bv_len -= bytes;
-                       bio_iovec(bio)->bv_offset += bytes;
-                       bytes = 0;
-               }
-       }
+       bio_advance_iter(bio, &bio->bi_iter, bytes);
 }
 EXPORT_SYMBOL(bio_advance);
 
@@ -874,117 +945,80 @@ EXPORT_SYMBOL(bio_alloc_pages);
  */
 void bio_copy_data(struct bio *dst, struct bio *src)
 {
-       struct bio_vec *src_bv, *dst_bv;
-       unsigned src_offset, dst_offset, bytes;
+       struct bvec_iter src_iter, dst_iter;
+       struct bio_vec src_bv, dst_bv;
        void *src_p, *dst_p;
+       unsigned bytes;
 
-       src_bv = bio_iovec(src);
-       dst_bv = bio_iovec(dst);
-
-       src_offset = src_bv->bv_offset;
-       dst_offset = dst_bv->bv_offset;
+       src_iter = src->bi_iter;
+       dst_iter = dst->bi_iter;
 
        while (1) {
-               if (src_offset == src_bv->bv_offset + src_bv->bv_len) {
-                       src_bv++;
-                       if (src_bv == bio_iovec_idx(src, src->bi_vcnt)) {
-                               src = src->bi_next;
-                               if (!src)
-                                       break;
-
-                               src_bv = bio_iovec(src);
-                       }
+               if (!src_iter.bi_size) {
+                       src = src->bi_next;
+                       if (!src)
+                               break;
 
-                       src_offset = src_bv->bv_offset;
+                       src_iter = src->bi_iter;
                }
 
-               if (dst_offset == dst_bv->bv_offset + dst_bv->bv_len) {
-                       dst_bv++;
-                       if (dst_bv == bio_iovec_idx(dst, dst->bi_vcnt)) {
-                               dst = dst->bi_next;
-                               if (!dst)
-                                       break;
-
-                               dst_bv = bio_iovec(dst);
-                       }
+               if (!dst_iter.bi_size) {
+                       dst = dst->bi_next;
+                       if (!dst)
+                               break;
 
-                       dst_offset = dst_bv->bv_offset;
+                       dst_iter = dst->bi_iter;
                }
 
-               bytes = min(dst_bv->bv_offset + dst_bv->bv_len - dst_offset,
-                           src_bv->bv_offset + src_bv->bv_len - src_offset);
+               src_bv = bio_iter_iovec(src, src_iter);
+               dst_bv = bio_iter_iovec(dst, dst_iter);
+
+               bytes = min(src_bv.bv_len, dst_bv.bv_len);
 
-               src_p = kmap_atomic(src_bv->bv_page);
-               dst_p = kmap_atomic(dst_bv->bv_page);
+               src_p = kmap_atomic(src_bv.bv_page);
+               dst_p = kmap_atomic(dst_bv.bv_page);
 
-               memcpy(dst_p + dst_offset,
-                      src_p + src_offset,
+               memcpy(dst_p + dst_bv.bv_offset,
+                      src_p + src_bv.bv_offset,
                       bytes);
 
                kunmap_atomic(dst_p);
                kunmap_atomic(src_p);
 
-               src_offset += bytes;
-               dst_offset += bytes;
+               bio_advance_iter(src, &src_iter, bytes);
+               bio_advance_iter(dst, &dst_iter, bytes);
        }
 }
 EXPORT_SYMBOL(bio_copy_data);
 
 struct bio_map_data {
-       struct bio_vec *iovecs;
-       struct sg_iovec *sgvecs;
        int nr_sgvecs;
        int is_our_pages;
+       struct sg_iovec sgvecs[];
 };
 
 static void bio_set_map_data(struct bio_map_data *bmd, struct bio *bio,
                             struct sg_iovec *iov, int iov_count,
                             int is_our_pages)
 {
-       memcpy(bmd->iovecs, bio->bi_io_vec, sizeof(struct bio_vec) * bio->bi_vcnt);
        memcpy(bmd->sgvecs, iov, sizeof(struct sg_iovec) * iov_count);
        bmd->nr_sgvecs = iov_count;
        bmd->is_our_pages = is_our_pages;
        bio->bi_private = bmd;
 }
 
-static void bio_free_map_data(struct bio_map_data *bmd)
-{
-       kfree(bmd->iovecs);
-       kfree(bmd->sgvecs);
-       kfree(bmd);
-}
-
 static struct bio_map_data *bio_alloc_map_data(int nr_segs,
                                               unsigned int iov_count,
                                               gfp_t gfp_mask)
 {
-       struct bio_map_data *bmd;
-
        if (iov_count > UIO_MAXIOV)
                return NULL;
 
-       bmd = kmalloc(sizeof(*bmd), gfp_mask);
-       if (!bmd)
-               return NULL;
-
-       bmd->iovecs = kmalloc(sizeof(struct bio_vec) * nr_segs, gfp_mask);
-       if (!bmd->iovecs) {
-               kfree(bmd);
-               return NULL;
-       }
-
-       bmd->sgvecs = kmalloc(sizeof(struct sg_iovec) * iov_count, gfp_mask);
-       if (bmd->sgvecs)
-               return bmd;
-
-       kfree(bmd->iovecs);
-       kfree(bmd);
-       return NULL;
+       return kmalloc(sizeof(struct bio_map_data) +
+                      sizeof(struct sg_iovec) * iov_count, gfp_mask);
 }
 
-static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs,
-                         struct sg_iovec *iov, int iov_count,
+static int __bio_copy_iov(struct bio *bio, struct sg_iovec *iov, int iov_count,
                          int to_user, int from_user, int do_free_page)
 {
        int ret = 0, i;
@@ -994,7 +1028,7 @@ static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs,
 
        bio_for_each_segment_all(bvec, bio, i) {
                char *bv_addr = page_address(bvec->bv_page);
-               unsigned int bv_len = iovecs[i].bv_len;
+               unsigned int bv_len = bvec->bv_len;
 
                while (bv_len && iov_idx < iov_count) {
                        unsigned int bytes;
@@ -1054,14 +1088,14 @@ int bio_uncopy_user(struct bio *bio)
                 * don't copy into a random user address space, just free.
                 */
                if (current->mm)
-                       ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs,
-                                            bmd->nr_sgvecs, bio_data_dir(bio) == READ,
+                       ret = __bio_copy_iov(bio, bmd->sgvecs, bmd->nr_sgvecs,
+                                            bio_data_dir(bio) == READ,
                                             0, bmd->is_our_pages);
                else if (bmd->is_our_pages)
                        bio_for_each_segment_all(bvec, bio, i)
                                __free_page(bvec->bv_page);
        }
-       bio_free_map_data(bmd);
+       kfree(bmd);
        bio_put(bio);
        return ret;
 }
@@ -1175,7 +1209,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
         */
        if ((!write_to_vm && (!map_data || !map_data->null_mapped)) ||
            (map_data && map_data->from_user)) {
-               ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0, 1, 0);
+               ret = __bio_copy_iov(bio, iov, iov_count, 0, 1, 0);
                if (ret)
                        goto cleanup;
        }
@@ -1189,7 +1223,7 @@ cleanup:
 
        bio_put(bio);
 out_bmd:
-       bio_free_map_data(bmd);
+       kfree(bmd);
        return ERR_PTR(ret);
 }
 
@@ -1485,7 +1519,7 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
        if (IS_ERR(bio))
                return bio;
 
-       if (bio->bi_size == len)
+       if (bio->bi_iter.bi_size == len)
                return bio;
 
        /*
@@ -1506,16 +1540,15 @@ static void bio_copy_kern_endio(struct bio *bio, int err)
 
        bio_for_each_segment_all(bvec, bio, i) {
                char *addr = page_address(bvec->bv_page);
-               int len = bmd->iovecs[i].bv_len;
 
                if (read)
-                       memcpy(p, addr, len);
+                       memcpy(p, addr, bvec->bv_len);
 
                __free_page(bvec->bv_page);
-               p += len;
+               p += bvec->bv_len;
        }
 
-       bio_free_map_data(bmd);
+       kfree(bmd);
        bio_put(bio);
 }
 
@@ -1686,11 +1719,11 @@ void bio_check_pages_dirty(struct bio *bio)
 #if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
 void bio_flush_dcache_pages(struct bio *bi)
 {
-       int i;
-       struct bio_vec *bvec;
+       struct bio_vec bvec;
+       struct bvec_iter iter;
 
-       bio_for_each_segment(bvec, bi, i)
-               flush_dcache_page(bvec->bv_page);
+       bio_for_each_segment(bvec, bi, iter)
+               flush_dcache_page(bvec.bv_page);
 }
 EXPORT_SYMBOL(bio_flush_dcache_pages);
 #endif
@@ -1711,96 +1744,86 @@ EXPORT_SYMBOL(bio_flush_dcache_pages);
  **/
 void bio_endio(struct bio *bio, int error)
 {
-       if (error)
-               clear_bit(BIO_UPTODATE, &bio->bi_flags);
-       else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
-               error = -EIO;
+       while (bio) {
+               BUG_ON(atomic_read(&bio->bi_remaining) <= 0);
 
-       if (bio->bi_end_io)
-               bio->bi_end_io(bio, error);
-}
-EXPORT_SYMBOL(bio_endio);
+               if (error)
+                       clear_bit(BIO_UPTODATE, &bio->bi_flags);
+               else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+                       error = -EIO;
 
-void bio_pair_release(struct bio_pair *bp)
-{
-       if (atomic_dec_and_test(&bp->cnt)) {
-               struct bio *master = bp->bio1.bi_private;
+               if (!atomic_dec_and_test(&bio->bi_remaining))
+                       return;
 
-               bio_endio(master, bp->error);
-               mempool_free(bp, bp->bio2.bi_private);
+               /*
+                * Need to have a real endio function for chained bios,
+                * otherwise various corner cases will break (like stacking
+                * block devices that save/restore bi_end_io) - however, we want
+                * to avoid unbounded recursion and blowing the stack. Tail call
+                * optimization would handle this, but compiling with frame
+                * pointers also disables gcc's sibling call optimization.
+                */
+               if (bio->bi_end_io == bio_chain_endio) {
+                       struct bio *parent = bio->bi_private;
+                       bio_put(bio);
+                       bio = parent;
+               } else {
+                       if (bio->bi_end_io)
+                               bio->bi_end_io(bio, error);
+                       bio = NULL;
+               }
        }
 }
-EXPORT_SYMBOL(bio_pair_release);
+EXPORT_SYMBOL(bio_endio);
 
-static void bio_pair_end_1(struct bio *bi, int err)
+/**
+ * bio_endio_nodec - end I/O on a bio, without decrementing bi_remaining
+ * @bio:       bio
+ * @error:     error, if any
+ *
+ * For code that has saved and restored bi_end_io; thing hard before using this
+ * function, probably you should've cloned the entire bio.
+ **/
+void bio_endio_nodec(struct bio *bio, int error)
 {
-       struct bio_pair *bp = container_of(bi, struct bio_pair, bio1);
-
-       if (err)
-               bp->error = err;
-
-       bio_pair_release(bp);
+       atomic_inc(&bio->bi_remaining);
+       bio_endio(bio, error);
 }
+EXPORT_SYMBOL(bio_endio_nodec);
 
-static void bio_pair_end_2(struct bio *bi, int err)
-{
-       struct bio_pair *bp = container_of(bi, struct bio_pair, bio2);
-
-       if (err)
-               bp->error = err;
-
-       bio_pair_release(bp);
-}
-
-/*
- * split a bio - only worry about a bio with a single page in its iovec
+/**
+ * bio_split - split a bio
+ * @bio:       bio to split
+ * @sectors:   number of sectors to split from the front of @bio
+ * @gfp:       gfp mask
+ * @bs:                bio set to allocate from
+ *
+ * Allocates and returns a new bio which represents @sectors from the start of
+ * @bio, and updates @bio to represent the remaining sectors.
+ *
+ * The newly allocated bio will point to @bio's bi_io_vec; it is the caller's
+ * responsibility to ensure that @bio is not freed before the split.
  */
-struct bio_pair *bio_split(struct bio *bi, int first_sectors)
+struct bio *bio_split(struct bio *bio, int sectors,
+                     gfp_t gfp, struct bio_set *bs)
 {
-       struct bio_pair *bp = mempool_alloc(bio_split_pool, GFP_NOIO);
-
-       if (!bp)
-               return bp;
-
-       trace_block_split(bdev_get_queue(bi->bi_bdev), bi,
-                               bi->bi_sector + first_sectors);
-
-       BUG_ON(bio_segments(bi) > 1);
-       atomic_set(&bp->cnt, 3);
-       bp->error = 0;
-       bp->bio1 = *bi;
-       bp->bio2 = *bi;
-       bp->bio2.bi_sector += first_sectors;
-       bp->bio2.bi_size -= first_sectors << 9;
-       bp->bio1.bi_size = first_sectors << 9;
-
-       if (bi->bi_vcnt != 0) {
-               bp->bv1 = *bio_iovec(bi);
-               bp->bv2 = *bio_iovec(bi);
-
-               if (bio_is_rw(bi)) {
-                       bp->bv2.bv_offset += first_sectors << 9;
-                       bp->bv2.bv_len -= first_sectors << 9;
-                       bp->bv1.bv_len = first_sectors << 9;
-               }
+       struct bio *split = NULL;
 
-               bp->bio1.bi_io_vec = &bp->bv1;
-               bp->bio2.bi_io_vec = &bp->bv2;
+       BUG_ON(sectors <= 0);
+       BUG_ON(sectors >= bio_sectors(bio));
 
-               bp->bio1.bi_max_vecs = 1;
-               bp->bio2.bi_max_vecs = 1;
-       }
+       split = bio_clone_fast(bio, gfp, bs);
+       if (!split)
+               return NULL;
 
-       bp->bio1.bi_end_io = bio_pair_end_1;
-       bp->bio2.bi_end_io = bio_pair_end_2;
+       split->bi_iter.bi_size = sectors << 9;
 
-       bp->bio1.bi_private = bi;
-       bp->bio2.bi_private = bio_split_pool;
+       if (bio_integrity(split))
+               bio_integrity_trim(split, 0, sectors);
 
-       if (bio_integrity(bi))
-               bio_integrity_split(bi, bp, first_sectors);
+       bio_advance(bio, split->bi_iter.bi_size);
 
-       return bp;
+       return split;
 }
 EXPORT_SYMBOL(bio_split);
 
@@ -1814,80 +1837,20 @@ void bio_trim(struct bio *bio, int offset, int size)
 {
        /* 'bio' is a cloned bio which we need to trim to match
         * the given offset and size.
-        * This requires adjusting bi_sector, bi_size, and bi_io_vec
         */
-       int i;
-       struct bio_vec *bvec;
-       int sofar = 0;
 
        size <<= 9;
-       if (offset == 0 && size == bio->bi_size)
+       if (offset == 0 && size == bio->bi_iter.bi_size)
                return;
 
        clear_bit(BIO_SEG_VALID, &bio->bi_flags);
 
        bio_advance(bio, offset << 9);
 
-       bio->bi_size = size;
-
-       /* avoid any complications with bi_idx being non-zero*/
-       if (bio->bi_idx) {
-               memmove(bio->bi_io_vec, bio->bi_io_vec+bio->bi_idx,
-                       (bio->bi_vcnt - bio->bi_idx) * sizeof(struct bio_vec));
-               bio->bi_vcnt -= bio->bi_idx;
-               bio->bi_idx = 0;
-       }
-       /* Make sure vcnt and last bv are not too big */
-       bio_for_each_segment(bvec, bio, i) {
-               if (sofar + bvec->bv_len > size)
-                       bvec->bv_len = size - sofar;
-               if (bvec->bv_len == 0) {
-                       bio->bi_vcnt = i;
-                       break;
-               }
-               sofar += bvec->bv_len;
-       }
+       bio->bi_iter.bi_size = size;
 }
 EXPORT_SYMBOL_GPL(bio_trim);
 
-/**
- *      bio_sector_offset - Find hardware sector offset in bio
- *      @bio:           bio to inspect
- *      @index:         bio_vec index
- *      @offset:        offset in bv_page
- *
- *      Return the number of hardware sectors between beginning of bio
- *      and an end point indicated by a bio_vec index and an offset
- *      within that vector's page.
- */
-sector_t bio_sector_offset(struct bio *bio, unsigned short index,
-                          unsigned int offset)
-{
-       unsigned int sector_sz;
-       struct bio_vec *bv;
-       sector_t sectors;
-       int i;
-
-       sector_sz = queue_logical_block_size(bio->bi_bdev->bd_disk->queue);
-       sectors = 0;
-
-       if (index >= bio->bi_idx)
-               index = bio->bi_vcnt - 1;
-
-       bio_for_each_segment_all(bv, bio, i) {
-               if (i == index) {
-                       if (offset > bv->bv_offset)
-                               sectors += (offset - bv->bv_offset) / sector_sz;
-                       break;
-               }
-
-               sectors += bv->bv_len / sector_sz;
-       }
-
-       return sectors;
-}
-EXPORT_SYMBOL(bio_sector_offset);
-
 /*
  * create memory pools for biovec's in a bio_set.
  * use the global biovec slabs created for general use.
@@ -2065,11 +2028,6 @@ static int __init init_bio(void)
        if (bioset_integrity_create(fs_bio_set, BIO_POOL_SIZE))
                panic("bio: can't create integrity pool\n");
 
-       bio_split_pool = mempool_create_kmalloc_pool(BIO_SPLIT_ENTRIES,
-                                                    sizeof(struct bio_pair));
-       if (!bio_split_pool)
-               panic("bio: can't create split pool\n");
-
        return 0;
 }
 subsys_initcall(init_bio);
index b50764bef1410c2750b17d943ae3597899b3ee9e..cb05e1c842c5b8b84dee98d1a3f452eaa179417e 100644 (file)
@@ -333,7 +333,6 @@ static void btrfsic_release_block_ctx(struct btrfsic_block_data_ctx *block_ctx);
 static int btrfsic_read_block(struct btrfsic_state *state,
                              struct btrfsic_block_data_ctx *block_ctx);
 static void btrfsic_dump_database(struct btrfsic_state *state);
-static void btrfsic_complete_bio_end_io(struct bio *bio, int err);
 static int btrfsic_test_for_metadata(struct btrfsic_state *state,
                                     char **datav, unsigned int num_pages);
 static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state,
@@ -1687,7 +1686,6 @@ static int btrfsic_read_block(struct btrfsic_state *state,
        for (i = 0; i < num_pages;) {
                struct bio *bio;
                unsigned int j;
-               DECLARE_COMPLETION_ONSTACK(complete);
 
                bio = btrfs_io_bio_alloc(GFP_NOFS, num_pages - i);
                if (!bio) {
@@ -1697,9 +1695,7 @@ static int btrfsic_read_block(struct btrfsic_state *state,
                        return -1;
                }
                bio->bi_bdev = block_ctx->dev->bdev;
-               bio->bi_sector = dev_bytenr >> 9;
-               bio->bi_end_io = btrfsic_complete_bio_end_io;
-               bio->bi_private = &complete;
+               bio->bi_iter.bi_sector = dev_bytenr >> 9;
 
                for (j = i; j < num_pages; j++) {
                        ret = bio_add_page(bio, block_ctx->pagev[j],
@@ -1712,12 +1708,7 @@ static int btrfsic_read_block(struct btrfsic_state *state,
                               "btrfsic: error, failed to add a single page!\n");
                        return -1;
                }
-               submit_bio(READ, bio);
-
-               /* this will also unplug the queue */
-               wait_for_completion(&complete);
-
-               if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+               if (submit_bio_wait(READ, bio)) {
                        printk(KERN_INFO
                               "btrfsic: read error at logical %llu dev %s!\n",
                               block_ctx->start, block_ctx->dev->name);
@@ -1740,11 +1731,6 @@ static int btrfsic_read_block(struct btrfsic_state *state,
        return block_ctx->len;
 }
 
-static void btrfsic_complete_bio_end_io(struct bio *bio, int err)
-{
-       complete((struct completion *)bio->bi_private);
-}
-
 static void btrfsic_dump_database(struct btrfsic_state *state)
 {
        struct list_head *elem_all;
@@ -3008,14 +2994,12 @@ int btrfsic_submit_bh(int rw, struct buffer_head *bh)
        return submit_bh(rw, bh);
 }
 
-void btrfsic_submit_bio(int rw, struct bio *bio)
+static void __btrfsic_submit_bio(int rw, struct bio *bio)
 {
        struct btrfsic_dev_state *dev_state;
 
-       if (!btrfsic_is_initialized) {
-               submit_bio(rw, bio);
+       if (!btrfsic_is_initialized)
                return;
-       }
 
        mutex_lock(&btrfsic_mutex);
        /* since btrfsic_submit_bio() is also called before
@@ -3029,7 +3013,7 @@ void btrfsic_submit_bio(int rw, struct bio *bio)
                int bio_is_patched;
                char **mapped_datav;
 
-               dev_bytenr = 512 * bio->bi_sector;
+               dev_bytenr = 512 * bio->bi_iter.bi_sector;
                bio_is_patched = 0;
                if (dev_state->state->print_mask &
                    BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH)
@@ -3037,8 +3021,8 @@ void btrfsic_submit_bio(int rw, struct bio *bio)
                               "submit_bio(rw=0x%x, bi_vcnt=%u,"
                               " bi_sector=%llu (bytenr %llu), bi_bdev=%p)\n",
                               rw, bio->bi_vcnt,
-                              (unsigned long long)bio->bi_sector, dev_bytenr,
-                              bio->bi_bdev);
+                              (unsigned long long)bio->bi_iter.bi_sector,
+                              dev_bytenr, bio->bi_bdev);
 
                mapped_datav = kmalloc(sizeof(*mapped_datav) * bio->bi_vcnt,
                                       GFP_NOFS);
@@ -3106,10 +3090,20 @@ void btrfsic_submit_bio(int rw, struct bio *bio)
        }
 leave:
        mutex_unlock(&btrfsic_mutex);
+}
 
+void btrfsic_submit_bio(int rw, struct bio *bio)
+{
+       __btrfsic_submit_bio(rw, bio);
        submit_bio(rw, bio);
 }
 
+int btrfsic_submit_bio_wait(int rw, struct bio *bio)
+{
+       __btrfsic_submit_bio(rw, bio);
+       return submit_bio_wait(rw, bio);
+}
+
 int btrfsic_mount(struct btrfs_root *root,
                  struct btrfs_fs_devices *fs_devices,
                  int including_extent_data, u32 print_mask)
index 8b59175cc50243c7bd525c91b265fa0f329f6af1..13b8566c97ab433f7455eeb6762942d5e623d16a 100644 (file)
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
 int btrfsic_submit_bh(int rw, struct buffer_head *bh);
 void btrfsic_submit_bio(int rw, struct bio *bio);
+int btrfsic_submit_bio_wait(int rw, struct bio *bio);
 #else
 #define btrfsic_submit_bh submit_bh
 #define btrfsic_submit_bio submit_bio
+#define btrfsic_submit_bio_wait submit_bio_wait
 #endif
 
 int btrfsic_mount(struct btrfs_root *root,
index 1499b27b41863e7dfbbe7da134b1a7fb66dece34..f5cdeb4b553824744429cff1f4d8b57c17a27909 100644 (file)
@@ -172,7 +172,8 @@ static void end_compressed_bio_read(struct bio *bio, int err)
                goto out;
 
        inode = cb->inode;
-       ret = check_compressed_csum(inode, cb, (u64)bio->bi_sector << 9);
+       ret = check_compressed_csum(inode, cb,
+                                   (u64)bio->bi_iter.bi_sector << 9);
        if (ret)
                goto csum_failed;
 
@@ -201,18 +202,16 @@ csum_failed:
        if (cb->errors) {
                bio_io_error(cb->orig_bio);
        } else {
-               int bio_index = 0;
-               struct bio_vec *bvec = cb->orig_bio->bi_io_vec;
+               int i;
+               struct bio_vec *bvec;
 
                /*
                 * we have verified the checksum already, set page
                 * checked so the end_io handlers know about it
                 */
-               while (bio_index < cb->orig_bio->bi_vcnt) {
+               bio_for_each_segment_all(bvec, cb->orig_bio, i)
                        SetPageChecked(bvec->bv_page);
-                       bvec++;
-                       bio_index++;
-               }
+
                bio_endio(cb->orig_bio, 0);
        }
 
@@ -372,7 +371,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
        for (pg_index = 0; pg_index < cb->nr_pages; pg_index++) {
                page = compressed_pages[pg_index];
                page->mapping = inode->i_mapping;
-               if (bio->bi_size)
+               if (bio->bi_iter.bi_size)
                        ret = io_tree->ops->merge_bio_hook(WRITE, page, 0,
                                                           PAGE_CACHE_SIZE,
                                                           bio, 0);
@@ -506,7 +505,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
 
                if (!em || last_offset < em->start ||
                    (last_offset + PAGE_CACHE_SIZE > extent_map_end(em)) ||
-                   (em->block_start >> 9) != cb->orig_bio->bi_sector) {
+                   (em->block_start >> 9) != cb->orig_bio->bi_iter.bi_sector) {
                        free_extent_map(em);
                        unlock_extent(tree, last_offset, end);
                        unlock_page(page);
@@ -552,7 +551,7 @@ next:
  * in it.  We don't actually do IO on those pages but allocate new ones
  * to hold the compressed pages on disk.
  *
- * bio->bi_sector points to the compressed extent on disk
+ * bio->bi_iter.bi_sector points to the compressed extent on disk
  * bio->bi_io_vec points to all of the inode pages
  * bio->bi_vcnt is a count of pages
  *
@@ -573,7 +572,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
        struct page *page;
        struct block_device *bdev;
        struct bio *comp_bio;
-       u64 cur_disk_byte = (u64)bio->bi_sector << 9;
+       u64 cur_disk_byte = (u64)bio->bi_iter.bi_sector << 9;
        u64 em_len;
        u64 em_start;
        struct extent_map *em;
@@ -659,7 +658,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
                page->mapping = inode->i_mapping;
                page->index = em_start >> PAGE_CACHE_SHIFT;
 
-               if (comp_bio->bi_size)
+               if (comp_bio->bi_iter.bi_size)
                        ret = tree->ops->merge_bio_hook(READ, page, 0,
                                                        PAGE_CACHE_SIZE,
                                                        comp_bio, 0);
@@ -687,8 +686,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
                                                        comp_bio, sums);
                                BUG_ON(ret); /* -ENOMEM */
                        }
-                       sums += (comp_bio->bi_size + root->sectorsize - 1) /
-                               root->sectorsize;
+                       sums += (comp_bio->bi_iter.bi_size +
+                                root->sectorsize - 1) / root->sectorsize;
 
                        ret = btrfs_map_bio(root, READ, comp_bio,
                                            mirror_num, 0);
index 8072cfa8a3b16c075e5c381f481e7cb874d9c531..5a10c61adafc6337278ba1b08b7e5c8df8d1f60f 100644 (file)
@@ -842,20 +842,17 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
 
 static int btree_csum_one_bio(struct bio *bio)
 {
-       struct bio_vec *bvec = bio->bi_io_vec;
-       int bio_index = 0;
+       struct bio_vec *bvec;
        struct btrfs_root *root;
-       int ret = 0;
+       int i, ret = 0;
 
-       WARN_ON(bio->bi_vcnt <= 0);
-       while (bio_index < bio->bi_vcnt) {
+       bio_for_each_segment_all(bvec, bio, i) {
                root = BTRFS_I(bvec->bv_page->mapping->host)->root;
                ret = csum_dirty_buffer(root, bvec->bv_page);
                if (ret)
                        break;
-               bio_index++;
-               bvec++;
        }
+
        return ret;
 }
 
index 8e457fca0a0ba5c04afb84414ccd640821a640d1..bcb6f1b780d64512868303c04a7939060612e3e3 100644 (file)
@@ -1952,11 +1952,6 @@ static int free_io_failure(struct inode *inode, struct io_failure_record *rec,
        return err;
 }
 
-static void repair_io_failure_callback(struct bio *bio, int err)
-{
-       complete(bio->bi_private);
-}
-
 /*
  * this bypasses the standard btrfs submit functions deliberately, as
  * the standard behavior is to write all copies in a raid setup. here we only
@@ -1973,7 +1968,6 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
 {
        struct bio *bio;
        struct btrfs_device *dev;
-       DECLARE_COMPLETION_ONSTACK(compl);
        u64 map_length = 0;
        u64 sector;
        struct btrfs_bio *bbio = NULL;
@@ -1990,9 +1984,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
        bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
        if (!bio)
                return -EIO;
-       bio->bi_private = &compl;
-       bio->bi_end_io = repair_io_failure_callback;
-       bio->bi_size = 0;
+       bio->bi_iter.bi_size = 0;
        map_length = length;
 
        ret = btrfs_map_block(fs_info, WRITE, logical,
@@ -2003,7 +1995,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
        }
        BUG_ON(mirror_num != bbio->mirror_num);
        sector = bbio->stripes[mirror_num-1].physical >> 9;
-       bio->bi_sector = sector;
+       bio->bi_iter.bi_sector = sector;
        dev = bbio->stripes[mirror_num-1].dev;
        kfree(bbio);
        if (!dev || !dev->bdev || !dev->writeable) {
@@ -2012,10 +2004,8 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
        }
        bio->bi_bdev = dev->bdev;
        bio_add_page(bio, page, length, start - page_offset(page));
-       btrfsic_submit_bio(WRITE_SYNC, bio);
-       wait_for_completion(&compl);
 
-       if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+       if (btrfsic_submit_bio_wait(WRITE_SYNC, bio)) {
                /* try to remap that extent elsewhere? */
                bio_put(bio);
                btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS);
@@ -2278,9 +2268,9 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset,
                return -EIO;
        }
        bio->bi_end_io = failed_bio->bi_end_io;
-       bio->bi_sector = failrec->logical >> 9;
+       bio->bi_iter.bi_sector = failrec->logical >> 9;
        bio->bi_bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev;
-       bio->bi_size = 0;
+       bio->bi_iter.bi_size = 0;
 
        btrfs_failed_bio = btrfs_io_bio(failed_bio);
        if (btrfs_failed_bio->csum) {
@@ -2342,12 +2332,13 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end)
  */
 static void end_bio_extent_writepage(struct bio *bio, int err)
 {
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+       struct bio_vec *bvec;
        struct extent_io_tree *tree;
        u64 start;
        u64 end;
+       int i;
 
-       do {
+       bio_for_each_segment_all(bvec, bio, i) {
                struct page *page = bvec->bv_page;
                tree = &BTRFS_I(page->mapping->host)->io_tree;
 
@@ -2365,14 +2356,11 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
                start = page_offset(page);
                end = start + bvec->bv_offset + bvec->bv_len - 1;
 
-               if (--bvec >= bio->bi_io_vec)
-                       prefetchw(&bvec->bv_page->flags);
-
                if (end_extent_writepage(page, err, start, end))
                        continue;
 
                end_page_writeback(page);
-       } while (bvec >= bio->bi_io_vec);
+       }
 
        bio_put(bio);
 }
@@ -2402,9 +2390,8 @@ endio_readpage_release_extent(struct extent_io_tree *tree, u64 start, u64 len,
  */
 static void end_bio_extent_readpage(struct bio *bio, int err)
 {
+       struct bio_vec *bvec;
        int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-       struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1;
-       struct bio_vec *bvec = bio->bi_io_vec;
        struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
        struct extent_io_tree *tree;
        u64 offset = 0;
@@ -2415,16 +2402,17 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
        u64 extent_len = 0;
        int mirror;
        int ret;
+       int i;
 
        if (err)
                uptodate = 0;
 
-       do {
+       bio_for_each_segment_all(bvec, bio, i) {
                struct page *page = bvec->bv_page;
                struct inode *inode = page->mapping->host;
 
                pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, "
-                        "mirror=%lu\n", (u64)bio->bi_sector, err,
+                        "mirror=%lu\n", (u64)bio->bi_iter.bi_sector, err,
                         io_bio->mirror_num);
                tree = &BTRFS_I(inode)->io_tree;
 
@@ -2443,9 +2431,6 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                end = start + bvec->bv_offset + bvec->bv_len - 1;
                len = bvec->bv_len;
 
-               if (++bvec <= bvec_end)
-                       prefetchw(&bvec->bv_page->flags);
-
                mirror = io_bio->mirror_num;
                if (likely(uptodate && tree->ops &&
                           tree->ops->readpage_end_io_hook)) {
@@ -2526,7 +2511,7 @@ readpage_ok:
                        extent_start = start;
                        extent_len = end + 1 - start;
                }
-       } while (bvec <= bvec_end);
+       }
 
        if (extent_len)
                endio_readpage_release_extent(tree, extent_start, extent_len,
@@ -2557,9 +2542,8 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
        }
 
        if (bio) {
-               bio->bi_size = 0;
                bio->bi_bdev = bdev;
-               bio->bi_sector = first_sector;
+               bio->bi_iter.bi_sector = first_sector;
                btrfs_bio = btrfs_io_bio(bio);
                btrfs_bio->csum = NULL;
                btrfs_bio->csum_allocated = NULL;
@@ -2653,7 +2637,7 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree,
        if (bio_ret && *bio_ret) {
                bio = *bio_ret;
                if (old_compressed)
-                       contig = bio->bi_sector == sector;
+                       contig = bio->bi_iter.bi_sector == sector;
                else
                        contig = bio_end_sector(bio) == sector;
 
@@ -3420,20 +3404,18 @@ static void end_extent_buffer_writeback(struct extent_buffer *eb)
 
 static void end_bio_extent_buffer_writepage(struct bio *bio, int err)
 {
-       int uptodate = err == 0;
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+       struct bio_vec *bvec;
        struct extent_buffer *eb;
-       int done;
+       int i, done;
 
-       do {
+       bio_for_each_segment_all(bvec, bio, i) {
                struct page *page = bvec->bv_page;
 
-               bvec--;
                eb = (struct extent_buffer *)page->private;
                BUG_ON(!eb);
                done = atomic_dec_and_test(&eb->io_pages);
 
-               if (!uptodate || test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) {
+               if (err || test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) {
                        set_bit(EXTENT_BUFFER_IOERR, &eb->bflags);
                        ClearPageUptodate(page);
                        SetPageError(page);
@@ -3445,10 +3427,9 @@ static void end_bio_extent_buffer_writepage(struct bio *bio, int err)
                        continue;
 
                end_extent_buffer_writeback(eb);
-       } while (bvec >= bio->bi_io_vec);
+       }
 
        bio_put(bio);
-
 }
 
 static int write_one_eb(struct extent_buffer *eb,
index 6f384886028386f2f069756ef18e757b10ba9dbf..84a46a42d26269b94fbb0a823e1fec43439d5e69 100644 (file)
@@ -182,7 +182,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
        if (!path)
                return -ENOMEM;
 
-       nblocks = bio->bi_size >> inode->i_sb->s_blocksize_bits;
+       nblocks = bio->bi_iter.bi_size >> inode->i_sb->s_blocksize_bits;
        if (!dst) {
                if (nblocks * csum_size > BTRFS_BIO_INLINE_CSUM_SIZE) {
                        btrfs_bio->csum_allocated = kmalloc(nblocks * csum_size,
@@ -201,7 +201,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
                csum = (u8 *)dst;
        }
 
-       if (bio->bi_size > PAGE_CACHE_SIZE * 8)
+       if (bio->bi_iter.bi_size > PAGE_CACHE_SIZE * 8)
                path->reada = 2;
 
        WARN_ON(bio->bi_vcnt <= 0);
@@ -217,7 +217,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
                path->skip_locking = 1;
        }
 
-       disk_bytenr = (u64)bio->bi_sector << 9;
+       disk_bytenr = (u64)bio->bi_iter.bi_sector << 9;
        if (dio)
                offset = logical_offset;
        while (bio_index < bio->bi_vcnt) {
@@ -302,7 +302,7 @@ int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode,
                              struct btrfs_dio_private *dip, struct bio *bio,
                              u64 offset)
 {
-       int len = (bio->bi_sector << 9) - dip->disk_bytenr;
+       int len = (bio->bi_iter.bi_sector << 9) - dip->disk_bytenr;
        u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
        int ret;
 
@@ -447,11 +447,12 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
        u64 offset;
 
        WARN_ON(bio->bi_vcnt <= 0);
-       sums = kzalloc(btrfs_ordered_sum_size(root, bio->bi_size), GFP_NOFS);
+       sums = kzalloc(btrfs_ordered_sum_size(root, bio->bi_iter.bi_size),
+                      GFP_NOFS);
        if (!sums)
                return -ENOMEM;
 
-       sums->len = bio->bi_size;
+       sums->len = bio->bi_iter.bi_size;
        INIT_LIST_HEAD(&sums->list);
 
        if (contig)
@@ -461,7 +462,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
 
        ordered = btrfs_lookup_ordered_extent(inode, offset);
        BUG_ON(!ordered); /* Logic error */
-       sums->bytenr = (u64)bio->bi_sector << 9;
+       sums->bytenr = (u64)bio->bi_iter.bi_sector << 9;
        index = 0;
 
        while (bio_index < bio->bi_vcnt) {
@@ -476,7 +477,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
                        btrfs_add_ordered_sum(inode, ordered, sums);
                        btrfs_put_ordered_extent(ordered);
 
-                       bytes_left = bio->bi_size - total_bytes;
+                       bytes_left = bio->bi_iter.bi_size - total_bytes;
 
                        sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
                                       GFP_NOFS);
@@ -484,7 +485,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
                        sums->len = bytes_left;
                        ordered = btrfs_lookup_ordered_extent(inode, offset);
                        BUG_ON(!ordered); /* Logic error */
-                       sums->bytenr = ((u64)bio->bi_sector << 9) +
+                       sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9) +
                                       total_bytes;
                        index = 0;
                }
index f1a77449d032b1fbd481eb16cd232653e5bfbefa..7ab0e94ad49244e6167e2c758383c78c233f0cbb 100644 (file)
@@ -1577,7 +1577,7 @@ int btrfs_merge_bio_hook(int rw, struct page *page, unsigned long offset,
                         unsigned long bio_flags)
 {
        struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
-       u64 logical = (u64)bio->bi_sector << 9;
+       u64 logical = (u64)bio->bi_iter.bi_sector << 9;
        u64 length = 0;
        u64 map_length;
        int ret;
@@ -1585,7 +1585,7 @@ int btrfs_merge_bio_hook(int rw, struct page *page, unsigned long offset,
        if (bio_flags & EXTENT_BIO_COMPRESSED)
                return 0;
 
-       length = bio->bi_size;
+       length = bio->bi_iter.bi_size;
        map_length = length;
        ret = btrfs_map_block(root->fs_info, rw, logical,
                              &map_length, NULL, 0);
@@ -6779,17 +6779,16 @@ unlock_err:
 static void btrfs_endio_direct_read(struct bio *bio, int err)
 {
        struct btrfs_dio_private *dip = bio->bi_private;
-       struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1;
-       struct bio_vec *bvec = bio->bi_io_vec;
+       struct bio_vec *bvec;
        struct inode *inode = dip->inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct bio *dio_bio;
        u32 *csums = (u32 *)dip->csum;
-       int index = 0;
        u64 start;
+       int i;
 
        start = dip->logical_offset;
-       do {
+       bio_for_each_segment_all(bvec, bio, i) {
                if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
                        struct page *page = bvec->bv_page;
                        char *kaddr;
@@ -6805,18 +6804,16 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
                        local_irq_restore(flags);
 
                        flush_dcache_page(bvec->bv_page);
-                       if (csum != csums[index]) {
+                       if (csum != csums[i]) {
                                btrfs_err(root->fs_info, "csum failed ino %llu off %llu csum %u expected csum %u",
                                          btrfs_ino(inode), start, csum,
-                                         csums[index]);
+                                         csums[i]);
                                err = -EIO;
                        }
                }
 
                start += bvec->bv_len;
-               bvec++;
-               index++;
-       } while (bvec <= bvec_end);
+       }
 
        unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset,
                      dip->logical_offset + dip->bytes - 1);
@@ -6897,7 +6894,8 @@ static void btrfs_end_dio_bio(struct bio *bio, int err)
                printk(KERN_ERR "btrfs direct IO failed ino %llu rw %lu "
                      "sector %#Lx len %u err no %d\n",
                      btrfs_ino(dip->inode), bio->bi_rw,
-                     (unsigned long long)bio->bi_sector, bio->bi_size, err);
+                     (unsigned long long)bio->bi_iter.bi_sector,
+                     bio->bi_iter.bi_size, err);
                dip->errors = 1;
 
                /*
@@ -6988,7 +6986,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
        struct bio *bio;
        struct bio *orig_bio = dip->orig_bio;
        struct bio_vec *bvec = orig_bio->bi_io_vec;
-       u64 start_sector = orig_bio->bi_sector;
+       u64 start_sector = orig_bio->bi_iter.bi_sector;
        u64 file_offset = dip->logical_offset;
        u64 submit_len = 0;
        u64 map_length;
@@ -6996,7 +6994,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
        int ret = 0;
        int async_submit = 0;
 
-       map_length = orig_bio->bi_size;
+       map_length = orig_bio->bi_iter.bi_size;
        ret = btrfs_map_block(root->fs_info, rw, start_sector << 9,
                              &map_length, NULL, 0);
        if (ret) {
@@ -7004,7 +7002,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
                return -EIO;
        }
 
-       if (map_length >= orig_bio->bi_size) {
+       if (map_length >= orig_bio->bi_iter.bi_size) {
                bio = orig_bio;
                goto submit;
        }
@@ -7056,7 +7054,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
                        bio->bi_private = dip;
                        bio->bi_end_io = btrfs_end_dio_bio;
 
-                       map_length = orig_bio->bi_size;
+                       map_length = orig_bio->bi_iter.bi_size;
                        ret = btrfs_map_block(root->fs_info, rw,
                                              start_sector << 9,
                                              &map_length, NULL, 0);
@@ -7114,7 +7112,8 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
 
        if (!skip_sum && !write) {
                csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
-               sum_len = dio_bio->bi_size >> inode->i_sb->s_blocksize_bits;
+               sum_len = dio_bio->bi_iter.bi_size >>
+                       inode->i_sb->s_blocksize_bits;
                sum_len *= csum_size;
        } else {
                sum_len = 0;
@@ -7129,8 +7128,8 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
        dip->private = dio_bio->bi_private;
        dip->inode = inode;
        dip->logical_offset = file_offset;
-       dip->bytes = dio_bio->bi_size;
-       dip->disk_bytenr = (u64)dio_bio->bi_sector << 9;
+       dip->bytes = dio_bio->bi_iter.bi_size;
+       dip->disk_bytenr = (u64)dio_bio->bi_iter.bi_sector << 9;
        io_bio->bi_private = dip;
        dip->errors = 0;
        dip->orig_bio = io_bio;
index 24ac21840a9a0797cdb086a58e90e64a3c1481ad..9af0b25d991a8c64653b4fa20f4dc31c2794b943 100644 (file)
@@ -1032,8 +1032,8 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio,
 
        /* see if we can add this page onto our existing bio */
        if (last) {
-               last_end = (u64)last->bi_sector << 9;
-               last_end += last->bi_size;
+               last_end = (u64)last->bi_iter.bi_sector << 9;
+               last_end += last->bi_iter.bi_size;
 
                /*
                 * we can't merge these if they are from different
@@ -1053,9 +1053,9 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio,
        if (!bio)
                return -ENOMEM;
 
-       bio->bi_size = 0;
+       bio->bi_iter.bi_size = 0;
        bio->bi_bdev = stripe->dev->bdev;
-       bio->bi_sector = disk_start >> 9;
+       bio->bi_iter.bi_sector = disk_start >> 9;
        set_bit(BIO_UPTODATE, &bio->bi_flags);
 
        bio_add_page(bio, page, PAGE_CACHE_SIZE, 0);
@@ -1111,7 +1111,7 @@ static void index_rbio_pages(struct btrfs_raid_bio *rbio)
 
        spin_lock_irq(&rbio->bio_list_lock);
        bio_list_for_each(bio, &rbio->bio_list) {
-               start = (u64)bio->bi_sector << 9;
+               start = (u64)bio->bi_iter.bi_sector << 9;
                stripe_offset = start - rbio->raid_map[0];
                page_index = stripe_offset >> PAGE_CACHE_SHIFT;
 
@@ -1272,7 +1272,7 @@ cleanup:
 static int find_bio_stripe(struct btrfs_raid_bio *rbio,
                           struct bio *bio)
 {
-       u64 physical = bio->bi_sector;
+       u64 physical = bio->bi_iter.bi_sector;
        u64 stripe_start;
        int i;
        struct btrfs_bio_stripe *stripe;
@@ -1298,7 +1298,7 @@ static int find_bio_stripe(struct btrfs_raid_bio *rbio,
 static int find_logical_bio_stripe(struct btrfs_raid_bio *rbio,
                                   struct bio *bio)
 {
-       u64 logical = bio->bi_sector;
+       u64 logical = bio->bi_iter.bi_sector;
        u64 stripe_start;
        int i;
 
@@ -1602,8 +1602,8 @@ static int plug_cmp(void *priv, struct list_head *a, struct list_head *b)
                                                 plug_list);
        struct btrfs_raid_bio *rb = container_of(b, struct btrfs_raid_bio,
                                                 plug_list);
-       u64 a_sector = ra->bio_list.head->bi_sector;
-       u64 b_sector = rb->bio_list.head->bi_sector;
+       u64 a_sector = ra->bio_list.head->bi_iter.bi_sector;
+       u64 b_sector = rb->bio_list.head->bi_iter.bi_sector;
 
        if (a_sector < b_sector)
                return -1;
@@ -1691,7 +1691,7 @@ int raid56_parity_write(struct btrfs_root *root, struct bio *bio,
        if (IS_ERR(rbio))
                return PTR_ERR(rbio);
        bio_list_add(&rbio->bio_list, bio);
-       rbio->bio_list_bytes = bio->bi_size;
+       rbio->bio_list_bytes = bio->bi_iter.bi_size;
 
        /*
         * don't plug on full rbios, just get them out the door
@@ -2044,7 +2044,7 @@ int raid56_parity_recover(struct btrfs_root *root, struct bio *bio,
 
        rbio->read_rebuild = 1;
        bio_list_add(&rbio->bio_list, bio);
-       rbio->bio_list_bytes = bio->bi_size;
+       rbio->bio_list_bytes = bio->bi_iter.bi_size;
 
        rbio->faila = find_logical_bio_stripe(rbio, bio);
        if (rbio->faila == -1) {
index 561e2f16ba3e3ff3b0be72b12b4a052b86082d2a..bb9a928fa3a848c597d842a94fe2e49a48766cf0 100644 (file)
@@ -208,7 +208,6 @@ static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info,
                                         int is_metadata, int have_csum,
                                         const u8 *csum, u64 generation,
                                         u16 csum_size);
-static void scrub_complete_bio_end_io(struct bio *bio, int err);
 static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad,
                                             struct scrub_block *sblock_good,
                                             int force_write);
@@ -1294,7 +1293,6 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
        for (page_num = 0; page_num < sblock->page_count; page_num++) {
                struct bio *bio;
                struct scrub_page *page = sblock->pagev[page_num];
-               DECLARE_COMPLETION_ONSTACK(complete);
 
                if (page->dev->bdev == NULL) {
                        page->io_error = 1;
@@ -1310,19 +1308,12 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
                        continue;
                }
                bio->bi_bdev = page->dev->bdev;
-               bio->bi_sector = page->physical >> 9;
-               bio->bi_end_io = scrub_complete_bio_end_io;
-               bio->bi_private = &complete;
+               bio->bi_iter.bi_sector = page->physical >> 9;
 
                bio_add_page(bio, page->page, PAGE_SIZE, 0);
-               btrfsic_submit_bio(READ, bio);
-
-               /* this will also unplug the queue */
-               wait_for_completion(&complete);
-
-               page->io_error = !test_bit(BIO_UPTODATE, &bio->bi_flags);
-               if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+               if (btrfsic_submit_bio_wait(READ, bio))
                        sblock->no_io_error_seen = 0;
+
                bio_put(bio);
        }
 
@@ -1391,11 +1382,6 @@ static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info,
                sblock->checksum_error = 1;
 }
 
-static void scrub_complete_bio_end_io(struct bio *bio, int err)
-{
-       complete((struct completion *)bio->bi_private);
-}
-
 static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad,
                                             struct scrub_block *sblock_good,
                                             int force_write)
@@ -1430,7 +1416,6 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad,
            sblock_bad->checksum_error || page_bad->io_error) {
                struct bio *bio;
                int ret;
-               DECLARE_COMPLETION_ONSTACK(complete);
 
                if (!page_bad->dev->bdev) {
                        printk_ratelimited(KERN_WARNING
@@ -1442,20 +1427,15 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad,
                if (!bio)
                        return -EIO;
                bio->bi_bdev = page_bad->dev->bdev;
-               bio->bi_sector = page_bad->physical >> 9;
-               bio->bi_end_io = scrub_complete_bio_end_io;
-               bio->bi_private = &complete;
+               bio->bi_iter.bi_sector = page_bad->physical >> 9;
 
                ret = bio_add_page(bio, page_good->page, PAGE_SIZE, 0);
                if (PAGE_SIZE != ret) {
                        bio_put(bio);
                        return -EIO;
                }
-               btrfsic_submit_bio(WRITE, bio);
 
-               /* this will also unplug the queue */
-               wait_for_completion(&complete);
-               if (!bio_flagged(bio, BIO_UPTODATE)) {
+               if (btrfsic_submit_bio_wait(WRITE, bio)) {
                        btrfs_dev_stat_inc_and_print(page_bad->dev,
                                BTRFS_DEV_STAT_WRITE_ERRS);
                        btrfs_dev_replace_stats_inc(
@@ -1540,7 +1520,7 @@ again:
                bio->bi_private = sbio;
                bio->bi_end_io = scrub_wr_bio_end_io;
                bio->bi_bdev = sbio->dev->bdev;
-               bio->bi_sector = sbio->physical >> 9;
+               bio->bi_iter.bi_sector = sbio->physical >> 9;
                sbio->err = 0;
        } else if (sbio->physical + sbio->page_count * PAGE_SIZE !=
                   spage->physical_for_dev_replace ||
@@ -1946,7 +1926,7 @@ again:
                bio->bi_private = sbio;
                bio->bi_end_io = scrub_bio_end_io;
                bio->bi_bdev = sbio->dev->bdev;
-               bio->bi_sector = sbio->physical >> 9;
+               bio->bi_iter.bi_sector = sbio->physical >> 9;
                sbio->err = 0;
        } else if (sbio->physical + sbio->page_count * PAGE_SIZE !=
                   spage->physical ||
@@ -3375,7 +3355,6 @@ static int write_page_nocow(struct scrub_ctx *sctx,
        struct bio *bio;
        struct btrfs_device *dev;
        int ret;
-       DECLARE_COMPLETION_ONSTACK(compl);
 
        dev = sctx->wr_ctx.tgtdev;
        if (!dev)
@@ -3392,10 +3371,8 @@ static int write_page_nocow(struct scrub_ctx *sctx,
                spin_unlock(&sctx->stat_lock);
                return -ENOMEM;
        }
-       bio->bi_private = &compl;
-       bio->bi_end_io = scrub_complete_bio_end_io;
-       bio->bi_size = 0;
-       bio->bi_sector = physical_for_dev_replace >> 9;
+       bio->bi_iter.bi_size = 0;
+       bio->bi_iter.bi_sector = physical_for_dev_replace >> 9;
        bio->bi_bdev = dev->bdev;
        ret = bio_add_page(bio, page, PAGE_CACHE_SIZE, 0);
        if (ret != PAGE_CACHE_SIZE) {
@@ -3404,10 +3381,8 @@ leave_with_eio:
                btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS);
                return -EIO;
        }
-       btrfsic_submit_bio(WRITE_SYNC, bio);
-       wait_for_completion(&compl);
 
-       if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+       if (btrfsic_submit_bio_wait(WRITE_SYNC, bio))
                goto leave_with_eio;
 
        bio_put(bio);
index 92303f42baaa92d5d845edddff1f8600fc46518e..f2130de0ddc2cf4bc668060dd77c1a03b64f0a8d 100644 (file)
@@ -5411,7 +5411,7 @@ static int bio_size_ok(struct block_device *bdev, struct bio *bio,
        if (!q->merge_bvec_fn)
                return 1;
 
-       bvm.bi_size = bio->bi_size - prev->bv_len;
+       bvm.bi_size = bio->bi_iter.bi_size - prev->bv_len;
        if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len)
                return 0;
        return 1;
@@ -5426,7 +5426,7 @@ static void submit_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio,
        bio->bi_private = bbio;
        btrfs_io_bio(bio)->stripe_index = dev_nr;
        bio->bi_end_io = btrfs_end_bio;
-       bio->bi_sector = physical >> 9;
+       bio->bi_iter.bi_sector = physical >> 9;
 #ifdef DEBUG
        {
                struct rcu_string *name;
@@ -5464,7 +5464,7 @@ again:
        while (bvec <= (first_bio->bi_io_vec + first_bio->bi_vcnt - 1)) {
                if (bio_add_page(bio, bvec->bv_page, bvec->bv_len,
                                 bvec->bv_offset) < bvec->bv_len) {
-                       u64 len = bio->bi_size;
+                       u64 len = bio->bi_iter.bi_size;
 
                        atomic_inc(&bbio->stripes_pending);
                        submit_stripe_bio(root, bbio, bio, physical, dev_nr,
@@ -5486,7 +5486,7 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
                bio->bi_private = bbio->private;
                bio->bi_end_io = bbio->end_io;
                btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
-               bio->bi_sector = logical >> 9;
+               bio->bi_iter.bi_sector = logical >> 9;
                kfree(bbio);
                bio_endio(bio, -EIO);
        }
@@ -5497,7 +5497,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
 {
        struct btrfs_device *dev;
        struct bio *first_bio = bio;
-       u64 logical = (u64)bio->bi_sector << 9;
+       u64 logical = (u64)bio->bi_iter.bi_sector << 9;
        u64 length = 0;
        u64 map_length;
        u64 *raid_map = NULL;
@@ -5506,7 +5506,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
        int total_devs = 1;
        struct btrfs_bio *bbio = NULL;
 
-       length = bio->bi_size;
+       length = bio->bi_iter.bi_size;
        map_length = length;
 
        ret = __btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio,
index 6024877335caf2a9dfa6af1018c5da19b0e8a2ae..1c04ec66974e0329e57d09f85f597632b3b9a26d 100644 (file)
@@ -2982,11 +2982,11 @@ static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh)
         * let it through, and the IO layer will turn it into
         * an EIO.
         */
-       if (unlikely(bio->bi_sector >= maxsector))
+       if (unlikely(bio->bi_iter.bi_sector >= maxsector))
                return;
 
-       maxsector -= bio->bi_sector;
-       bytes = bio->bi_size;
+       maxsector -= bio->bi_iter.bi_sector;
+       bytes = bio->bi_iter.bi_size;
        if (likely((bytes >> 9) <= maxsector))
                return;
 
@@ -2994,7 +2994,7 @@ static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh)
        bytes = maxsector << 9;
 
        /* Truncate the bio.. */
-       bio->bi_size = bytes;
+       bio->bi_iter.bi_size = bytes;
        bio->bi_io_vec[0].bv_len = bytes;
 
        /* ..and clear the end of the buffer for reads */
@@ -3029,14 +3029,14 @@ int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags)
         */
        bio = bio_alloc(GFP_NOIO, 1);
 
-       bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
+       bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9);
        bio->bi_bdev = bh->b_bdev;
        bio->bi_io_vec[0].bv_page = bh->b_page;
        bio->bi_io_vec[0].bv_len = bh->b_size;
        bio->bi_io_vec[0].bv_offset = bh_offset(bh);
 
        bio->bi_vcnt = 1;
-       bio->bi_size = bh->b_size;
+       bio->bi_iter.bi_size = bh->b_size;
 
        bio->bi_end_io = end_bio_bh_io_sync;
        bio->bi_private = bh;
index 6df8bd481425379006912990ee6f9461eaf3cf1b..1e561c059539542e83a118edb003ffabca08506b 100644 (file)
@@ -216,7 +216,7 @@ static int readpage_nounlock(struct file *filp, struct page *page)
        }
        SetPageUptodate(page);
 
-       if (err == 0)
+       if (err >= 0)
                ceph_readpage_to_fscache(inode, page);
 
 out:
index 7db2e6ca4b8f0b07146c137a80e24567a03d3e43..8c44fdd4e1c39f836b2c8a9b2a7a025f1844d3b3 100644 (file)
@@ -324,6 +324,9 @@ void ceph_invalidate_fscache_page(struct inode* inode, struct page *page)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
 
+       if (!PageFsCache(page))
+               return;
+
        fscache_wait_on_page_write(ci->fscache, page);
        fscache_uncache_page(ci->fscache, page);
 }
index 13976c33332ec1fd7ca3999053b15b7079c5ab31..3c0a4bd7499645ca8bf90fd1a6ba16f6831c164c 100644 (file)
@@ -897,7 +897,7 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci)
  * caller should hold i_ceph_lock.
  * caller will not hold session s_mutex if called from destroy_inode.
  */
-void __ceph_remove_cap(struct ceph_cap *cap)
+void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
 {
        struct ceph_mds_session *session = cap->session;
        struct ceph_inode_info *ci = cap->ci;
@@ -909,6 +909,16 @@ void __ceph_remove_cap(struct ceph_cap *cap)
 
        /* remove from session list */
        spin_lock(&session->s_cap_lock);
+       /*
+        * s_cap_reconnect is protected by s_cap_lock. no one changes
+        * s_cap_gen while session is in the reconnect state.
+        */
+       if (queue_release &&
+           (!session->s_cap_reconnect ||
+            cap->cap_gen == session->s_cap_gen))
+               __queue_cap_release(session, ci->i_vino.ino, cap->cap_id,
+                                   cap->mseq, cap->issue_seq);
+
        if (session->s_cap_iterator == cap) {
                /* not yet, we are iterating over this very cap */
                dout("__ceph_remove_cap  delaying %p removal from session %p\n",
@@ -1023,7 +1033,6 @@ void __queue_cap_release(struct ceph_mds_session *session,
        struct ceph_mds_cap_release *head;
        struct ceph_mds_cap_item *item;
 
-       spin_lock(&session->s_cap_lock);
        BUG_ON(!session->s_num_cap_releases);
        msg = list_first_entry(&session->s_cap_releases,
                               struct ceph_msg, list_head);
@@ -1052,7 +1061,6 @@ void __queue_cap_release(struct ceph_mds_session *session,
                     (int)CEPH_CAPS_PER_RELEASE,
                     (int)msg->front.iov_len);
        }
-       spin_unlock(&session->s_cap_lock);
 }
 
 /*
@@ -1067,12 +1075,8 @@ void ceph_queue_caps_release(struct inode *inode)
        p = rb_first(&ci->i_caps);
        while (p) {
                struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node);
-               struct ceph_mds_session *session = cap->session;
-
-               __queue_cap_release(session, ceph_ino(inode), cap->cap_id,
-                                   cap->mseq, cap->issue_seq);
                p = rb_next(p);
-               __ceph_remove_cap(cap);
+               __ceph_remove_cap(cap, true);
        }
 }
 
@@ -2791,7 +2795,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
                        }
                        spin_unlock(&mdsc->cap_dirty_lock);
                }
-               __ceph_remove_cap(cap);
+               __ceph_remove_cap(cap, false);
        }
        /* else, we already released it */
 
@@ -2931,9 +2935,12 @@ void ceph_handle_caps(struct ceph_mds_session *session,
        if (!inode) {
                dout(" i don't have ino %llx\n", vino.ino);
 
-               if (op == CEPH_CAP_OP_IMPORT)
+               if (op == CEPH_CAP_OP_IMPORT) {
+                       spin_lock(&session->s_cap_lock);
                        __queue_cap_release(session, vino.ino, cap_id,
                                            mseq, seq);
+                       spin_unlock(&session->s_cap_lock);
+               }
                goto flush_cap_releases;
        }
 
index 868b61d56cac77f3a8328d5ba4851ec7947fe827..2a0bcaeb189acd18b124aff8d54619667fd97bf2 100644 (file)
@@ -352,8 +352,18 @@ more:
                }
 
                /* note next offset and last dentry name */
+               rinfo = &req->r_reply_info;
+               if (le32_to_cpu(rinfo->dir_dir->frag) != frag) {
+                       frag = le32_to_cpu(rinfo->dir_dir->frag);
+                       if (ceph_frag_is_leftmost(frag))
+                               fi->next_offset = 2;
+                       else
+                               fi->next_offset = 0;
+                       off = fi->next_offset;
+               }
                fi->offset = fi->next_offset;
                fi->last_readdir = req;
+               fi->frag = frag;
 
                if (req->r_reply_info.dir_end) {
                        kfree(fi->last_name);
@@ -363,7 +373,6 @@ more:
                        else
                                fi->next_offset = 0;
                } else {
-                       rinfo = &req->r_reply_info;
                        err = note_last_dentry(fi,
                                       rinfo->dir_dname[rinfo->dir_nr-1],
                                       rinfo->dir_dname_len[rinfo->dir_nr-1]);
index 3de89829e2a162ab6bce2a58296b25aef9235c43..c4419e848a4f89eced64c8a156a560f62bc2cbdd 100644 (file)
@@ -408,51 +408,92 @@ more:
  *
  * If the read spans object boundary, just do multiple reads.
  */
-static ssize_t ceph_sync_read(struct file *file, char __user *data,
-                             unsigned len, loff_t *poff, int *checkeof)
+static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i,
+                               int *checkeof)
 {
+       struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
        struct page **pages;
-       u64 off = *poff;
+       u64 off = iocb->ki_pos;
        int num_pages, ret;
+       size_t len = i->count;
 
-       dout("sync_read on file %p %llu~%u %s\n", file, off, len,
+       dout("sync_read on file %p %llu~%u %s\n", file, off,
+            (unsigned)len,
             (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
-
-       if (file->f_flags & O_DIRECT) {
-               num_pages = calc_pages_for((unsigned long)data, len);
-               pages = ceph_get_direct_page_vector(data, num_pages, true);
-       } else {
-               num_pages = calc_pages_for(off, len);
-               pages = ceph_alloc_page_vector(num_pages, GFP_NOFS);
-       }
-       if (IS_ERR(pages))
-               return PTR_ERR(pages);
-
        /*
         * flush any page cache pages in this range.  this
         * will make concurrent normal and sync io slow,
         * but it will at least behave sensibly when they are
         * in sequence.
         */
-       ret = filemap_write_and_wait(inode->i_mapping);
+       ret = filemap_write_and_wait_range(inode->i_mapping, off,
+                                               off + len);
        if (ret < 0)
-               goto done;
+               return ret;
 
-       ret = striped_read(inode, off, len, pages, num_pages, checkeof,
-                          file->f_flags & O_DIRECT,
-                          (unsigned long)data & ~PAGE_MASK);
+       if (file->f_flags & O_DIRECT) {
+               while (iov_iter_count(i)) {
+                       void __user *data = i->iov[0].iov_base + i->iov_offset;
+                       size_t len = i->iov[0].iov_len - i->iov_offset;
+
+                       num_pages = calc_pages_for((unsigned long)data, len);
+                       pages = ceph_get_direct_page_vector(data,
+                                                           num_pages, true);
+                       if (IS_ERR(pages))
+                               return PTR_ERR(pages);
+
+                       ret = striped_read(inode, off, len,
+                                          pages, num_pages, checkeof,
+                                          1, (unsigned long)data & ~PAGE_MASK);
+                       ceph_put_page_vector(pages, num_pages, true);
+
+                       if (ret <= 0)
+                               break;
+                       off += ret;
+                       iov_iter_advance(i, ret);
+                       if (ret < len)
+                               break;
+               }
+       } else {
+               num_pages = calc_pages_for(off, len);
+               pages = ceph_alloc_page_vector(num_pages, GFP_NOFS);
+               if (IS_ERR(pages))
+                       return PTR_ERR(pages);
+               ret = striped_read(inode, off, len, pages,
+                                       num_pages, checkeof, 0, 0);
+               if (ret > 0) {
+                       int l, k = 0;
+                       size_t left = len = ret;
+
+                       while (left) {
+                               void __user *data = i->iov[0].iov_base
+                                                       + i->iov_offset;
+                               l = min(i->iov[0].iov_len - i->iov_offset,
+                                       left);
+
+                               ret = ceph_copy_page_vector_to_user(&pages[k],
+                                                                   data, off,
+                                                                   l);
+                               if (ret > 0) {
+                                       iov_iter_advance(i, ret);
+                                       left -= ret;
+                                       off += ret;
+                                       k = calc_pages_for(iocb->ki_pos,
+                                                          len - left + 1) - 1;
+                                       BUG_ON(k >= num_pages && left);
+                               } else
+                                       break;
+                       }
+               }
+               ceph_release_page_vector(pages, num_pages);
+       }
 
-       if (ret >= 0 && (file->f_flags & O_DIRECT) == 0)
-               ret = ceph_copy_page_vector_to_user(pages, data, off, ret);
-       if (ret >= 0)
-               *poff = off + ret;
+       if (off > iocb->ki_pos) {
+               ret = off - iocb->ki_pos;
+               iocb->ki_pos = off;
+       }
 
-done:
-       if (file->f_flags & O_DIRECT)
-               ceph_put_page_vector(pages, num_pages, true);
-       else
-               ceph_release_page_vector(pages, num_pages);
        dout("sync_read result %d\n", ret);
        return ret;
 }
@@ -489,83 +530,79 @@ static void ceph_sync_write_unsafe(struct ceph_osd_request *req, bool unsafe)
        }
 }
 
+
 /*
- * Synchronous write, straight from __user pointer or user pages (if
- * O_DIRECT).
+ * Synchronous write, straight from __user pointer or user pages.
  *
  * If write spans object boundary, just do multiple writes.  (For a
  * correct atomic write, we should e.g. take write locks on all
  * objects, rollback on failure, etc.)
  */
-static ssize_t ceph_sync_write(struct file *file, const char __user *data,
-                              size_t left, loff_t pos, loff_t *ppos)
+static ssize_t
+ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
+                      unsigned long nr_segs, size_t count)
 {
+       struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        struct ceph_snap_context *snapc;
        struct ceph_vino vino;
        struct ceph_osd_request *req;
-       int num_ops = 1;
        struct page **pages;
        int num_pages;
-       u64 len;
        int written = 0;
        int flags;
        int check_caps = 0;
-       int page_align, io_align;
-       unsigned long buf_align;
+       int page_align;
        int ret;
        struct timespec mtime = CURRENT_TIME;
-       bool own_pages = false;
+       loff_t pos = iocb->ki_pos;
+       struct iov_iter i;
 
        if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
                return -EROFS;
 
-       dout("sync_write on file %p %lld~%u %s\n", file, pos,
-            (unsigned)left, (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
+       dout("sync_direct_write on file %p %lld~%u\n", file, pos,
+            (unsigned)count);
 
-       ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
+       ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + count);
        if (ret < 0)
                return ret;
 
        ret = invalidate_inode_pages2_range(inode->i_mapping,
                                            pos >> PAGE_CACHE_SHIFT,
-                                           (pos + left) >> PAGE_CACHE_SHIFT);
+                                           (pos + count) >> PAGE_CACHE_SHIFT);
        if (ret < 0)
                dout("invalidate_inode_pages2_range returned %d\n", ret);
 
        flags = CEPH_OSD_FLAG_ORDERSNAP |
                CEPH_OSD_FLAG_ONDISK |
                CEPH_OSD_FLAG_WRITE;
-       if ((file->f_flags & (O_SYNC|O_DIRECT)) == 0)
-               flags |= CEPH_OSD_FLAG_ACK;
-       else
-               num_ops++;      /* Also include a 'startsync' command. */
 
-       /*
-        * we may need to do multiple writes here if we span an object
-        * boundary.  this isn't atomic, unfortunately.  :(
-        */
-more:
-       io_align = pos & ~PAGE_MASK;
-       buf_align = (unsigned long)data & ~PAGE_MASK;
-       len = left;
-
-       snapc = ci->i_snap_realm->cached_context;
-       vino = ceph_vino(inode);
-       req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
-                                   vino, pos, &len, num_ops,
-                                   CEPH_OSD_OP_WRITE, flags, snapc,
-                                   ci->i_truncate_seq, ci->i_truncate_size,
-                                   false);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       iov_iter_init(&i, iov, nr_segs, count, 0);
+
+       while (iov_iter_count(&i) > 0) {
+               void __user *data = i.iov->iov_base + i.iov_offset;
+               u64 len = i.iov->iov_len - i.iov_offset;
+
+               page_align = (unsigned long)data & ~PAGE_MASK;
+
+               snapc = ci->i_snap_realm->cached_context;
+               vino = ceph_vino(inode);
+               req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
+                                           vino, pos, &len,
+                                           2,/*include a 'startsync' command*/
+                                           CEPH_OSD_OP_WRITE, flags, snapc,
+                                           ci->i_truncate_seq,
+                                           ci->i_truncate_size,
+                                           false);
+               if (IS_ERR(req)) {
+                       ret = PTR_ERR(req);
+                       goto out;
+               }
 
-       /* write from beginning of first page, regardless of io alignment */
-       page_align = file->f_flags & O_DIRECT ? buf_align : io_align;
-       num_pages = calc_pages_for(page_align, len);
-       if (file->f_flags & O_DIRECT) {
+               num_pages = calc_pages_for(page_align, len);
                pages = ceph_get_direct_page_vector(data, num_pages, false);
                if (IS_ERR(pages)) {
                        ret = PTR_ERR(pages);
@@ -577,60 +614,175 @@ more:
                 * may block.
                 */
                truncate_inode_pages_range(inode->i_mapping, pos,
-                                          (pos+len) | (PAGE_CACHE_SIZE-1));
-       } else {
+                                  (pos+len) | (PAGE_CACHE_SIZE-1));
+               osd_req_op_extent_osd_data_pages(req, 0, pages, len, page_align,
+                                               false, false);
+
+               /* BUG_ON(vino.snap != CEPH_NOSNAP); */
+               ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime);
+
+               ret = ceph_osdc_start_request(&fsc->client->osdc, req, false);
+               if (!ret)
+                       ret = ceph_osdc_wait_request(&fsc->client->osdc, req);
+
+               ceph_put_page_vector(pages, num_pages, false);
+
+out:
+               ceph_osdc_put_request(req);
+               if (ret == 0) {
+                       pos += len;
+                       written += len;
+                       iov_iter_advance(&i, (size_t)len);
+
+                       if (pos > i_size_read(inode)) {
+                               check_caps = ceph_inode_set_size(inode, pos);
+                               if (check_caps)
+                                       ceph_check_caps(ceph_inode(inode),
+                                                       CHECK_CAPS_AUTHONLY,
+                                                       NULL);
+                       }
+               } else
+                       break;
+       }
+
+       if (ret != -EOLDSNAPC && written > 0) {
+               iocb->ki_pos = pos;
+               ret = written;
+       }
+       return ret;
+}
+
+
+/*
+ * Synchronous write, straight from __user pointer or user pages.
+ *
+ * If write spans object boundary, just do multiple writes.  (For a
+ * correct atomic write, we should e.g. take write locks on all
+ * objects, rollback on failure, etc.)
+ */
+static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov,
+                              unsigned long nr_segs, size_t count)
+{
+       struct file *file = iocb->ki_filp;
+       struct inode *inode = file_inode(file);
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
+       struct ceph_snap_context *snapc;
+       struct ceph_vino vino;
+       struct ceph_osd_request *req;
+       struct page **pages;
+       u64 len;
+       int num_pages;
+       int written = 0;
+       int flags;
+       int check_caps = 0;
+       int ret;
+       struct timespec mtime = CURRENT_TIME;
+       loff_t pos = iocb->ki_pos;
+       struct iov_iter i;
+
+       if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
+               return -EROFS;
+
+       dout("sync_write on file %p %lld~%u\n", file, pos, (unsigned)count);
+
+       ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + count);
+       if (ret < 0)
+               return ret;
+
+       ret = invalidate_inode_pages2_range(inode->i_mapping,
+                                           pos >> PAGE_CACHE_SHIFT,
+                                           (pos + count) >> PAGE_CACHE_SHIFT);
+       if (ret < 0)
+               dout("invalidate_inode_pages2_range returned %d\n", ret);
+
+       flags = CEPH_OSD_FLAG_ORDERSNAP |
+               CEPH_OSD_FLAG_ONDISK |
+               CEPH_OSD_FLAG_WRITE |
+               CEPH_OSD_FLAG_ACK;
+
+       iov_iter_init(&i, iov, nr_segs, count, 0);
+
+       while ((len = iov_iter_count(&i)) > 0) {
+               size_t left;
+               int n;
+
+               snapc = ci->i_snap_realm->cached_context;
+               vino = ceph_vino(inode);
+               req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
+                                           vino, pos, &len, 1,
+                                           CEPH_OSD_OP_WRITE, flags, snapc,
+                                           ci->i_truncate_seq,
+                                           ci->i_truncate_size,
+                                           false);
+               if (IS_ERR(req)) {
+                       ret = PTR_ERR(req);
+                       goto out;
+               }
+
+               /*
+                * write from beginning of first page,
+                * regardless of io alignment
+                */
+               num_pages = (len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+
                pages = ceph_alloc_page_vector(num_pages, GFP_NOFS);
                if (IS_ERR(pages)) {
                        ret = PTR_ERR(pages);
                        goto out;
                }
-               ret = ceph_copy_user_to_page_vector(pages, data, pos, len);
+
+               left = len;
+               for (n = 0; n < num_pages; n++) {
+                       size_t plen = min(left, PAGE_SIZE);
+                       ret = iov_iter_copy_from_user(pages[n], &i, 0, plen);
+                       if (ret != plen) {
+                               ret = -EFAULT;
+                               break;
+                       }
+                       left -= ret;
+                       iov_iter_advance(&i, ret);
+               }
+
                if (ret < 0) {
                        ceph_release_page_vector(pages, num_pages);
                        goto out;
                }
 
-               if ((file->f_flags & O_SYNC) == 0) {
-                       /* get a second commit callback */
-                       req->r_unsafe_callback = ceph_sync_write_unsafe;
-                       req->r_inode = inode;
-                       own_pages = true;
-               }
-       }
-       osd_req_op_extent_osd_data_pages(req, 0, pages, len, page_align,
-                                       false, own_pages);
+               /* get a second commit callback */
+               req->r_unsafe_callback = ceph_sync_write_unsafe;
+               req->r_inode = inode;
 
-       /* BUG_ON(vino.snap != CEPH_NOSNAP); */
-       ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime);
+               osd_req_op_extent_osd_data_pages(req, 0, pages, len, 0,
+                                               false, true);
 
-       ret = ceph_osdc_start_request(&fsc->client->osdc, req, false);
-       if (!ret)
-               ret = ceph_osdc_wait_request(&fsc->client->osdc, req);
+               /* BUG_ON(vino.snap != CEPH_NOSNAP); */
+               ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime);
 
-       if (file->f_flags & O_DIRECT)
-               ceph_put_page_vector(pages, num_pages, false);
-       else if (file->f_flags & O_SYNC)
-               ceph_release_page_vector(pages, num_pages);
+               ret = ceph_osdc_start_request(&fsc->client->osdc, req, false);
+               if (!ret)
+                       ret = ceph_osdc_wait_request(&fsc->client->osdc, req);
 
 out:
-       ceph_osdc_put_request(req);
-       if (ret == 0) {
-               pos += len;
-               written += len;
-               left -= len;
-               data += len;
-               if (left)
-                       goto more;
+               ceph_osdc_put_request(req);
+               if (ret == 0) {
+                       pos += len;
+                       written += len;
+
+                       if (pos > i_size_read(inode)) {
+                               check_caps = ceph_inode_set_size(inode, pos);
+                               if (check_caps)
+                                       ceph_check_caps(ceph_inode(inode),
+                                                       CHECK_CAPS_AUTHONLY,
+                                                       NULL);
+                       }
+               } else
+                       break;
+       }
 
+       if (ret != -EOLDSNAPC && written > 0) {
                ret = written;
-               *ppos = pos;
-               if (pos > i_size_read(inode))
-                       check_caps = ceph_inode_set_size(inode, pos);
-               if (check_caps)
-                       ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY,
-                                       NULL);
-       } else if (ret != -EOLDSNAPC && written > 0) {
-               ret = written;
+               iocb->ki_pos = pos;
        }
        return ret;
 }
@@ -647,55 +799,84 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
 {
        struct file *filp = iocb->ki_filp;
        struct ceph_file_info *fi = filp->private_data;
-       loff_t *ppos = &iocb->ki_pos;
-       size_t len = iov->iov_len;
+       size_t len = iocb->ki_nbytes;
        struct inode *inode = file_inode(filp);
        struct ceph_inode_info *ci = ceph_inode(inode);
-       void __user *base = iov->iov_base;
        ssize_t ret;
        int want, got = 0;
        int checkeof = 0, read = 0;
 
-       dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n",
-            inode, ceph_vinop(inode), pos, (unsigned)len, inode);
 again:
+       dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n",
+            inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len, inode);
+
        if (fi->fmode & CEPH_FILE_MODE_LAZY)
                want = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO;
        else
                want = CEPH_CAP_FILE_CACHE;
        ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, &got, -1);
        if (ret < 0)
-               goto out;
-       dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n",
-            inode, ceph_vinop(inode), pos, (unsigned)len,
-            ceph_cap_string(got));
+               return ret;
 
        if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 ||
            (iocb->ki_filp->f_flags & O_DIRECT) ||
-           (fi->flags & CEPH_F_SYNC))
+           (fi->flags & CEPH_F_SYNC)) {
+               struct iov_iter i;
+
+               dout("aio_sync_read %p %llx.%llx %llu~%u got cap refs on %s\n",
+                    inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len,
+                    ceph_cap_string(got));
+
+               if (!read) {
+                       ret = generic_segment_checks(iov, &nr_segs,
+                                                       &len, VERIFY_WRITE);
+                       if (ret)
+                               goto out;
+               }
+
+               iov_iter_init(&i, iov, nr_segs, len, read);
+
                /* hmm, this isn't really async... */
-               ret = ceph_sync_read(filp, base, len, ppos, &checkeof);
-       else
-               ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
+               ret = ceph_sync_read(iocb, &i, &checkeof);
+       } else {
+               /*
+                * We can't modify the content of iov,
+                * so we only read from beginning.
+                */
+               if (read) {
+                       iocb->ki_pos = pos;
+                       len = iocb->ki_nbytes;
+                       read = 0;
+               }
+               dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n",
+                    inode, ceph_vinop(inode), pos, (unsigned)len,
+                    ceph_cap_string(got));
 
+               ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
+       }
 out:
        dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n",
             inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret);
        ceph_put_cap_refs(ci, got);
 
        if (checkeof && ret >= 0) {
-               int statret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE);
+               int statret = ceph_do_getattr(inode,
+                                             CEPH_STAT_CAP_SIZE);
 
                /* hit EOF or hole? */
-               if (statret == 0 && *ppos < inode->i_size) {
-                       dout("aio_read sync_read hit hole, ppos %lld < size %lld, reading more\n", *ppos, inode->i_size);
+               if (statret == 0 && iocb->ki_pos < inode->i_size &&
+                       ret < len) {
+                       dout("sync_read hit hole, ppos %lld < size %lld"
+                            ", reading more\n", iocb->ki_pos,
+                            inode->i_size);
+
                        read += ret;
-                       base += ret;
                        len -= ret;
                        checkeof = 0;
                        goto again;
                }
        }
+
        if (ret >= 0)
                ret += read;
 
@@ -772,11 +953,13 @@ retry_snap:
             inode, ceph_vinop(inode), pos, count, ceph_cap_string(got));
 
        if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 ||
-           (iocb->ki_filp->f_flags & O_DIRECT) ||
-           (fi->flags & CEPH_F_SYNC)) {
+           (file->f_flags & O_DIRECT) || (fi->flags & CEPH_F_SYNC)) {
                mutex_unlock(&inode->i_mutex);
-               written = ceph_sync_write(file, iov->iov_base, count,
-                                         pos, &iocb->ki_pos);
+               if (file->f_flags & O_DIRECT)
+                       written = ceph_sync_direct_write(iocb, iov,
+                                                        nr_segs, count);
+               else
+                       written = ceph_sync_write(iocb, iov, nr_segs, count);
                if (written == -EOLDSNAPC) {
                        dout("aio_write %p %llx.%llx %llu~%u"
                                "got EOLDSNAPC, retrying\n",
index 8549a48115f71b23e1f35ef444caf3eb32dbced3..2ae1381de64a102c89d3fbe9b92dee3893fbbe7a 100644 (file)
@@ -436,6 +436,16 @@ void ceph_destroy_inode(struct inode *inode)
        call_rcu(&inode->i_rcu, ceph_i_callback);
 }
 
+int ceph_drop_inode(struct inode *inode)
+{
+       /*
+        * Positve dentry and corresponding inode are always accompanied
+        * in MDS reply. So no need to keep inode in the cache after
+        * dropping all its aliases.
+        */
+       return 1;
+}
+
 /*
  * Helpers to fill in size, ctime, mtime, and atime.  We have to be
  * careful because either the client or MDS may have more up to date
@@ -577,6 +587,8 @@ static int fill_inode(struct inode *inode,
        int issued = 0, implemented;
        struct timespec mtime, atime, ctime;
        u32 nsplits;
+       struct ceph_inode_frag *frag;
+       struct rb_node *rb_node;
        struct ceph_buffer *xattr_blob = NULL;
        int err = 0;
        int queue_trunc = 0;
@@ -751,15 +763,38 @@ no_change:
        /* FIXME: move me up, if/when version reflects fragtree changes */
        nsplits = le32_to_cpu(info->fragtree.nsplits);
        mutex_lock(&ci->i_fragtree_mutex);
+       rb_node = rb_first(&ci->i_fragtree);
        for (i = 0; i < nsplits; i++) {
                u32 id = le32_to_cpu(info->fragtree.splits[i].frag);
-               struct ceph_inode_frag *frag = __get_or_create_frag(ci, id);
-
-               if (IS_ERR(frag))
-                       continue;
+               frag = NULL;
+               while (rb_node) {
+                       frag = rb_entry(rb_node, struct ceph_inode_frag, node);
+                       if (ceph_frag_compare(frag->frag, id) >= 0) {
+                               if (frag->frag != id)
+                                       frag = NULL;
+                               else
+                                       rb_node = rb_next(rb_node);
+                               break;
+                       }
+                       rb_node = rb_next(rb_node);
+                       rb_erase(&frag->node, &ci->i_fragtree);
+                       kfree(frag);
+                       frag = NULL;
+               }
+               if (!frag) {
+                       frag = __get_or_create_frag(ci, id);
+                       if (IS_ERR(frag))
+                               continue;
+               }
                frag->split_by = le32_to_cpu(info->fragtree.splits[i].by);
                dout(" frag %x split by %d\n", frag->frag, frag->split_by);
        }
+       while (rb_node) {
+               frag = rb_entry(rb_node, struct ceph_inode_frag, node);
+               rb_node = rb_next(rb_node);
+               rb_erase(&frag->node, &ci->i_fragtree);
+               kfree(frag);
+       }
        mutex_unlock(&ci->i_fragtree_mutex);
 
        /* were we issued a capability? */
@@ -1250,8 +1285,20 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
        int err = 0, i;
        struct inode *snapdir = NULL;
        struct ceph_mds_request_head *rhead = req->r_request->front.iov_base;
-       u64 frag = le32_to_cpu(rhead->args.readdir.frag);
        struct ceph_dentry_info *di;
+       u64 r_readdir_offset = req->r_readdir_offset;
+       u32 frag = le32_to_cpu(rhead->args.readdir.frag);
+
+       if (rinfo->dir_dir &&
+           le32_to_cpu(rinfo->dir_dir->frag) != frag) {
+               dout("readdir_prepopulate got new frag %x -> %x\n",
+                    frag, le32_to_cpu(rinfo->dir_dir->frag));
+               frag = le32_to_cpu(rinfo->dir_dir->frag);
+               if (ceph_frag_is_leftmost(frag))
+                       r_readdir_offset = 2;
+               else
+                       r_readdir_offset = 0;
+       }
 
        if (req->r_aborted)
                return readdir_prepopulate_inodes_only(req, session);
@@ -1315,7 +1362,7 @@ retry_lookup:
                }
 
                di = dn->d_fsdata;
-               di->offset = ceph_make_fpos(frag, i + req->r_readdir_offset);
+               di->offset = ceph_make_fpos(frag, i + r_readdir_offset);
 
                /* inode */
                if (dn->d_inode) {
index b7bda5d9611da031aaf6f104ece9fa6351993070..d90861f452107cc47b7242e8ea66dc1257f7c235 100644 (file)
@@ -43,6 +43,7 @@
  */
 
 struct ceph_reconnect_state {
+       int nr_caps;
        struct ceph_pagelist *pagelist;
        bool flock;
 };
@@ -443,6 +444,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
        INIT_LIST_HEAD(&s->s_waiting);
        INIT_LIST_HEAD(&s->s_unsafe);
        s->s_num_cap_releases = 0;
+       s->s_cap_reconnect = 0;
        s->s_cap_iterator = NULL;
        INIT_LIST_HEAD(&s->s_cap_releases);
        INIT_LIST_HEAD(&s->s_cap_releases_done);
@@ -642,6 +644,8 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
                req->r_unsafe_dir = NULL;
        }
 
+       complete_all(&req->r_safe_completion);
+
        ceph_mdsc_put_request(req);
 }
 
@@ -986,7 +990,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
        dout("removing cap %p, ci is %p, inode is %p\n",
             cap, ci, &ci->vfs_inode);
        spin_lock(&ci->i_ceph_lock);
-       __ceph_remove_cap(cap);
+       __ceph_remove_cap(cap, false);
        if (!__ceph_is_any_real_caps(ci)) {
                struct ceph_mds_client *mdsc =
                        ceph_sb_to_client(inode->i_sb)->mdsc;
@@ -1231,9 +1235,7 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
        session->s_trim_caps--;
        if (oissued) {
                /* we aren't the only cap.. just remove us */
-               __queue_cap_release(session, ceph_ino(inode), cap->cap_id,
-                                   cap->mseq, cap->issue_seq);
-               __ceph_remove_cap(cap);
+               __ceph_remove_cap(cap, true);
        } else {
                /* try to drop referring dentries */
                spin_unlock(&ci->i_ceph_lock);
@@ -1416,7 +1418,6 @@ static void discard_cap_releases(struct ceph_mds_client *mdsc,
        unsigned num;
 
        dout("discard_cap_releases mds%d\n", session->s_mds);
-       spin_lock(&session->s_cap_lock);
 
        /* zero out the in-progress message */
        msg = list_first_entry(&session->s_cap_releases,
@@ -1443,8 +1444,6 @@ static void discard_cap_releases(struct ceph_mds_client *mdsc,
                msg->front.iov_len = sizeof(*head);
                list_add(&msg->list_head, &session->s_cap_releases);
        }
-
-       spin_unlock(&session->s_cap_lock);
 }
 
 /*
@@ -1875,8 +1874,11 @@ static int __do_request(struct ceph_mds_client *mdsc,
        int mds = -1;
        int err = -EAGAIN;
 
-       if (req->r_err || req->r_got_result)
+       if (req->r_err || req->r_got_result) {
+               if (req->r_aborted)
+                       __unregister_request(mdsc, req);
                goto out;
+       }
 
        if (req->r_timeout &&
            time_after_eq(jiffies, req->r_started + req->r_timeout)) {
@@ -2186,7 +2188,6 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
        if (head->safe) {
                req->r_got_safe = true;
                __unregister_request(mdsc, req);
-               complete_all(&req->r_safe_completion);
 
                if (req->r_got_unsafe) {
                        /*
@@ -2238,8 +2239,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
        err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session);
        if (err == 0) {
                if (result == 0 && (req->r_op == CEPH_MDS_OP_READDIR ||
-                                   req->r_op == CEPH_MDS_OP_LSSNAP) &&
-                   rinfo->dir_nr)
+                                   req->r_op == CEPH_MDS_OP_LSSNAP))
                        ceph_readdir_prepopulate(req, req->r_session);
                ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
        }
@@ -2490,6 +2490,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
        cap->seq = 0;        /* reset cap seq */
        cap->issue_seq = 0;  /* and issue_seq */
        cap->mseq = 0;       /* and migrate_seq */
+       cap->cap_gen = cap->session->s_cap_gen;
 
        if (recon_state->flock) {
                rec.v2.cap_id = cpu_to_le64(cap->cap_id);
@@ -2552,6 +2553,8 @@ encode_again:
        } else {
                err = ceph_pagelist_append(pagelist, &rec, reclen);
        }
+
+       recon_state->nr_caps++;
 out_free:
        kfree(path);
 out_dput:
@@ -2579,6 +2582,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
        struct rb_node *p;
        int mds = session->s_mds;
        int err = -ENOMEM;
+       int s_nr_caps;
        struct ceph_pagelist *pagelist;
        struct ceph_reconnect_state recon_state;
 
@@ -2610,20 +2614,38 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
        dout("session %p state %s\n", session,
             session_state_name(session->s_state));
 
+       spin_lock(&session->s_gen_ttl_lock);
+       session->s_cap_gen++;
+       spin_unlock(&session->s_gen_ttl_lock);
+
+       spin_lock(&session->s_cap_lock);
+       /*
+        * notify __ceph_remove_cap() that we are composing cap reconnect.
+        * If a cap get released before being added to the cap reconnect,
+        * __ceph_remove_cap() should skip queuing cap release.
+        */
+       session->s_cap_reconnect = 1;
        /* drop old cap expires; we're about to reestablish that state */
        discard_cap_releases(mdsc, session);
+       spin_unlock(&session->s_cap_lock);
 
        /* traverse this session's caps */
-       err = ceph_pagelist_encode_32(pagelist, session->s_nr_caps);
+       s_nr_caps = session->s_nr_caps;
+       err = ceph_pagelist_encode_32(pagelist, s_nr_caps);
        if (err)
                goto fail;
 
+       recon_state.nr_caps = 0;
        recon_state.pagelist = pagelist;
        recon_state.flock = session->s_con.peer_features & CEPH_FEATURE_FLOCK;
        err = iterate_session_caps(session, encode_caps_cb, &recon_state);
        if (err < 0)
                goto fail;
 
+       spin_lock(&session->s_cap_lock);
+       session->s_cap_reconnect = 0;
+       spin_unlock(&session->s_cap_lock);
+
        /*
         * snaprealms.  we provide mds with the ino, seq (version), and
         * parent for all of our realms.  If the mds has any newer info,
@@ -2646,11 +2668,18 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
 
        if (recon_state.flock)
                reply->hdr.version = cpu_to_le16(2);
-       if (pagelist->length) {
-               /* set up outbound data if we have any */
-               reply->hdr.data_len = cpu_to_le32(pagelist->length);
-               ceph_msg_data_add_pagelist(reply, pagelist);
+
+       /* raced with cap release? */
+       if (s_nr_caps != recon_state.nr_caps) {
+               struct page *page = list_first_entry(&pagelist->head,
+                                                    struct page, lru);
+               __le32 *addr = kmap_atomic(page);
+               *addr = cpu_to_le32(recon_state.nr_caps);
+               kunmap_atomic(addr);
        }
+
+       reply->hdr.data_len = cpu_to_le32(pagelist->length);
+       ceph_msg_data_add_pagelist(reply, pagelist);
        ceph_con_send(&session->s_con, reply);
 
        mutex_unlock(&session->s_mutex);
index c2a19fbbe5177b619b7a3d7e6132b626df8c8508..4c053d099ae4e60400dbcbdcce21844138ba8a47 100644 (file)
@@ -132,6 +132,7 @@ struct ceph_mds_session {
        struct list_head  s_caps;     /* all caps issued by this session */
        int               s_nr_caps, s_trim_caps;
        int               s_num_cap_releases;
+       int               s_cap_reconnect;
        struct list_head  s_cap_releases; /* waiting cap_release messages */
        struct list_head  s_cap_releases_done; /* ready to send */
        struct ceph_cap  *s_cap_iterator;
index 6a0951e4304441a241ca8fe550aba36cc097c271..e58bd4a23bfb532bd2c119345bb4669be1d9336b 100644 (file)
@@ -686,6 +686,7 @@ static const struct super_operations ceph_super_ops = {
        .alloc_inode    = ceph_alloc_inode,
        .destroy_inode  = ceph_destroy_inode,
        .write_inode    = ceph_write_inode,
+       .drop_inode     = ceph_drop_inode,
        .sync_fs        = ceph_sync_fs,
        .put_super      = ceph_put_super,
        .show_options   = ceph_show_options,
index 6014b0a3c405cb12dfb62fdac7887f83a4977b96..8de94b564d670d28a033d6ccfc309a37f799ab57 100644 (file)
@@ -691,6 +691,7 @@ extern const struct inode_operations ceph_file_iops;
 
 extern struct inode *ceph_alloc_inode(struct super_block *sb);
 extern void ceph_destroy_inode(struct inode *inode);
+extern int ceph_drop_inode(struct inode *inode);
 
 extern struct inode *ceph_get_inode(struct super_block *sb,
                                    struct ceph_vino vino);
@@ -741,13 +742,7 @@ extern int ceph_add_cap(struct inode *inode,
                        int fmode, unsigned issued, unsigned wanted,
                        unsigned cap, unsigned seq, u64 realmino, int flags,
                        struct ceph_cap_reservation *caps_reservation);
-extern void __ceph_remove_cap(struct ceph_cap *cap);
-static inline void ceph_remove_cap(struct ceph_cap *cap)
-{
-       spin_lock(&cap->ci->i_ceph_lock);
-       __ceph_remove_cap(cap);
-       spin_unlock(&cap->ci->i_ceph_lock);
-}
+extern void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release);
 extern void ceph_put_cap(struct ceph_mds_client *mdsc,
                         struct ceph_cap *cap);
 
index 0227b45ef00a372e4c201519710a123f63d44f35..226ed8220cb61303186bc42f343b2c882a1a941f 100644 (file)
@@ -350,6 +350,8 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
        }
 
 ctoUTF16_out:
+       /* Null terminate the string */
+       put_unaligned(0, &target[j]);
        return j;
 }
 
index d9ea7ada1378f95e48b08e286e38e2d080893993..f918a998a08758caac54bf8205cd7da7705c1efc 100644 (file)
@@ -384,6 +384,7 @@ struct smb_version_operations {
        int (*clone_range)(const unsigned int, struct cifsFileInfo *src_file,
                        struct cifsFileInfo *target_file, u64 src_off, u64 len,
                        u64 dest_off);
+       int (*validate_negotiate)(const unsigned int, struct cifs_tcon *);
 };
 
 struct smb_version_values {
index 409b45eefe7086899ae4da636b96cd8c07794dd5..77492301cc2b16c0f82ecea64de7bfb02fe31db5 100644 (file)
 #include <linux/mount.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
-#include <linux/btrfs.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsproto.h"
 #include "cifs_debug.h"
 #include "cifsfs.h"
 
+#define CIFS_IOCTL_MAGIC       0xCF
+#define CIFS_IOC_COPYCHUNK_FILE        _IOW(CIFS_IOCTL_MAGIC, 3, int)
+
 static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
                        unsigned long srcfd, u64 off, u64 len, u64 destoff)
 {
@@ -213,7 +215,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
                                cifs_dbg(FYI, "set compress flag rc %d\n", rc);
                        }
                        break;
-               case BTRFS_IOC_CLONE:
+               case CIFS_IOC_COPYCHUNK_FILE:
                        rc = cifs_ioctl_clone(xid, filep, arg, 0, 0, 0);
                        break;
                default:
index 11dde4b24f8aa1dce05354cef65fa93feb82735f..757da3e54d3dce601b71b97883f3430556040107 100644 (file)
@@ -532,7 +532,10 @@ smb2_clone_range(const unsigned int xid,
        int rc;
        unsigned int ret_data_len;
        struct copychunk_ioctl *pcchunk;
-       char *retbuf = NULL;
+       struct copychunk_ioctl_rsp *retbuf = NULL;
+       struct cifs_tcon *tcon;
+       int chunks_copied = 0;
+       bool chunk_sizes_updated = false;
 
        pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);
 
@@ -547,27 +550,96 @@ smb2_clone_range(const unsigned int xid,
 
        /* Note: request_res_key sets res_key null only if rc !=0 */
        if (rc)
-               return rc;
+               goto cchunk_out;
 
        /* For now array only one chunk long, will make more flexible later */
        pcchunk->ChunkCount = __constant_cpu_to_le32(1);
        pcchunk->Reserved = 0;
-       pcchunk->SourceOffset = cpu_to_le64(src_off);
-       pcchunk->TargetOffset = cpu_to_le64(dest_off);
-       pcchunk->Length = cpu_to_le32(len);
        pcchunk->Reserved2 = 0;
 
-       /* Request that server copy to target from src file identified by key */
-       rc = SMB2_ioctl(xid, tlink_tcon(trgtfile->tlink),
-                       trgtfile->fid.persistent_fid,
-                       trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE,
-                       true /* is_fsctl */, (char *)pcchunk,
-                       sizeof(struct copychunk_ioctl), &retbuf, &ret_data_len);
+       tcon = tlink_tcon(trgtfile->tlink);
 
-       /* BB need to special case rc = EINVAL to alter chunk size */
+       while (len > 0) {
+               pcchunk->SourceOffset = cpu_to_le64(src_off);
+               pcchunk->TargetOffset = cpu_to_le64(dest_off);
+               pcchunk->Length =
+                       cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk));
 
-       cifs_dbg(FYI, "rc %d data length out %d\n", rc, ret_data_len);
+               /* Request server copy to target from src identified by key */
+               rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
+                       trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE,
+                       true /* is_fsctl */, (char *)pcchunk,
+                       sizeof(struct copychunk_ioctl), (char **)&retbuf,
+                       &ret_data_len);
+               if (rc == 0) {
+                       if (ret_data_len !=
+                                       sizeof(struct copychunk_ioctl_rsp)) {
+                               cifs_dbg(VFS, "invalid cchunk response size\n");
+                               rc = -EIO;
+                               goto cchunk_out;
+                       }
+                       if (retbuf->TotalBytesWritten == 0) {
+                               cifs_dbg(FYI, "no bytes copied\n");
+                               rc = -EIO;
+                               goto cchunk_out;
+                       }
+                       /*
+                        * Check if server claimed to write more than we asked
+                        */
+                       if (le32_to_cpu(retbuf->TotalBytesWritten) >
+                           le32_to_cpu(pcchunk->Length)) {
+                               cifs_dbg(VFS, "invalid copy chunk response\n");
+                               rc = -EIO;
+                               goto cchunk_out;
+                       }
+                       if (le32_to_cpu(retbuf->ChunksWritten) != 1) {
+                               cifs_dbg(VFS, "invalid num chunks written\n");
+                               rc = -EIO;
+                               goto cchunk_out;
+                       }
+                       chunks_copied++;
+
+                       src_off += le32_to_cpu(retbuf->TotalBytesWritten);
+                       dest_off += le32_to_cpu(retbuf->TotalBytesWritten);
+                       len -= le32_to_cpu(retbuf->TotalBytesWritten);
+
+                       cifs_dbg(FYI, "Chunks %d PartialChunk %d Total %d\n",
+                               le32_to_cpu(retbuf->ChunksWritten),
+                               le32_to_cpu(retbuf->ChunkBytesWritten),
+                               le32_to_cpu(retbuf->TotalBytesWritten));
+               } else if (rc == -EINVAL) {
+                       if (ret_data_len != sizeof(struct copychunk_ioctl_rsp))
+                               goto cchunk_out;
+
+                       cifs_dbg(FYI, "MaxChunks %d BytesChunk %d MaxCopy %d\n",
+                               le32_to_cpu(retbuf->ChunksWritten),
+                               le32_to_cpu(retbuf->ChunkBytesWritten),
+                               le32_to_cpu(retbuf->TotalBytesWritten));
+
+                       /*
+                        * Check if this is the first request using these sizes,
+                        * (ie check if copy succeed once with original sizes
+                        * and check if the server gave us different sizes after
+                        * we already updated max sizes on previous request).
+                        * if not then why is the server returning an error now
+                        */
+                       if ((chunks_copied != 0) || chunk_sizes_updated)
+                               goto cchunk_out;
+
+                       /* Check that server is not asking us to grow size */
+                       if (le32_to_cpu(retbuf->ChunkBytesWritten) <
+                                       tcon->max_bytes_chunk)
+                               tcon->max_bytes_chunk =
+                                       le32_to_cpu(retbuf->ChunkBytesWritten);
+                       else
+                               goto cchunk_out; /* server gave us bogus size */
+
+                       /* No need to change MaxChunks since already set to 1 */
+                       chunk_sizes_updated = true;
+               }
+       }
 
+cchunk_out:
        kfree(pcchunk);
        return rc;
 }
@@ -1247,6 +1319,7 @@ struct smb_version_operations smb30_operations = {
        .create_lease_buf = smb3_create_lease_buf,
        .parse_lease_buf = smb3_parse_lease_buf,
        .clone_range = smb2_clone_range,
+       .validate_negotiate = smb3_validate_negotiate,
 };
 
 struct smb_version_values smb20_values = {
index d65270c290a1b488157e14b316b7de59fe9bac54..2013234b73adc47a5a34cb907ce0b818f65a16f5 100644 (file)
@@ -454,6 +454,81 @@ neg_exit:
        return rc;
 }
 
+int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
+{
+       int rc = 0;
+       struct validate_negotiate_info_req vneg_inbuf;
+       struct validate_negotiate_info_rsp *pneg_rsp;
+       u32 rsplen;
+
+       cifs_dbg(FYI, "validate negotiate\n");
+
+       /*
+        * validation ioctl must be signed, so no point sending this if we
+        * can not sign it.  We could eventually change this to selectively
+        * sign just this, the first and only signed request on a connection.
+        * This is good enough for now since a user who wants better security
+        * would also enable signing on the mount. Having validation of
+        * negotiate info for signed connections helps reduce attack vectors
+        */
+       if (tcon->ses->server->sign == false)
+               return 0; /* validation requires signing */
+
+       vneg_inbuf.Capabilities =
+                       cpu_to_le32(tcon->ses->server->vals->req_capabilities);
+       memcpy(vneg_inbuf.Guid, cifs_client_guid, SMB2_CLIENT_GUID_SIZE);
+
+       if (tcon->ses->sign)
+               vneg_inbuf.SecurityMode =
+                       cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED);
+       else if (global_secflags & CIFSSEC_MAY_SIGN)
+               vneg_inbuf.SecurityMode =
+                       cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED);
+       else
+               vneg_inbuf.SecurityMode = 0;
+
+       vneg_inbuf.DialectCount = cpu_to_le16(1);
+       vneg_inbuf.Dialects[0] =
+               cpu_to_le16(tcon->ses->server->vals->protocol_id);
+
+       rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
+               FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */,
+               (char *)&vneg_inbuf, sizeof(struct validate_negotiate_info_req),
+               (char **)&pneg_rsp, &rsplen);
+
+       if (rc != 0) {
+               cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc);
+               return -EIO;
+       }
+
+       if (rsplen != sizeof(struct validate_negotiate_info_rsp)) {
+               cifs_dbg(VFS, "invalid size of protocol negotiate response\n");
+               return -EIO;
+       }
+
+       /* check validate negotiate info response matches what we got earlier */
+       if (pneg_rsp->Dialect !=
+                       cpu_to_le16(tcon->ses->server->vals->protocol_id))
+               goto vneg_out;
+
+       if (pneg_rsp->SecurityMode != cpu_to_le16(tcon->ses->server->sec_mode))
+               goto vneg_out;
+
+       /* do not validate server guid because not saved at negprot time yet */
+
+       if ((le32_to_cpu(pneg_rsp->Capabilities) | SMB2_NT_FIND |
+             SMB2_LARGE_FILES) != tcon->ses->server->capabilities)
+               goto vneg_out;
+
+       /* validate negotiate successful */
+       cifs_dbg(FYI, "validate negotiate info successful\n");
+       return 0;
+
+vneg_out:
+       cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n");
+       return -EIO;
+}
+
 int
 SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
                const struct nls_table *nls_cp)
@@ -829,6 +904,8 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
            ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
                cifs_dbg(VFS, "DFS capability contradicts DFS flag\n");
        init_copy_chunk_defaults(tcon);
+       if (tcon->ses->server->ops->validate_negotiate)
+               rc = tcon->ses->server->ops->validate_negotiate(xid, tcon);
 tcon_exit:
        free_rsp_buf(resp_buftype, rsp);
        kfree(unc_path);
@@ -1214,10 +1291,17 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
        rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
        rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
 
-       if (rc != 0) {
+       if ((rc != 0) && (rc != -EINVAL)) {
                if (tcon)
                        cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
                goto ioctl_exit;
+       } else if (rc == -EINVAL) {
+               if ((opcode != FSCTL_SRV_COPYCHUNK_WRITE) &&
+                   (opcode != FSCTL_SRV_COPYCHUNK)) {
+                       if (tcon)
+                               cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
+                       goto ioctl_exit;
+               }
        }
 
        /* check if caller wants to look at return data or just return rc */
@@ -2154,11 +2238,9 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
        rc = SendReceive2(xid, ses, iov, num, &resp_buftype, 0);
        rsp = (struct smb2_set_info_rsp *)iov[0].iov_base;
 
-       if (rc != 0) {
+       if (rc != 0)
                cifs_stats_fail_inc(tcon, SMB2_SET_INFO_HE);
-               goto out;
-       }
-out:
+
        free_rsp_buf(resp_buftype, rsp);
        kfree(iov);
        return rc;
index f88320bbb47772923fe81f89b1a2352d783b89c0..2022c542ea3aa65ddf15cf511ee652d3040b73a2 100644 (file)
@@ -577,13 +577,19 @@ struct copychunk_ioctl_rsp {
        __le32 TotalBytesWritten;
 } __packed;
 
-/* Response and Request are the same format */
-struct validate_negotiate_info {
+struct validate_negotiate_info_req {
        __le32 Capabilities;
        __u8   Guid[SMB2_CLIENT_GUID_SIZE];
        __le16 SecurityMode;
        __le16 DialectCount;
-       __le16 Dialect[1];
+       __le16 Dialects[1]; /* dialect (someday maybe list) client asked for */
+} __packed;
+
+struct validate_negotiate_info_rsp {
+       __le32 Capabilities;
+       __u8   Guid[SMB2_CLIENT_GUID_SIZE];
+       __le16 SecurityMode;
+       __le16 Dialect; /* Dialect in use for the connection */
 } __packed;
 
 #define RSS_CAPABLE    0x00000001
index b4eea105b08cf96b22444d19181ee500a437787f..93adc64666f310345b4c6d76bba628741aa4e634 100644 (file)
@@ -162,5 +162,6 @@ extern int smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon,
                      struct smb2_lock_element *buf);
 extern int SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
                            __u8 *lease_key, const __le32 lease_state);
+extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *);
 
 #endif                 /* _SMB2PROTO_H */
index a4b2391fe66e4e11cea93e7396b987c335d43823..0e538b5c96221f61f55f9a8bff58d6d88cfc836b 100644 (file)
@@ -90,7 +90,7 @@
 #define FSCTL_LMR_REQUEST_RESILIENCY 0x001401D4 /* BB add struct */
 #define FSCTL_LMR_GET_LINK_TRACK_INF 0x001400E8 /* BB add struct */
 #define FSCTL_LMR_SET_LINK_TRACK_INF 0x001400EC /* BB add struct */
-#define FSCTL_VALIDATE_NEGOTIATE_INFO 0x00140204 /* BB add struct */
+#define FSCTL_VALIDATE_NEGOTIATE_INFO 0x00140204
 /* Perform server-side data movement */
 #define FSCTL_SRV_COPYCHUNK 0x001440F2
 #define FSCTL_SRV_COPYCHUNK_WRITE 0x001480F2
index 0e04142d5962312fcb055738479247b2364a252e..160a5489a93936372c85683ee8cfd6da5185007b 100644 (file)
@@ -375,7 +375,7 @@ dio_bio_alloc(struct dio *dio, struct dio_submit *sdio,
        bio = bio_alloc(GFP_KERNEL, nr_vecs);
 
        bio->bi_bdev = bdev;
-       bio->bi_sector = first_sector;
+       bio->bi_iter.bi_sector = first_sector;
        if (dio->is_async)
                bio->bi_end_io = dio_bio_end_aio;
        else
@@ -719,7 +719,7 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio,
        if (sdio->bio) {
                loff_t cur_offset = sdio->cur_page_fs_offset;
                loff_t bio_next_offset = sdio->logical_offset_in_bio +
-                       sdio->bio->bi_size;
+                       sdio->bio->bi_iter.bi_size;
 
                /*
                 * See whether this new request is contiguous with the old.
index d488f80ee32df1137e91df0aed72bef2f61b49ac..ab95508e3d4018eab92647c6d2308e98524080d1 100644 (file)
@@ -65,9 +65,9 @@ static void ext4_finish_bio(struct bio *bio)
 {
        int i;
        int error = !test_bit(BIO_UPTODATE, &bio->bi_flags);
+       struct bio_vec *bvec;
 
-       for (i = 0; i < bio->bi_vcnt; i++) {
-               struct bio_vec *bvec = &bio->bi_io_vec[i];
+       bio_for_each_segment_all(bvec, bio, i) {
                struct page *page = bvec->bv_page;
                struct buffer_head *bh, *head;
                unsigned bio_start = bvec->bv_offset;
@@ -298,7 +298,7 @@ ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
 static void ext4_end_bio(struct bio *bio, int error)
 {
        ext4_io_end_t *io_end = bio->bi_private;
-       sector_t bi_sector = bio->bi_sector;
+       sector_t bi_sector = bio->bi_iter.bi_sector;
 
        BUG_ON(!io_end);
        bio->bi_end_io = NULL;
@@ -366,7 +366,7 @@ static int io_submit_init_bio(struct ext4_io_submit *io,
        bio = bio_alloc(GFP_NOIO, min(nvecs, BIO_MAX_PAGES));
        if (!bio)
                return -ENOMEM;
-       bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
+       bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9);
        bio->bi_bdev = bh->b_bdev;
        bio->bi_end_io = ext4_end_bio;
        bio->bi_private = ext4_get_io_end(io->io_end);
index 5716e5eb4e8ec7ab2c63c69079259e2c5d772918..38f4a2245085ae5615918c240f39f0b8bd5e5acd 100644 (file)
@@ -61,7 +61,8 @@ repeat:
        if (PageUptodate(page))
                goto out;
 
-       if (f2fs_readpage(sbi, page, index, READ_SYNC))
+       if (f2fs_submit_page_bio(sbi, page, index,
+                               READ_SYNC | REQ_META | REQ_PRIO))
                goto repeat;
 
        lock_page(page);
@@ -157,7 +158,8 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
        }
 
        if (nwritten)
-               f2fs_submit_bio(sbi, type, nr_to_write == LONG_MAX);
+               f2fs_submit_merged_bio(sbi, type, nr_to_write == LONG_MAX,
+                                                               WRITE);
 
        return nwritten;
 }
@@ -190,12 +192,13 @@ int acquire_orphan_inode(struct f2fs_sb_info *sbi)
        int err = 0;
 
        /*
-        * considering 512 blocks in a segment 5 blocks are needed for cp
+        * considering 512 blocks in a segment 8 blocks are needed for cp
         * and log segment summaries. Remaining blocks are used to keep
         * orphan entries with the limitation one reserved segment
-        * for cp pack we can have max 1020*507 orphan entries
+        * for cp pack we can have max 1020*504 orphan entries
         */
-       max_orphans = (sbi->blocks_per_seg - 5) * F2FS_ORPHANS_PER_BLOCK;
+       max_orphans = (sbi->blocks_per_seg - 2 - NR_CURSEG_TYPE)
+                               * F2FS_ORPHANS_PER_BLOCK;
        mutex_lock(&sbi->orphan_inode_mutex);
        if (sbi->n_orphans >= max_orphans)
                err = -ENOSPC;
@@ -270,12 +273,12 @@ static void recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
        iput(inode);
 }
 
-int recover_orphan_inodes(struct f2fs_sb_info *sbi)
+void recover_orphan_inodes(struct f2fs_sb_info *sbi)
 {
        block_t start_blk, orphan_blkaddr, i, j;
 
        if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG))
-               return 0;
+               return;
 
        sbi->por_doing = true;
        start_blk = __start_cp_addr(sbi) + 1;
@@ -295,17 +298,18 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi)
        /* clear Orphan Flag */
        clear_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG);
        sbi->por_doing = false;
-       return 0;
+       return;
 }
 
 static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk)
 {
-       struct list_head *head, *this, *next;
+       struct list_head *head;
        struct f2fs_orphan_block *orphan_blk = NULL;
        struct page *page = NULL;
        unsigned int nentries = 0;
        unsigned short index = 1;
        unsigned short orphan_blocks;
+       struct orphan_inode_entry *orphan = NULL;
 
        orphan_blocks = (unsigned short)((sbi->n_orphans +
                (F2FS_ORPHANS_PER_BLOCK - 1)) / F2FS_ORPHANS_PER_BLOCK);
@@ -314,10 +318,15 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk)
        head = &sbi->orphan_inode_list;
 
        /* loop for each orphan inode entry and write them in Jornal block */
-       list_for_each_safe(this, next, head) {
-               struct orphan_inode_entry *orphan;
+       list_for_each_entry(orphan, head, list) {
+               if (!page) {
+                       page = grab_meta_page(sbi, start_blk);
+                       orphan_blk =
+                               (struct f2fs_orphan_block *)page_address(page);
+                       memset(orphan_blk, 0, sizeof(*orphan_blk));
+               }
 
-               orphan = list_entry(this, struct orphan_inode_entry, list);
+               orphan_blk->ino[nentries++] = cpu_to_le32(orphan->ino);
 
                if (nentries == F2FS_ORPHANS_PER_BLOCK) {
                        /*
@@ -335,24 +344,16 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk)
                        nentries = 0;
                        page = NULL;
                }
-               if (page)
-                       goto page_exist;
+       }
 
-               page = grab_meta_page(sbi, start_blk);
-               orphan_blk = (struct f2fs_orphan_block *)page_address(page);
-               memset(orphan_blk, 0, sizeof(*orphan_blk));
-page_exist:
-               orphan_blk->ino[nentries++] = cpu_to_le32(orphan->ino);
+       if (page) {
+               orphan_blk->blk_addr = cpu_to_le16(index);
+               orphan_blk->blk_count = cpu_to_le16(orphan_blocks);
+               orphan_blk->entry_count = cpu_to_le32(nentries);
+               set_page_dirty(page);
+               f2fs_put_page(page, 1);
        }
-       if (!page)
-               goto end;
-
-       orphan_blk->blk_addr = cpu_to_le16(index);
-       orphan_blk->blk_count = cpu_to_le16(orphan_blocks);
-       orphan_blk->entry_count = cpu_to_le32(nentries);
-       set_page_dirty(page);
-       f2fs_put_page(page, 1);
-end:
+
        mutex_unlock(&sbi->orphan_inode_mutex);
 }
 
@@ -428,7 +429,8 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
        cp1 = validate_checkpoint(sbi, cp_start_blk_no, &cp1_version);
 
        /* The second checkpoint pack should start at the next segment */
-       cp_start_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg);
+       cp_start_blk_no += ((unsigned long long)1) <<
+                               le32_to_cpu(fsb->log_blocks_per_seg);
        cp2 = validate_checkpoint(sbi, cp_start_blk_no, &cp2_version);
 
        if (cp1 && cp2) {
@@ -513,8 +515,8 @@ void add_dirty_dir_inode(struct inode *inode)
 void remove_dirty_dir_inode(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
-       struct list_head *head = &sbi->dir_inode_list;
-       struct list_head *this;
+
+       struct list_head *this, *head;
 
        if (!S_ISDIR(inode->i_mode))
                return;
@@ -525,6 +527,7 @@ void remove_dirty_dir_inode(struct inode *inode)
                return;
        }
 
+       head = &sbi->dir_inode_list;
        list_for_each(this, head) {
                struct dir_inode_entry *entry;
                entry = list_entry(this, struct dir_inode_entry, list);
@@ -546,11 +549,13 @@ void remove_dirty_dir_inode(struct inode *inode)
 
 struct inode *check_dirty_dir_inode(struct f2fs_sb_info *sbi, nid_t ino)
 {
-       struct list_head *head = &sbi->dir_inode_list;
-       struct list_head *this;
+
+       struct list_head *this, *head;
        struct inode *inode = NULL;
 
        spin_lock(&sbi->dir_inode_lock);
+
+       head = &sbi->dir_inode_list;
        list_for_each(this, head) {
                struct dir_inode_entry *entry;
                entry = list_entry(this, struct dir_inode_entry, list);
@@ -565,11 +570,13 @@ struct inode *check_dirty_dir_inode(struct f2fs_sb_info *sbi, nid_t ino)
 
 void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi)
 {
-       struct list_head *head = &sbi->dir_inode_list;
+       struct list_head *head;
        struct dir_inode_entry *entry;
        struct inode *inode;
 retry:
        spin_lock(&sbi->dir_inode_lock);
+
+       head = &sbi->dir_inode_list;
        if (list_empty(head)) {
                spin_unlock(&sbi->dir_inode_lock);
                return;
@@ -585,7 +592,7 @@ retry:
                 * We should submit bio, since it exists several
                 * wribacking dentry pages in the freeing inode.
                 */
-               f2fs_submit_bio(sbi, DATA, true);
+               f2fs_submit_merged_bio(sbi, DATA, true, WRITE);
        }
        goto retry;
 }
@@ -791,9 +798,9 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
 
        trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish block_ops");
 
-       f2fs_submit_bio(sbi, DATA, true);
-       f2fs_submit_bio(sbi, NODE, true);
-       f2fs_submit_bio(sbi, META, true);
+       f2fs_submit_merged_bio(sbi, DATA, true, WRITE);
+       f2fs_submit_merged_bio(sbi, NODE, true, WRITE);
+       f2fs_submit_merged_bio(sbi, META, true, WRITE);
 
        /*
         * update checkpoint pack index
index aa3438c571fa9a2dfaf3e1ab61bd4328f580b0d6..b62a99cf65612cd616ec61ebf93daa7b2a5ec735 100644 (file)
 #include "segment.h"
 #include <trace/events/f2fs.h>
 
+/*
+ * Low-level block read/write IO operations.
+ */
+static struct bio *__bio_alloc(struct block_device *bdev, int npages)
+{
+       struct bio *bio;
+
+       /* No failure on bio allocation */
+       bio = bio_alloc(GFP_NOIO, npages);
+       bio->bi_bdev = bdev;
+       bio->bi_private = NULL;
+       return bio;
+}
+
+static void f2fs_read_end_io(struct bio *bio, int err)
+{
+       struct bio_vec *bvec;
+       int i;
+
+       bio_for_each_segment_all(bvec, bio, i) {
+               struct page *page = bvec->bv_page;
+
+               if (!err) {
+                       SetPageUptodate(page);
+               } else {
+                       ClearPageUptodate(page);
+                       SetPageError(page);
+               }
+               unlock_page(page);
+       }
+
+       bio_put(bio);
+}
+
+static void f2fs_write_end_io(struct bio *bio, int err)
+{
+       struct f2fs_sb_info *sbi = NULL;
+       struct bio_vec *bvec;
+       int i;
+
+       bio_for_each_segment_all(bvec, bio, i) {
+               struct page *page = bvec->bv_page;
+
+               if (!sbi)
+                       sbi = F2FS_SB(bvec->bv_page->mapping->host->i_sb);
+               if (err) {
+                       SetPageError(page);
+                       set_bit(AS_EIO, &page->mapping->flags);
+                       set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
+                       sbi->sb->s_flags |= MS_RDONLY;
+               }
+               end_page_writeback(page);
+               dec_page_count(sbi, F2FS_WRITEBACK);
+       }
+
+       if (bio->bi_private)
+               complete(bio->bi_private);
+
+       if (!get_pages(sbi, F2FS_WRITEBACK) &&
+                       !list_empty(&sbi->cp_wait.task_list))
+               wake_up(&sbi->cp_wait);
+
+       bio_put(bio);
+}
+
+static void __submit_merged_bio(struct f2fs_sb_info *sbi,
+                               struct f2fs_bio_info *io,
+                               enum page_type type, bool sync, int rw)
+{
+       enum page_type btype = PAGE_TYPE_OF_BIO(type);
+
+       if (!io->bio)
+               return;
+
+       if (btype == META)
+               rw |= REQ_META;
+
+       if (is_read_io(rw)) {
+               if (sync)
+                       rw |= READ_SYNC;
+               submit_bio(rw, io->bio);
+               trace_f2fs_submit_read_bio(sbi->sb, rw, type, io->bio);
+               io->bio = NULL;
+               return;
+       }
+
+       if (sync)
+               rw |= WRITE_SYNC;
+       if (type >= META_FLUSH)
+               rw |= WRITE_FLUSH_FUA;
+
+       /*
+        * META_FLUSH is only from the checkpoint procedure, and we should wait
+        * this metadata bio for FS consistency.
+        */
+       if (type == META_FLUSH) {
+               DECLARE_COMPLETION_ONSTACK(wait);
+               io->bio->bi_private = &wait;
+               submit_bio(rw, io->bio);
+               wait_for_completion(&wait);
+       } else {
+               submit_bio(rw, io->bio);
+       }
+       trace_f2fs_submit_write_bio(sbi->sb, rw, btype, io->bio);
+       io->bio = NULL;
+}
+
+void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
+                               enum page_type type, bool sync, int rw)
+{
+       enum page_type btype = PAGE_TYPE_OF_BIO(type);
+       struct f2fs_bio_info *io;
+
+       io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype];
+
+       mutex_lock(&io->io_mutex);
+       __submit_merged_bio(sbi, io, type, sync, rw);
+       mutex_unlock(&io->io_mutex);
+}
+
+/*
+ * Fill the locked page with data located in the block address.
+ * Return unlocked page.
+ */
+int f2fs_submit_page_bio(struct f2fs_sb_info *sbi, struct page *page,
+                                       block_t blk_addr, int rw)
+{
+       struct block_device *bdev = sbi->sb->s_bdev;
+       struct bio *bio;
+
+       trace_f2fs_submit_page_bio(page, blk_addr, rw);
+
+       /* Allocate a new bio */
+       bio = __bio_alloc(bdev, 1);
+
+       /* Initialize the bio */
+       bio->bi_iter.bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr);
+       bio->bi_end_io = is_read_io(rw) ? f2fs_read_end_io : f2fs_write_end_io;
+
+       if (bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) {
+               bio_put(bio);
+               f2fs_put_page(page, 1);
+               return -EFAULT;
+       }
+
+       submit_bio(rw, bio);
+       return 0;
+}
+
+void f2fs_submit_page_mbio(struct f2fs_sb_info *sbi, struct page *page,
+                       block_t blk_addr, enum page_type type, int rw)
+{
+       enum page_type btype = PAGE_TYPE_OF_BIO(type);
+       struct block_device *bdev = sbi->sb->s_bdev;
+       struct f2fs_bio_info *io;
+       int bio_blocks;
+
+       io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype];
+
+       verify_block_addr(sbi, blk_addr);
+
+       mutex_lock(&io->io_mutex);
+
+       if (!is_read_io(rw))
+               inc_page_count(sbi, F2FS_WRITEBACK);
+
+       if (io->bio && io->last_block_in_bio != blk_addr - 1)
+               __submit_merged_bio(sbi, io, type, true, rw);
+alloc_new:
+       if (io->bio == NULL) {
+               bio_blocks = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
+               io->bio = __bio_alloc(bdev, bio_blocks);
+               io->bio->bi_iter.bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr);
+               io->bio->bi_end_io = is_read_io(rw) ? f2fs_read_end_io :
+                                                       f2fs_write_end_io;
+               /*
+                * The end_io will be assigned at the sumbission phase.
+                * Until then, let bio_add_page() merge consecutive IOs as much
+                * as possible.
+                */
+       }
+
+       if (bio_add_page(io->bio, page, PAGE_CACHE_SIZE, 0) <
+                                                       PAGE_CACHE_SIZE) {
+               __submit_merged_bio(sbi, io, type, true, rw);
+               io->bio = NULL;
+               goto alloc_new;
+       }
+
+       io->last_block_in_bio = blk_addr;
+
+       mutex_unlock(&io->io_mutex);
+       trace_f2fs_submit_page_mbio(page, rw, type, blk_addr);
+}
+
 /*
  * Lock ordering for the change of data block address:
  * ->data_page
@@ -64,6 +259,22 @@ int reserve_new_block(struct dnode_of_data *dn)
        return 0;
 }
 
+int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index)
+{
+       bool need_put = dn->inode_page ? false : true;
+       int err;
+
+       err = get_dnode_of_data(dn, index, ALLOC_NODE);
+       if (err)
+               return err;
+       if (dn->data_blkaddr == NULL_ADDR)
+               err = reserve_new_block(dn);
+
+       if (need_put)
+               f2fs_put_dnode(dn);
+       return err;
+}
+
 static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
                                        struct buffer_head *bh_result)
 {
@@ -71,6 +282,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
        pgoff_t start_fofs, end_fofs;
        block_t start_blkaddr;
 
+       if (is_inode_flag_set(fi, FI_NO_EXTENT))
+               return 0;
+
        read_lock(&fi->ext.ext_lock);
        if (fi->ext.len == 0) {
                read_unlock(&fi->ext.ext_lock);
@@ -109,6 +323,7 @@ void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn)
        struct f2fs_inode_info *fi = F2FS_I(dn->inode);
        pgoff_t fofs, start_fofs, end_fofs;
        block_t start_blkaddr, end_blkaddr;
+       int need_update = true;
 
        f2fs_bug_on(blk_addr == NEW_ADDR);
        fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) +
@@ -117,6 +332,9 @@ void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn)
        /* Update the page address in the parent node */
        __set_data_blkaddr(dn, blk_addr);
 
+       if (is_inode_flag_set(fi, FI_NO_EXTENT))
+               return;
+
        write_lock(&fi->ext.ext_lock);
 
        start_fofs = fi->ext.fofs;
@@ -163,14 +381,21 @@ void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn)
                                        fofs - start_fofs + 1;
                        fi->ext.len -= fofs - start_fofs + 1;
                }
-               goto end_update;
+       } else {
+               need_update = false;
        }
-       write_unlock(&fi->ext.ext_lock);
-       return;
 
+       /* Finally, if the extent is very fragmented, let's drop the cache. */
+       if (fi->ext.len < F2FS_MIN_EXTENT_LEN) {
+               fi->ext.len = 0;
+               set_inode_flag(fi, FI_NO_EXTENT);
+               need_update = true;
+       }
 end_update:
        write_unlock(&fi->ext.ext_lock);
-       sync_inode_page(dn);
+       if (need_update)
+               sync_inode_page(dn);
+       return;
 }
 
 struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync)
@@ -208,8 +433,11 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync)
                return page;
        }
 
-       err = f2fs_readpage(sbi, page, dn.data_blkaddr,
+       err = f2fs_submit_page_bio(sbi, page, dn.data_blkaddr,
                                        sync ? READ_SYNC : READA);
+       if (err)
+               return ERR_PTR(err);
+
        if (sync) {
                wait_on_page_locked(page);
                if (!PageUptodate(page)) {
@@ -266,7 +494,7 @@ repeat:
                return page;
        }
 
-       err = f2fs_readpage(sbi, page, dn.data_blkaddr, READ_SYNC);
+       err = f2fs_submit_page_bio(sbi, page, dn.data_blkaddr, READ_SYNC);
        if (err)
                return ERR_PTR(err);
 
@@ -300,19 +528,10 @@ struct page *get_new_data_page(struct inode *inode,
        int err;
 
        set_new_dnode(&dn, inode, npage, npage, 0);
-       err = get_dnode_of_data(&dn, index, ALLOC_NODE);
+       err = f2fs_reserve_block(&dn, index);
        if (err)
                return ERR_PTR(err);
 
-       if (dn.data_blkaddr == NULL_ADDR) {
-               if (reserve_new_block(&dn)) {
-                       if (!npage)
-                               f2fs_put_dnode(&dn);
-                       return ERR_PTR(-ENOSPC);
-               }
-       }
-       if (!npage)
-               f2fs_put_dnode(&dn);
 repeat:
        page = grab_cache_page(mapping, index);
        if (!page)
@@ -325,7 +544,8 @@ repeat:
                zero_user_segment(page, 0, PAGE_CACHE_SIZE);
                SetPageUptodate(page);
        } else {
-               err = f2fs_readpage(sbi, page, dn.data_blkaddr, READ_SYNC);
+               err = f2fs_submit_page_bio(sbi, page, dn.data_blkaddr,
+                                                               READ_SYNC);
                if (err)
                        return ERR_PTR(err);
                lock_page(page);
@@ -349,61 +569,6 @@ repeat:
        return page;
 }
 
-static void read_end_io(struct bio *bio, int err)
-{
-       const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-
-       do {
-               struct page *page = bvec->bv_page;
-
-               if (--bvec >= bio->bi_io_vec)
-                       prefetchw(&bvec->bv_page->flags);
-
-               if (uptodate) {
-                       SetPageUptodate(page);
-               } else {
-                       ClearPageUptodate(page);
-                       SetPageError(page);
-               }
-               unlock_page(page);
-       } while (bvec >= bio->bi_io_vec);
-       bio_put(bio);
-}
-
-/*
- * Fill the locked page with data located in the block address.
- * Return unlocked page.
- */
-int f2fs_readpage(struct f2fs_sb_info *sbi, struct page *page,
-                                       block_t blk_addr, int type)
-{
-       struct block_device *bdev = sbi->sb->s_bdev;
-       struct bio *bio;
-
-       trace_f2fs_readpage(page, blk_addr, type);
-
-       down_read(&sbi->bio_sem);
-
-       /* Allocate a new bio */
-       bio = f2fs_bio_alloc(bdev, 1);
-
-       /* Initialize the bio */
-       bio->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr);
-       bio->bi_end_io = read_end_io;
-
-       if (bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) {
-               bio_put(bio);
-               up_read(&sbi->bio_sem);
-               f2fs_put_page(page, 1);
-               return -EFAULT;
-       }
-
-       submit_bio(type, bio);
-       up_read(&sbi->bio_sem);
-       return 0;
-}
-
 /*
  * This function should be used by the data read flow only where it
  * does not check the "create" flag that indicates block allocation.
@@ -455,7 +620,7 @@ static int get_data_block_ro(struct inode *inode, sector_t iblock,
                                != (dn.data_blkaddr + i)) || maxblocks == i)
                                break;
                map_bh(bh_result, inode->i_sb, dn.data_blkaddr);
-               bh_result->b_size = (i << blkbits);
+               bh_result->b_size = (((size_t)i) << blkbits);
        }
        f2fs_put_dnode(&dn);
        trace_f2fs_get_data_block(inode, iblock, bh_result, 0);
@@ -565,7 +730,7 @@ write:
                goto redirty_out;
 
        if (wbc->for_reclaim)
-               f2fs_submit_bio(sbi, DATA, true);
+               f2fs_submit_merged_bio(sbi, DATA, true, WRITE);
 
        clear_cold_data(page);
 out:
@@ -617,7 +782,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
        ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping);
        if (locked)
                mutex_unlock(&sbi->writepages);
-       f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL));
+       f2fs_submit_merged_bio(sbi, DATA, wbc->sync_mode == WB_SYNC_ALL, WRITE);
 
        remove_dirty_dir_inode(inode);
 
@@ -644,21 +809,15 @@ repeat:
        *pagep = page;
 
        f2fs_lock_op(sbi);
-
        set_new_dnode(&dn, inode, NULL, NULL, 0);
-       err = get_dnode_of_data(&dn, index, ALLOC_NODE);
-       if (err)
-               goto err;
-
-       if (dn.data_blkaddr == NULL_ADDR)
-               err = reserve_new_block(&dn);
-
-       f2fs_put_dnode(&dn);
-       if (err)
-               goto err;
-
+       err = f2fs_reserve_block(&dn, index);
        f2fs_unlock_op(sbi);
 
+       if (err) {
+               f2fs_put_page(page, 1);
+               return err;
+       }
+
        if ((len == PAGE_CACHE_SIZE) || PageUptodate(page))
                return 0;
 
@@ -674,7 +833,8 @@ repeat:
        if (dn.data_blkaddr == NEW_ADDR) {
                zero_user_segment(page, 0, PAGE_CACHE_SIZE);
        } else {
-               err = f2fs_readpage(sbi, page, dn.data_blkaddr, READ_SYNC);
+               err = f2fs_submit_page_bio(sbi, page, dn.data_blkaddr,
+                                                       READ_SYNC);
                if (err)
                        return err;
                lock_page(page);
@@ -691,11 +851,6 @@ out:
        SetPageUptodate(page);
        clear_cold_data(page);
        return 0;
-
-err:
-       f2fs_unlock_op(sbi);
-       f2fs_put_page(page, 1);
-       return err;
 }
 
 static int f2fs_write_end(struct file *file,
@@ -714,8 +869,7 @@ static int f2fs_write_end(struct file *file,
                update_inode_page(inode);
        }
 
-       unlock_page(page);
-       page_cache_release(page);
+       f2fs_put_page(page, 1);
        return copied;
 }
 
index 89dc7508faf2edf173441a9e25cad8a9ff4856aa..66d7c80e65f90199625b165a5bda1a23a5f8a2a3 100644 (file)
 
 #ifdef CONFIG_F2FS_CHECK_FS
 #define f2fs_bug_on(condition) BUG_ON(condition)
+#define f2fs_down_write(x, y)  down_write_nest_lock(x, y)
 #else
 #define f2fs_bug_on(condition)
+#define f2fs_down_write(x, y)  down_write(x)
 #endif
 
 /*
@@ -37,6 +39,7 @@
 #define F2FS_MOUNT_POSIX_ACL           0x00000020
 #define F2FS_MOUNT_DISABLE_EXT_IDENTIFY        0x00000040
 #define F2FS_MOUNT_INLINE_XATTR                0x00000080
+#define F2FS_MOUNT_INLINE_DATA         0x00000100
 
 #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option)
 #define set_opt(sbi, option)   (sbi->mount_opt.opt |= F2FS_MOUNT_##option)
@@ -97,6 +100,13 @@ struct dir_inode_entry {
        struct inode *inode;    /* vfs inode pointer */
 };
 
+/* for the list of blockaddresses to be discarded */
+struct discard_entry {
+       struct list_head list;  /* list head */
+       block_t blkaddr;        /* block address to be discarded */
+       int len;                /* # of consecutive blocks of the discard */
+};
+
 /* for the list of fsync inodes, used only during recovery */
 struct fsync_inode_entry {
        struct list_head list;  /* list head */
@@ -162,6 +172,8 @@ enum {
 #define F2FS_LINK_MAX          32000   /* maximum link count per file */
 
 /* for in-memory extent cache entry */
+#define F2FS_MIN_EXTENT_LEN    16      /* minimum extent length */
+
 struct extent_info {
        rwlock_t ext_lock;      /* rwlock for consistency */
        unsigned int fofs;      /* start offset in a file */
@@ -308,6 +320,11 @@ struct f2fs_sm_info {
 
        /* a threshold to reclaim prefree segments */
        unsigned int rec_prefree_segments;
+
+       /* for small discard management */
+       struct list_head discard_list;          /* 4KB discard list */
+       int nr_discards;                        /* # of discards in the list */
+       int max_discards;                       /* max. discards to be issued */
 };
 
 /*
@@ -338,6 +355,7 @@ enum count_type {
  *                     with waiting the bio's completion
  * ...                 Only can be used with META.
  */
+#define PAGE_TYPE_OF_BIO(type) ((type) > META ? META : (type))
 enum page_type {
        DATA,
        NODE,
@@ -346,6 +364,13 @@ enum page_type {
        META_FLUSH,
 };
 
+#define is_read_io(rw) (((rw) & 1) == READ)
+struct f2fs_bio_info {
+       struct bio *bio;                /* bios to merge */
+       sector_t last_block_in_bio;     /* last block number */
+       struct mutex io_mutex;          /* mutex for bio */
+};
+
 struct f2fs_sb_info {
        struct super_block *sb;                 /* pointer to VFS super block */
        struct proc_dir_entry *s_proc;          /* proc entry */
@@ -359,9 +384,10 @@ struct f2fs_sb_info {
 
        /* for segment-related operations */
        struct f2fs_sm_info *sm_info;           /* segment manager */
-       struct bio *bio[NR_PAGE_TYPE];          /* bios to merge */
-       sector_t last_block_in_bio[NR_PAGE_TYPE];       /* last block number */
-       struct rw_semaphore bio_sem;            /* IO semaphore */
+
+       /* for bio operations */
+       struct f2fs_bio_info read_io;                   /* for read bios */
+       struct f2fs_bio_info write_io[NR_PAGE_TYPE];    /* for write bios */
 
        /* for checkpoint */
        struct f2fs_checkpoint *ckpt;           /* raw checkpoint pointer */
@@ -534,7 +560,7 @@ static inline void f2fs_unlock_op(struct f2fs_sb_info *sbi)
 
 static inline void f2fs_lock_all(struct f2fs_sb_info *sbi)
 {
-       down_write_nest_lock(&sbi->cp_rwsem, &sbi->cp_mutex);
+       f2fs_down_write(&sbi->cp_rwsem, &sbi->cp_mutex);
 }
 
 static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi)
@@ -585,7 +611,7 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
        return true;
 }
 
-static inline int dec_valid_block_count(struct f2fs_sb_info *sbi,
+static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
                                                struct inode *inode,
                                                blkcnt_t count)
 {
@@ -595,7 +621,6 @@ static inline int dec_valid_block_count(struct f2fs_sb_info *sbi,
        inode->i_blocks -= count;
        sbi->total_valid_block_count -= (block_t)count;
        spin_unlock(&sbi->stat_lock);
-       return 0;
 }
 
 static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
@@ -686,50 +711,48 @@ static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi)
 }
 
 static inline bool inc_valid_node_count(struct f2fs_sb_info *sbi,
-                                               struct inode *inode,
-                                               unsigned int count)
+                                               struct inode *inode)
 {
        block_t valid_block_count;
        unsigned int valid_node_count;
 
        spin_lock(&sbi->stat_lock);
 
-       valid_block_count = sbi->total_valid_block_count + (block_t)count;
-       sbi->alloc_valid_block_count += (block_t)count;
-       valid_node_count = sbi->total_valid_node_count + count;
-
+       valid_block_count = sbi->total_valid_block_count + 1;
        if (valid_block_count > sbi->user_block_count) {
                spin_unlock(&sbi->stat_lock);
                return false;
        }
 
+       valid_node_count = sbi->total_valid_node_count + 1;
        if (valid_node_count > sbi->total_node_count) {
                spin_unlock(&sbi->stat_lock);
                return false;
        }
 
        if (inode)
-               inode->i_blocks += count;
-       sbi->total_valid_node_count = valid_node_count;
-       sbi->total_valid_block_count = valid_block_count;
+               inode->i_blocks++;
+
+       sbi->alloc_valid_block_count++;
+       sbi->total_valid_node_count++;
+       sbi->total_valid_block_count++;
        spin_unlock(&sbi->stat_lock);
 
        return true;
 }
 
 static inline void dec_valid_node_count(struct f2fs_sb_info *sbi,
-                                               struct inode *inode,
-                                               unsigned int count)
+                                               struct inode *inode)
 {
        spin_lock(&sbi->stat_lock);
 
-       f2fs_bug_on(sbi->total_valid_block_count < count);
-       f2fs_bug_on(sbi->total_valid_node_count < count);
-       f2fs_bug_on(inode->i_blocks < count);
+       f2fs_bug_on(!sbi->total_valid_block_count);
+       f2fs_bug_on(!sbi->total_valid_node_count);
+       f2fs_bug_on(!inode->i_blocks);
 
-       inode->i_blocks -= count;
-       sbi->total_valid_node_count -= count;
-       sbi->total_valid_block_count -= (block_t)count;
+       inode->i_blocks--;
+       sbi->total_valid_node_count--;
+       sbi->total_valid_block_count--;
 
        spin_unlock(&sbi->stat_lock);
 }
@@ -751,13 +774,12 @@ static inline void inc_valid_inode_count(struct f2fs_sb_info *sbi)
        spin_unlock(&sbi->stat_lock);
 }
 
-static inline int dec_valid_inode_count(struct f2fs_sb_info *sbi)
+static inline void dec_valid_inode_count(struct f2fs_sb_info *sbi)
 {
        spin_lock(&sbi->stat_lock);
        f2fs_bug_on(!sbi->total_valid_inode_count);
        sbi->total_valid_inode_count--;
        spin_unlock(&sbi->stat_lock);
-       return 0;
 }
 
 static inline unsigned int valid_inode_count(struct f2fs_sb_info *sbi)
@@ -771,7 +793,7 @@ static inline unsigned int valid_inode_count(struct f2fs_sb_info *sbi)
 
 static inline void f2fs_put_page(struct page *page, int unlock)
 {
-       if (!page || IS_ERR(page))
+       if (!page)
                return;
 
        if (unlock) {
@@ -876,7 +898,9 @@ enum {
        FI_NO_ALLOC,            /* should not allocate any blocks */
        FI_UPDATE_DIR,          /* should update inode block for consistency */
        FI_DELAY_IPUT,          /* used for the recovery */
+       FI_NO_EXTENT,           /* not to use the extent cache */
        FI_INLINE_XATTR,        /* used for inline xattr */
+       FI_INLINE_DATA,         /* used for inline data*/
 };
 
 static inline void set_inode_flag(struct f2fs_inode_info *fi, int flag)
@@ -914,6 +938,8 @@ static inline void get_inline_info(struct f2fs_inode_info *fi,
 {
        if (ri->i_inline & F2FS_INLINE_XATTR)
                set_inode_flag(fi, FI_INLINE_XATTR);
+       if (ri->i_inline & F2FS_INLINE_DATA)
+               set_inode_flag(fi, FI_INLINE_DATA);
 }
 
 static inline void set_raw_inline(struct f2fs_inode_info *fi,
@@ -923,6 +949,8 @@ static inline void set_raw_inline(struct f2fs_inode_info *fi,
 
        if (is_inode_flag_set(fi, FI_INLINE_XATTR))
                ri->i_inline |= F2FS_INLINE_XATTR;
+       if (is_inode_flag_set(fi, FI_INLINE_DATA))
+               ri->i_inline |= F2FS_INLINE_DATA;
 }
 
 static inline unsigned int addrs_per_inode(struct f2fs_inode_info *fi)
@@ -948,6 +976,13 @@ static inline int inline_xattr_size(struct inode *inode)
                return 0;
 }
 
+static inline void *inline_data_addr(struct page *page)
+{
+       struct f2fs_inode *ri;
+       ri = (struct f2fs_inode *)page_address(page);
+       return (void *)&(ri->i_addr[1]);
+}
+
 static inline int f2fs_readonly(struct super_block *sb)
 {
        return sb->s_flags & MS_RDONLY;
@@ -1027,7 +1062,7 @@ int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int);
 int truncate_inode_blocks(struct inode *, pgoff_t);
 int truncate_xattr_node(struct inode *, struct page *);
 int wait_on_node_pages_writeback(struct f2fs_sb_info *, nid_t);
-int remove_inode_page(struct inode *);
+void remove_inode_page(struct inode *);
 struct page *new_inode_page(struct inode *, const struct qstr *);
 struct page *new_node_page(struct dnode_of_data *, unsigned int, struct page *);
 void ra_node_page(struct f2fs_sb_info *, nid_t);
@@ -1059,9 +1094,6 @@ void clear_prefree_segments(struct f2fs_sb_info *);
 int npages_for_summary_flush(struct f2fs_sb_info *);
 void allocate_new_segments(struct f2fs_sb_info *);
 struct page *get_sum_page(struct f2fs_sb_info *, unsigned int);
-struct bio *f2fs_bio_alloc(struct block_device *, int);
-void f2fs_submit_bio(struct f2fs_sb_info *, enum page_type, bool);
-void f2fs_wait_on_page_writeback(struct page *, enum page_type, bool);
 void write_meta_page(struct f2fs_sb_info *, struct page *);
 void write_node_page(struct f2fs_sb_info *, struct page *, unsigned int,
                                        block_t, block_t *);
@@ -1072,6 +1104,7 @@ void recover_data_page(struct f2fs_sb_info *, struct page *,
                                struct f2fs_summary *, block_t, block_t);
 void rewrite_node_page(struct f2fs_sb_info *, struct page *,
                                struct f2fs_summary *, block_t, block_t);
+void f2fs_wait_on_page_writeback(struct page *, enum page_type, bool);
 void write_data_summaries(struct f2fs_sb_info *, block_t);
 void write_node_summaries(struct f2fs_sb_info *, block_t);
 int lookup_journal_in_cursum(struct f2fs_summary_block *,
@@ -1079,6 +1112,8 @@ int lookup_journal_in_cursum(struct f2fs_summary_block *,
 void flush_sit_entries(struct f2fs_sb_info *);
 int build_segment_manager(struct f2fs_sb_info *);
 void destroy_segment_manager(struct f2fs_sb_info *);
+int __init create_segment_manager_caches(void);
+void destroy_segment_manager_caches(void);
 
 /*
  * checkpoint.c
@@ -1090,7 +1125,7 @@ int acquire_orphan_inode(struct f2fs_sb_info *);
 void release_orphan_inode(struct f2fs_sb_info *);
 void add_orphan_inode(struct f2fs_sb_info *, nid_t);
 void remove_orphan_inode(struct f2fs_sb_info *, nid_t);
-int recover_orphan_inodes(struct f2fs_sb_info *);
+void recover_orphan_inodes(struct f2fs_sb_info *);
 int get_valid_checkpoint(struct f2fs_sb_info *);
 void set_dirty_dir_page(struct inode *, struct page *);
 void add_dirty_dir_inode(struct inode *);
@@ -1105,12 +1140,17 @@ void destroy_checkpoint_caches(void);
 /*
  * data.c
  */
+void f2fs_submit_merged_bio(struct f2fs_sb_info *, enum page_type, bool, int);
+int f2fs_submit_page_bio(struct f2fs_sb_info *, struct page *, block_t, int);
+void f2fs_submit_page_mbio(struct f2fs_sb_info *, struct page *, block_t,
+                                                       enum page_type, int);
 int reserve_new_block(struct dnode_of_data *);
+int f2fs_reserve_block(struct dnode_of_data *, pgoff_t);
 void update_extent_cache(block_t, struct dnode_of_data *);
 struct page *find_data_page(struct inode *, pgoff_t, bool);
 struct page *get_lock_data_page(struct inode *, pgoff_t);
 struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool);
-int f2fs_readpage(struct f2fs_sb_info *, struct page *, block_t, int);
+int f2fs_submit_page_bio(struct f2fs_sb_info *, struct page *, block_t, int);
 int do_write_data_page(struct page *);
 
 /*
@@ -1238,4 +1278,5 @@ extern const struct address_space_operations f2fs_meta_aops;
 extern const struct inode_operations f2fs_dir_inode_operations;
 extern const struct inode_operations f2fs_symlink_inode_operations;
 extern const struct inode_operations f2fs_special_inode_operations;
+
 #endif
index 7d714f4972d59505e04576306dfd99a363f3b7d4..2b47adcd852ac4914898350b36f8b1ce7022a534 100644 (file)
@@ -33,7 +33,6 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
        struct page *page = vmf->page;
        struct inode *inode = file_inode(vma->vm_file);
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
-       block_t old_blk_addr;
        struct dnode_of_data dn;
        int err;
 
@@ -44,24 +43,10 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
        /* block allocation */
        f2fs_lock_op(sbi);
        set_new_dnode(&dn, inode, NULL, NULL, 0);
-       err = get_dnode_of_data(&dn, page->index, ALLOC_NODE);
-       if (err) {
-               f2fs_unlock_op(sbi);
-               goto out;
-       }
-
-       old_blk_addr = dn.data_blkaddr;
-
-       if (old_blk_addr == NULL_ADDR) {
-               err = reserve_new_block(&dn);
-               if (err) {
-                       f2fs_put_dnode(&dn);
-                       f2fs_unlock_op(sbi);
-                       goto out;
-               }
-       }
-       f2fs_put_dnode(&dn);
+       err = f2fs_reserve_block(&dn, page->index);
        f2fs_unlock_op(sbi);
+       if (err)
+               goto out;
 
        file_update_time(vma->vm_file);
        lock_page(page);
@@ -459,7 +444,7 @@ int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end)
        return 0;
 }
 
-static int punch_hole(struct inode *inode, loff_t offset, loff_t len, int mode)
+static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
 {
        pgoff_t pg_start, pg_end;
        loff_t off_start, off_end;
@@ -499,12 +484,6 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len, int mode)
                }
        }
 
-       if (!(mode & FALLOC_FL_KEEP_SIZE) &&
-               i_size_read(inode) <= (offset + len)) {
-               i_size_write(inode, offset);
-               mark_inode_dirty(inode);
-       }
-
        return ret;
 }
 
@@ -532,22 +511,11 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
 
                f2fs_lock_op(sbi);
                set_new_dnode(&dn, inode, NULL, NULL, 0);
-               ret = get_dnode_of_data(&dn, index, ALLOC_NODE);
-               if (ret) {
-                       f2fs_unlock_op(sbi);
+               ret = f2fs_reserve_block(&dn, index);
+               f2fs_unlock_op(sbi);
+               if (ret)
                        break;
-               }
 
-               if (dn.data_blkaddr == NULL_ADDR) {
-                       ret = reserve_new_block(&dn);
-                       if (ret) {
-                               f2fs_put_dnode(&dn);
-                               f2fs_unlock_op(sbi);
-                               break;
-                       }
-               }
-               f2fs_put_dnode(&dn);
-               f2fs_unlock_op(sbi);
 
                if (pg_start == pg_end)
                        new_size = offset + len;
@@ -578,7 +546,7 @@ static long f2fs_fallocate(struct file *file, int mode,
                return -EOPNOTSUPP;
 
        if (mode & FALLOC_FL_PUNCH_HOLE)
-               ret = punch_hole(inode, offset, len, mode);
+               ret = punch_hole(inode, offset, len);
        else
                ret = expand_inode_data(inode, offset, len, mode);
 
index b7ad1ec7e4ccb50227d1b48ce6d9ee7d26796f07..2886aef35d5984fb66673af3568cf8acd4bfbad1 100644 (file)
@@ -631,7 +631,7 @@ next_iput:
                goto next_step;
 
        if (gc_type == FG_GC) {
-               f2fs_submit_bio(sbi, DATA, true);
+               f2fs_submit_merged_bio(sbi, DATA, true, WRITE);
 
                /*
                 * In the case of FG_GC, it'd be better to reclaim this victim
@@ -664,8 +664,6 @@ static void do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno,
 
        /* read segment summary of victim */
        sum_page = get_sum_page(sbi, segno);
-       if (IS_ERR(sum_page))
-               return;
 
        blk_start_plug(&plug);
 
index 4ac4150d421dc05e6c20812d5fd36dcc910a938a..0e1a3df18e58c167344f7c31afce21e7e3c5cc3b 100644 (file)
@@ -89,13 +89,10 @@ static void ra_nat_pages(struct f2fs_sb_info *sbi, int nid)
 {
        struct address_space *mapping = sbi->meta_inode->i_mapping;
        struct f2fs_nm_info *nm_i = NM_I(sbi);
-       struct blk_plug plug;
        struct page *page;
        pgoff_t index;
        int i;
 
-       blk_start_plug(&plug);
-
        for (i = 0; i < FREE_NID_PAGES; i++, nid += NAT_ENTRY_PER_BLOCK) {
                if (nid >= nm_i->max_nid)
                        nid = 0;
@@ -105,15 +102,15 @@ static void ra_nat_pages(struct f2fs_sb_info *sbi, int nid)
                if (!page)
                        continue;
                if (PageUptodate(page)) {
+                       mark_page_accessed(page);
                        f2fs_put_page(page, 1);
                        continue;
                }
-               if (f2fs_readpage(sbi, page, index, READ))
-                       continue;
-
+               f2fs_submit_page_mbio(sbi, page, index, META, READ);
+               mark_page_accessed(page);
                f2fs_put_page(page, 0);
        }
-       blk_finish_plug(&plug);
+       f2fs_submit_merged_bio(sbi, META, true, READ);
 }
 
 static struct nat_entry *__lookup_nat_cache(struct f2fs_nm_info *nm_i, nid_t n)
@@ -502,7 +499,7 @@ static void truncate_node(struct dnode_of_data *dn)
 
        /* Deallocate node address */
        invalidate_blocks(sbi, ni.blk_addr);
-       dec_valid_node_count(sbi, dn->inode, 1);
+       dec_valid_node_count(sbi, dn->inode);
        set_node_addr(sbi, &ni, NULL_ADDR);
 
        if (dn->nid == dn->inode->i_ino) {
@@ -794,7 +791,7 @@ int truncate_xattr_node(struct inode *inode, struct page *page)
        set_new_dnode(&dn, inode, page, npage, nid);
 
        if (page)
-               dn.inode_page_locked = 1;
+               dn.inode_page_locked = true;
        truncate_node(&dn);
        return 0;
 }
@@ -803,29 +800,25 @@ int truncate_xattr_node(struct inode *inode, struct page *page)
  * Caller should grab and release a mutex by calling mutex_lock_op() and
  * mutex_unlock_op().
  */
-int remove_inode_page(struct inode *inode)
+void remove_inode_page(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        struct page *page;
        nid_t ino = inode->i_ino;
        struct dnode_of_data dn;
-       int err;
 
        page = get_node_page(sbi, ino);
        if (IS_ERR(page))
-               return PTR_ERR(page);
+               return;
 
-       err = truncate_xattr_node(inode, page);
-       if (err) {
+       if (truncate_xattr_node(inode, page)) {
                f2fs_put_page(page, 1);
-               return err;
+               return;
        }
-
        /* 0 is possible, after f2fs_new_inode() is failed */
        f2fs_bug_on(inode->i_blocks != 0 && inode->i_blocks != 1);
        set_new_dnode(&dn, inode, page, page, ino);
        truncate_node(&dn);
-       return 0;
 }
 
 struct page *new_inode_page(struct inode *inode, const struct qstr *name)
@@ -855,7 +848,7 @@ struct page *new_node_page(struct dnode_of_data *dn,
        if (!page)
                return ERR_PTR(-ENOMEM);
 
-       if (!inc_valid_node_count(sbi, dn->inode, 1)) {
+       if (!inc_valid_node_count(sbi, dn->inode)) {
                err = -ENOSPC;
                goto fail;
        }
@@ -898,7 +891,7 @@ fail:
  * LOCKED_PAGE: f2fs_put_page(page, 1)
  * error: nothing
  */
-static int read_node_page(struct page *page, int type)
+static int read_node_page(struct page *page, int rw)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb);
        struct node_info ni;
@@ -913,7 +906,7 @@ static int read_node_page(struct page *page, int type)
        if (PageUptodate(page))
                return LOCKED_PAGE;
 
-       return f2fs_readpage(sbi, page, ni.blk_addr, type);
+       return f2fs_submit_page_bio(sbi, page, ni.blk_addr, rw);
 }
 
 /*
@@ -1143,8 +1136,8 @@ continue_unlock:
        }
 
        if (wrote)
-               f2fs_submit_bio(sbi, NODE, wbc->sync_mode == WB_SYNC_ALL);
-
+               f2fs_submit_merged_bio(sbi, NODE, wbc->sync_mode == WB_SYNC_ALL,
+                                                                       WRITE);
        return nwritten;
 }
 
@@ -1564,7 +1557,7 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
        new_ni = old_ni;
        new_ni.ino = ino;
 
-       if (!inc_valid_node_count(sbi, NULL, 1))
+       if (!inc_valid_node_count(sbi, NULL))
                WARN_ON(1);
        set_node_addr(sbi, &new_ni, NEW_ADDR);
        inc_valid_inode_count(sbi);
@@ -1599,7 +1592,7 @@ int restore_node_summary(struct f2fs_sb_info *sbi,
                 */
                ClearPageUptodate(page);
 
-               if (f2fs_readpage(sbi, page, addr, READ_SYNC))
+               if (f2fs_submit_page_bio(sbi, page, addr, READ_SYNC))
                        goto out;
 
                lock_page(page);
index fdc81161f2543a4818e371946ba691515aa9f3c4..c209b8652927650262c47ac1804830c9a098f3d8 100644 (file)
@@ -143,7 +143,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
        while (1) {
                struct fsync_inode_entry *entry;
 
-               err = f2fs_readpage(sbi, page, blkaddr, READ_SYNC);
+               err = f2fs_submit_page_bio(sbi, page, blkaddr, READ_SYNC);
                if (err)
                        goto out;
 
@@ -386,7 +386,7 @@ static int recover_data(struct f2fs_sb_info *sbi,
        while (1) {
                struct fsync_inode_entry *entry;
 
-               err = f2fs_readpage(sbi, page, blkaddr, READ_SYNC);
+               err = f2fs_submit_page_bio(sbi, page, blkaddr, READ_SYNC);
                if (err)
                        goto out;
 
index fa284d397199faed53f1c8ffb4de611440ad2e73..ca9adf5914cc79d115bc5901226d39a622079d58 100644 (file)
 #include <linux/blkdev.h>
 #include <linux/prefetch.h>
 #include <linux/vmalloc.h>
+#include <linux/swap.h>
 
 #include "f2fs.h"
 #include "segment.h"
 #include "node.h"
 #include <trace/events/f2fs.h>
 
+#define __reverse_ffz(x) __reverse_ffs(~(x))
+
+static struct kmem_cache *discard_entry_slab;
+
+/*
+ * __reverse_ffs is copied from include/asm-generic/bitops/__ffs.h since
+ * MSB and LSB are reversed in a byte by f2fs_set_bit.
+ */
+static inline unsigned long __reverse_ffs(unsigned long word)
+{
+       int num = 0;
+
+#if BITS_PER_LONG == 64
+       if ((word & 0xffffffff) == 0) {
+               num += 32;
+               word >>= 32;
+       }
+#endif
+       if ((word & 0xffff) == 0) {
+               num += 16;
+               word >>= 16;
+       }
+       if ((word & 0xff) == 0) {
+               num += 8;
+               word >>= 8;
+       }
+       if ((word & 0xf0) == 0)
+               num += 4;
+       else
+               word >>= 4;
+       if ((word & 0xc) == 0)
+               num += 2;
+       else
+               word >>= 2;
+       if ((word & 0x2) == 0)
+               num += 1;
+       return num;
+}
+
+/*
+ * __find_rev_next(_zero)_bit is copied from lib/find_next_bit.c becasue
+ * f2fs_set_bit makes MSB and LSB reversed in a byte.
+ * Example:
+ *                             LSB <--> MSB
+ *   f2fs_set_bit(0, bitmap) => 0000 0001
+ *   f2fs_set_bit(7, bitmap) => 1000 0000
+ */
+static unsigned long __find_rev_next_bit(const unsigned long *addr,
+                       unsigned long size, unsigned long offset)
+{
+       const unsigned long *p = addr + BIT_WORD(offset);
+       unsigned long result = offset & ~(BITS_PER_LONG - 1);
+       unsigned long tmp;
+       unsigned long mask, submask;
+       unsigned long quot, rest;
+
+       if (offset >= size)
+               return size;
+
+       size -= result;
+       offset %= BITS_PER_LONG;
+       if (!offset)
+               goto aligned;
+
+       tmp = *(p++);
+       quot = (offset >> 3) << 3;
+       rest = offset & 0x7;
+       mask = ~0UL << quot;
+       submask = (unsigned char)(0xff << rest) >> rest;
+       submask <<= quot;
+       mask &= submask;
+       tmp &= mask;
+       if (size < BITS_PER_LONG)
+               goto found_first;
+       if (tmp)
+               goto found_middle;
+
+       size -= BITS_PER_LONG;
+       result += BITS_PER_LONG;
+aligned:
+       while (size & ~(BITS_PER_LONG-1)) {
+               tmp = *(p++);
+               if (tmp)
+                       goto found_middle;
+               result += BITS_PER_LONG;
+               size -= BITS_PER_LONG;
+       }
+       if (!size)
+               return result;
+       tmp = *p;
+found_first:
+       tmp &= (~0UL >> (BITS_PER_LONG - size));
+       if (tmp == 0UL)         /* Are any bits set? */
+               return result + size;   /* Nope. */
+found_middle:
+       return result + __reverse_ffs(tmp);
+}
+
+static unsigned long __find_rev_next_zero_bit(const unsigned long *addr,
+                       unsigned long size, unsigned long offset)
+{
+       const unsigned long *p = addr + BIT_WORD(offset);
+       unsigned long result = offset & ~(BITS_PER_LONG - 1);
+       unsigned long tmp;
+       unsigned long mask, submask;
+       unsigned long quot, rest;
+
+       if (offset >= size)
+               return size;
+
+       size -= result;
+       offset %= BITS_PER_LONG;
+       if (!offset)
+               goto aligned;
+
+       tmp = *(p++);
+       quot = (offset >> 3) << 3;
+       rest = offset & 0x7;
+       mask = ~(~0UL << quot);
+       submask = (unsigned char)~((unsigned char)(0xff << rest) >> rest);
+       submask <<= quot;
+       mask += submask;
+       tmp |= mask;
+       if (size < BITS_PER_LONG)
+               goto found_first;
+       if (~tmp)
+               goto found_middle;
+
+       size -= BITS_PER_LONG;
+       result += BITS_PER_LONG;
+aligned:
+       while (size & ~(BITS_PER_LONG - 1)) {
+               tmp = *(p++);
+               if (~tmp)
+                       goto found_middle;
+               result += BITS_PER_LONG;
+               size -= BITS_PER_LONG;
+       }
+       if (!size)
+               return result;
+       tmp = *p;
+
+found_first:
+       tmp |= ~0UL << size;
+       if (tmp == ~0UL)        /* Are any bits zero? */
+               return result + size;   /* Nope. */
+found_middle:
+       return result + __reverse_ffz(tmp);
+}
+
 /*
  * This function balances dirty node and dentry pages.
  * In addition, it controls garbage collection.
@@ -116,6 +267,56 @@ static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
        mutex_unlock(&dirty_i->seglist_lock);
 }
 
+static void f2fs_issue_discard(struct f2fs_sb_info *sbi,
+                               block_t blkstart, block_t blklen)
+{
+       sector_t start = SECTOR_FROM_BLOCK(sbi, blkstart);
+       sector_t len = SECTOR_FROM_BLOCK(sbi, blklen);
+       blkdev_issue_discard(sbi->sb->s_bdev, start, len, GFP_NOFS, 0);
+       trace_f2fs_issue_discard(sbi->sb, blkstart, blklen);
+}
+
+static void add_discard_addrs(struct f2fs_sb_info *sbi,
+                       unsigned int segno, struct seg_entry *se)
+{
+       struct list_head *head = &SM_I(sbi)->discard_list;
+       struct discard_entry *new;
+       int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long);
+       int max_blocks = sbi->blocks_per_seg;
+       unsigned long *cur_map = (unsigned long *)se->cur_valid_map;
+       unsigned long *ckpt_map = (unsigned long *)se->ckpt_valid_map;
+       unsigned long dmap[entries];
+       unsigned int start = 0, end = -1;
+       int i;
+
+       if (!test_opt(sbi, DISCARD))
+               return;
+
+       /* zero block will be discarded through the prefree list */
+       if (!se->valid_blocks || se->valid_blocks == max_blocks)
+               return;
+
+       /* SIT_VBLOCK_MAP_SIZE should be multiple of sizeof(unsigned long) */
+       for (i = 0; i < entries; i++)
+               dmap[i] = (cur_map[i] ^ ckpt_map[i]) & ckpt_map[i];
+
+       while (SM_I(sbi)->nr_discards <= SM_I(sbi)->max_discards) {
+               start = __find_rev_next_bit(dmap, max_blocks, end + 1);
+               if (start >= max_blocks)
+                       break;
+
+               end = __find_rev_next_zero_bit(dmap, max_blocks, start + 1);
+
+               new = f2fs_kmem_cache_alloc(discard_entry_slab, GFP_NOFS);
+               INIT_LIST_HEAD(&new->list);
+               new->blkaddr = START_BLOCK(sbi, segno) + start;
+               new->len = end - start;
+
+               list_add_tail(&new->list, head);
+               SM_I(sbi)->nr_discards += end - start;
+       }
+}
+
 /*
  * Should call clear_prefree_segments after checkpoint is done.
  */
@@ -138,6 +339,9 @@ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
 
 void clear_prefree_segments(struct f2fs_sb_info *sbi)
 {
+       struct list_head *head = &(SM_I(sbi)->discard_list);
+       struct list_head *this, *next;
+       struct discard_entry *entry;
        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
        unsigned long *prefree_map = dirty_i->dirty_segmap[PRE];
        unsigned int total_segs = TOTAL_SEGS(sbi);
@@ -160,14 +364,19 @@ void clear_prefree_segments(struct f2fs_sb_info *sbi)
                if (!test_opt(sbi, DISCARD))
                        continue;
 
-               blkdev_issue_discard(sbi->sb->s_bdev,
-                               START_BLOCK(sbi, start) <<
-                               sbi->log_sectors_per_block,
-                               (1 << (sbi->log_sectors_per_block +
-                               sbi->log_blocks_per_seg)) * (end - start),
-                               GFP_NOFS, 0);
+               f2fs_issue_discard(sbi, START_BLOCK(sbi, start),
+                               (end - start) << sbi->log_blocks_per_seg);
        }
        mutex_unlock(&dirty_i->seglist_lock);
+
+       /* send small discards */
+       list_for_each_safe(this, next, head) {
+               entry = list_entry(this, struct discard_entry, list);
+               f2fs_issue_discard(sbi, entry->blkaddr, entry->len);
+               list_del(&entry->list);
+               SM_I(sbi)->nr_discards -= entry->len;
+               kmem_cache_free(discard_entry_slab, entry);
+       }
 }
 
 static void __mark_sit_entry_dirty(struct f2fs_sb_info *sbi, unsigned int segno)
@@ -459,13 +668,18 @@ static void __next_free_blkoff(struct f2fs_sb_info *sbi,
                        struct curseg_info *seg, block_t start)
 {
        struct seg_entry *se = get_seg_entry(sbi, seg->segno);
-       block_t ofs;
-       for (ofs = start; ofs < sbi->blocks_per_seg; ofs++) {
-               if (!f2fs_test_bit(ofs, se->ckpt_valid_map)
-                       && !f2fs_test_bit(ofs, se->cur_valid_map))
-                       break;
-       }
-       seg->next_blkoff = ofs;
+       int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long);
+       unsigned long target_map[entries];
+       unsigned long *ckpt_map = (unsigned long *)se->ckpt_valid_map;
+       unsigned long *cur_map = (unsigned long *)se->cur_valid_map;
+       int i, pos;
+
+       for (i = 0; i < entries; i++)
+               target_map[i] = ckpt_map[i] | cur_map[i];
+
+       pos = __find_rev_next_zero_bit(target_map, sbi->blocks_per_seg, start);
+
+       seg->next_blkoff = pos;
 }
 
 /*
@@ -573,148 +787,6 @@ static const struct segment_allocation default_salloc_ops = {
        .allocate_segment = allocate_segment_by_default,
 };
 
-static void f2fs_end_io_write(struct bio *bio, int err)
-{
-       const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-       struct bio_private *p = bio->bi_private;
-
-       do {
-               struct page *page = bvec->bv_page;
-
-               if (--bvec >= bio->bi_io_vec)
-                       prefetchw(&bvec->bv_page->flags);
-               if (!uptodate) {
-                       SetPageError(page);
-                       if (page->mapping)
-                               set_bit(AS_EIO, &page->mapping->flags);
-                       set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG);
-                       p->sbi->sb->s_flags |= MS_RDONLY;
-               }
-               end_page_writeback(page);
-               dec_page_count(p->sbi, F2FS_WRITEBACK);
-       } while (bvec >= bio->bi_io_vec);
-
-       if (p->is_sync)
-               complete(p->wait);
-
-       if (!get_pages(p->sbi, F2FS_WRITEBACK) &&
-                       !list_empty(&p->sbi->cp_wait.task_list))
-               wake_up(&p->sbi->cp_wait);
-
-       kfree(p);
-       bio_put(bio);
-}
-
-struct bio *f2fs_bio_alloc(struct block_device *bdev, int npages)
-{
-       struct bio *bio;
-
-       /* No failure on bio allocation */
-       bio = bio_alloc(GFP_NOIO, npages);
-       bio->bi_bdev = bdev;
-       bio->bi_private = NULL;
-
-       return bio;
-}
-
-static void do_submit_bio(struct f2fs_sb_info *sbi,
-                               enum page_type type, bool sync)
-{
-       int rw = sync ? WRITE_SYNC : WRITE;
-       enum page_type btype = type > META ? META : type;
-
-       if (type >= META_FLUSH)
-               rw = WRITE_FLUSH_FUA;
-
-       if (btype == META)
-               rw |= REQ_META;
-
-       if (sbi->bio[btype]) {
-               struct bio_private *p = sbi->bio[btype]->bi_private;
-               p->sbi = sbi;
-               sbi->bio[btype]->bi_end_io = f2fs_end_io_write;
-
-               trace_f2fs_do_submit_bio(sbi->sb, btype, sync, sbi->bio[btype]);
-
-               if (type == META_FLUSH) {
-                       DECLARE_COMPLETION_ONSTACK(wait);
-                       p->is_sync = true;
-                       p->wait = &wait;
-                       submit_bio(rw, sbi->bio[btype]);
-                       wait_for_completion(&wait);
-               } else {
-                       p->is_sync = false;
-                       submit_bio(rw, sbi->bio[btype]);
-               }
-               sbi->bio[btype] = NULL;
-       }
-}
-
-void f2fs_submit_bio(struct f2fs_sb_info *sbi, enum page_type type, bool sync)
-{
-       down_write(&sbi->bio_sem);
-       do_submit_bio(sbi, type, sync);
-       up_write(&sbi->bio_sem);
-}
-
-static void submit_write_page(struct f2fs_sb_info *sbi, struct page *page,
-                               block_t blk_addr, enum page_type type)
-{
-       struct block_device *bdev = sbi->sb->s_bdev;
-       int bio_blocks;
-
-       verify_block_addr(sbi, blk_addr);
-
-       down_write(&sbi->bio_sem);
-
-       inc_page_count(sbi, F2FS_WRITEBACK);
-
-       if (sbi->bio[type] && sbi->last_block_in_bio[type] != blk_addr - 1)
-               do_submit_bio(sbi, type, false);
-alloc_new:
-       if (sbi->bio[type] == NULL) {
-               struct bio_private *priv;
-retry:
-               priv = kmalloc(sizeof(struct bio_private), GFP_NOFS);
-               if (!priv) {
-                       cond_resched();
-                       goto retry;
-               }
-
-               bio_blocks = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
-               sbi->bio[type] = f2fs_bio_alloc(bdev, bio_blocks);
-               sbi->bio[type]->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr);
-               sbi->bio[type]->bi_private = priv;
-               /*
-                * The end_io will be assigned at the sumbission phase.
-                * Until then, let bio_add_page() merge consecutive IOs as much
-                * as possible.
-                */
-       }
-
-       if (bio_add_page(sbi->bio[type], page, PAGE_CACHE_SIZE, 0) <
-                                                       PAGE_CACHE_SIZE) {
-               do_submit_bio(sbi, type, false);
-               goto alloc_new;
-       }
-
-       sbi->last_block_in_bio[type] = blk_addr;
-
-       up_write(&sbi->bio_sem);
-       trace_f2fs_submit_write_page(page, blk_addr, type);
-}
-
-void f2fs_wait_on_page_writeback(struct page *page,
-                               enum page_type type, bool sync)
-{
-       struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb);
-       if (PageWriteback(page)) {
-               f2fs_submit_bio(sbi, type, sync);
-               wait_on_page_writeback(page);
-       }
-}
-
 static bool __has_curseg_space(struct f2fs_sb_info *sbi, int type)
 {
        struct curseg_info *curseg = CURSEG_I(sbi, type);
@@ -828,7 +900,7 @@ static void do_write_page(struct f2fs_sb_info *sbi, struct page *page,
                fill_node_footer_blkaddr(page, NEXT_FREE_BLKADDR(sbi, curseg));
 
        /* writeout dirty page into bdev */
-       submit_write_page(sbi, page, *new_blkaddr, p_type);
+       f2fs_submit_page_mbio(sbi, page, *new_blkaddr, p_type, WRITE);
 
        mutex_unlock(&curseg->curseg_mutex);
 }
@@ -836,7 +908,7 @@ static void do_write_page(struct f2fs_sb_info *sbi, struct page *page,
 void write_meta_page(struct f2fs_sb_info *sbi, struct page *page)
 {
        set_page_writeback(page);
-       submit_write_page(sbi, page, page->index, META);
+       f2fs_submit_page_mbio(sbi, page, page->index, META, WRITE);
 }
 
 void write_node_page(struct f2fs_sb_info *sbi, struct page *page,
@@ -866,7 +938,7 @@ void write_data_page(struct inode *inode, struct page *page,
 void rewrite_data_page(struct f2fs_sb_info *sbi, struct page *page,
                                        block_t old_blk_addr)
 {
-       submit_write_page(sbi, page, old_blk_addr, DATA);
+       f2fs_submit_page_mbio(sbi, page, old_blk_addr, DATA, WRITE);
 }
 
 void recover_data_page(struct f2fs_sb_info *sbi,
@@ -953,8 +1025,8 @@ void rewrite_node_page(struct f2fs_sb_info *sbi,
 
        /* rewrite node page */
        set_page_writeback(page);
-       submit_write_page(sbi, page, new_blkaddr, NODE);
-       f2fs_submit_bio(sbi, NODE, true);
+       f2fs_submit_page_mbio(sbi, page, new_blkaddr, NODE, WRITE);
+       f2fs_submit_merged_bio(sbi, NODE, true, WRITE);
        refresh_sit_entry(sbi, old_blkaddr, new_blkaddr);
 
        locate_dirty_segment(sbi, old_cursegno);
@@ -964,6 +1036,16 @@ void rewrite_node_page(struct f2fs_sb_info *sbi,
        mutex_unlock(&curseg->curseg_mutex);
 }
 
+void f2fs_wait_on_page_writeback(struct page *page,
+                               enum page_type type, bool sync)
+{
+       struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb);
+       if (PageWriteback(page)) {
+               f2fs_submit_merged_bio(sbi, type, sync, WRITE);
+               wait_on_page_writeback(page);
+       }
+}
+
 static int read_compacted_summaries(struct f2fs_sb_info *sbi)
 {
        struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
@@ -1314,6 +1396,10 @@ void flush_sit_entries(struct f2fs_sb_info *sbi)
 
                sit_offset = SIT_ENTRY_OFFSET(sit_i, segno);
 
+               /* add discard candidates */
+               if (SM_I(sbi)->nr_discards < SM_I(sbi)->max_discards)
+                       add_discard_addrs(sbi, segno, se);
+
                if (flushed)
                        goto to_sit_page;
 
@@ -1480,41 +1566,89 @@ static int build_curseg(struct f2fs_sb_info *sbi)
        return restore_curseg_summaries(sbi);
 }
 
+static int ra_sit_pages(struct f2fs_sb_info *sbi, int start, int nrpages)
+{
+       struct address_space *mapping = sbi->meta_inode->i_mapping;
+       struct page *page;
+       block_t blk_addr, prev_blk_addr = 0;
+       int sit_blk_cnt = SIT_BLK_CNT(sbi);
+       int blkno = start;
+
+       for (; blkno < start + nrpages && blkno < sit_blk_cnt; blkno++) {
+
+               blk_addr = current_sit_addr(sbi, blkno * SIT_ENTRY_PER_BLOCK);
+
+               if (blkno != start && prev_blk_addr + 1 != blk_addr)
+                       break;
+               prev_blk_addr = blk_addr;
+repeat:
+               page = grab_cache_page(mapping, blk_addr);
+               if (!page) {
+                       cond_resched();
+                       goto repeat;
+               }
+               if (PageUptodate(page)) {
+                       mark_page_accessed(page);
+                       f2fs_put_page(page, 1);
+                       continue;
+               }
+
+               f2fs_submit_page_mbio(sbi, page, blk_addr, META, READ);
+
+               mark_page_accessed(page);
+               f2fs_put_page(page, 0);
+       }
+
+       f2fs_submit_merged_bio(sbi, META, true, READ);
+       return blkno - start;
+}
+
 static void build_sit_entries(struct f2fs_sb_info *sbi)
 {
        struct sit_info *sit_i = SIT_I(sbi);
        struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
        struct f2fs_summary_block *sum = curseg->sum_blk;
-       unsigned int start;
-
-       for (start = 0; start < TOTAL_SEGS(sbi); start++) {
-               struct seg_entry *se = &sit_i->sentries[start];
-               struct f2fs_sit_block *sit_blk;
-               struct f2fs_sit_entry sit;
-               struct page *page;
-               int i;
+       int sit_blk_cnt = SIT_BLK_CNT(sbi);
+       unsigned int i, start, end;
+       unsigned int readed, start_blk = 0;
+       int nrpages = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
 
-               mutex_lock(&curseg->curseg_mutex);
-               for (i = 0; i < sits_in_cursum(sum); i++) {
-                       if (le32_to_cpu(segno_in_journal(sum, i)) == start) {
-                               sit = sit_in_journal(sum, i);
-                               mutex_unlock(&curseg->curseg_mutex);
-                               goto got_it;
+       do {
+               readed = ra_sit_pages(sbi, start_blk, nrpages);
+
+               start = start_blk * sit_i->sents_per_block;
+               end = (start_blk + readed) * sit_i->sents_per_block;
+
+               for (; start < end && start < TOTAL_SEGS(sbi); start++) {
+                       struct seg_entry *se = &sit_i->sentries[start];
+                       struct f2fs_sit_block *sit_blk;
+                       struct f2fs_sit_entry sit;
+                       struct page *page;
+
+                       mutex_lock(&curseg->curseg_mutex);
+                       for (i = 0; i < sits_in_cursum(sum); i++) {
+                               if (le32_to_cpu(segno_in_journal(sum, i)) == start) {
+                                       sit = sit_in_journal(sum, i);
+                                       mutex_unlock(&curseg->curseg_mutex);
+                                       goto got_it;
+                               }
                        }
-               }
-               mutex_unlock(&curseg->curseg_mutex);
-               page = get_current_sit_page(sbi, start);
-               sit_blk = (struct f2fs_sit_block *)page_address(page);
-               sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)];
-               f2fs_put_page(page, 1);
+                       mutex_unlock(&curseg->curseg_mutex);
+
+                       page = get_current_sit_page(sbi, start);
+                       sit_blk = (struct f2fs_sit_block *)page_address(page);
+                       sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)];
+                       f2fs_put_page(page, 1);
 got_it:
-               check_block_count(sbi, start, &sit);
-               seg_info_from_raw_sit(se, &sit);
-               if (sbi->segs_per_sec > 1) {
-                       struct sec_entry *e = get_sec_entry(sbi, start);
-                       e->valid_blocks += se->valid_blocks;
+                       check_block_count(sbi, start, &sit);
+                       seg_info_from_raw_sit(se, &sit);
+                       if (sbi->segs_per_sec > 1) {
+                               struct sec_entry *e = get_sec_entry(sbi, start);
+                               e->valid_blocks += se->valid_blocks;
+                       }
                }
-       }
+               start_blk += readed;
+       } while (start_blk < sit_blk_cnt);
 }
 
 static void init_free_segmap(struct f2fs_sb_info *sbi)
@@ -1645,6 +1779,10 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
        sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
        sm_info->rec_prefree_segments = DEF_RECLAIM_PREFREE_SEGMENTS;
 
+       INIT_LIST_HEAD(&sm_info->discard_list);
+       sm_info->nr_discards = 0;
+       sm_info->max_discards = 0;
+
        err = build_sit_info(sbi);
        if (err)
                return err;
@@ -1760,3 +1898,17 @@ void destroy_segment_manager(struct f2fs_sb_info *sbi)
        sbi->sm_info = NULL;
        kfree(sm_info);
 }
+
+int __init create_segment_manager_caches(void)
+{
+       discard_entry_slab = f2fs_kmem_cache_create("discard_entry",
+                       sizeof(struct discard_entry), NULL);
+       if (!discard_entry_slab)
+               return -ENOMEM;
+       return 0;
+}
+
+void destroy_segment_manager_caches(void)
+{
+       kmem_cache_destroy(discard_entry_slab);
+}
index 269f690b4e2492c65bf1a59e9d10302d87725a4e..26812fc0fa12b7cf458fd32bb5bbbdd65777f8b2 100644 (file)
 #define GET_L2R_SEGNO(free_i, segno)   (segno - free_i->start_segno)
 #define GET_R2L_SEGNO(free_i, segno)   (segno + free_i->start_segno)
 
-#define IS_DATASEG(t)                                                  \
-       ((t == CURSEG_HOT_DATA) || (t == CURSEG_COLD_DATA) ||           \
-       (t == CURSEG_WARM_DATA))
-
-#define IS_NODESEG(t)                                                  \
-       ((t == CURSEG_HOT_NODE) || (t == CURSEG_COLD_NODE) ||           \
-       (t == CURSEG_WARM_NODE))
+#define IS_DATASEG(t)  (t <= CURSEG_COLD_DATA)
+#define IS_NODESEG(t)  (t >= CURSEG_HOT_NODE)
 
 #define IS_CURSEG(sbi, seg)                                            \
        ((seg == CURSEG_I(sbi, CURSEG_HOT_DATA)->segno) ||      \
        (segno / SIT_ENTRY_PER_BLOCK)
 #define        START_SEGNO(sit_i, segno)               \
        (SIT_BLOCK_OFFSET(sit_i, segno) * SIT_ENTRY_PER_BLOCK)
+#define SIT_BLK_CNT(sbi)                       \
+       ((TOTAL_SEGS(sbi) + SIT_ENTRY_PER_BLOCK - 1) / SIT_ENTRY_PER_BLOCK)
 #define f2fs_bitmap_size(nr)                   \
        (BITS_TO_LONGS(nr) * sizeof(unsigned long))
 #define TOTAL_SEGS(sbi)        (SM_I(sbi)->main_segments)
 #define TOTAL_SECS(sbi)        (sbi->total_sections)
 
 #define SECTOR_FROM_BLOCK(sbi, blk_addr)                               \
-       (blk_addr << ((sbi)->log_blocksize - F2FS_LOG_SECTOR_SIZE))
+       (((sector_t)blk_addr) << (sbi)->log_sectors_per_block)
 #define SECTOR_TO_BLOCK(sbi, sectors)                                  \
-       (sectors >> ((sbi)->log_blocksize - F2FS_LOG_SECTOR_SIZE))
+       (sectors >> (sbi)->log_sectors_per_block)
 #define MAX_BIO_BLOCKS(max_hw_blocks)                                  \
        (min((int)max_hw_blocks, BIO_MAX_PAGES))
 
-/* during checkpoint, bio_private is used to synchronize the last bio */
-struct bio_private {
-       struct f2fs_sb_info *sbi;
-       bool is_sync;
-       void *wait;
-};
-
 /*
  * indicate a block allocation direction: RIGHT and LEFT.
  * RIGHT means allocating new sections towards the end of volume.
index bafff72de8e841afba9d609a8001c71af67f42fc..dd55074a304fb412f34e13e6607b354466640dbb 100644 (file)
@@ -50,6 +50,7 @@ enum {
        Opt_active_logs,
        Opt_disable_ext_identify,
        Opt_inline_xattr,
+       Opt_inline_data,
        Opt_err,
 };
 
@@ -65,6 +66,7 @@ static match_table_t f2fs_tokens = {
        {Opt_active_logs, "active_logs=%u"},
        {Opt_disable_ext_identify, "disable_ext_identify"},
        {Opt_inline_xattr, "inline_xattr"},
+       {Opt_inline_data, "inline_data"},
        {Opt_err, NULL},
 };
 
@@ -175,6 +177,7 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
+F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -183,6 +186,7 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(gc_no_gc_sleep_time),
        ATTR_LIST(gc_idle),
        ATTR_LIST(reclaim_segments),
+       ATTR_LIST(max_small_discards),
        NULL,
 };
 
@@ -311,6 +315,9 @@ static int parse_options(struct super_block *sb, char *options)
                case Opt_disable_ext_identify:
                        set_opt(sbi, DISABLE_EXT_IDENTIFY);
                        break;
+               case Opt_inline_data:
+                       set_opt(sbi, INLINE_DATA);
+                       break;
                default:
                        f2fs_msg(sb, KERN_ERR,
                                "Unrecognized mount option \"%s\" or missing value",
@@ -508,7 +515,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
 #endif
        if (test_opt(sbi, DISABLE_EXT_IDENTIFY))
                seq_puts(seq, ",disable_ext_identify");
-
+       if (test_opt(sbi, INLINE_DATA))
+               seq_puts(seq, ",inline_data");
        seq_printf(seq, ",active_logs=%u", sbi->active_logs);
 
        return 0;
@@ -818,6 +826,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
        struct buffer_head *raw_super_buf;
        struct inode *root;
        long err = -EINVAL;
+       int i;
 
        /* allocate memory for f2fs-specific super block info */
        sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL);
@@ -874,7 +883,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
        mutex_init(&sbi->node_write);
        sbi->por_doing = false;
        spin_lock_init(&sbi->stat_lock);
-       init_rwsem(&sbi->bio_sem);
+
+       mutex_init(&sbi->read_io.io_mutex);
+       for (i = 0; i < NR_PAGE_TYPE; i++)
+               mutex_init(&sbi->write_io[i].io_mutex);
+
        init_rwsem(&sbi->cp_rwsem);
        init_waitqueue_head(&sbi->cp_wait);
        init_sb_info(sbi);
@@ -939,9 +952,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
        }
 
        /* if there are nt orphan nodes free them */
-       err = -EINVAL;
-       if (recover_orphan_inodes(sbi))
-               goto free_node_inode;
+       recover_orphan_inodes(sbi);
 
        /* read root inode and dentry */
        root = f2fs_iget(sb, F2FS_ROOT_INO(sbi));
@@ -950,8 +961,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
                err = PTR_ERR(root);
                goto free_node_inode;
        }
-       if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size)
+       if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
+               err = -EINVAL;
                goto free_root_inode;
+       }
 
        sb->s_root = d_make_root(root); /* allocate root dentry */
        if (!sb->s_root) {
@@ -1078,9 +1091,12 @@ static int __init init_f2fs_fs(void)
        err = create_node_manager_caches();
        if (err)
                goto free_inodecache;
-       err = create_gc_caches();
+       err = create_segment_manager_caches();
        if (err)
                goto free_node_manager_caches;
+       err = create_gc_caches();
+       if (err)
+               goto free_segment_manager_caches;
        err = create_checkpoint_caches();
        if (err)
                goto free_gc_caches;
@@ -1102,6 +1118,8 @@ free_checkpoint_caches:
        destroy_checkpoint_caches();
 free_gc_caches:
        destroy_gc_caches();
+free_segment_manager_caches:
+       destroy_segment_manager_caches();
 free_node_manager_caches:
        destroy_node_manager_caches();
 free_inodecache:
index 7f5c658af755f9b43296c1dacfab5def788c4a1c..b4730cf52aec9172727816820174fb53d7e001b8 100644 (file)
@@ -755,6 +755,7 @@ static void fscache_write_op(struct fscache_operation *_op)
        struct fscache_object *object = op->op.object;
        struct fscache_cookie *cookie;
        struct page *page;
+       pgoff_t index;
        unsigned n;
        void *results[1];
        int ret;
@@ -803,7 +804,7 @@ static void fscache_write_op(struct fscache_operation *_op)
        _debug("gang %d [%lx]", n, page->index);
        if (page->index > op->store_limit) {
                fscache_stat(&fscache_n_store_pages_over_limit);
-               goto superseded;
+               goto page_beyond_limit;
        }
 
        radix_tree_tag_set(&cookie->stores, page->index,
@@ -829,6 +830,40 @@ static void fscache_write_op(struct fscache_operation *_op)
        _leave("");
        return;
 
+page_beyond_limit:
+       spin_unlock(&object->lock);
+
+page_beyond_limit_unlocked:
+       /* pages that are now beyond the end of the storage object must have
+        * their pending storage records cleared.
+        */
+       index = page->index;
+       radix_tree_tag_clear(&cookie->stores, page->index,
+                            FSCACHE_COOKIE_PENDING_TAG);
+       if (!radix_tree_tag_get(&cookie->stores, page->index,
+                               FSCACHE_COOKIE_STORING_TAG)) {
+               fscache_stat(&fscache_n_store_radix_deletes);
+               radix_tree_delete(&cookie->stores, page->index);
+               page_cache_release(page);
+       }
+       if (!need_resched()) {
+               n = radix_tree_gang_lookup_tag(&cookie->stores, results,
+                                              index + 1, 1,
+                                              FSCACHE_COOKIE_PENDING_TAG);
+               if (n == 1) {
+                       page = results[0];
+                       goto page_beyond_limit_unlocked;
+               }
+               spin_unlock(&cookie->stores_lock);
+               wake_up_bit(&cookie->flags, 0);
+       } else {
+               spin_unlock(&cookie->stores_lock);
+       }
+
+       fscache_enqueue_operation(&op->op);
+       _leave("");
+       return;
+
 superseded:
        /* this writer is going away and there aren't any more things to
         * write */
index b7fc035a6943cc40f649f1cca7be5858fbcf1cbc..028281303beacc580992411ac11e2816d2ad76ad 100644 (file)
@@ -1050,30 +1050,22 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
                bh = bh->b_this_page;
        } while(bh != head);
        spin_unlock(&sdp->sd_ail_lock);
-       gfs2_log_unlock(sdp);
 
        head = bh = page_buffers(page);
        do {
-               gfs2_log_lock(sdp);
                bd = bh->b_private;
                if (bd) {
                        gfs2_assert_warn(sdp, bd->bd_bh == bh);
-                       if (!list_empty(&bd->bd_list)) {
-                               if (!buffer_pinned(bh))
-                                       list_del_init(&bd->bd_list);
-                               else
-                                       bd = NULL;
-                       }
-                       if (bd)
-                               bd->bd_bh = NULL;
+                       if (!list_empty(&bd->bd_list))
+                               list_del_init(&bd->bd_list);
+                       bd->bd_bh = NULL;
                        bh->b_private = NULL;
-               }
-               gfs2_log_unlock(sdp);
-               if (bd)
                        kmem_cache_free(gfs2_bufdata_cachep, bd);
+               }
 
                bh = bh->b_this_page;
        } while (bh != head);
+       gfs2_log_unlock(sdp);
 
        return try_to_free_buffers(page);
 
index ba1ea67f4eeb1c99e826f54be8b9b6d8d57909f8..01328162c9527503536e4e95c4a6fdcb3d4caa58 100644 (file)
@@ -93,6 +93,7 @@ struct gfs2_rgrpd {
        struct gfs2_rgrp_lvb *rd_rgl;
        u32 rd_last_alloc;
        u32 rd_flags;
+       u32 rd_extfail_pt;              /* extent failure point */
 #define GFS2_RDF_CHECK         0x10000000 /* check for unlinked inodes */
 #define GFS2_RDF_UPTODATE      0x20000000 /* rg is up to date */
 #define GFS2_RDF_ERROR         0x40000000 /* error in rg */
index 010b9fb9fec6e781cb80a6982d746896ba6cffdb..2b212bd20b8e01ab3d6d1acee6bf55daba1a9ccd 100644 (file)
@@ -83,6 +83,7 @@ static void maybe_release_space(struct gfs2_bufdata *bd)
               bd->bd_bh->b_data + bi->bi_offset, bi->bi_len);
        clear_bit(GBF_FULL, &bi->bi_flags);
        rgd->rd_free_clone = rgd->rd_free;
+       rgd->rd_extfail_pt = rgd->rd_free;
 }
 
 /**
@@ -272,7 +273,7 @@ static struct bio *gfs2_log_alloc_bio(struct gfs2_sbd *sdp, u64 blkno)
                nrvecs = max(nrvecs/2, 1U);
        }
 
-       bio->bi_sector = blkno * (sb->s_blocksize >> 9);
+       bio->bi_iter.bi_sector = blkno * (sb->s_blocksize >> 9);
        bio->bi_bdev = sb->s_bdev;
        bio->bi_end_io = gfs2_end_log_write;
        bio->bi_private = sdp;
index 82303b4749582cd3c00d402a9f42b9972b1de677..16194da91652becfca5019a296f097206358e1d2 100644 (file)
@@ -224,7 +224,7 @@ static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector, int silent)
        lock_page(page);
 
        bio = bio_alloc(GFP_NOFS, 1);
-       bio->bi_sector = sector * (sb->s_blocksize >> 9);
+       bio->bi_iter.bi_sector = sector * (sb->s_blocksize >> 9);
        bio->bi_bdev = sb->s_bdev;
        bio_add_page(bio, page, PAGE_SIZE, 0);
 
index 98236d0df3cae7ce7666a10dc7fc907590b873b0..1b6b3675ee1d546b15b78bdf5dc1ee9fb5823b0d 100644 (file)
 #include "inode.h"
 #include "util.h"
 
-struct gfs2_quota_change_host {
-       u64 qc_change;
-       u32 qc_flags; /* GFS2_QCF_... */
-       struct kqid qc_id;
-};
-
 /* Lock order: qd_lock -> qd->lockref.lock -> lru lock */
 static DEFINE_SPINLOCK(qd_lock);
 struct list_lru gfs2_qd_lru;
@@ -1214,17 +1208,6 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid)
        return error;
 }
 
-static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf)
-{
-       const struct gfs2_quota_change *str = buf;
-
-       qc->qc_change = be64_to_cpu(str->qc_change);
-       qc->qc_flags = be32_to_cpu(str->qc_flags);
-       qc->qc_id = make_kqid(&init_user_ns,
-                             (qc->qc_flags & GFS2_QCF_USER)?USRQUOTA:GRPQUOTA,
-                             be32_to_cpu(str->qc_id));
-}
-
 int gfs2_quota_init(struct gfs2_sbd *sdp)
 {
        struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
@@ -1257,6 +1240,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
 
        for (x = 0; x < blocks; x++) {
                struct buffer_head *bh;
+               const struct gfs2_quota_change *qc;
                unsigned int y;
 
                if (!extlen) {
@@ -1274,25 +1258,28 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
                        goto fail;
                }
 
+               qc = (const struct gfs2_quota_change *)(bh->b_data + sizeof(struct gfs2_meta_header));
                for (y = 0; y < sdp->sd_qc_per_block && slot < sdp->sd_quota_slots;
                     y++, slot++) {
-                       struct gfs2_quota_change_host qc;
                        struct gfs2_quota_data *qd;
-
-                       gfs2_quota_change_in(&qc, bh->b_data +
-                                         sizeof(struct gfs2_meta_header) +
-                                         y * sizeof(struct gfs2_quota_change));
-                       if (!qc.qc_change)
+                       s64 qc_change = be64_to_cpu(qc->qc_change);
+                       u32 qc_flags = be32_to_cpu(qc->qc_flags);
+                       enum quota_type qtype = (qc_flags & GFS2_QCF_USER) ?
+                                               USRQUOTA : GRPQUOTA;
+                       struct kqid qc_id = make_kqid(&init_user_ns, qtype,
+                                                     be32_to_cpu(qc->qc_id));
+                       qc++;
+                       if (!qc_change)
                                continue;
 
-                       error = qd_alloc(sdp, qc.qc_id, &qd);
+                       error = qd_alloc(sdp, qc_id, &qd);
                        if (error) {
                                brelse(bh);
                                goto fail;
                        }
 
                        set_bit(QDF_CHANGE, &qd->qd_flags);
-                       qd->qd_change = qc.qc_change;
+                       qd->qd_change = qc_change;
                        qd->qd_slot = slot;
                        qd->qd_slot_count = 1;
 
index c8d6161bd682bd6cbd05247e2f0efc8274afe0b9..797f1d3114ef22684fed08d076e9d329d01c8807 100644 (file)
  * 3 = Used (metadata)
  */
 
+struct gfs2_extent {
+       struct gfs2_rbm rbm;
+       u32 len;
+};
+
 static const char valid_change[16] = {
                /* current */
        /* n */ 0, 1, 1, 1,
@@ -65,8 +70,9 @@ static const char valid_change[16] = {
                1, 0, 0, 0
 };
 
-static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 minext,
-                         const struct gfs2_inode *ip, bool nowrap);
+static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext,
+                        const struct gfs2_inode *ip, bool nowrap,
+                        const struct gfs2_alloc_parms *ap);
 
 
 /**
@@ -635,9 +641,13 @@ static void __rs_deltree(struct gfs2_blkreserv *rs)
                /* return reserved blocks to the rgrp */
                BUG_ON(rs->rs_rbm.rgd->rd_reserved < rs->rs_free);
                rs->rs_rbm.rgd->rd_reserved -= rs->rs_free;
+               /* The rgrp extent failure point is likely not to increase;
+                  it will only do so if the freed blocks are somehow
+                  contiguous with a span of free blocks that follows. Still,
+                  it will force the number to be recalculated later. */
+               rgd->rd_extfail_pt += rs->rs_free;
                rs->rs_free = 0;
                clear_bit(GBF_FULL, &bi->bi_flags);
-               smp_mb__after_clear_bit();
        }
 }
 
@@ -1126,6 +1136,8 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
                gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data);
                rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK);
                rgd->rd_free_clone = rgd->rd_free;
+               /* max out the rgrp allocation failure point */
+               rgd->rd_extfail_pt = rgd->rd_free;
        }
        if (cpu_to_be32(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) {
                rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd));
@@ -1455,7 +1467,7 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
        if (WARN_ON(gfs2_rbm_from_block(&rbm, goal)))
                return;
 
-       ret = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, extlen, ip, true);
+       ret = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &extlen, ip, true, ap);
        if (ret == 0) {
                rs->rs_rbm = rbm;
                rs->rs_free = extlen;
@@ -1520,6 +1532,7 @@ static u64 gfs2_next_unreserved_block(struct gfs2_rgrpd *rgd, u64 block,
  * @rbm: The current position in the resource group
  * @ip: The inode for which we are searching for blocks
  * @minext: The minimum extent length
+ * @maxext: A pointer to the maximum extent structure
  *
  * This checks the current position in the rgrp to see whether there is
  * a reservation covering this block. If not then this function is a
@@ -1532,7 +1545,8 @@ static u64 gfs2_next_unreserved_block(struct gfs2_rgrpd *rgd, u64 block,
 
 static int gfs2_reservation_check_and_update(struct gfs2_rbm *rbm,
                                             const struct gfs2_inode *ip,
-                                            u32 minext)
+                                            u32 minext,
+                                            struct gfs2_extent *maxext)
 {
        u64 block = gfs2_rbm_to_block(rbm);
        u32 extlen = 1;
@@ -1545,8 +1559,7 @@ static int gfs2_reservation_check_and_update(struct gfs2_rbm *rbm,
         */
        if (minext) {
                extlen = gfs2_free_extlen(rbm, minext);
-               nblock = block + extlen;
-               if (extlen < minext)
+               if (extlen <= maxext->len)
                        goto fail;
        }
 
@@ -1555,9 +1568,17 @@ static int gfs2_reservation_check_and_update(struct gfs2_rbm *rbm,
         * and skip if parts of it are already reserved
         */
        nblock = gfs2_next_unreserved_block(rbm->rgd, block, extlen, ip);
-       if (nblock == block)
-               return 0;
+       if (nblock == block) {
+               if (!minext || extlen >= minext)
+                       return 0;
+
+               if (extlen > maxext->len) {
+                       maxext->len = extlen;
+                       maxext->rbm = *rbm;
+               }
 fail:
+               nblock = block + extlen;
+       }
        ret = gfs2_rbm_from_block(rbm, nblock);
        if (ret < 0)
                return ret;
@@ -1568,30 +1589,38 @@ fail:
  * gfs2_rbm_find - Look for blocks of a particular state
  * @rbm: Value/result starting position and final position
  * @state: The state which we want to find
- * @minext: The requested extent length (0 for a single block)
+ * @minext: Pointer to the requested extent length (NULL for a single block)
+ *          This is updated to be the actual reservation size.
  * @ip: If set, check for reservations
  * @nowrap: Stop looking at the end of the rgrp, rather than wrapping
  *          around until we've reached the starting point.
+ * @ap: the allocation parameters
  *
  * Side effects:
  * - If looking for free blocks, we set GBF_FULL on each bitmap which
  *   has no free blocks in it.
+ * - If looking for free blocks, we set rd_extfail_pt on each rgrp which
+ *   has come up short on a free block search.
  *
  * Returns: 0 on success, -ENOSPC if there is no block of the requested state
  */
 
-static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 minext,
-                        const struct gfs2_inode *ip, bool nowrap)
+static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext,
+                        const struct gfs2_inode *ip, bool nowrap,
+                        const struct gfs2_alloc_parms *ap)
 {
        struct buffer_head *bh;
        int initial_bii;
        u32 initial_offset;
+       int first_bii = rbm->bii;
+       u32 first_offset = rbm->offset;
        u32 offset;
        u8 *buffer;
        int n = 0;
        int iters = rbm->rgd->rd_length;
        int ret;
        struct gfs2_bitmap *bi;
+       struct gfs2_extent maxext = { .rbm.rgd = rbm->rgd, };
 
        /* If we are not starting at the beginning of a bitmap, then we
         * need to add one to the bitmap count to ensure that we search
@@ -1620,7 +1649,9 @@ static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 minext,
                        return 0;
 
                initial_bii = rbm->bii;
-               ret = gfs2_reservation_check_and_update(rbm, ip, minext);
+               ret = gfs2_reservation_check_and_update(rbm, ip,
+                                                       minext ? *minext : 0,
+                                                       &maxext);
                if (ret == 0)
                        return 0;
                if (ret > 0) {
@@ -1655,6 +1686,24 @@ next_iter:
                        break;
        }
 
+       if (minext == NULL || state != GFS2_BLKST_FREE)
+               return -ENOSPC;
+
+       /* If the extent was too small, and it's smaller than the smallest
+          to have failed before, remember for future reference that it's
+          useless to search this rgrp again for this amount or more. */
+       if ((first_offset == 0) && (first_bii == 0) &&
+           (*minext < rbm->rgd->rd_extfail_pt))
+               rbm->rgd->rd_extfail_pt = *minext;
+
+       /* If the maximum extent we found is big enough to fulfill the
+          minimum requirements, use it anyway. */
+       if (maxext.len) {
+               *rbm = maxext.rbm;
+               *minext = maxext.len;
+               return 0;
+       }
+
        return -ENOSPC;
 }
 
@@ -1680,7 +1729,8 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip
 
        while (1) {
                down_write(&sdp->sd_log_flush_lock);
-               error = gfs2_rbm_find(&rbm, GFS2_BLKST_UNLINKED, 0, NULL, true);
+               error = gfs2_rbm_find(&rbm, GFS2_BLKST_UNLINKED, NULL, NULL,
+                                     true, NULL);
                up_write(&sdp->sd_log_flush_lock);
                if (error == -ENOSPC)
                        break;
@@ -1891,7 +1941,9 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a
                }
 
                /* Skip unuseable resource groups */
-               if (rs->rs_rbm.rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR))
+               if ((rs->rs_rbm.rgd->rd_flags & (GFS2_RGF_NOALLOC |
+                                                GFS2_RDF_ERROR)) ||
+                   (ap && (ap->target > rs->rs_rbm.rgd->rd_extfail_pt)))
                        goto skip_rgrp;
 
                if (sdp->sd_args.ar_rgrplvb)
@@ -1911,15 +1963,16 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a
                        return 0;
                }
 
-               /* Drop reservation, if we couldn't use reserved rgrp */
-               if (gfs2_rs_active(rs))
-                       gfs2_rs_deltree(rs);
 check_rgrp:
                /* Check for unlinked inodes which can be reclaimed */
                if (rs->rs_rbm.rgd->rd_flags & GFS2_RDF_CHECK)
                        try_rgrp_unlink(rs->rs_rbm.rgd, &last_unlinked,
                                        ip->i_no_addr);
 skip_rgrp:
+               /* Drop reservation, if we couldn't use reserved rgrp */
+               if (gfs2_rs_active(rs))
+                       gfs2_rs_deltree(rs);
+
                /* Unlock rgrp if required */
                if (!rg_locked)
                        gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
@@ -2072,10 +2125,10 @@ int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl)
 
        if (rgd == NULL)
                return 0;
-       gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u r:%u\n",
+       gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u r:%u e:%u\n",
                       (unsigned long long)rgd->rd_addr, rgd->rd_flags,
                       rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes,
-                      rgd->rd_reserved);
+                      rgd->rd_reserved, rgd->rd_extfail_pt);
        spin_lock(&rgd->rd_rsspin);
        for (n = rb_first(&rgd->rd_rstree); n; n = rb_next(&trs->rs_node)) {
                trs = rb_entry(n, struct gfs2_blkreserv, rs_node);
@@ -2184,18 +2237,20 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
        int error;
 
        gfs2_set_alloc_start(&rbm, ip, dinode);
-       error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, 0, ip, false);
+       error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, NULL, ip, false, NULL);
 
        if (error == -ENOSPC) {
                gfs2_set_alloc_start(&rbm, ip, dinode);
-               error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, 0, NULL, false);
+               error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, NULL, NULL, false,
+                                     NULL);
        }
 
        /* Since all blocks are reserved in advance, this shouldn't happen */
        if (error) {
-               fs_warn(sdp, "inum=%llu error=%d, nblocks=%u, full=%d\n",
+               fs_warn(sdp, "inum=%llu error=%d, nblocks=%u, full=%d fail_pt=%d\n",
                        (unsigned long long)ip->i_no_addr, error, *nblocks,
-                       test_bit(GBF_FULL, &rbm.rgd->rd_bits->bi_flags));
+                       test_bit(GBF_FULL, &rbm.rgd->rd_bits->bi_flags),
+                       rbm.rgd->rd_extfail_pt);
                goto rgrp_error;
        }
 
index b51a6079108d1d4fa4a696b222a63c6634b0a36c..3f999649587ff8185ebd326c3672acee83542de4 100644 (file)
@@ -24,13 +24,6 @@ struct hfsplus_wd {
        u16 embed_count;
 };
 
-static void hfsplus_end_io_sync(struct bio *bio, int err)
-{
-       if (err)
-               clear_bit(BIO_UPTODATE, &bio->bi_flags);
-       complete(bio->bi_private);
-}
-
 /*
  * hfsplus_submit_bio - Perfrom block I/O
  * @sb: super block of volume for I/O
@@ -53,7 +46,6 @@ static void hfsplus_end_io_sync(struct bio *bio, int err)
 int hfsplus_submit_bio(struct super_block *sb, sector_t sector,
                void *buf, void **data, int rw)
 {
-       DECLARE_COMPLETION_ONSTACK(wait);
        struct bio *bio;
        int ret = 0;
        u64 io_size;
@@ -71,10 +63,8 @@ int hfsplus_submit_bio(struct super_block *sb, sector_t sector,
        sector &= ~((io_size >> HFSPLUS_SECTOR_SHIFT) - 1);
 
        bio = bio_alloc(GFP_NOIO, 1);
-       bio->bi_sector = sector;
+       bio->bi_iter.bi_sector = sector;
        bio->bi_bdev = sb->s_bdev;
-       bio->bi_end_io = hfsplus_end_io_sync;
-       bio->bi_private = &wait;
 
        if (!(rw & WRITE) && data)
                *data = (u8 *)buf + offset;
@@ -93,12 +83,7 @@ int hfsplus_submit_bio(struct super_block *sb, sector_t sector,
                buf = (u8 *)buf + len;
        }
 
-       submit_bio(rw, bio);
-       wait_for_completion(&wait);
-
-       if (!bio_flagged(bio, BIO_UPTODATE))
-               ret = -EIO;
-
+       ret = submit_bio_wait(rw, bio);
 out:
        bio_put(bio);
        return ret < 0 ? ret : 0;
index 360d27c488873825fed5c04f8bb2320a51a39d62..8d811e02b4b92bb26d28367c727fcbe909fa95d5 100644 (file)
@@ -1998,20 +1998,20 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp)
 
        bio = bio_alloc(GFP_NOFS, 1);
 
-       bio->bi_sector = bp->l_blkno << (log->l2bsize - 9);
+       bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9);
        bio->bi_bdev = log->bdev;
        bio->bi_io_vec[0].bv_page = bp->l_page;
        bio->bi_io_vec[0].bv_len = LOGPSIZE;
        bio->bi_io_vec[0].bv_offset = bp->l_offset;
 
        bio->bi_vcnt = 1;
-       bio->bi_size = LOGPSIZE;
+       bio->bi_iter.bi_size = LOGPSIZE;
 
        bio->bi_end_io = lbmIODone;
        bio->bi_private = bp;
        /*check if journaling to disk has been disabled*/
        if (log->no_integrity) {
-               bio->bi_size = 0;
+               bio->bi_iter.bi_size = 0;
                lbmIODone(bio, 0);
        } else {
                submit_bio(READ_SYNC, bio);
@@ -2144,21 +2144,21 @@ static void lbmStartIO(struct lbuf * bp)
        jfs_info("lbmStartIO\n");
 
        bio = bio_alloc(GFP_NOFS, 1);
-       bio->bi_sector = bp->l_blkno << (log->l2bsize - 9);
+       bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9);
        bio->bi_bdev = log->bdev;
        bio->bi_io_vec[0].bv_page = bp->l_page;
        bio->bi_io_vec[0].bv_len = LOGPSIZE;
        bio->bi_io_vec[0].bv_offset = bp->l_offset;
 
        bio->bi_vcnt = 1;
-       bio->bi_size = LOGPSIZE;
+       bio->bi_iter.bi_size = LOGPSIZE;
 
        bio->bi_end_io = lbmIODone;
        bio->bi_private = bp;
 
        /* check if journaling to disk has been disabled */
        if (log->no_integrity) {
-               bio->bi_size = 0;
+               bio->bi_iter.bi_size = 0;
                lbmIODone(bio, 0);
        } else {
                submit_bio(WRITE_SYNC, bio);
index d165cde0c68dda885c2f5bb512f48465f521c4a1..49ba7ff1bbb9a15d8939128df2021354f2db6c52 100644 (file)
@@ -416,7 +416,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc)
                         * count from hitting zero before we're through
                         */
                        inc_io(page);
-                       if (!bio->bi_size)
+                       if (!bio->bi_iter.bi_size)
                                goto dump_bio;
                        submit_bio(WRITE, bio);
                        nr_underway++;
@@ -438,7 +438,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc)
 
                bio = bio_alloc(GFP_NOFS, 1);
                bio->bi_bdev = inode->i_sb->s_bdev;
-               bio->bi_sector = pblock << (inode->i_blkbits - 9);
+               bio->bi_iter.bi_sector = pblock << (inode->i_blkbits - 9);
                bio->bi_end_io = metapage_write_end_io;
                bio->bi_private = page;
 
@@ -452,7 +452,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc)
        if (bio) {
                if (bio_add_page(bio, page, bio_bytes, bio_offset) < bio_bytes)
                                goto add_failed;
-               if (!bio->bi_size)
+               if (!bio->bi_iter.bi_size)
                        goto dump_bio;
 
                submit_bio(WRITE, bio);
@@ -517,7 +517,8 @@ static int metapage_readpage(struct file *fp, struct page *page)
 
                        bio = bio_alloc(GFP_NOFS, 1);
                        bio->bi_bdev = inode->i_sb->s_bdev;
-                       bio->bi_sector = pblock << (inode->i_blkbits - 9);
+                       bio->bi_iter.bi_sector =
+                               pblock << (inode->i_blkbits - 9);
                        bio->bi_end_io = metapage_read_end_io;
                        bio->bi_private = page;
                        len = xlen << inode->i_blkbits;
diff --git a/fs/kernfs/Makefile b/fs/kernfs/Makefile
new file mode 100644 (file)
index 0000000..674337c
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the kernfs pseudo filesystem
+#
+
+obj-y          := mount.o inode.o dir.o file.o symlink.o
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
new file mode 100644 (file)
index 0000000..f51e062
--- /dev/null
@@ -0,0 +1,1014 @@
+/*
+ * fs/kernfs/dir.c - kernfs directory implementation
+ *
+ * Copyright (c) 2001-3 Patrick Mochel
+ * Copyright (c) 2007 SUSE Linux Products GmbH
+ * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/fs.h>
+#include <linux/namei.h>
+#include <linux/idr.h>
+#include <linux/slab.h>
+#include <linux/security.h>
+#include <linux/hash.h>
+
+#include "kernfs-internal.h"
+
+DEFINE_MUTEX(sysfs_mutex);
+
+#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb)
+
+/**
+ *     sysfs_name_hash
+ *     @name: Null terminated string to hash
+ *     @ns:   Namespace tag to hash
+ *
+ *     Returns 31 bit hash of ns + name (so it fits in an off_t )
+ */
+static unsigned int sysfs_name_hash(const char *name, const void *ns)
+{
+       unsigned long hash = init_name_hash();
+       unsigned int len = strlen(name);
+       while (len--)
+               hash = partial_name_hash(*name++, hash);
+       hash = (end_name_hash(hash) ^ hash_ptr((void *)ns, 31));
+       hash &= 0x7fffffffU;
+       /* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */
+       if (hash < 1)
+               hash += 2;
+       if (hash >= INT_MAX)
+               hash = INT_MAX - 1;
+       return hash;
+}
+
+static int sysfs_name_compare(unsigned int hash, const char *name,
+                             const void *ns, const struct sysfs_dirent *sd)
+{
+       if (hash != sd->s_hash)
+               return hash - sd->s_hash;
+       if (ns != sd->s_ns)
+               return ns - sd->s_ns;
+       return strcmp(name, sd->s_name);
+}
+
+static int sysfs_sd_compare(const struct sysfs_dirent *left,
+                           const struct sysfs_dirent *right)
+{
+       return sysfs_name_compare(left->s_hash, left->s_name, left->s_ns,
+                                 right);
+}
+
+/**
+ *     sysfs_link_sibling - link sysfs_dirent into sibling rbtree
+ *     @sd: sysfs_dirent of interest
+ *
+ *     Link @sd into its sibling rbtree which starts from
+ *     sd->s_parent->s_dir.children.
+ *
+ *     Locking:
+ *     mutex_lock(sysfs_mutex)
+ *
+ *     RETURNS:
+ *     0 on susccess -EEXIST on failure.
+ */
+static int sysfs_link_sibling(struct sysfs_dirent *sd)
+{
+       struct rb_node **node = &sd->s_parent->s_dir.children.rb_node;
+       struct rb_node *parent = NULL;
+
+       if (sysfs_type(sd) == SYSFS_DIR)
+               sd->s_parent->s_dir.subdirs++;
+
+       while (*node) {
+               struct sysfs_dirent *pos;
+               int result;
+
+               pos = to_sysfs_dirent(*node);
+               parent = *node;
+               result = sysfs_sd_compare(sd, pos);
+               if (result < 0)
+                       node = &pos->s_rb.rb_left;
+               else if (result > 0)
+                       node = &pos->s_rb.rb_right;
+               else
+                       return -EEXIST;
+       }
+       /* add new node and rebalance the tree */
+       rb_link_node(&sd->s_rb, parent, node);
+       rb_insert_color(&sd->s_rb, &sd->s_parent->s_dir.children);
+       return 0;
+}
+
+/**
+ *     sysfs_unlink_sibling - unlink sysfs_dirent from sibling rbtree
+ *     @sd: sysfs_dirent of interest
+ *
+ *     Unlink @sd from its sibling rbtree which starts from
+ *     sd->s_parent->s_dir.children.
+ *
+ *     Locking:
+ *     mutex_lock(sysfs_mutex)
+ */
+static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
+{
+       if (sysfs_type(sd) == SYSFS_DIR)
+               sd->s_parent->s_dir.subdirs--;
+
+       rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children);
+}
+
+/**
+ *     sysfs_get_active - get an active reference to sysfs_dirent
+ *     @sd: sysfs_dirent to get an active reference to
+ *
+ *     Get an active reference of @sd.  This function is noop if @sd
+ *     is NULL.
+ *
+ *     RETURNS:
+ *     Pointer to @sd on success, NULL on failure.
+ */
+struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
+{
+       if (unlikely(!sd))
+               return NULL;
+
+       if (!atomic_inc_unless_negative(&sd->s_active))
+               return NULL;
+
+       if (sd->s_flags & SYSFS_FLAG_LOCKDEP)
+               rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_);
+       return sd;
+}
+
+/**
+ *     sysfs_put_active - put an active reference to sysfs_dirent
+ *     @sd: sysfs_dirent to put an active reference to
+ *
+ *     Put an active reference to @sd.  This function is noop if @sd
+ *     is NULL.
+ */
+void sysfs_put_active(struct sysfs_dirent *sd)
+{
+       int v;
+
+       if (unlikely(!sd))
+               return;
+
+       if (sd->s_flags & SYSFS_FLAG_LOCKDEP)
+               rwsem_release(&sd->dep_map, 1, _RET_IP_);
+       v = atomic_dec_return(&sd->s_active);
+       if (likely(v != SD_DEACTIVATED_BIAS))
+               return;
+
+       /* atomic_dec_return() is a mb(), we'll always see the updated
+        * sd->u.completion.
+        */
+       complete(sd->u.completion);
+}
+
+/**
+ *     sysfs_deactivate - deactivate sysfs_dirent
+ *     @sd: sysfs_dirent to deactivate
+ *
+ *     Deny new active references and drain existing ones.
+ */
+static void sysfs_deactivate(struct sysfs_dirent *sd)
+{
+       DECLARE_COMPLETION_ONSTACK(wait);
+       int v;
+
+       BUG_ON(!(sd->s_flags & SYSFS_FLAG_REMOVED));
+
+       if (!(sysfs_type(sd) & SYSFS_ACTIVE_REF))
+               return;
+
+       sd->u.completion = (void *)&wait;
+
+       rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_);
+       /* atomic_add_return() is a mb(), put_active() will always see
+        * the updated sd->u.completion.
+        */
+       v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active);
+
+       if (v != SD_DEACTIVATED_BIAS) {
+               lock_contended(&sd->dep_map, _RET_IP_);
+               wait_for_completion(&wait);
+       }
+
+       lock_acquired(&sd->dep_map, _RET_IP_);
+       rwsem_release(&sd->dep_map, 1, _RET_IP_);
+}
+
+/**
+ * kernfs_get - get a reference count on a sysfs_dirent
+ * @sd: the target sysfs_dirent
+ */
+void kernfs_get(struct sysfs_dirent *sd)
+{
+       if (sd) {
+               WARN_ON(!atomic_read(&sd->s_count));
+               atomic_inc(&sd->s_count);
+       }
+}
+EXPORT_SYMBOL_GPL(kernfs_get);
+
+/**
+ * kernfs_put - put a reference count on a sysfs_dirent
+ * @sd: the target sysfs_dirent
+ *
+ * Put a reference count of @sd and destroy it if it reached zero.
+ */
+void kernfs_put(struct sysfs_dirent *sd)
+{
+       struct sysfs_dirent *parent_sd;
+       struct kernfs_root *root;
+
+       if (!sd || !atomic_dec_and_test(&sd->s_count))
+               return;
+       root = kernfs_root(sd);
+ repeat:
+       /* Moving/renaming is always done while holding reference.
+        * sd->s_parent won't change beneath us.
+        */
+       parent_sd = sd->s_parent;
+
+       WARN(!(sd->s_flags & SYSFS_FLAG_REMOVED),
+               "sysfs: free using entry: %s/%s\n",
+               parent_sd ? parent_sd->s_name : "", sd->s_name);
+
+       if (sysfs_type(sd) == SYSFS_KOBJ_LINK)
+               kernfs_put(sd->s_symlink.target_sd);
+       if (sysfs_type(sd) & SYSFS_COPY_NAME)
+               kfree(sd->s_name);
+       if (sd->s_iattr && sd->s_iattr->ia_secdata)
+               security_release_secctx(sd->s_iattr->ia_secdata,
+                                       sd->s_iattr->ia_secdata_len);
+       kfree(sd->s_iattr);
+       ida_simple_remove(&root->ino_ida, sd->s_ino);
+       kmem_cache_free(sysfs_dir_cachep, sd);
+
+       sd = parent_sd;
+       if (sd) {
+               if (atomic_dec_and_test(&sd->s_count))
+                       goto repeat;
+       } else {
+               /* just released the root sd, free @root too */
+               ida_destroy(&root->ino_ida);
+               kfree(root);
+       }
+}
+EXPORT_SYMBOL_GPL(kernfs_put);
+
+static int sysfs_dentry_delete(const struct dentry *dentry)
+{
+       struct sysfs_dirent *sd = dentry->d_fsdata;
+       return !(sd && !(sd->s_flags & SYSFS_FLAG_REMOVED));
+}
+
+static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags)
+{
+       struct sysfs_dirent *sd;
+
+       if (flags & LOOKUP_RCU)
+               return -ECHILD;
+
+       sd = dentry->d_fsdata;
+       mutex_lock(&sysfs_mutex);
+
+       /* The sysfs dirent has been deleted */
+       if (sd->s_flags & SYSFS_FLAG_REMOVED)
+               goto out_bad;
+
+       /* The sysfs dirent has been moved? */
+       if (dentry->d_parent->d_fsdata != sd->s_parent)
+               goto out_bad;
+
+       /* The sysfs dirent has been renamed */
+       if (strcmp(dentry->d_name.name, sd->s_name) != 0)
+               goto out_bad;
+
+       /* The sysfs dirent has been moved to a different namespace */
+       if (sd->s_parent && kernfs_ns_enabled(sd->s_parent) &&
+           sysfs_info(dentry->d_sb)->ns != sd->s_ns)
+               goto out_bad;
+
+       mutex_unlock(&sysfs_mutex);
+out_valid:
+       return 1;
+out_bad:
+       /* Remove the dentry from the dcache hashes.
+        * If this is a deleted dentry we use d_drop instead of d_delete
+        * so sysfs doesn't need to cope with negative dentries.
+        *
+        * If this is a dentry that has simply been renamed we
+        * use d_drop to remove it from the dcache lookup on its
+        * old parent.  If this dentry persists later when a lookup
+        * is performed at its new name the dentry will be readded
+        * to the dcache hashes.
+        */
+       mutex_unlock(&sysfs_mutex);
+
+       /* If we have submounts we must allow the vfs caches
+        * to lie about the state of the filesystem to prevent
+        * leaks and other nasty things.
+        */
+       if (check_submounts_and_drop(dentry) != 0)
+               goto out_valid;
+
+       return 0;
+}
+
+static void sysfs_dentry_release(struct dentry *dentry)
+{
+       kernfs_put(dentry->d_fsdata);
+}
+
+const struct dentry_operations sysfs_dentry_ops = {
+       .d_revalidate   = sysfs_dentry_revalidate,
+       .d_delete       = sysfs_dentry_delete,
+       .d_release      = sysfs_dentry_release,
+};
+
+struct sysfs_dirent *sysfs_new_dirent(struct kernfs_root *root,
+                                     const char *name, umode_t mode, int type)
+{
+       char *dup_name = NULL;
+       struct sysfs_dirent *sd;
+       int ret;
+
+       if (type & SYSFS_COPY_NAME) {
+               name = dup_name = kstrdup(name, GFP_KERNEL);
+               if (!name)
+                       return NULL;
+       }
+
+       sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL);
+       if (!sd)
+               goto err_out1;
+
+       ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL);
+       if (ret < 0)
+               goto err_out2;
+       sd->s_ino = ret;
+
+       atomic_set(&sd->s_count, 1);
+       atomic_set(&sd->s_active, 0);
+
+       sd->s_name = name;
+       sd->s_mode = mode;
+       sd->s_flags = type | SYSFS_FLAG_REMOVED;
+
+       return sd;
+
+ err_out2:
+       kmem_cache_free(sysfs_dir_cachep, sd);
+ err_out1:
+       kfree(dup_name);
+       return NULL;
+}
+
+/**
+ *     sysfs_addrm_start - prepare for sysfs_dirent add/remove
+ *     @acxt: pointer to sysfs_addrm_cxt to be used
+ *
+ *     This function is called when the caller is about to add or remove
+ *     sysfs_dirent.  This function acquires sysfs_mutex.  @acxt is used
+ *     to keep and pass context to other addrm functions.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).  sysfs_mutex is locked on
+ *     return.
+ */
+void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt)
+       __acquires(sysfs_mutex)
+{
+       memset(acxt, 0, sizeof(*acxt));
+
+       mutex_lock(&sysfs_mutex);
+}
+
+/**
+ *     sysfs_add_one - add sysfs_dirent to parent without warning
+ *     @acxt: addrm context to use
+ *     @sd: sysfs_dirent to be added
+ *     @parent_sd: the parent sysfs_dirent to add @sd to
+ *
+ *     Get @parent_sd and set @sd->s_parent to it and increment nlink of
+ *     the parent inode if @sd is a directory and link into the children
+ *     list of the parent.
+ *
+ *     This function should be called between calls to
+ *     sysfs_addrm_start() and sysfs_addrm_finish() and should be
+ *     passed the same @acxt as passed to sysfs_addrm_start().
+ *
+ *     LOCKING:
+ *     Determined by sysfs_addrm_start().
+ *
+ *     RETURNS:
+ *     0 on success, -EEXIST if entry with the given name already
+ *     exists.
+ */
+int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
+                 struct sysfs_dirent *parent_sd)
+{
+       bool has_ns = kernfs_ns_enabled(parent_sd);
+       struct sysfs_inode_attrs *ps_iattr;
+       int ret;
+
+       if (has_ns != (bool)sd->s_ns) {
+               WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
+                    has_ns ? "required" : "invalid",
+                    parent_sd->s_name, sd->s_name);
+               return -EINVAL;
+       }
+
+       if (sysfs_type(parent_sd) != SYSFS_DIR)
+               return -EINVAL;
+
+       sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
+       sd->s_parent = parent_sd;
+       kernfs_get(parent_sd);
+
+       ret = sysfs_link_sibling(sd);
+       if (ret)
+               return ret;
+
+       /* Update timestamps on the parent */
+       ps_iattr = parent_sd->s_iattr;
+       if (ps_iattr) {
+               struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
+               ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
+       }
+
+       /* Mark the entry added into directory tree */
+       sd->s_flags &= ~SYSFS_FLAG_REMOVED;
+
+       return 0;
+}
+
+/**
+ *     sysfs_remove_one - remove sysfs_dirent from parent
+ *     @acxt: addrm context to use
+ *     @sd: sysfs_dirent to be removed
+ *
+ *     Mark @sd removed and drop nlink of parent inode if @sd is a
+ *     directory.  @sd is unlinked from the children list.
+ *
+ *     This function should be called between calls to
+ *     sysfs_addrm_start() and sysfs_addrm_finish() and should be
+ *     passed the same @acxt as passed to sysfs_addrm_start().
+ *
+ *     LOCKING:
+ *     Determined by sysfs_addrm_start().
+ */
+static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
+                            struct sysfs_dirent *sd)
+{
+       struct sysfs_inode_attrs *ps_iattr;
+
+       /*
+        * Removal can be called multiple times on the same node.  Only the
+        * first invocation is effective and puts the base ref.
+        */
+       if (sd->s_flags & SYSFS_FLAG_REMOVED)
+               return;
+
+       if (sd->s_parent) {
+               sysfs_unlink_sibling(sd);
+
+               /* Update timestamps on the parent */
+               ps_iattr = sd->s_parent->s_iattr;
+               if (ps_iattr) {
+                       ps_iattr->ia_iattr.ia_ctime = CURRENT_TIME;
+                       ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME;
+               }
+       }
+
+       sd->s_flags |= SYSFS_FLAG_REMOVED;
+       sd->u.removed_list = acxt->removed;
+       acxt->removed = sd;
+}
+
+/**
+ *     sysfs_addrm_finish - finish up sysfs_dirent add/remove
+ *     @acxt: addrm context to finish up
+ *
+ *     Finish up sysfs_dirent add/remove.  Resources acquired by
+ *     sysfs_addrm_start() are released and removed sysfs_dirents are
+ *     cleaned up.
+ *
+ *     LOCKING:
+ *     sysfs_mutex is released.
+ */
+void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
+       __releases(sysfs_mutex)
+{
+       /* release resources acquired by sysfs_addrm_start() */
+       mutex_unlock(&sysfs_mutex);
+
+       /* kill removed sysfs_dirents */
+       while (acxt->removed) {
+               struct sysfs_dirent *sd = acxt->removed;
+
+               acxt->removed = sd->u.removed_list;
+
+               sysfs_deactivate(sd);
+               sysfs_unmap_bin_file(sd);
+               kernfs_put(sd);
+       }
+}
+
+/**
+ * kernfs_find_ns - find sysfs_dirent with the given name
+ * @parent: sysfs_dirent to search under
+ * @name: name to look for
+ * @ns: the namespace tag to use
+ *
+ * Look for sysfs_dirent with name @name under @parent.  Returns pointer to
+ * the found sysfs_dirent on success, %NULL on failure.
+ */
+static struct sysfs_dirent *kernfs_find_ns(struct sysfs_dirent *parent,
+                                          const unsigned char *name,
+                                          const void *ns)
+{
+       struct rb_node *node = parent->s_dir.children.rb_node;
+       bool has_ns = kernfs_ns_enabled(parent);
+       unsigned int hash;
+
+       lockdep_assert_held(&sysfs_mutex);
+
+       if (has_ns != (bool)ns) {
+               WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
+                    has_ns ? "required" : "invalid",
+                    parent->s_name, name);
+               return NULL;
+       }
+
+       hash = sysfs_name_hash(name, ns);
+       while (node) {
+               struct sysfs_dirent *sd;
+               int result;
+
+               sd = to_sysfs_dirent(node);
+               result = sysfs_name_compare(hash, name, ns, sd);
+               if (result < 0)
+                       node = node->rb_left;
+               else if (result > 0)
+                       node = node->rb_right;
+               else
+                       return sd;
+       }
+       return NULL;
+}
+
+/**
+ * kernfs_find_and_get_ns - find and get sysfs_dirent with the given name
+ * @parent: sysfs_dirent to search under
+ * @name: name to look for
+ * @ns: the namespace tag to use
+ *
+ * Look for sysfs_dirent with name @name under @parent and get a reference
+ * if found.  This function may sleep and returns pointer to the found
+ * sysfs_dirent on success, %NULL on failure.
+ */
+struct sysfs_dirent *kernfs_find_and_get_ns(struct sysfs_dirent *parent,
+                                           const char *name, const void *ns)
+{
+       struct sysfs_dirent *sd;
+
+       mutex_lock(&sysfs_mutex);
+       sd = kernfs_find_ns(parent, name, ns);
+       kernfs_get(sd);
+       mutex_unlock(&sysfs_mutex);
+
+       return sd;
+}
+EXPORT_SYMBOL_GPL(kernfs_find_and_get_ns);
+
+/**
+ * kernfs_create_root - create a new kernfs hierarchy
+ * @priv: opaque data associated with the new directory
+ *
+ * Returns the root of the new hierarchy on success, ERR_PTR() value on
+ * failure.
+ */
+struct kernfs_root *kernfs_create_root(void *priv)
+{
+       struct kernfs_root *root;
+       struct sysfs_dirent *sd;
+
+       root = kzalloc(sizeof(*root), GFP_KERNEL);
+       if (!root)
+               return ERR_PTR(-ENOMEM);
+
+       ida_init(&root->ino_ida);
+
+       sd = sysfs_new_dirent(root, "", S_IFDIR | S_IRUGO | S_IXUGO, SYSFS_DIR);
+       if (!sd) {
+               ida_destroy(&root->ino_ida);
+               kfree(root);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       sd->s_flags &= ~SYSFS_FLAG_REMOVED;
+       sd->priv = priv;
+       sd->s_dir.root = root;
+
+       root->sd = sd;
+
+       return root;
+}
+
+/**
+ * kernfs_destroy_root - destroy a kernfs hierarchy
+ * @root: root of the hierarchy to destroy
+ *
+ * Destroy the hierarchy anchored at @root by removing all existing
+ * directories and destroying @root.
+ */
+void kernfs_destroy_root(struct kernfs_root *root)
+{
+       kernfs_remove(root->sd);        /* will also free @root */
+}
+
+/**
+ * kernfs_create_dir_ns - create a directory
+ * @parent: parent in which to create a new directory
+ * @name: name of the new directory
+ * @priv: opaque data associated with the new directory
+ * @ns: optional namespace tag of the directory
+ *
+ * Returns the created node on success, ERR_PTR() value on failure.
+ */
+struct sysfs_dirent *kernfs_create_dir_ns(struct sysfs_dirent *parent,
+                                         const char *name, void *priv,
+                                         const void *ns)
+{
+       umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+       struct sysfs_addrm_cxt acxt;
+       struct sysfs_dirent *sd;
+       int rc;
+
+       /* allocate */
+       sd = sysfs_new_dirent(kernfs_root(parent), name, mode, SYSFS_DIR);
+       if (!sd)
+               return ERR_PTR(-ENOMEM);
+
+       sd->s_dir.root = parent->s_dir.root;
+       sd->s_ns = ns;
+       sd->priv = priv;
+
+       /* link in */
+       sysfs_addrm_start(&acxt);
+       rc = sysfs_add_one(&acxt, sd, parent);
+       sysfs_addrm_finish(&acxt);
+
+       if (!rc)
+               return sd;
+
+       kernfs_put(sd);
+       return ERR_PTR(rc);
+}
+
+static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry,
+                                  unsigned int flags)
+{
+       struct dentry *ret = NULL;
+       struct dentry *parent = dentry->d_parent;
+       struct sysfs_dirent *parent_sd = parent->d_fsdata;
+       struct sysfs_dirent *sd;
+       struct inode *inode;
+       const void *ns = NULL;
+
+       mutex_lock(&sysfs_mutex);
+
+       if (kernfs_ns_enabled(parent_sd))
+               ns = sysfs_info(dir->i_sb)->ns;
+
+       sd = kernfs_find_ns(parent_sd, dentry->d_name.name, ns);
+
+       /* no such entry */
+       if (!sd) {
+               ret = ERR_PTR(-ENOENT);
+               goto out_unlock;
+       }
+       kernfs_get(sd);
+       dentry->d_fsdata = sd;
+
+       /* attach dentry and inode */
+       inode = sysfs_get_inode(dir->i_sb, sd);
+       if (!inode) {
+               ret = ERR_PTR(-ENOMEM);
+               goto out_unlock;
+       }
+
+       /* instantiate and hash dentry */
+       ret = d_materialise_unique(dentry, inode);
+ out_unlock:
+       mutex_unlock(&sysfs_mutex);
+       return ret;
+}
+
+const struct inode_operations sysfs_dir_inode_operations = {
+       .lookup         = sysfs_lookup,
+       .permission     = sysfs_permission,
+       .setattr        = sysfs_setattr,
+       .getattr        = sysfs_getattr,
+       .setxattr       = sysfs_setxattr,
+};
+
+static struct sysfs_dirent *sysfs_leftmost_descendant(struct sysfs_dirent *pos)
+{
+       struct sysfs_dirent *last;
+
+       while (true) {
+               struct rb_node *rbn;
+
+               last = pos;
+
+               if (sysfs_type(pos) != SYSFS_DIR)
+                       break;
+
+               rbn = rb_first(&pos->s_dir.children);
+               if (!rbn)
+                       break;
+
+               pos = to_sysfs_dirent(rbn);
+       }
+
+       return last;
+}
+
+/**
+ * sysfs_next_descendant_post - find the next descendant for post-order walk
+ * @pos: the current position (%NULL to initiate traversal)
+ * @root: sysfs_dirent whose descendants to walk
+ *
+ * Find the next descendant to visit for post-order traversal of @root's
+ * descendants.  @root is included in the iteration and the last node to be
+ * visited.
+ */
+static struct sysfs_dirent *sysfs_next_descendant_post(struct sysfs_dirent *pos,
+                                                      struct sysfs_dirent *root)
+{
+       struct rb_node *rbn;
+
+       lockdep_assert_held(&sysfs_mutex);
+
+       /* if first iteration, visit leftmost descendant which may be root */
+       if (!pos)
+               return sysfs_leftmost_descendant(root);
+
+       /* if we visited @root, we're done */
+       if (pos == root)
+               return NULL;
+
+       /* if there's an unvisited sibling, visit its leftmost descendant */
+       rbn = rb_next(&pos->s_rb);
+       if (rbn)
+               return sysfs_leftmost_descendant(to_sysfs_dirent(rbn));
+
+       /* no sibling left, visit parent */
+       return pos->s_parent;
+}
+
+static void __kernfs_remove(struct sysfs_addrm_cxt *acxt,
+                           struct sysfs_dirent *sd)
+{
+       struct sysfs_dirent *pos, *next;
+
+       if (!sd)
+               return;
+
+       pr_debug("sysfs %s: removing\n", sd->s_name);
+
+       next = NULL;
+       do {
+               pos = next;
+               next = sysfs_next_descendant_post(pos, sd);
+               if (pos)
+                       sysfs_remove_one(acxt, pos);
+       } while (next);
+}
+
+/**
+ * kernfs_remove - remove a sysfs_dirent recursively
+ * @sd: the sysfs_dirent to remove
+ *
+ * Remove @sd along with all its subdirectories and files.
+ */
+void kernfs_remove(struct sysfs_dirent *sd)
+{
+       struct sysfs_addrm_cxt acxt;
+
+       sysfs_addrm_start(&acxt);
+       __kernfs_remove(&acxt, sd);
+       sysfs_addrm_finish(&acxt);
+}
+
+/**
+ * kernfs_remove_by_name_ns - find a sysfs_dirent by name and remove it
+ * @dir_sd: parent of the target
+ * @name: name of the sysfs_dirent to remove
+ * @ns: namespace tag of the sysfs_dirent to remove
+ *
+ * Look for the sysfs_dirent with @name and @ns under @dir_sd and remove
+ * it.  Returns 0 on success, -ENOENT if such entry doesn't exist.
+ */
+int kernfs_remove_by_name_ns(struct sysfs_dirent *dir_sd, const char *name,
+                            const void *ns)
+{
+       struct sysfs_addrm_cxt acxt;
+       struct sysfs_dirent *sd;
+
+       if (!dir_sd) {
+               WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n",
+                       name);
+               return -ENOENT;
+       }
+
+       sysfs_addrm_start(&acxt);
+
+       sd = kernfs_find_ns(dir_sd, name, ns);
+       if (sd)
+               __kernfs_remove(&acxt, sd);
+
+       sysfs_addrm_finish(&acxt);
+
+       if (sd)
+               return 0;
+       else
+               return -ENOENT;
+}
+
+/**
+ * kernfs_rename_ns - move and rename a kernfs_node
+ * @sd: target node
+ * @new_parent: new parent to put @sd under
+ * @new_name: new name
+ * @new_ns: new namespace tag
+ */
+int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent,
+                    const char *new_name, const void *new_ns)
+{
+       int error;
+
+       mutex_lock(&sysfs_mutex);
+
+       error = 0;
+       if ((sd->s_parent == new_parent) && (sd->s_ns == new_ns) &&
+           (strcmp(sd->s_name, new_name) == 0))
+               goto out;       /* nothing to rename */
+
+       error = -EEXIST;
+       if (kernfs_find_ns(new_parent, new_name, new_ns))
+               goto out;
+
+       /* rename sysfs_dirent */
+       if (strcmp(sd->s_name, new_name) != 0) {
+               error = -ENOMEM;
+               new_name = kstrdup(new_name, GFP_KERNEL);
+               if (!new_name)
+                       goto out;
+
+               kfree(sd->s_name);
+               sd->s_name = new_name;
+       }
+
+       /*
+        * Move to the appropriate place in the appropriate directories rbtree.
+        */
+       sysfs_unlink_sibling(sd);
+       kernfs_get(new_parent);
+       kernfs_put(sd->s_parent);
+       sd->s_ns = new_ns;
+       sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
+       sd->s_parent = new_parent;
+       sysfs_link_sibling(sd);
+
+       error = 0;
+ out:
+       mutex_unlock(&sysfs_mutex);
+       return error;
+}
+
+/* Relationship between s_mode and the DT_xxx types */
+static inline unsigned char dt_type(struct sysfs_dirent *sd)
+{
+       return (sd->s_mode >> 12) & 15;
+}
+
+static int sysfs_dir_release(struct inode *inode, struct file *filp)
+{
+       kernfs_put(filp->private_data);
+       return 0;
+}
+
+static struct sysfs_dirent *sysfs_dir_pos(const void *ns,
+       struct sysfs_dirent *parent_sd, loff_t hash, struct sysfs_dirent *pos)
+{
+       if (pos) {
+               int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) &&
+                       pos->s_parent == parent_sd &&
+                       hash == pos->s_hash;
+               kernfs_put(pos);
+               if (!valid)
+                       pos = NULL;
+       }
+       if (!pos && (hash > 1) && (hash < INT_MAX)) {
+               struct rb_node *node = parent_sd->s_dir.children.rb_node;
+               while (node) {
+                       pos = to_sysfs_dirent(node);
+
+                       if (hash < pos->s_hash)
+                               node = node->rb_left;
+                       else if (hash > pos->s_hash)
+                               node = node->rb_right;
+                       else
+                               break;
+               }
+       }
+       /* Skip over entries in the wrong namespace */
+       while (pos && pos->s_ns != ns) {
+               struct rb_node *node = rb_next(&pos->s_rb);
+               if (!node)
+                       pos = NULL;
+               else
+                       pos = to_sysfs_dirent(node);
+       }
+       return pos;
+}
+
+static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
+       struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
+{
+       pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
+       if (pos)
+               do {
+                       struct rb_node *node = rb_next(&pos->s_rb);
+                       if (!node)
+                               pos = NULL;
+                       else
+                               pos = to_sysfs_dirent(node);
+               } while (pos && pos->s_ns != ns);
+       return pos;
+}
+
+static int sysfs_readdir(struct file *file, struct dir_context *ctx)
+{
+       struct dentry *dentry = file->f_path.dentry;
+       struct sysfs_dirent *parent_sd = dentry->d_fsdata;
+       struct sysfs_dirent *pos = file->private_data;
+       const void *ns = NULL;
+
+       if (!dir_emit_dots(file, ctx))
+               return 0;
+       mutex_lock(&sysfs_mutex);
+
+       if (kernfs_ns_enabled(parent_sd))
+               ns = sysfs_info(dentry->d_sb)->ns;
+
+       for (pos = sysfs_dir_pos(ns, parent_sd, ctx->pos, pos);
+            pos;
+            pos = sysfs_dir_next_pos(ns, parent_sd, ctx->pos, pos)) {
+               const char *name = pos->s_name;
+               unsigned int type = dt_type(pos);
+               int len = strlen(name);
+               ino_t ino = pos->s_ino;
+
+               ctx->pos = pos->s_hash;
+               file->private_data = pos;
+               kernfs_get(pos);
+
+               mutex_unlock(&sysfs_mutex);
+               if (!dir_emit(ctx, name, len, ino, type))
+                       return 0;
+               mutex_lock(&sysfs_mutex);
+       }
+       mutex_unlock(&sysfs_mutex);
+       file->private_data = NULL;
+       ctx->pos = INT_MAX;
+       return 0;
+}
+
+static loff_t sysfs_dir_llseek(struct file *file, loff_t offset, int whence)
+{
+       struct inode *inode = file_inode(file);
+       loff_t ret;
+
+       mutex_lock(&inode->i_mutex);
+       ret = generic_file_llseek(file, offset, whence);
+       mutex_unlock(&inode->i_mutex);
+
+       return ret;
+}
+
+const struct file_operations sysfs_dir_operations = {
+       .read           = generic_read_dir,
+       .iterate        = sysfs_readdir,
+       .release        = sysfs_dir_release,
+       .llseek         = sysfs_dir_llseek,
+};
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
new file mode 100644 (file)
index 0000000..990c97f
--- /dev/null
@@ -0,0 +1,814 @@
+/*
+ * fs/kernfs/file.c - kernfs file implementation
+ *
+ * Copyright (c) 2001-3 Patrick Mochel
+ * Copyright (c) 2007 SUSE Linux Products GmbH
+ * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/pagemap.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+
+#include "kernfs-internal.h"
+
+/*
+ * There's one sysfs_open_file for each open file and one sysfs_open_dirent
+ * for each sysfs_dirent with one or more open files.
+ *
+ * sysfs_dirent->s_attr.open points to sysfs_open_dirent.  s_attr.open is
+ * protected by sysfs_open_dirent_lock.
+ *
+ * filp->private_data points to seq_file whose ->private points to
+ * sysfs_open_file.  sysfs_open_files are chained at
+ * sysfs_open_dirent->files, which is protected by sysfs_open_file_mutex.
+ */
+static DEFINE_SPINLOCK(sysfs_open_dirent_lock);
+static DEFINE_MUTEX(sysfs_open_file_mutex);
+
+struct sysfs_open_dirent {
+       atomic_t                refcnt;
+       atomic_t                event;
+       wait_queue_head_t       poll;
+       struct list_head        files; /* goes through sysfs_open_file.list */
+};
+
+static struct sysfs_open_file *sysfs_of(struct file *file)
+{
+       return ((struct seq_file *)file->private_data)->private;
+}
+
+/*
+ * Determine the kernfs_ops for the given sysfs_dirent.  This function must
+ * be called while holding an active reference.
+ */
+static const struct kernfs_ops *kernfs_ops(struct sysfs_dirent *sd)
+{
+       if (sd->s_flags & SYSFS_FLAG_LOCKDEP)
+               lockdep_assert_held(sd);
+       return sd->s_attr.ops;
+}
+
+static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos)
+{
+       struct sysfs_open_file *of = sf->private;
+       const struct kernfs_ops *ops;
+
+       /*
+        * @of->mutex nests outside active ref and is just to ensure that
+        * the ops aren't called concurrently for the same open file.
+        */
+       mutex_lock(&of->mutex);
+       if (!sysfs_get_active(of->sd))
+               return ERR_PTR(-ENODEV);
+
+       ops = kernfs_ops(of->sd);
+       if (ops->seq_start) {
+               return ops->seq_start(sf, ppos);
+       } else {
+               /*
+                * The same behavior and code as single_open().  Returns
+                * !NULL if pos is at the beginning; otherwise, NULL.
+                */
+               return NULL + !*ppos;
+       }
+}
+
+static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos)
+{
+       struct sysfs_open_file *of = sf->private;
+       const struct kernfs_ops *ops = kernfs_ops(of->sd);
+
+       if (ops->seq_next) {
+               return ops->seq_next(sf, v, ppos);
+       } else {
+               /*
+                * The same behavior and code as single_open(), always
+                * terminate after the initial read.
+                */
+               ++*ppos;
+               return NULL;
+       }
+}
+
+static void kernfs_seq_stop(struct seq_file *sf, void *v)
+{
+       struct sysfs_open_file *of = sf->private;
+       const struct kernfs_ops *ops = kernfs_ops(of->sd);
+
+       if (ops->seq_stop)
+               ops->seq_stop(sf, v);
+
+       sysfs_put_active(of->sd);
+       mutex_unlock(&of->mutex);
+}
+
+static int kernfs_seq_show(struct seq_file *sf, void *v)
+{
+       struct sysfs_open_file *of = sf->private;
+
+       of->event = atomic_read(&of->sd->s_attr.open->event);
+
+       return of->sd->s_attr.ops->seq_show(sf, v);
+}
+
+static const struct seq_operations kernfs_seq_ops = {
+       .start = kernfs_seq_start,
+       .next = kernfs_seq_next,
+       .stop = kernfs_seq_stop,
+       .show = kernfs_seq_show,
+};
+
+/*
+ * As reading a bin file can have side-effects, the exact offset and bytes
+ * specified in read(2) call should be passed to the read callback making
+ * it difficult to use seq_file.  Implement simplistic custom buffering for
+ * bin files.
+ */
+static ssize_t kernfs_file_direct_read(struct sysfs_open_file *of,
+                                      char __user *user_buf, size_t count,
+                                      loff_t *ppos)
+{
+       ssize_t len = min_t(size_t, count, PAGE_SIZE);
+       const struct kernfs_ops *ops;
+       char *buf;
+
+       buf = kmalloc(len, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       /*
+        * @of->mutex nests outside active ref and is just to ensure that
+        * the ops aren't called concurrently for the same open file.
+        */
+       mutex_lock(&of->mutex);
+       if (!sysfs_get_active(of->sd)) {
+               len = -ENODEV;
+               mutex_unlock(&of->mutex);
+               goto out_free;
+       }
+
+       ops = kernfs_ops(of->sd);
+       if (ops->read)
+               len = ops->read(of, buf, len, *ppos);
+       else
+               len = -EINVAL;
+
+       sysfs_put_active(of->sd);
+       mutex_unlock(&of->mutex);
+
+       if (len < 0)
+               goto out_free;
+
+       if (copy_to_user(user_buf, buf, len)) {
+               len = -EFAULT;
+               goto out_free;
+       }
+
+       *ppos += len;
+
+ out_free:
+       kfree(buf);
+       return len;
+}
+
+/**
+ * kernfs_file_read - kernfs vfs read callback
+ * @file: file pointer
+ * @user_buf: data to write
+ * @count: number of bytes
+ * @ppos: starting offset
+ */
+static ssize_t kernfs_file_read(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct sysfs_open_file *of = sysfs_of(file);
+
+       if (of->sd->s_flags & SYSFS_FLAG_HAS_SEQ_SHOW)
+               return seq_read(file, user_buf, count, ppos);
+       else
+               return kernfs_file_direct_read(of, user_buf, count, ppos);
+}
+
+/**
+ * kernfs_file_write - kernfs vfs write callback
+ * @file: file pointer
+ * @user_buf: data to write
+ * @count: number of bytes
+ * @ppos: starting offset
+ *
+ * Copy data in from userland and pass it to the matching kernfs write
+ * operation.
+ *
+ * There is no easy way for us to know if userspace is only doing a partial
+ * write, so we don't support them. We expect the entire buffer to come on
+ * the first write.  Hint: if you're writing a value, first read the file,
+ * modify only the the value you're changing, then write entire buffer
+ * back.
+ */
+static ssize_t kernfs_file_write(struct file *file, const char __user *user_buf,
+                                size_t count, loff_t *ppos)
+{
+       struct sysfs_open_file *of = sysfs_of(file);
+       ssize_t len = min_t(size_t, count, PAGE_SIZE);
+       const struct kernfs_ops *ops;
+       char *buf;
+
+       buf = kmalloc(len + 1, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       if (copy_from_user(buf, user_buf, len)) {
+               len = -EFAULT;
+               goto out_free;
+       }
+       buf[len] = '\0';        /* guarantee string termination */
+
+       /*
+        * @of->mutex nests outside active ref and is just to ensure that
+        * the ops aren't called concurrently for the same open file.
+        */
+       mutex_lock(&of->mutex);
+       if (!sysfs_get_active(of->sd)) {
+               mutex_unlock(&of->mutex);
+               len = -ENODEV;
+               goto out_free;
+       }
+
+       ops = kernfs_ops(of->sd);
+       if (ops->write)
+               len = ops->write(of, buf, len, *ppos);
+       else
+               len = -EINVAL;
+
+       sysfs_put_active(of->sd);
+       mutex_unlock(&of->mutex);
+
+       if (len > 0)
+               *ppos += len;
+out_free:
+       kfree(buf);
+       return len;
+}
+
+static void kernfs_vma_open(struct vm_area_struct *vma)
+{
+       struct file *file = vma->vm_file;
+       struct sysfs_open_file *of = sysfs_of(file);
+
+       if (!of->vm_ops)
+               return;
+
+       if (!sysfs_get_active(of->sd))
+               return;
+
+       if (of->vm_ops->open)
+               of->vm_ops->open(vma);
+
+       sysfs_put_active(of->sd);
+}
+
+static int kernfs_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+       struct file *file = vma->vm_file;
+       struct sysfs_open_file *of = sysfs_of(file);
+       int ret;
+
+       if (!of->vm_ops)
+               return VM_FAULT_SIGBUS;
+
+       if (!sysfs_get_active(of->sd))
+               return VM_FAULT_SIGBUS;
+
+       ret = VM_FAULT_SIGBUS;
+       if (of->vm_ops->fault)
+               ret = of->vm_ops->fault(vma, vmf);
+
+       sysfs_put_active(of->sd);
+       return ret;
+}
+
+static int kernfs_vma_page_mkwrite(struct vm_area_struct *vma,
+                                  struct vm_fault *vmf)
+{
+       struct file *file = vma->vm_file;
+       struct sysfs_open_file *of = sysfs_of(file);
+       int ret;
+
+       if (!of->vm_ops)
+               return VM_FAULT_SIGBUS;
+
+       if (!sysfs_get_active(of->sd))
+               return VM_FAULT_SIGBUS;
+
+       ret = 0;
+       if (of->vm_ops->page_mkwrite)
+               ret = of->vm_ops->page_mkwrite(vma, vmf);
+       else
+               file_update_time(file);
+
+       sysfs_put_active(of->sd);
+       return ret;
+}
+
+static int kernfs_vma_access(struct vm_area_struct *vma, unsigned long addr,
+                            void *buf, int len, int write)
+{
+       struct file *file = vma->vm_file;
+       struct sysfs_open_file *of = sysfs_of(file);
+       int ret;
+
+       if (!of->vm_ops)
+               return -EINVAL;
+
+       if (!sysfs_get_active(of->sd))
+               return -EINVAL;
+
+       ret = -EINVAL;
+       if (of->vm_ops->access)
+               ret = of->vm_ops->access(vma, addr, buf, len, write);
+
+       sysfs_put_active(of->sd);
+       return ret;
+}
+
+#ifdef CONFIG_NUMA
+static int kernfs_vma_set_policy(struct vm_area_struct *vma,
+                                struct mempolicy *new)
+{
+       struct file *file = vma->vm_file;
+       struct sysfs_open_file *of = sysfs_of(file);
+       int ret;
+
+       if (!of->vm_ops)
+               return 0;
+
+       if (!sysfs_get_active(of->sd))
+               return -EINVAL;
+
+       ret = 0;
+       if (of->vm_ops->set_policy)
+               ret = of->vm_ops->set_policy(vma, new);
+
+       sysfs_put_active(of->sd);
+       return ret;
+}
+
+static struct mempolicy *kernfs_vma_get_policy(struct vm_area_struct *vma,
+                                              unsigned long addr)
+{
+       struct file *file = vma->vm_file;
+       struct sysfs_open_file *of = sysfs_of(file);
+       struct mempolicy *pol;
+
+       if (!of->vm_ops)
+               return vma->vm_policy;
+
+       if (!sysfs_get_active(of->sd))
+               return vma->vm_policy;
+
+       pol = vma->vm_policy;
+       if (of->vm_ops->get_policy)
+               pol = of->vm_ops->get_policy(vma, addr);
+
+       sysfs_put_active(of->sd);
+       return pol;
+}
+
+static int kernfs_vma_migrate(struct vm_area_struct *vma,
+                             const nodemask_t *from, const nodemask_t *to,
+                             unsigned long flags)
+{
+       struct file *file = vma->vm_file;
+       struct sysfs_open_file *of = sysfs_of(file);
+       int ret;
+
+       if (!of->vm_ops)
+               return 0;
+
+       if (!sysfs_get_active(of->sd))
+               return 0;
+
+       ret = 0;
+       if (of->vm_ops->migrate)
+               ret = of->vm_ops->migrate(vma, from, to, flags);
+
+       sysfs_put_active(of->sd);
+       return ret;
+}
+#endif
+
+static const struct vm_operations_struct kernfs_vm_ops = {
+       .open           = kernfs_vma_open,
+       .fault          = kernfs_vma_fault,
+       .page_mkwrite   = kernfs_vma_page_mkwrite,
+       .access         = kernfs_vma_access,
+#ifdef CONFIG_NUMA
+       .set_policy     = kernfs_vma_set_policy,
+       .get_policy     = kernfs_vma_get_policy,
+       .migrate        = kernfs_vma_migrate,
+#endif
+};
+
+static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       struct sysfs_open_file *of = sysfs_of(file);
+       const struct kernfs_ops *ops;
+       int rc;
+
+       mutex_lock(&of->mutex);
+
+       rc = -ENODEV;
+       if (!sysfs_get_active(of->sd))
+               goto out_unlock;
+
+       ops = kernfs_ops(of->sd);
+       if (ops->mmap)
+               rc = ops->mmap(of, vma);
+       if (rc)
+               goto out_put;
+
+       /*
+        * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup()
+        * to satisfy versions of X which crash if the mmap fails: that
+        * substitutes a new vm_file, and we don't then want bin_vm_ops.
+        */
+       if (vma->vm_file != file)
+               goto out_put;
+
+       rc = -EINVAL;
+       if (of->mmapped && of->vm_ops != vma->vm_ops)
+               goto out_put;
+
+       /*
+        * It is not possible to successfully wrap close.
+        * So error if someone is trying to use close.
+        */
+       rc = -EINVAL;
+       if (vma->vm_ops && vma->vm_ops->close)
+               goto out_put;
+
+       rc = 0;
+       of->mmapped = 1;
+       of->vm_ops = vma->vm_ops;
+       vma->vm_ops = &kernfs_vm_ops;
+out_put:
+       sysfs_put_active(of->sd);
+out_unlock:
+       mutex_unlock(&of->mutex);
+
+       return rc;
+}
+
+/**
+ *     sysfs_get_open_dirent - get or create sysfs_open_dirent
+ *     @sd: target sysfs_dirent
+ *     @of: sysfs_open_file for this instance of open
+ *
+ *     If @sd->s_attr.open exists, increment its reference count;
+ *     otherwise, create one.  @of is chained to the files list.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno on failure.
+ */
+static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
+                                struct sysfs_open_file *of)
+{
+       struct sysfs_open_dirent *od, *new_od = NULL;
+
+ retry:
+       mutex_lock(&sysfs_open_file_mutex);
+       spin_lock_irq(&sysfs_open_dirent_lock);
+
+       if (!sd->s_attr.open && new_od) {
+               sd->s_attr.open = new_od;
+               new_od = NULL;
+       }
+
+       od = sd->s_attr.open;
+       if (od) {
+               atomic_inc(&od->refcnt);
+               list_add_tail(&of->list, &od->files);
+       }
+
+       spin_unlock_irq(&sysfs_open_dirent_lock);
+       mutex_unlock(&sysfs_open_file_mutex);
+
+       if (od) {
+               kfree(new_od);
+               return 0;
+       }
+
+       /* not there, initialize a new one and retry */
+       new_od = kmalloc(sizeof(*new_od), GFP_KERNEL);
+       if (!new_od)
+               return -ENOMEM;
+
+       atomic_set(&new_od->refcnt, 0);
+       atomic_set(&new_od->event, 1);
+       init_waitqueue_head(&new_od->poll);
+       INIT_LIST_HEAD(&new_od->files);
+       goto retry;
+}
+
+/**
+ *     sysfs_put_open_dirent - put sysfs_open_dirent
+ *     @sd: target sysfs_dirent
+ *     @of: associated sysfs_open_file
+ *
+ *     Put @sd->s_attr.open and unlink @of from the files list.  If
+ *     reference count reaches zero, disassociate and free it.
+ *
+ *     LOCKING:
+ *     None.
+ */
+static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
+                                 struct sysfs_open_file *of)
+{
+       struct sysfs_open_dirent *od = sd->s_attr.open;
+       unsigned long flags;
+
+       mutex_lock(&sysfs_open_file_mutex);
+       spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
+
+       if (of)
+               list_del(&of->list);
+
+       if (atomic_dec_and_test(&od->refcnt))
+               sd->s_attr.open = NULL;
+       else
+               od = NULL;
+
+       spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
+       mutex_unlock(&sysfs_open_file_mutex);
+
+       kfree(od);
+}
+
+static int kernfs_file_open(struct inode *inode, struct file *file)
+{
+       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+       const struct kernfs_ops *ops;
+       struct sysfs_open_file *of;
+       bool has_read, has_write, has_mmap;
+       int error = -EACCES;
+
+       if (!sysfs_get_active(attr_sd))
+               return -ENODEV;
+
+       ops = kernfs_ops(attr_sd);
+
+       has_read = ops->seq_show || ops->read || ops->mmap;
+       has_write = ops->write || ops->mmap;
+       has_mmap = ops->mmap;
+
+       /* check perms and supported operations */
+       if ((file->f_mode & FMODE_WRITE) &&
+           (!(inode->i_mode & S_IWUGO) || !has_write))
+               goto err_out;
+
+       if ((file->f_mode & FMODE_READ) &&
+           (!(inode->i_mode & S_IRUGO) || !has_read))
+               goto err_out;
+
+       /* allocate a sysfs_open_file for the file */
+       error = -ENOMEM;
+       of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL);
+       if (!of)
+               goto err_out;
+
+       /*
+        * The following is done to give a different lockdep key to
+        * @of->mutex for files which implement mmap.  This is a rather
+        * crude way to avoid false positive lockdep warning around
+        * mm->mmap_sem - mmap nests @of->mutex under mm->mmap_sem and
+        * reading /sys/block/sda/trace/act_mask grabs sr_mutex, under
+        * which mm->mmap_sem nests, while holding @of->mutex.  As each
+        * open file has a separate mutex, it's okay as long as those don't
+        * happen on the same file.  At this point, we can't easily give
+        * each file a separate locking class.  Let's differentiate on
+        * whether the file has mmap or not for now.
+        */
+       if (has_mmap)
+               mutex_init(&of->mutex);
+       else
+               mutex_init(&of->mutex);
+
+       of->sd = attr_sd;
+       of->file = file;
+
+       /*
+        * Always instantiate seq_file even if read access doesn't use
+        * seq_file or is not requested.  This unifies private data access
+        * and readable regular files are the vast majority anyway.
+        */
+       if (ops->seq_show)
+               error = seq_open(file, &kernfs_seq_ops);
+       else
+               error = seq_open(file, NULL);
+       if (error)
+               goto err_free;
+
+       ((struct seq_file *)file->private_data)->private = of;
+
+       /* seq_file clears PWRITE unconditionally, restore it if WRITE */
+       if (file->f_mode & FMODE_WRITE)
+               file->f_mode |= FMODE_PWRITE;
+
+       /* make sure we have open dirent struct */
+       error = sysfs_get_open_dirent(attr_sd, of);
+       if (error)
+               goto err_close;
+
+       /* open succeeded, put active references */
+       sysfs_put_active(attr_sd);
+       return 0;
+
+err_close:
+       seq_release(inode, file);
+err_free:
+       kfree(of);
+err_out:
+       sysfs_put_active(attr_sd);
+       return error;
+}
+
+static int kernfs_file_release(struct inode *inode, struct file *filp)
+{
+       struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata;
+       struct sysfs_open_file *of = sysfs_of(filp);
+
+       sysfs_put_open_dirent(sd, of);
+       seq_release(inode, filp);
+       kfree(of);
+
+       return 0;
+}
+
+void sysfs_unmap_bin_file(struct sysfs_dirent *sd)
+{
+       struct sysfs_open_dirent *od;
+       struct sysfs_open_file *of;
+
+       if (!(sd->s_flags & SYSFS_FLAG_HAS_MMAP))
+               return;
+
+       spin_lock_irq(&sysfs_open_dirent_lock);
+       od = sd->s_attr.open;
+       if (od)
+               atomic_inc(&od->refcnt);
+       spin_unlock_irq(&sysfs_open_dirent_lock);
+       if (!od)
+               return;
+
+       mutex_lock(&sysfs_open_file_mutex);
+       list_for_each_entry(of, &od->files, list) {
+               struct inode *inode = file_inode(of->file);
+               unmap_mapping_range(inode->i_mapping, 0, 0, 1);
+       }
+       mutex_unlock(&sysfs_open_file_mutex);
+
+       sysfs_put_open_dirent(sd, NULL);
+}
+
+/* Sysfs attribute files are pollable.  The idea is that you read
+ * the content and then you use 'poll' or 'select' to wait for
+ * the content to change.  When the content changes (assuming the
+ * manager for the kobject supports notification), poll will
+ * return POLLERR|POLLPRI, and select will return the fd whether
+ * it is waiting for read, write, or exceptions.
+ * Once poll/select indicates that the value has changed, you
+ * need to close and re-open the file, or seek to 0 and read again.
+ * Reminder: this only works for attributes which actively support
+ * it, and it is not possible to test an attribute from userspace
+ * to see if it supports poll (Neither 'poll' nor 'select' return
+ * an appropriate error code).  When in doubt, set a suitable timeout value.
+ */
+static unsigned int kernfs_file_poll(struct file *filp, poll_table *wait)
+{
+       struct sysfs_open_file *of = sysfs_of(filp);
+       struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
+       struct sysfs_open_dirent *od = attr_sd->s_attr.open;
+
+       /* need parent for the kobj, grab both */
+       if (!sysfs_get_active(attr_sd))
+               goto trigger;
+
+       poll_wait(filp, &od->poll, wait);
+
+       sysfs_put_active(attr_sd);
+
+       if (of->event != atomic_read(&od->event))
+               goto trigger;
+
+       return DEFAULT_POLLMASK;
+
+ trigger:
+       return DEFAULT_POLLMASK|POLLERR|POLLPRI;
+}
+
+/**
+ * kernfs_notify - notify a kernfs file
+ * @sd: file to notify
+ *
+ * Notify @sd such that poll(2) on @sd wakes up.
+ */
+void kernfs_notify(struct sysfs_dirent *sd)
+{
+       struct sysfs_open_dirent *od;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
+
+       if (!WARN_ON(sysfs_type(sd) != SYSFS_KOBJ_ATTR)) {
+               od = sd->s_attr.open;
+               if (od) {
+                       atomic_inc(&od->event);
+                       wake_up_interruptible(&od->poll);
+               }
+       }
+
+       spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
+}
+EXPORT_SYMBOL_GPL(kernfs_notify);
+
+const struct file_operations kernfs_file_operations = {
+       .read           = kernfs_file_read,
+       .write          = kernfs_file_write,
+       .llseek         = generic_file_llseek,
+       .mmap           = kernfs_file_mmap,
+       .open           = kernfs_file_open,
+       .release        = kernfs_file_release,
+       .poll           = kernfs_file_poll,
+};
+
+/**
+ * kernfs_create_file_ns_key - create a file
+ * @parent: directory to create the file in
+ * @name: name of the file
+ * @mode: mode of the file
+ * @size: size of the file
+ * @ops: kernfs operations for the file
+ * @priv: private data for the file
+ * @ns: optional namespace tag of the file
+ * @key: lockdep key for the file's active_ref, %NULL to disable lockdep
+ *
+ * Returns the created node on success, ERR_PTR() value on error.
+ */
+struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent,
+                                              const char *name,
+                                              umode_t mode, loff_t size,
+                                              const struct kernfs_ops *ops,
+                                              void *priv, const void *ns,
+                                              struct lock_class_key *key)
+{
+       struct sysfs_addrm_cxt acxt;
+       struct sysfs_dirent *sd;
+       int rc;
+
+       sd = sysfs_new_dirent(kernfs_root(parent), name,
+                             (mode & S_IALLUGO) | S_IFREG, SYSFS_KOBJ_ATTR);
+       if (!sd)
+               return ERR_PTR(-ENOMEM);
+
+       sd->s_attr.ops = ops;
+       sd->s_attr.size = size;
+       sd->s_ns = ns;
+       sd->priv = priv;
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       if (key) {
+               lockdep_init_map(&sd->dep_map, "s_active", key, 0);
+               sd->s_flags |= SYSFS_FLAG_LOCKDEP;
+       }
+#endif
+
+       /*
+        * sd->s_attr.ops is accesible only while holding active ref.  We
+        * need to know whether some ops are implemented outside active
+        * ref.  Cache their existence in flags.
+        */
+       if (ops->seq_show)
+               sd->s_flags |= SYSFS_FLAG_HAS_SEQ_SHOW;
+       if (ops->mmap)
+               sd->s_flags |= SYSFS_FLAG_HAS_MMAP;
+
+       sysfs_addrm_start(&acxt);
+       rc = sysfs_add_one(&acxt, sd, parent);
+       sysfs_addrm_finish(&acxt);
+
+       if (rc) {
+               kernfs_put(sd);
+               return ERR_PTR(rc);
+       }
+       return sd;
+}
similarity index 89%
rename from fs/sysfs/inode.c
rename to fs/kernfs/inode.c
index 1750f790af3b9a3714580c73705acc3cb21c613b..b4cae6fd717beb7044cd49fd223a90431c578c4b 100644 (file)
@@ -1,28 +1,22 @@
 /*
- * fs/sysfs/inode.c - basic sysfs inode and dentry operations
+ * fs/kernfs/inode.c - kernfs inode implementation
  *
  * Copyright (c) 2001-3 Patrick Mochel
  * Copyright (c) 2007 SUSE Linux Products GmbH
- * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
+ * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
  *
  * This file is released under the GPLv2.
- *
- * Please see Documentation/filesystems/sysfs.txt for more information.
  */
 
-#undef DEBUG
-
 #include <linux/pagemap.h>
-#include <linux/namei.h>
 #include <linux/backing-dev.h>
 #include <linux/capability.h>
 #include <linux/errno.h>
-#include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/sysfs.h>
 #include <linux/xattr.h>
 #include <linux/security.h>
-#include "sysfs.h"
+
+#include "kernfs-internal.h"
 
 static const struct address_space_operations sysfs_aops = {
        .readpage       = simple_readpage,
@@ -43,9 +37,10 @@ static const struct inode_operations sysfs_inode_operations = {
        .setxattr       = sysfs_setxattr,
 };
 
-int __init sysfs_inode_init(void)
+void __init sysfs_inode_init(void)
 {
-       return bdi_init(&sysfs_backing_dev_info);
+       if (bdi_init(&sysfs_backing_dev_info))
+               panic("failed to init sysfs_backing_dev_info");
 }
 
 static struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)
@@ -67,7 +62,7 @@ static struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)
        return attrs;
 }
 
-int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr)
+static int __kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr)
 {
        struct sysfs_inode_attrs *sd_attrs;
        struct iattr *iattrs;
@@ -102,6 +97,23 @@ int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr)
        return 0;
 }
 
+/**
+ * kernfs_setattr - set iattr on a node
+ * @sd: target node
+ * @iattr: iattr to set
+ *
+ * Returns 0 on success, -errno on failure.
+ */
+int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr)
+{
+       int ret;
+
+       mutex_lock(&sysfs_mutex);
+       ret = __kernfs_setattr(sd, iattr);
+       mutex_unlock(&sysfs_mutex);
+       return ret;
+}
+
 int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
 {
        struct inode *inode = dentry->d_inode;
@@ -116,7 +128,7 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
        if (error)
                goto out;
 
-       error = sysfs_sd_setattr(sd, iattr);
+       error = __kernfs_setattr(sd, iattr);
        if (error)
                goto out;
 
@@ -237,9 +249,8 @@ int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
 
 static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
 {
-       struct bin_attribute *bin_attr;
-
-       inode->i_private = sysfs_get(sd);
+       kernfs_get(sd);
+       inode->i_private = sd;
        inode->i_mapping->a_ops = &sysfs_aops;
        inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
        inode->i_op = &sysfs_inode_operations;
@@ -254,13 +265,8 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
                inode->i_fop = &sysfs_dir_operations;
                break;
        case SYSFS_KOBJ_ATTR:
-               inode->i_size = PAGE_SIZE;
-               inode->i_fop = &sysfs_file_operations;
-               break;
-       case SYSFS_KOBJ_BIN_ATTR:
-               bin_attr = sd->s_attr.bin_attr;
-               inode->i_size = bin_attr->size;
-               inode->i_fop = &sysfs_bin_operations;
+               inode->i_size = sd->s_attr.size;
+               inode->i_fop = &kernfs_file_operations;
                break;
        case SYSFS_KOBJ_LINK:
                inode->i_op = &sysfs_symlink_inode_operations;
@@ -311,7 +317,7 @@ void sysfs_evict_inode(struct inode *inode)
 
        truncate_inode_pages(&inode->i_data, 0);
        clear_inode(inode);
-       sysfs_put(sd);
+       kernfs_put(sd);
 }
 
 int sysfs_permission(struct inode *inode, int mask)
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
new file mode 100644 (file)
index 0000000..d1ff591
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * fs/kernfs/kernfs-internal.h - kernfs internal header file
+ *
+ * Copyright (c) 2001-3 Patrick Mochel
+ * Copyright (c) 2007 SUSE Linux Products GmbH
+ * Copyright (c) 2007, 2013 Tejun Heo <teheo@suse.de>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#ifndef __KERNFS_INTERNAL_H
+#define __KERNFS_INTERNAL_H
+
+#include <linux/lockdep.h>
+#include <linux/fs.h>
+#include <linux/mutex.h>
+
+#include <linux/kernfs.h>
+
+struct sysfs_inode_attrs {
+       struct iattr    ia_iattr;
+       void            *ia_secdata;
+       u32             ia_secdata_len;
+};
+
+#define SD_DEACTIVATED_BIAS            INT_MIN
+
+/* SYSFS_TYPE_MASK and types are defined in include/linux/kernfs.h */
+
+/**
+ * kernfs_root - find out the kernfs_root a sysfs_dirent belongs to
+ * @sd: sysfs_dirent of interest
+ *
+ * Return the kernfs_root @sd belongs to.
+ */
+static inline struct kernfs_root *kernfs_root(struct sysfs_dirent *sd)
+{
+       /* if parent exists, it's always a dir; otherwise, @sd is a dir */
+       if (sd->s_parent)
+               sd = sd->s_parent;
+       return sd->s_dir.root;
+}
+
+/*
+ * Context structure to be used while adding/removing nodes.
+ */
+struct sysfs_addrm_cxt {
+       struct sysfs_dirent     *removed;
+};
+
+/*
+ * mount.c
+ */
+struct sysfs_super_info {
+       /*
+        * The root associated with this super_block.  Each super_block is
+        * identified by the root and ns it's associated with.
+        */
+       struct kernfs_root      *root;
+
+       /*
+        * Each sb is associated with one namespace tag, currently the network
+        * namespace of the task which mounted this sysfs instance.  If multiple
+        * tags become necessary, make the following an array and compare
+        * sysfs_dirent tag against every entry.
+        */
+       const void              *ns;
+};
+#define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info))
+
+extern struct kmem_cache *sysfs_dir_cachep;
+
+/*
+ * inode.c
+ */
+struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd);
+void sysfs_evict_inode(struct inode *inode);
+int sysfs_permission(struct inode *inode, int mask);
+int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
+int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                 struct kstat *stat);
+int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+                  size_t size, int flags);
+void sysfs_inode_init(void);
+
+/*
+ * dir.c
+ */
+extern struct mutex sysfs_mutex;
+extern const struct dentry_operations sysfs_dentry_ops;
+extern const struct file_operations sysfs_dir_operations;
+extern const struct inode_operations sysfs_dir_inode_operations;
+
+struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
+void sysfs_put_active(struct sysfs_dirent *sd);
+void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt);
+int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
+                 struct sysfs_dirent *parent_sd);
+void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
+struct sysfs_dirent *sysfs_new_dirent(struct kernfs_root *root,
+                                     const char *name, umode_t mode, int type);
+
+/*
+ * file.c
+ */
+extern const struct file_operations kernfs_file_operations;
+
+void sysfs_unmap_bin_file(struct sysfs_dirent *sd);
+
+/*
+ * symlink.c
+ */
+extern const struct inode_operations sysfs_symlink_inode_operations;
+
+#endif /* __KERNFS_INTERNAL_H */
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c
new file mode 100644 (file)
index 0000000..84c83e2
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * fs/kernfs/mount.c - kernfs mount implementation
+ *
+ * Copyright (c) 2001-3 Patrick Mochel
+ * Copyright (c) 2007 SUSE Linux Products GmbH
+ * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/init.h>
+#include <linux/magic.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+
+#include "kernfs-internal.h"
+
+struct kmem_cache *sysfs_dir_cachep;
+
+static const struct super_operations sysfs_ops = {
+       .statfs         = simple_statfs,
+       .drop_inode     = generic_delete_inode,
+       .evict_inode    = sysfs_evict_inode,
+};
+
+static int sysfs_fill_super(struct super_block *sb)
+{
+       struct sysfs_super_info *info = sysfs_info(sb);
+       struct inode *inode;
+       struct dentry *root;
+
+       sb->s_blocksize = PAGE_CACHE_SIZE;
+       sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+       sb->s_magic = SYSFS_MAGIC;
+       sb->s_op = &sysfs_ops;
+       sb->s_time_gran = 1;
+
+       /* get root inode, initialize and unlock it */
+       mutex_lock(&sysfs_mutex);
+       inode = sysfs_get_inode(sb, info->root->sd);
+       mutex_unlock(&sysfs_mutex);
+       if (!inode) {
+               pr_debug("sysfs: could not get root inode\n");
+               return -ENOMEM;
+       }
+
+       /* instantiate and link root dentry */
+       root = d_make_root(inode);
+       if (!root) {
+               pr_debug("%s: could not get root dentry!\n", __func__);
+               return -ENOMEM;
+       }
+       kernfs_get(info->root->sd);
+       root->d_fsdata = info->root->sd;
+       sb->s_root = root;
+       sb->s_d_op = &sysfs_dentry_ops;
+       return 0;
+}
+
+static int sysfs_test_super(struct super_block *sb, void *data)
+{
+       struct sysfs_super_info *sb_info = sysfs_info(sb);
+       struct sysfs_super_info *info = data;
+
+       return sb_info->root == info->root && sb_info->ns == info->ns;
+}
+
+static int sysfs_set_super(struct super_block *sb, void *data)
+{
+       int error;
+       error = set_anon_super(sb, data);
+       if (!error)
+               sb->s_fs_info = data;
+       return error;
+}
+
+/**
+ * kernfs_super_ns - determine the namespace tag of a kernfs super_block
+ * @sb: super_block of interest
+ *
+ * Return the namespace tag associated with kernfs super_block @sb.
+ */
+const void *kernfs_super_ns(struct super_block *sb)
+{
+       struct sysfs_super_info *info = sysfs_info(sb);
+
+       return info->ns;
+}
+
+/**
+ * kernfs_mount_ns - kernfs mount helper
+ * @fs_type: file_system_type of the fs being mounted
+ * @flags: mount flags specified for the mount
+ * @root: kernfs_root of the hierarchy being mounted
+ * @ns: optional namespace tag of the mount
+ *
+ * This is to be called from each kernfs user's file_system_type->mount()
+ * implementation, which should pass through the specified @fs_type and
+ * @flags, and specify the hierarchy and namespace tag to mount via @root
+ * and @ns, respectively.
+ *
+ * The return value can be passed to the vfs layer verbatim.
+ */
+struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags,
+                              struct kernfs_root *root, const void *ns)
+{
+       struct super_block *sb;
+       struct sysfs_super_info *info;
+       int error;
+
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return ERR_PTR(-ENOMEM);
+
+       info->root = root;
+       info->ns = ns;
+
+       sb = sget(fs_type, sysfs_test_super, sysfs_set_super, flags, info);
+       if (IS_ERR(sb) || sb->s_fs_info != info)
+               kfree(info);
+       if (IS_ERR(sb))
+               return ERR_CAST(sb);
+       if (!sb->s_root) {
+               error = sysfs_fill_super(sb);
+               if (error) {
+                       deactivate_locked_super(sb);
+                       return ERR_PTR(error);
+               }
+               sb->s_flags |= MS_ACTIVE;
+       }
+
+       return dget(sb->s_root);
+}
+
+/**
+ * kernfs_kill_sb - kill_sb for kernfs
+ * @sb: super_block being killed
+ *
+ * This can be used directly for file_system_type->kill_sb().  If a kernfs
+ * user needs extra cleanup, it can implement its own kill_sb() and call
+ * this function at the end.
+ */
+void kernfs_kill_sb(struct super_block *sb)
+{
+       struct sysfs_super_info *info = sysfs_info(sb);
+       struct sysfs_dirent *root_sd = sb->s_root->d_fsdata;
+
+       /*
+        * Remove the superblock from fs_supers/s_instances
+        * so we can't find it, before freeing sysfs_super_info.
+        */
+       kill_anon_super(sb);
+       kfree(info);
+       kernfs_put(root_sd);
+}
+
+void __init kernfs_init(void)
+{
+       sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
+                                             sizeof(struct sysfs_dirent),
+                                             0, SLAB_PANIC, NULL);
+       sysfs_inode_init();
+}
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c
new file mode 100644 (file)
index 0000000..12569a7
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * fs/kernfs/symlink.c - kernfs symlink implementation
+ *
+ * Copyright (c) 2001-3 Patrick Mochel
+ * Copyright (c) 2007 SUSE Linux Products GmbH
+ * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/fs.h>
+#include <linux/gfp.h>
+#include <linux/namei.h>
+
+#include "kernfs-internal.h"
+
+/**
+ * kernfs_create_link - create a symlink
+ * @parent: directory to create the symlink in
+ * @name: name of the symlink
+ * @target: target node for the symlink to point to
+ *
+ * Returns the created node on success, ERR_PTR() value on error.
+ */
+struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent,
+                                       const char *name,
+                                       struct sysfs_dirent *target)
+{
+       struct sysfs_dirent *sd;
+       struct sysfs_addrm_cxt acxt;
+       int error;
+
+       sd = sysfs_new_dirent(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO,
+                             SYSFS_KOBJ_LINK);
+       if (!sd)
+               return ERR_PTR(-ENOMEM);
+
+       if (kernfs_ns_enabled(parent))
+               sd->s_ns = target->s_ns;
+       sd->s_symlink.target_sd = target;
+       kernfs_get(target);     /* ref owned by symlink */
+
+       sysfs_addrm_start(&acxt);
+       error = sysfs_add_one(&acxt, sd, parent);
+       sysfs_addrm_finish(&acxt);
+
+       if (!error)
+               return sd;
+
+       kernfs_put(sd);
+       return ERR_PTR(error);
+}
+
+static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
+                                struct sysfs_dirent *target_sd, char *path)
+{
+       struct sysfs_dirent *base, *sd;
+       char *s = path;
+       int len = 0;
+
+       /* go up to the root, stop at the base */
+       base = parent_sd;
+       while (base->s_parent) {
+               sd = target_sd->s_parent;
+               while (sd->s_parent && base != sd)
+                       sd = sd->s_parent;
+
+               if (base == sd)
+                       break;
+
+               strcpy(s, "../");
+               s += 3;
+               base = base->s_parent;
+       }
+
+       /* determine end of target string for reverse fillup */
+       sd = target_sd;
+       while (sd->s_parent && sd != base) {
+               len += strlen(sd->s_name) + 1;
+               sd = sd->s_parent;
+       }
+
+       /* check limits */
+       if (len < 2)
+               return -EINVAL;
+       len--;
+       if ((s - path) + len > PATH_MAX)
+               return -ENAMETOOLONG;
+
+       /* reverse fillup of target string from target to base */
+       sd = target_sd;
+       while (sd->s_parent && sd != base) {
+               int slen = strlen(sd->s_name);
+
+               len -= slen;
+               strncpy(s + len, sd->s_name, slen);
+               if (len)
+                       s[--len] = '/';
+
+               sd = sd->s_parent;
+       }
+
+       return 0;
+}
+
+static int sysfs_getlink(struct dentry *dentry, char *path)
+{
+       struct sysfs_dirent *sd = dentry->d_fsdata;
+       struct sysfs_dirent *parent_sd = sd->s_parent;
+       struct sysfs_dirent *target_sd = sd->s_symlink.target_sd;
+       int error;
+
+       mutex_lock(&sysfs_mutex);
+       error = sysfs_get_target_path(parent_sd, target_sd, path);
+       mutex_unlock(&sysfs_mutex);
+
+       return error;
+}
+
+static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+       int error = -ENOMEM;
+       unsigned long page = get_zeroed_page(GFP_KERNEL);
+       if (page) {
+               error = sysfs_getlink(dentry, (char *) page);
+               if (error < 0)
+                       free_page((unsigned long)page);
+       }
+       nd_set_link(nd, error ? ERR_PTR(error) : (char *)page);
+       return NULL;
+}
+
+static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd,
+                          void *cookie)
+{
+       char *page = nd_get_link(nd);
+       if (!IS_ERR(page))
+               free_page((unsigned long)page);
+}
+
+const struct inode_operations sysfs_symlink_inode_operations = {
+       .setxattr       = sysfs_setxattr,
+       .readlink       = generic_readlink,
+       .follow_link    = sysfs_follow_link,
+       .put_link       = sysfs_put_link,
+       .setattr        = sysfs_setattr,
+       .getattr        = sysfs_getattr,
+       .permission     = sysfs_permission,
+};
index 550475ca6a0e0ec35c82d90b10372f2e4434fe90..76279e11982d854c9b22312cf51b3bd3a97e256d 100644 (file)
 
 #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
 
-static void request_complete(struct bio *bio, int err)
-{
-       complete((struct completion *)bio->bi_private);
-}
-
 static int sync_request(struct page *page, struct block_device *bdev, int rw)
 {
        struct bio bio;
        struct bio_vec bio_vec;
-       struct completion complete;
 
        bio_init(&bio);
        bio.bi_max_vecs = 1;
@@ -32,16 +26,11 @@ static int sync_request(struct page *page, struct block_device *bdev, int rw)
        bio_vec.bv_len = PAGE_SIZE;
        bio_vec.bv_offset = 0;
        bio.bi_vcnt = 1;
-       bio.bi_size = PAGE_SIZE;
        bio.bi_bdev = bdev;
-       bio.bi_sector = page->index * (PAGE_SIZE >> 9);
-       init_completion(&complete);
-       bio.bi_private = &complete;
-       bio.bi_end_io = request_complete;
-
-       submit_bio(rw, &bio);
-       wait_for_completion(&complete);
-       return test_bit(BIO_UPTODATE, &bio.bi_flags) ? 0 : -EIO;
+       bio.bi_iter.bi_sector = page->index * (PAGE_SIZE >> 9);
+       bio.bi_iter.bi_size = PAGE_SIZE;
+
+       return submit_bio_wait(rw, &bio);
 }
 
 static int bdev_readpage(void *_sb, struct page *page)
@@ -67,22 +56,18 @@ static DECLARE_WAIT_QUEUE_HEAD(wq);
 static void writeseg_end_io(struct bio *bio, int err)
 {
        const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+       struct bio_vec *bvec;
+       int i;
        struct super_block *sb = bio->bi_private;
        struct logfs_super *super = logfs_super(sb);
-       struct page *page;
 
        BUG_ON(!uptodate); /* FIXME: Retry io or write elsewhere */
        BUG_ON(err);
-       BUG_ON(bio->bi_vcnt == 0);
-       do {
-               page = bvec->bv_page;
-               if (--bvec >= bio->bi_io_vec)
-                       prefetchw(&bvec->bv_page->flags);
-
-               end_page_writeback(page);
-               page_cache_release(page);
-       } while (bvec >= bio->bi_io_vec);
+
+       bio_for_each_segment_all(bvec, bio, i) {
+               end_page_writeback(bvec->bv_page);
+               page_cache_release(bvec->bv_page);
+       }
        bio_put(bio);
        if (atomic_dec_and_test(&super->s_pending_writes))
                wake_up(&wq);
@@ -107,9 +92,9 @@ static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
                if (i >= max_pages) {
                        /* Block layer cannot split bios :( */
                        bio->bi_vcnt = i;
-                       bio->bi_size = i * PAGE_SIZE;
+                       bio->bi_iter.bi_size = i * PAGE_SIZE;
                        bio->bi_bdev = super->s_bdev;
-                       bio->bi_sector = ofs >> 9;
+                       bio->bi_iter.bi_sector = ofs >> 9;
                        bio->bi_private = sb;
                        bio->bi_end_io = writeseg_end_io;
                        atomic_inc(&super->s_pending_writes);
@@ -134,9 +119,9 @@ static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
                unlock_page(page);
        }
        bio->bi_vcnt = nr_pages;
-       bio->bi_size = nr_pages * PAGE_SIZE;
+       bio->bi_iter.bi_size = nr_pages * PAGE_SIZE;
        bio->bi_bdev = super->s_bdev;
-       bio->bi_sector = ofs >> 9;
+       bio->bi_iter.bi_sector = ofs >> 9;
        bio->bi_private = sb;
        bio->bi_end_io = writeseg_end_io;
        atomic_inc(&super->s_pending_writes);
@@ -199,9 +184,9 @@ static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index,
                if (i >= max_pages) {
                        /* Block layer cannot split bios :( */
                        bio->bi_vcnt = i;
-                       bio->bi_size = i * PAGE_SIZE;
+                       bio->bi_iter.bi_size = i * PAGE_SIZE;
                        bio->bi_bdev = super->s_bdev;
-                       bio->bi_sector = ofs >> 9;
+                       bio->bi_iter.bi_sector = ofs >> 9;
                        bio->bi_private = sb;
                        bio->bi_end_io = erase_end_io;
                        atomic_inc(&super->s_pending_writes);
@@ -220,9 +205,9 @@ static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index,
                bio->bi_io_vec[i].bv_offset = 0;
        }
        bio->bi_vcnt = nr_pages;
-       bio->bi_size = nr_pages * PAGE_SIZE;
+       bio->bi_iter.bi_size = nr_pages * PAGE_SIZE;
        bio->bi_bdev = super->s_bdev;
-       bio->bi_sector = ofs >> 9;
+       bio->bi_iter.bi_sector = ofs >> 9;
        bio->bi_private = sb;
        bio->bi_end_io = erase_end_io;
        atomic_inc(&super->s_pending_writes);
index 9c501449450dc9be6891e5d9c1a035ca31b5687b..427bb73e298f197d4cfc73b17baeffdd1c848c5d 100644 (file)
@@ -245,8 +245,8 @@ static int logfs_mtd_can_write_buf(struct super_block *sb, u64 ofs)
                goto out;
        if (memchr_inv(buf, 0xff, super->s_writesize))
                err = -EIO;
-       kfree(buf);
 out:
+       kfree(buf);
        return err;
 }
 
index 54360293bcb5cd0680c3042e6f0b9b87e342c649..b256c0690e5b66f5b16a2b81be033cc3b345dec6 100644 (file)
@@ -287,14 +287,14 @@ static int logfs_make_writeable(struct super_block *sb)
        if (err)
                return err;
 
+       /* Do one GC pass before any data gets dirtied */
+       logfs_gc_pass(sb);
+
        /* Check areas for trailing unaccounted data */
        err = logfs_check_areas(sb);
        if (err)
                return err;
 
-       /* Do one GC pass before any data gets dirtied */
-       logfs_gc_pass(sb);
-
        /* after all initializations are done, replay the journal
         * for rw-mounts, if necessary */
        err = logfs_replay_journal(sb);
index 0face1c4d4c6bd4ea33cb60e45b8c7fad8235acf..4979ffa60aaabfd36839adec6feafcb17a876d98 100644 (file)
  */
 static void mpage_end_io(struct bio *bio, int err)
 {
-       const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+       struct bio_vec *bv;
+       int i;
 
-       do {
-               struct page *page = bvec->bv_page;
+       bio_for_each_segment_all(bv, bio, i) {
+               struct page *page = bv->bv_page;
 
-               if (--bvec >= bio->bi_io_vec)
-                       prefetchw(&bvec->bv_page->flags);
                if (bio_data_dir(bio) == READ) {
-                       if (uptodate) {
+                       if (!err) {
                                SetPageUptodate(page);
                        } else {
                                ClearPageUptodate(page);
@@ -60,14 +58,15 @@ static void mpage_end_io(struct bio *bio, int err)
                        }
                        unlock_page(page);
                } else { /* bio_data_dir(bio) == WRITE */
-                       if (!uptodate) {
+                       if (err) {
                                SetPageError(page);
                                if (page->mapping)
                                        set_bit(AS_EIO, &page->mapping->flags);
                        }
                        end_page_writeback(page);
                }
-       } while (bvec >= bio->bi_io_vec);
+       }
+
        bio_put(bio);
 }
 
@@ -94,7 +93,7 @@ mpage_alloc(struct block_device *bdev,
 
        if (bio) {
                bio->bi_bdev = bdev;
-               bio->bi_sector = first_sector;
+               bio->bi_iter.bi_sector = first_sector;
        }
        return bio;
 }
index 8f77a8cea289350b9d0e427b284cc01a2df4691d..c53d3a9547f9295408fa3cfe0d5abfb72023e29e 100644 (file)
@@ -513,8 +513,7 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry)
 
        if (!lockref_get_not_dead(&parent->d_lockref)) {
                nd->path.dentry = NULL; 
-               rcu_read_unlock();
-               return -ECHILD;
+               goto out;
        }
 
        /*
index ac2ce8a766e1a9c6250cdac616f9a951dddee45e..a511ea003f89aba28f66023f680c4de1873797ff 100644 (file)
@@ -2790,6 +2790,8 @@ void __init mnt_init(void)
        for (u = 0; u < HASH_SIZE; u++)
                INIT_LIST_HEAD(&mountpoint_hashtable[u]);
 
+       kernfs_init();
+
        err = sysfs_init();
        if (err)
                printk(KERN_WARNING "%s: sysfs_init error: %d\n",
index e242bbf729723d1d45ae0cac7370952167b026cd..56ff823ca82e0979f08355f80aaf75ae4a019393 100644 (file)
@@ -134,8 +134,8 @@ bl_submit_bio(int rw, struct bio *bio)
        if (bio) {
                get_parallel(bio->bi_private);
                dprintk("%s submitting %s bio %u@%llu\n", __func__,
-                       rw == READ ? "read" : "write",
-                       bio->bi_size, (unsigned long long)bio->bi_sector);
+                       rw == READ ? "read" : "write", bio->bi_iter.bi_size,
+                       (unsigned long long)bio->bi_iter.bi_sector);
                submit_bio(rw, bio);
        }
        return NULL;
@@ -156,7 +156,8 @@ static struct bio *bl_alloc_init_bio(int npg, sector_t isect,
        }
 
        if (bio) {
-               bio->bi_sector = isect - be->be_f_offset + be->be_v_offset;
+               bio->bi_iter.bi_sector = isect - be->be_f_offset +
+                       be->be_v_offset;
                bio->bi_bdev = be->be_mdev;
                bio->bi_end_io = end_io;
                bio->bi_private = par;
@@ -201,18 +202,14 @@ static struct bio *bl_add_page_to_bio(struct bio *bio, int npg, int rw,
 static void bl_end_io_read(struct bio *bio, int err)
 {
        struct parallel_io *par = bio->bi_private;
-       const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+       struct bio_vec *bvec;
+       int i;
 
-       do {
-               struct page *page = bvec->bv_page;
+       if (!err)
+               bio_for_each_segment_all(bvec, bio, i)
+                       SetPageUptodate(bvec->bv_page);
 
-               if (--bvec >= bio->bi_io_vec)
-                       prefetchw(&bvec->bv_page->flags);
-               if (uptodate)
-                       SetPageUptodate(page);
-       } while (bvec >= bio->bi_io_vec);
-       if (!uptodate) {
+       if (err) {
                struct nfs_read_data *rdata = par->data;
                struct nfs_pgio_header *header = rdata->header;
 
@@ -383,20 +380,16 @@ static void mark_extents_written(struct pnfs_block_layout *bl,
 static void bl_end_io_write_zero(struct bio *bio, int err)
 {
        struct parallel_io *par = bio->bi_private;
-       const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-
-       do {
-               struct page *page = bvec->bv_page;
+       struct bio_vec *bvec;
+       int i;
 
-               if (--bvec >= bio->bi_io_vec)
-                       prefetchw(&bvec->bv_page->flags);
+       bio_for_each_segment_all(bvec, bio, i) {
                /* This is the zeroing page we added */
-               end_page_writeback(page);
-               page_cache_release(page);
-       } while (bvec >= bio->bi_io_vec);
+               end_page_writeback(bvec->bv_page);
+               page_cache_release(bvec->bv_page);
+       }
 
-       if (unlikely(!uptodate)) {
+       if (unlikely(err)) {
                struct nfs_write_data *data = par->data;
                struct nfs_pgio_header *header = data->header;
 
@@ -519,7 +512,7 @@ bl_do_readpage_sync(struct page *page, struct pnfs_block_extent *be,
        isect = (page->index << PAGE_CACHE_SECTOR_SHIFT) +
                (offset / SECTOR_SIZE);
 
-       bio->bi_sector = isect - be->be_f_offset + be->be_v_offset;
+       bio->bi_iter.bi_sector = isect - be->be_f_offset + be->be_v_offset;
        bio->bi_bdev = be->be_mdev;
        bio->bi_end_io = bl_read_single_end_io;
 
index 8485978993e85bcbda9772b55a2ed26f5442a228..9838fb020473c935817b34da4a1127b4c75af3fe 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/nfs_fs.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 
+#include "../nfs4_fs.h"
 #include "../pnfs.h"
 #include "../netns.h"
 
index fc0f95ec73587f9fbcfa7fca24438da29012b5b9..d25f10fb4926b09dc39ac3f6f62a433d4bcdc58b 100644 (file)
@@ -46,7 +46,9 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
 #include <linux/sunrpc/cache.h>
 #include <linux/sunrpc/svcauth.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
+#include <linux/nfs_fs.h>
 
+#include "nfs4_fs.h"
 #include "dns_resolve.h"
 #include "cache_lib.h"
 #include "netns.h"
index 18ab2da4eeb65dbf7c8f7d7b578a35fc5251b0b6..00ad1c2b217ded2338c0ac4154681f83963581ab 100644 (file)
@@ -312,7 +312,7 @@ struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags)
 }
 EXPORT_SYMBOL_GPL(nfs4_label_alloc);
 #else
-void inline nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
+void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
                                        struct nfs4_label *label)
 {
 }
index bca6a3e3c49ce58e9cdfa1552e25afce2158584e..8b5cc04a86115e05f0a2e98e9b02a0b307b1b910 100644 (file)
@@ -269,6 +269,21 @@ extern const u32 nfs41_maxgetdevinfo_overhead;
 extern struct rpc_procinfo nfs4_procedures[];
 #endif
 
+#ifdef CONFIG_NFS_V4_SECURITY_LABEL
+extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags);
+static inline void nfs4_label_free(struct nfs4_label *label)
+{
+       if (label) {
+               kfree(label->label);
+               kfree(label);
+       }
+       return;
+}
+#else
+static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
+static inline void nfs4_label_free(void *label) {}
+#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
+
 /* proc.c */
 void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
 extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
index 3ce79b04522eb19b2ecee294c3a59a2b0c49b4b9..5609edc742a0fc42568c73e7d26b4c2feb336c33 100644 (file)
@@ -9,6 +9,14 @@
 #ifndef __LINUX_FS_NFS_NFS4_FS_H
 #define __LINUX_FS_NFS_NFS4_FS_H
 
+#if defined(CONFIG_NFS_V4_2)
+#define NFS4_MAX_MINOR_VERSION 2
+#elif defined(CONFIG_NFS_V4_1)
+#define NFS4_MAX_MINOR_VERSION 1
+#else
+#define NFS4_MAX_MINOR_VERSION 0
+#endif
+
 #if IS_ENABLED(CONFIG_NFS_V4)
 
 #define NFS4_MAX_LOOP_ON_RECOVER (10)
index 659990c0109e3173298b92385d585be566e161de..5ae9c56ee889083973accb2b8d72167014e632a3 100644 (file)
@@ -4802,7 +4802,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
                        dprintk("%s ERROR %d, Reset session\n", __func__,
                                task->tk_status);
                        nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
-                       goto restart_call;
+                       goto wait_on_recovery;
 #endif /* CONFIG_NFS_V4_1 */
                case -NFS4ERR_DELAY:
                        nfs_inc_server_stats(server, NFSIOS_DELAY);
@@ -4987,11 +4987,17 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
 
        trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status);
        switch (task->tk_status) {
-       case -NFS4ERR_STALE_STATEID:
-       case -NFS4ERR_EXPIRED:
        case 0:
                renew_lease(data->res.server, data->timestamp);
                break;
+       case -NFS4ERR_ADMIN_REVOKED:
+       case -NFS4ERR_DELEG_REVOKED:
+       case -NFS4ERR_BAD_STATEID:
+       case -NFS4ERR_OLD_STATEID:
+       case -NFS4ERR_STALE_STATEID:
+       case -NFS4ERR_EXPIRED:
+               task->tk_status = 0;
+               break;
        default:
                if (nfs4_async_handle_error(task, data->res.server, NULL) ==
                                -EAGAIN) {
index 2d8be51f90dc9257bf74cad77b719d17f781c739..dc3a9efdaab87751e47edcf9ef3a807fed4573db 100644 (file)
@@ -416,7 +416,8 @@ static struct bio *nilfs_alloc_seg_bio(struct the_nilfs *nilfs, sector_t start,
        }
        if (likely(bio)) {
                bio->bi_bdev = nilfs->ns_bdev;
-               bio->bi_sector = start << (nilfs->ns_blocksize_bits - 9);
+               bio->bi_iter.bi_sector =
+                       start << (nilfs->ns_blocksize_bits - 9);
        }
        return bio;
 }
index 73920ffda05b331c85ef1760d97083d1590a4a16..bf482dfed14fecf17406a6aa2d517929d6834800 100644 (file)
@@ -413,7 +413,7 @@ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,
        }
 
        /* Must put everything in 512 byte sectors for the bio... */
-       bio->bi_sector = (reg->hr_start_block + cs) << (bits - 9);
+       bio->bi_iter.bi_sector = (reg->hr_start_block + cs) << (bits - 9);
        bio->bi_bdev = reg->hr_bdev;
        bio->bi_private = wc;
        bio->bi_end_io = o2hb_bio_end_io;
index 2943b2bfae482ac83d352f317af4c074ce6597ae..62a0de6632e1aa3c8de599e19db3f8d7e2a383e2 100644 (file)
@@ -84,6 +84,9 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize)
                 */
                res = squashfs_read_cache(target_page, block, bsize, pages,
                                                                page);
+               if (res < 0)
+                       goto mark_errored;
+
                goto out;
        }
 
@@ -119,7 +122,7 @@ mark_errored:
         * dealt with by the caller
         */
        for (i = 0; i < pages; i++) {
-               if (page[i] == target_page)
+               if (page[i] == NULL || page[i] == target_page)
                        continue;
                flush_dcache_page(page[i]);
                SetPageError(page[i]);
index 8876ac18337319b16f0da09ea40a52f5c642478f..6eff6e1205a58582ccdfb5562fc1f787abe0bd9e 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for the sysfs virtual filesystem
 #
 
-obj-y          := inode.o file.o dir.o symlink.o mount.o group.o
+obj-y          := file.o dir.o symlink.o mount.o group.o
index 5e73d6626e50593ef95eeca259d71d6e8babbb55..2fea501889e756774da3ccd110088ff08c0d354e 100644 (file)
 #undef DEBUG
 
 #include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/module.h>
 #include <linux/kobject.h>
-#include <linux/namei.h>
-#include <linux/idr.h>
-#include <linux/completion.h>
-#include <linux/mutex.h>
 #include <linux/slab.h>
-#include <linux/security.h>
-#include <linux/hash.h>
 #include "sysfs.h"
 
-DEFINE_MUTEX(sysfs_mutex);
 DEFINE_SPINLOCK(sysfs_symlink_target_lock);
 
-#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb)
-
-static DEFINE_SPINLOCK(sysfs_ino_lock);
-static DEFINE_IDA(sysfs_ino_ida);
-
-/**
- *     sysfs_name_hash
- *     @name: Null terminated string to hash
- *     @ns:   Namespace tag to hash
- *
- *     Returns 31 bit hash of ns + name (so it fits in an off_t )
- */
-static unsigned int sysfs_name_hash(const char *name, const void *ns)
-{
-       unsigned long hash = init_name_hash();
-       unsigned int len = strlen(name);
-       while (len--)
-               hash = partial_name_hash(*name++, hash);
-       hash = (end_name_hash(hash) ^ hash_ptr((void *)ns, 31));
-       hash &= 0x7fffffffU;
-       /* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */
-       if (hash < 1)
-               hash += 2;
-       if (hash >= INT_MAX)
-               hash = INT_MAX - 1;
-       return hash;
-}
-
-static int sysfs_name_compare(unsigned int hash, const char *name,
-                             const void *ns, const struct sysfs_dirent *sd)
-{
-       if (hash != sd->s_hash)
-               return hash - sd->s_hash;
-       if (ns != sd->s_ns)
-               return ns - sd->s_ns;
-       return strcmp(name, sd->s_name);
-}
-
-static int sysfs_sd_compare(const struct sysfs_dirent *left,
-                           const struct sysfs_dirent *right)
-{
-       return sysfs_name_compare(left->s_hash, left->s_name, left->s_ns,
-                                 right);
-}
-
-/**
- *     sysfs_link_sibling - link sysfs_dirent into sibling rbtree
- *     @sd: sysfs_dirent of interest
- *
- *     Link @sd into its sibling rbtree which starts from
- *     sd->s_parent->s_dir.children.
- *
- *     Locking:
- *     mutex_lock(sysfs_mutex)
- *
- *     RETURNS:
- *     0 on susccess -EEXIST on failure.
- */
-static int sysfs_link_sibling(struct sysfs_dirent *sd)
-{
-       struct rb_node **node = &sd->s_parent->s_dir.children.rb_node;
-       struct rb_node *parent = NULL;
-
-       if (sysfs_type(sd) == SYSFS_DIR)
-               sd->s_parent->s_dir.subdirs++;
-
-       while (*node) {
-               struct sysfs_dirent *pos;
-               int result;
-
-               pos = to_sysfs_dirent(*node);
-               parent = *node;
-               result = sysfs_sd_compare(sd, pos);
-               if (result < 0)
-                       node = &pos->s_rb.rb_left;
-               else if (result > 0)
-                       node = &pos->s_rb.rb_right;
-               else
-                       return -EEXIST;
-       }
-       /* add new node and rebalance the tree */
-       rb_link_node(&sd->s_rb, parent, node);
-       rb_insert_color(&sd->s_rb, &sd->s_parent->s_dir.children);
-       return 0;
-}
-
-/**
- *     sysfs_unlink_sibling - unlink sysfs_dirent from sibling rbtree
- *     @sd: sysfs_dirent of interest
- *
- *     Unlink @sd from its sibling rbtree which starts from
- *     sd->s_parent->s_dir.children.
- *
- *     Locking:
- *     mutex_lock(sysfs_mutex)
- */
-static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
-{
-       if (sysfs_type(sd) == SYSFS_DIR)
-               sd->s_parent->s_dir.subdirs--;
-
-       rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children);
-}
-
-/**
- *     sysfs_get_active - get an active reference to sysfs_dirent
- *     @sd: sysfs_dirent to get an active reference to
- *
- *     Get an active reference of @sd.  This function is noop if @sd
- *     is NULL.
- *
- *     RETURNS:
- *     Pointer to @sd on success, NULL on failure.
- */
-struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
-{
-       if (unlikely(!sd))
-               return NULL;
-
-       if (!atomic_inc_unless_negative(&sd->s_active))
-               return NULL;
-
-       if (likely(!sysfs_ignore_lockdep(sd)))
-               rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_);
-       return sd;
-}
-
-/**
- *     sysfs_put_active - put an active reference to sysfs_dirent
- *     @sd: sysfs_dirent to put an active reference to
- *
- *     Put an active reference to @sd.  This function is noop if @sd
- *     is NULL.
- */
-void sysfs_put_active(struct sysfs_dirent *sd)
-{
-       int v;
-
-       if (unlikely(!sd))
-               return;
-
-       if (likely(!sysfs_ignore_lockdep(sd)))
-               rwsem_release(&sd->dep_map, 1, _RET_IP_);
-       v = atomic_dec_return(&sd->s_active);
-       if (likely(v != SD_DEACTIVATED_BIAS))
-               return;
-
-       /* atomic_dec_return() is a mb(), we'll always see the updated
-        * sd->u.completion.
-        */
-       complete(sd->u.completion);
-}
-
-/**
- *     sysfs_deactivate - deactivate sysfs_dirent
- *     @sd: sysfs_dirent to deactivate
- *
- *     Deny new active references and drain existing ones.
- */
-static void sysfs_deactivate(struct sysfs_dirent *sd)
-{
-       DECLARE_COMPLETION_ONSTACK(wait);
-       int v;
-
-       BUG_ON(!(sd->s_flags & SYSFS_FLAG_REMOVED));
-
-       if (!(sysfs_type(sd) & SYSFS_ACTIVE_REF))
-               return;
-
-       sd->u.completion = (void *)&wait;
-
-       rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_);
-       /* atomic_add_return() is a mb(), put_active() will always see
-        * the updated sd->u.completion.
-        */
-       v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active);
-
-       if (v != SD_DEACTIVATED_BIAS) {
-               lock_contended(&sd->dep_map, _RET_IP_);
-               wait_for_completion(&wait);
-       }
-
-       lock_acquired(&sd->dep_map, _RET_IP_);
-       rwsem_release(&sd->dep_map, 1, _RET_IP_);
-}
-
-static int sysfs_alloc_ino(unsigned int *pino)
-{
-       int ino, rc;
-
- retry:
-       spin_lock(&sysfs_ino_lock);
-       rc = ida_get_new_above(&sysfs_ino_ida, 2, &ino);
-       spin_unlock(&sysfs_ino_lock);
-
-       if (rc == -EAGAIN) {
-               if (ida_pre_get(&sysfs_ino_ida, GFP_KERNEL))
-                       goto retry;
-               rc = -ENOMEM;
-       }
-
-       *pino = ino;
-       return rc;
-}
-
-static void sysfs_free_ino(unsigned int ino)
-{
-       spin_lock(&sysfs_ino_lock);
-       ida_remove(&sysfs_ino_ida, ino);
-       spin_unlock(&sysfs_ino_lock);
-}
-
-void release_sysfs_dirent(struct sysfs_dirent *sd)
-{
-       struct sysfs_dirent *parent_sd;
-
- repeat:
-       /* Moving/renaming is always done while holding reference.
-        * sd->s_parent won't change beneath us.
-        */
-       parent_sd = sd->s_parent;
-
-       WARN(!(sd->s_flags & SYSFS_FLAG_REMOVED),
-               "sysfs: free using entry: %s/%s\n",
-               parent_sd ? parent_sd->s_name : "", sd->s_name);
-
-       if (sysfs_type(sd) == SYSFS_KOBJ_LINK)
-               sysfs_put(sd->s_symlink.target_sd);
-       if (sysfs_type(sd) & SYSFS_COPY_NAME)
-               kfree(sd->s_name);
-       if (sd->s_iattr && sd->s_iattr->ia_secdata)
-               security_release_secctx(sd->s_iattr->ia_secdata,
-                                       sd->s_iattr->ia_secdata_len);
-       kfree(sd->s_iattr);
-       sysfs_free_ino(sd->s_ino);
-       kmem_cache_free(sysfs_dir_cachep, sd);
-
-       sd = parent_sd;
-       if (sd && atomic_dec_and_test(&sd->s_count))
-               goto repeat;
-}
-
-static int sysfs_dentry_delete(const struct dentry *dentry)
-{
-       struct sysfs_dirent *sd = dentry->d_fsdata;
-       return !(sd && !(sd->s_flags & SYSFS_FLAG_REMOVED));
-}
-
-static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags)
-{
-       struct sysfs_dirent *sd;
-       int type;
-
-       if (flags & LOOKUP_RCU)
-               return -ECHILD;
-
-       sd = dentry->d_fsdata;
-       mutex_lock(&sysfs_mutex);
-
-       /* The sysfs dirent has been deleted */
-       if (sd->s_flags & SYSFS_FLAG_REMOVED)
-               goto out_bad;
-
-       /* The sysfs dirent has been moved? */
-       if (dentry->d_parent->d_fsdata != sd->s_parent)
-               goto out_bad;
-
-       /* The sysfs dirent has been renamed */
-       if (strcmp(dentry->d_name.name, sd->s_name) != 0)
-               goto out_bad;
-
-       /* The sysfs dirent has been moved to a different namespace */
-       type = KOBJ_NS_TYPE_NONE;
-       if (sd->s_parent) {
-               type = sysfs_ns_type(sd->s_parent);
-               if (type != KOBJ_NS_TYPE_NONE &&
-                               sysfs_info(dentry->d_sb)->ns[type] != sd->s_ns)
-                       goto out_bad;
-       }
-
-       mutex_unlock(&sysfs_mutex);
-out_valid:
-       return 1;
-out_bad:
-       /* Remove the dentry from the dcache hashes.
-        * If this is a deleted dentry we use d_drop instead of d_delete
-        * so sysfs doesn't need to cope with negative dentries.
-        *
-        * If this is a dentry that has simply been renamed we
-        * use d_drop to remove it from the dcache lookup on its
-        * old parent.  If this dentry persists later when a lookup
-        * is performed at its new name the dentry will be readded
-        * to the dcache hashes.
-        */
-       mutex_unlock(&sysfs_mutex);
-
-       /* If we have submounts we must allow the vfs caches
-        * to lie about the state of the filesystem to prevent
-        * leaks and other nasty things.
-        */
-       if (check_submounts_and_drop(dentry) != 0)
-               goto out_valid;
-
-       return 0;
-}
-
-static void sysfs_dentry_release(struct dentry *dentry)
-{
-       sysfs_put(dentry->d_fsdata);
-}
-
-const struct dentry_operations sysfs_dentry_ops = {
-       .d_revalidate   = sysfs_dentry_revalidate,
-       .d_delete       = sysfs_dentry_delete,
-       .d_release      = sysfs_dentry_release,
-};
-
-struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
-{
-       char *dup_name = NULL;
-       struct sysfs_dirent *sd;
-
-       if (type & SYSFS_COPY_NAME) {
-               name = dup_name = kstrdup(name, GFP_KERNEL);
-               if (!name)
-                       return NULL;
-       }
-
-       sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL);
-       if (!sd)
-               goto err_out1;
-
-       if (sysfs_alloc_ino(&sd->s_ino))
-               goto err_out2;
-
-       atomic_set(&sd->s_count, 1);
-       atomic_set(&sd->s_active, 0);
-
-       sd->s_name = name;
-       sd->s_mode = mode;
-       sd->s_flags = type | SYSFS_FLAG_REMOVED;
-
-       return sd;
-
- err_out2:
-       kmem_cache_free(sysfs_dir_cachep, sd);
- err_out1:
-       kfree(dup_name);
-       return NULL;
-}
-
-/**
- *     sysfs_addrm_start - prepare for sysfs_dirent add/remove
- *     @acxt: pointer to sysfs_addrm_cxt to be used
- *
- *     This function is called when the caller is about to add or remove
- *     sysfs_dirent.  This function acquires sysfs_mutex.  @acxt is used
- *     to keep and pass context to other addrm functions.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).  sysfs_mutex is locked on
- *     return.
- */
-void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt)
-       __acquires(sysfs_mutex)
-{
-       memset(acxt, 0, sizeof(*acxt));
-
-       mutex_lock(&sysfs_mutex);
-}
-
-/**
- *     __sysfs_add_one - add sysfs_dirent to parent without warning
- *     @acxt: addrm context to use
- *     @sd: sysfs_dirent to be added
- *     @parent_sd: the parent sysfs_dirent to add @sd to
- *
- *     Get @parent_sd and set @sd->s_parent to it and increment nlink of
- *     the parent inode if @sd is a directory and link into the children
- *     list of the parent.
- *
- *     This function should be called between calls to
- *     sysfs_addrm_start() and sysfs_addrm_finish() and should be
- *     passed the same @acxt as passed to sysfs_addrm_start().
- *
- *     LOCKING:
- *     Determined by sysfs_addrm_start().
- *
- *     RETURNS:
- *     0 on success, -EEXIST if entry with the given name already
- *     exists.
- */
-int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
-                   struct sysfs_dirent *parent_sd)
-{
-       struct sysfs_inode_attrs *ps_iattr;
-       int ret;
-
-       if (!!sysfs_ns_type(parent_sd) != !!sd->s_ns) {
-               WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
-                       sysfs_ns_type(parent_sd) ? "required" : "invalid",
-                       parent_sd->s_name, sd->s_name);
-               return -EINVAL;
-       }
-
-       sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
-       sd->s_parent = sysfs_get(parent_sd);
-
-       ret = sysfs_link_sibling(sd);
-       if (ret)
-               return ret;
-
-       /* Update timestamps on the parent */
-       ps_iattr = parent_sd->s_iattr;
-       if (ps_iattr) {
-               struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
-               ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
-       }
-
-       /* Mark the entry added into directory tree */
-       sd->s_flags &= ~SYSFS_FLAG_REMOVED;
-
-       return 0;
-}
-
 /**
  *     sysfs_pathname - return full path to sysfs dirent
  *     @sd: sysfs_dirent whose path we want
@@ -488,248 +54,6 @@ void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name)
        kfree(path);
 }
 
-/**
- *     sysfs_add_one - add sysfs_dirent to parent
- *     @acxt: addrm context to use
- *     @sd: sysfs_dirent to be added
- *     @parent_sd: the parent sysfs_dirent to add @sd to
- *
- *     Get @parent_sd and set @sd->s_parent to it and increment nlink of
- *     the parent inode if @sd is a directory and link into the children
- *     list of the parent.
- *
- *     This function should be called between calls to
- *     sysfs_addrm_start() and sysfs_addrm_finish() and should be
- *     passed the same @acxt as passed to sysfs_addrm_start().
- *
- *     LOCKING:
- *     Determined by sysfs_addrm_start().
- *
- *     RETURNS:
- *     0 on success, -EEXIST if entry with the given name already
- *     exists.
- */
-int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
-                 struct sysfs_dirent *parent_sd)
-{
-       int ret;
-
-       ret = __sysfs_add_one(acxt, sd, parent_sd);
-
-       if (ret == -EEXIST)
-               sysfs_warn_dup(parent_sd, sd->s_name);
-       return ret;
-}
-
-/**
- *     sysfs_remove_one - remove sysfs_dirent from parent
- *     @acxt: addrm context to use
- *     @sd: sysfs_dirent to be removed
- *
- *     Mark @sd removed and drop nlink of parent inode if @sd is a
- *     directory.  @sd is unlinked from the children list.
- *
- *     This function should be called between calls to
- *     sysfs_addrm_start() and sysfs_addrm_finish() and should be
- *     passed the same @acxt as passed to sysfs_addrm_start().
- *
- *     LOCKING:
- *     Determined by sysfs_addrm_start().
- */
-static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
-                            struct sysfs_dirent *sd)
-{
-       struct sysfs_inode_attrs *ps_iattr;
-
-       /*
-        * Removal can be called multiple times on the same node.  Only the
-        * first invocation is effective and puts the base ref.
-        */
-       if (sd->s_flags & SYSFS_FLAG_REMOVED)
-               return;
-
-       sysfs_unlink_sibling(sd);
-
-       /* Update timestamps on the parent */
-       ps_iattr = sd->s_parent->s_iattr;
-       if (ps_iattr) {
-               struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
-               ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
-       }
-
-       sd->s_flags |= SYSFS_FLAG_REMOVED;
-       sd->u.removed_list = acxt->removed;
-       acxt->removed = sd;
-}
-
-/**
- *     sysfs_addrm_finish - finish up sysfs_dirent add/remove
- *     @acxt: addrm context to finish up
- *
- *     Finish up sysfs_dirent add/remove.  Resources acquired by
- *     sysfs_addrm_start() are released and removed sysfs_dirents are
- *     cleaned up.
- *
- *     LOCKING:
- *     sysfs_mutex is released.
- */
-void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
-       __releases(sysfs_mutex)
-{
-       /* release resources acquired by sysfs_addrm_start() */
-       mutex_unlock(&sysfs_mutex);
-
-       /* kill removed sysfs_dirents */
-       while (acxt->removed) {
-               struct sysfs_dirent *sd = acxt->removed;
-
-               acxt->removed = sd->u.removed_list;
-
-               sysfs_deactivate(sd);
-               sysfs_unmap_bin_file(sd);
-               sysfs_put(sd);
-       }
-}
-
-/**
- *     sysfs_find_dirent - find sysfs_dirent with the given name
- *     @parent_sd: sysfs_dirent to search under
- *     @name: name to look for
- *     @ns: the namespace tag to use
- *
- *     Look for sysfs_dirent with name @name under @parent_sd.
- *
- *     LOCKING:
- *     mutex_lock(sysfs_mutex)
- *
- *     RETURNS:
- *     Pointer to sysfs_dirent if found, NULL if not.
- */
-struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
-                                      const unsigned char *name,
-                                      const void *ns)
-{
-       struct rb_node *node = parent_sd->s_dir.children.rb_node;
-       unsigned int hash;
-
-       if (!!sysfs_ns_type(parent_sd) != !!ns) {
-               WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
-                       sysfs_ns_type(parent_sd) ? "required" : "invalid",
-                       parent_sd->s_name, name);
-               return NULL;
-       }
-
-       hash = sysfs_name_hash(name, ns);
-       while (node) {
-               struct sysfs_dirent *sd;
-               int result;
-
-               sd = to_sysfs_dirent(node);
-               result = sysfs_name_compare(hash, name, ns, sd);
-               if (result < 0)
-                       node = node->rb_left;
-               else if (result > 0)
-                       node = node->rb_right;
-               else
-                       return sd;
-       }
-       return NULL;
-}
-
-/**
- *     sysfs_get_dirent_ns - find and get sysfs_dirent with the given name
- *     @parent_sd: sysfs_dirent to search under
- *     @name: name to look for
- *     @ns: the namespace tag to use
- *
- *     Look for sysfs_dirent with name @name under @parent_sd and get
- *     it if found.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).  Grabs sysfs_mutex.
- *
- *     RETURNS:
- *     Pointer to sysfs_dirent if found, NULL if not.
- */
-struct sysfs_dirent *sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd,
-                                        const unsigned char *name,
-                                        const void *ns)
-{
-       struct sysfs_dirent *sd;
-
-       mutex_lock(&sysfs_mutex);
-       sd = sysfs_find_dirent(parent_sd, name, ns);
-       sysfs_get(sd);
-       mutex_unlock(&sysfs_mutex);
-
-       return sd;
-}
-EXPORT_SYMBOL_GPL(sysfs_get_dirent_ns);
-
-static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
-                     enum kobj_ns_type type,
-                     const char *name, const void *ns,
-                     struct sysfs_dirent **p_sd)
-{
-       umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
-       struct sysfs_addrm_cxt acxt;
-       struct sysfs_dirent *sd;
-       int rc;
-
-       /* allocate */
-       sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
-       if (!sd)
-               return -ENOMEM;
-
-       sd->s_flags |= (type << SYSFS_NS_TYPE_SHIFT);
-       sd->s_ns = ns;
-       sd->s_dir.kobj = kobj;
-
-       /* link in */
-       sysfs_addrm_start(&acxt);
-       rc = sysfs_add_one(&acxt, sd, parent_sd);
-       sysfs_addrm_finish(&acxt);
-
-       if (rc == 0)
-               *p_sd = sd;
-       else
-               sysfs_put(sd);
-
-       return rc;
-}
-
-int sysfs_create_subdir(struct kobject *kobj, const char *name,
-                       struct sysfs_dirent **p_sd)
-{
-       return create_dir(kobj, kobj->sd,
-                         KOBJ_NS_TYPE_NONE, name, NULL, p_sd);
-}
-
-/**
- *     sysfs_read_ns_type: return associated ns_type
- *     @kobj: the kobject being queried
- *
- *     Each kobject can be tagged with exactly one namespace type
- *     (i.e. network or user).  Return the ns_type associated with
- *     this object if any
- */
-static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
-{
-       const struct kobj_ns_type_operations *ops;
-       enum kobj_ns_type type;
-
-       ops = kobj_child_ns_ops(kobj);
-       if (!ops)
-               return KOBJ_NS_TYPE_NONE;
-
-       type = ops->type;
-       BUG_ON(type <= KOBJ_NS_TYPE_NONE);
-       BUG_ON(type >= KOBJ_NS_TYPES);
-       BUG_ON(!kobj_ns_type_registered(type));
-
-       return type;
-}
-
 /**
  * sysfs_create_dir_ns - create a directory for an object with a namespace tag
  * @kobj: object we're creating directory for
@@ -737,197 +61,27 @@ static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
  */
 int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
 {
-       enum kobj_ns_type type;
        struct sysfs_dirent *parent_sd, *sd;
-       int error = 0;
 
        BUG_ON(!kobj);
 
        if (kobj->parent)
                parent_sd = kobj->parent->sd;
        else
-               parent_sd = &sysfs_root;
+               parent_sd = sysfs_root_sd;
 
        if (!parent_sd)
                return -ENOENT;
 
-       type = sysfs_read_ns_type(kobj);
-
-       error = create_dir(kobj, parent_sd, type, kobject_name(kobj), ns, &sd);
-       if (!error)
-               kobj->sd = sd;
-       return error;
-}
-
-static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry,
-                                  unsigned int flags)
-{
-       struct dentry *ret = NULL;
-       struct dentry *parent = dentry->d_parent;
-       struct sysfs_dirent *parent_sd = parent->d_fsdata;
-       struct sysfs_dirent *sd;
-       struct inode *inode;
-       enum kobj_ns_type type;
-       const void *ns;
-
-       mutex_lock(&sysfs_mutex);
-
-       type = sysfs_ns_type(parent_sd);
-       ns = sysfs_info(dir->i_sb)->ns[type];
-
-       sd = sysfs_find_dirent(parent_sd, dentry->d_name.name, ns);
-
-       /* no such entry */
-       if (!sd) {
-               ret = ERR_PTR(-ENOENT);
-               goto out_unlock;
-       }
-       dentry->d_fsdata = sysfs_get(sd);
-
-       /* attach dentry and inode */
-       inode = sysfs_get_inode(dir->i_sb, sd);
-       if (!inode) {
-               ret = ERR_PTR(-ENOMEM);
-               goto out_unlock;
+       sd = kernfs_create_dir_ns(parent_sd, kobject_name(kobj), kobj, ns);
+       if (IS_ERR(sd)) {
+               if (PTR_ERR(sd) == -EEXIST)
+                       sysfs_warn_dup(parent_sd, kobject_name(kobj));
+               return PTR_ERR(sd);
        }
 
-       /* instantiate and hash dentry */
-       ret = d_materialise_unique(dentry, inode);
- out_unlock:
-       mutex_unlock(&sysfs_mutex);
-       return ret;
-}
-
-const struct inode_operations sysfs_dir_inode_operations = {
-       .lookup         = sysfs_lookup,
-       .permission     = sysfs_permission,
-       .setattr        = sysfs_setattr,
-       .getattr        = sysfs_getattr,
-       .setxattr       = sysfs_setxattr,
-};
-
-static struct sysfs_dirent *sysfs_leftmost_descendant(struct sysfs_dirent *pos)
-{
-       struct sysfs_dirent *last;
-
-       while (true) {
-               struct rb_node *rbn;
-
-               last = pos;
-
-               if (sysfs_type(pos) != SYSFS_DIR)
-                       break;
-
-               rbn = rb_first(&pos->s_dir.children);
-               if (!rbn)
-                       break;
-
-               pos = to_sysfs_dirent(rbn);
-       }
-
-       return last;
-}
-
-/**
- * sysfs_next_descendant_post - find the next descendant for post-order walk
- * @pos: the current position (%NULL to initiate traversal)
- * @root: sysfs_dirent whose descendants to walk
- *
- * Find the next descendant to visit for post-order traversal of @root's
- * descendants.  @root is included in the iteration and the last node to be
- * visited.
- */
-static struct sysfs_dirent *sysfs_next_descendant_post(struct sysfs_dirent *pos,
-                                                      struct sysfs_dirent *root)
-{
-       struct rb_node *rbn;
-
-       lockdep_assert_held(&sysfs_mutex);
-
-       /* if first iteration, visit leftmost descendant which may be root */
-       if (!pos)
-               return sysfs_leftmost_descendant(root);
-
-       /* if we visited @root, we're done */
-       if (pos == root)
-               return NULL;
-
-       /* if there's an unvisited sibling, visit its leftmost descendant */
-       rbn = rb_next(&pos->s_rb);
-       if (rbn)
-               return sysfs_leftmost_descendant(to_sysfs_dirent(rbn));
-
-       /* no sibling left, visit parent */
-       return pos->s_parent;
-}
-
-static void __sysfs_remove(struct sysfs_addrm_cxt *acxt,
-                          struct sysfs_dirent *sd)
-{
-       struct sysfs_dirent *pos, *next;
-
-       if (!sd)
-               return;
-
-       pr_debug("sysfs %s: removing\n", sd->s_name);
-
-       next = NULL;
-       do {
-               pos = next;
-               next = sysfs_next_descendant_post(pos, sd);
-               if (pos)
-                       sysfs_remove_one(acxt, pos);
-       } while (next);
-}
-
-/**
- * sysfs_remove - remove a sysfs_dirent recursively
- * @sd: the sysfs_dirent to remove
- *
- * Remove @sd along with all its subdirectories and files.
- */
-void sysfs_remove(struct sysfs_dirent *sd)
-{
-       struct sysfs_addrm_cxt acxt;
-
-       sysfs_addrm_start(&acxt);
-       __sysfs_remove(&acxt, sd);
-       sysfs_addrm_finish(&acxt);
-}
-
-/**
- * sysfs_hash_and_remove - find a sysfs_dirent by name and remove it
- * @dir_sd: parent of the target
- * @name: name of the sysfs_dirent to remove
- * @ns: namespace tag of the sysfs_dirent to remove
- *
- * Look for the sysfs_dirent with @name and @ns under @dir_sd and remove
- * it.  Returns 0 on success, -ENOENT if such entry doesn't exist.
- */
-int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name,
-                         const void *ns)
-{
-       struct sysfs_addrm_cxt acxt;
-       struct sysfs_dirent *sd;
-
-       if (!dir_sd) {
-               WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n",
-                       name);
-               return -ENOENT;
-       }
-
-       sysfs_addrm_start(&acxt);
-
-       sd = sysfs_find_dirent(dir_sd, name, ns);
-       if (sd)
-               __sysfs_remove(&acxt, sd);
-
-       sysfs_addrm_finish(&acxt);
-
-       if (sd)
-               return 0;
-       else
-               return -ENOENT;
+       kobj->sd = sd;
+       return 0;
 }
 
 /**
@@ -960,60 +114,16 @@ void sysfs_remove_dir(struct kobject *kobj)
 
        if (sd) {
                WARN_ON_ONCE(sysfs_type(sd) != SYSFS_DIR);
-               sysfs_remove(sd);
+               kernfs_remove(sd);
        }
 }
 
-int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,
-                const char *new_name, const void *new_ns)
-{
-       int error;
-
-       mutex_lock(&sysfs_mutex);
-
-       error = 0;
-       if ((sd->s_parent == new_parent_sd) && (sd->s_ns == new_ns) &&
-           (strcmp(sd->s_name, new_name) == 0))
-               goto out;       /* nothing to rename */
-
-       error = -EEXIST;
-       if (sysfs_find_dirent(new_parent_sd, new_name, new_ns))
-               goto out;
-
-       /* rename sysfs_dirent */
-       if (strcmp(sd->s_name, new_name) != 0) {
-               error = -ENOMEM;
-               new_name = kstrdup(new_name, GFP_KERNEL);
-               if (!new_name)
-                       goto out;
-
-               kfree(sd->s_name);
-               sd->s_name = new_name;
-       }
-
-       /*
-        * Move to the appropriate place in the appropriate directories rbtree.
-        */
-       sysfs_unlink_sibling(sd);
-       sysfs_get(new_parent_sd);
-       sysfs_put(sd->s_parent);
-       sd->s_ns = new_ns;
-       sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
-       sd->s_parent = new_parent_sd;
-       sysfs_link_sibling(sd);
-
-       error = 0;
- out:
-       mutex_unlock(&sysfs_mutex);
-       return error;
-}
-
 int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
                        const void *new_ns)
 {
        struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
 
-       return sysfs_rename(kobj->sd, parent_sd, new_name, new_ns);
+       return kernfs_rename_ns(kobj->sd, parent_sd, new_name, new_ns);
 }
 
 int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
@@ -1024,123 +134,7 @@ int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
 
        BUG_ON(!sd->s_parent);
        new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
-               new_parent_kobj->sd : &sysfs_root;
+               new_parent_kobj->sd : sysfs_root_sd;
 
-       return sysfs_rename(sd, new_parent_sd, sd->s_name, new_ns);
+       return kernfs_rename_ns(sd, new_parent_sd, sd->s_name, new_ns);
 }
-
-/* Relationship between s_mode and the DT_xxx types */
-static inline unsigned char dt_type(struct sysfs_dirent *sd)
-{
-       return (sd->s_mode >> 12) & 15;
-}
-
-static int sysfs_dir_release(struct inode *inode, struct file *filp)
-{
-       sysfs_put(filp->private_data);
-       return 0;
-}
-
-static struct sysfs_dirent *sysfs_dir_pos(const void *ns,
-       struct sysfs_dirent *parent_sd, loff_t hash, struct sysfs_dirent *pos)
-{
-       if (pos) {
-               int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) &&
-                       pos->s_parent == parent_sd &&
-                       hash == pos->s_hash;
-               sysfs_put(pos);
-               if (!valid)
-                       pos = NULL;
-       }
-       if (!pos && (hash > 1) && (hash < INT_MAX)) {
-               struct rb_node *node = parent_sd->s_dir.children.rb_node;
-               while (node) {
-                       pos = to_sysfs_dirent(node);
-
-                       if (hash < pos->s_hash)
-                               node = node->rb_left;
-                       else if (hash > pos->s_hash)
-                               node = node->rb_right;
-                       else
-                               break;
-               }
-       }
-       /* Skip over entries in the wrong namespace */
-       while (pos && pos->s_ns != ns) {
-               struct rb_node *node = rb_next(&pos->s_rb);
-               if (!node)
-                       pos = NULL;
-               else
-                       pos = to_sysfs_dirent(node);
-       }
-       return pos;
-}
-
-static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
-       struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
-{
-       pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
-       if (pos)
-               do {
-                       struct rb_node *node = rb_next(&pos->s_rb);
-                       if (!node)
-                               pos = NULL;
-                       else
-                               pos = to_sysfs_dirent(node);
-               } while (pos && pos->s_ns != ns);
-       return pos;
-}
-
-static int sysfs_readdir(struct file *file, struct dir_context *ctx)
-{
-       struct dentry *dentry = file->f_path.dentry;
-       struct sysfs_dirent *parent_sd = dentry->d_fsdata;
-       struct sysfs_dirent *pos = file->private_data;
-       enum kobj_ns_type type;
-       const void *ns;
-
-       type = sysfs_ns_type(parent_sd);
-       ns = sysfs_info(dentry->d_sb)->ns[type];
-
-       if (!dir_emit_dots(file, ctx))
-               return 0;
-       mutex_lock(&sysfs_mutex);
-       for (pos = sysfs_dir_pos(ns, parent_sd, ctx->pos, pos);
-            pos;
-            pos = sysfs_dir_next_pos(ns, parent_sd, ctx->pos, pos)) {
-               const char *name = pos->s_name;
-               unsigned int type = dt_type(pos);
-               int len = strlen(name);
-               ino_t ino = pos->s_ino;
-               ctx->pos = pos->s_hash;
-               file->private_data = sysfs_get(pos);
-
-               mutex_unlock(&sysfs_mutex);
-               if (!dir_emit(ctx, name, len, ino, type))
-                       return 0;
-               mutex_lock(&sysfs_mutex);
-       }
-       mutex_unlock(&sysfs_mutex);
-       file->private_data = NULL;
-       ctx->pos = INT_MAX;
-       return 0;
-}
-
-static loff_t sysfs_dir_llseek(struct file *file, loff_t offset, int whence)
-{
-       struct inode *inode = file_inode(file);
-       loff_t ret;
-
-       mutex_lock(&inode->i_mutex);
-       ret = generic_file_llseek(file, offset, whence);
-       mutex_unlock(&inode->i_mutex);
-
-       return ret;
-}
-
-const struct file_operations sysfs_dir_operations = {
-       .read           = generic_read_dir,
-       .iterate        = sysfs_readdir,
-       .release        = sysfs_dir_release,
-       .llseek         = sysfs_dir_llseek,
-};
index 79b5da2acbe184353475f53ccb03793404bd3563..ac77d2be3c312df08fa1b1fc90fd9525cf06aafd 100644 (file)
 #include <linux/kobject.h>
 #include <linux/kallsyms.h>
 #include <linux/slab.h>
-#include <linux/fsnotify.h>
-#include <linux/namei.h>
-#include <linux/poll.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include <linux/limits.h>
-#include <linux/uaccess.h>
 #include <linux/seq_file.h>
-#include <linux/mm.h>
 
 #include "sysfs.h"
-
-/*
- * There's one sysfs_open_file for each open file and one sysfs_open_dirent
- * for each sysfs_dirent with one or more open files.
- *
- * sysfs_dirent->s_attr.open points to sysfs_open_dirent.  s_attr.open is
- * protected by sysfs_open_dirent_lock.
- *
- * filp->private_data points to seq_file whose ->private points to
- * sysfs_open_file.  sysfs_open_files are chained at
- * sysfs_open_dirent->files, which is protected by sysfs_open_file_mutex.
- */
-static DEFINE_SPINLOCK(sysfs_open_dirent_lock);
-static DEFINE_MUTEX(sysfs_open_file_mutex);
-
-struct sysfs_open_dirent {
-       atomic_t                refcnt;
-       atomic_t                event;
-       wait_queue_head_t       poll;
-       struct list_head        files; /* goes through sysfs_open_file.list */
-};
-
-struct sysfs_open_file {
-       struct sysfs_dirent     *sd;
-       struct file             *file;
-       struct mutex            mutex;
-       int                     event;
-       struct list_head        list;
-
-       bool                    mmapped;
-       const struct vm_operations_struct *vm_ops;
-};
-
-static bool sysfs_is_bin(struct sysfs_dirent *sd)
-{
-       return sysfs_type(sd) == SYSFS_KOBJ_BIN_ATTR;
-}
-
-static struct sysfs_open_file *sysfs_of(struct file *file)
-{
-       return ((struct seq_file *)file->private_data)->private;
-}
+#include "../kernfs/kernfs-internal.h"
 
 /*
  * Determine ktype->sysfs_ops for the given sysfs_dirent.  This function
@@ -74,9 +27,9 @@ static struct sysfs_open_file *sysfs_of(struct file *file)
  */
 static const struct sysfs_ops *sysfs_file_ops(struct sysfs_dirent *sd)
 {
-       struct kobject *kobj = sd->s_parent->s_dir.kobj;
+       struct kobject *kobj = sd->s_parent->priv;
 
-       if (!sysfs_ignore_lockdep(sd))
+       if (sd->s_flags & SYSFS_FLAG_LOCKDEP)
                lockdep_assert_held(sd);
        return kobj->ktype ? kobj->ktype->sysfs_ops : NULL;
 }
@@ -86,13 +39,13 @@ static const struct sysfs_ops *sysfs_file_ops(struct sysfs_dirent *sd)
  * details like buffering and seeking.  The following function pipes
  * sysfs_ops->show() result through seq_file.
  */
-static int sysfs_seq_show(struct seq_file *sf, void *v)
+static int sysfs_kf_seq_show(struct seq_file *sf, void *v)
 {
        struct sysfs_open_file *of = sf->private;
-       struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
-       const struct sysfs_ops *ops;
-       char *buf;
+       struct kobject *kobj = of->sd->s_parent->priv;
+       const struct sysfs_ops *ops = sysfs_file_ops(of->sd);
        ssize_t count;
+       char *buf;
 
        /* acquire buffer and ensure that it's >= PAGE_SIZE */
        count = seq_get_buf(sf, &buf);
@@ -102,34 +55,15 @@ static int sysfs_seq_show(struct seq_file *sf, void *v)
        }
 
        /*
-        * Need @of->sd for attr and ops, its parent for kobj.  @of->mutex
-        * nests outside active ref and is just to ensure that the ops
-        * aren't called concurrently for the same open file.
+        * Invoke show().  Control may reach here via seq file lseek even
+        * if @ops->show() isn't implemented.
         */
-       mutex_lock(&of->mutex);
-       if (!sysfs_get_active(of->sd)) {
-               mutex_unlock(&of->mutex);
-               return -ENODEV;
+       if (ops->show) {
+               count = ops->show(kobj, of->sd->priv, buf);
+               if (count < 0)
+                       return count;
        }
 
-       of->event = atomic_read(&of->sd->s_attr.open->event);
-
-       /*
-        * Lookup @ops and invoke show().  Control may reach here via seq
-        * file lseek even if @ops->show() isn't implemented.
-        */
-       ops = sysfs_file_ops(of->sd);
-       if (ops->show)
-               count = ops->show(kobj, of->sd->s_attr.attr, buf);
-       else
-               count = 0;
-
-       sysfs_put_active(of->sd);
-       mutex_unlock(&of->mutex);
-
-       if (count < 0)
-               return count;
-
        /*
         * The code works fine with PAGE_SIZE return but it's likely to
         * indicate truncated result or overflow in normal use cases.
@@ -144,710 +78,190 @@ static int sysfs_seq_show(struct seq_file *sf, void *v)
        return 0;
 }
 
-/*
- * Read method for bin files.  As reading a bin file can have side-effects,
- * the exact offset and bytes specified in read(2) call should be passed to
- * the read callback making it difficult to use seq_file.  Implement
- * simplistic custom buffering for bin files.
- */
-static ssize_t sysfs_bin_read(struct file *file, char __user *userbuf,
-                             size_t bytes, loff_t *off)
+static ssize_t sysfs_kf_bin_read(struct sysfs_open_file *of, char *buf,
+                                size_t count, loff_t pos)
 {
-       struct sysfs_open_file *of = sysfs_of(file);
-       struct bin_attribute *battr = of->sd->s_attr.bin_attr;
-       struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
-       loff_t size = file_inode(file)->i_size;
-       int count = min_t(size_t, bytes, PAGE_SIZE);
-       loff_t offs = *off;
-       char *buf;
+       struct bin_attribute *battr = of->sd->priv;
+       struct kobject *kobj = of->sd->s_parent->priv;
+       loff_t size = file_inode(of->file)->i_size;
 
-       if (!bytes)
+       if (!count)
                return 0;
 
        if (size) {
-               if (offs > size)
+               if (pos > size)
                        return 0;
-               if (offs + count > size)
-                       count = size - offs;
+               if (pos + count > size)
+                       count = size - pos;
        }
 
-       buf = kmalloc(count, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-
-       /* need of->sd for battr, its parent for kobj */
-       mutex_lock(&of->mutex);
-       if (!sysfs_get_active(of->sd)) {
-               count = -ENODEV;
-               mutex_unlock(&of->mutex);
-               goto out_free;
-       }
+       if (!battr->read)
+               return -EIO;
 
-       if (battr->read)
-               count = battr->read(file, kobj, battr, buf, offs, count);
-       else
-               count = -EIO;
-
-       sysfs_put_active(of->sd);
-       mutex_unlock(&of->mutex);
-
-       if (count < 0)
-               goto out_free;
-
-       if (copy_to_user(userbuf, buf, count)) {
-               count = -EFAULT;
-               goto out_free;
-       }
-
-       pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count);
-
-       *off = offs + count;
-
- out_free:
-       kfree(buf);
-       return count;
+       return battr->read(of->file, kobj, battr, buf, pos, count);
 }
 
-/**
- * flush_write_buffer - push buffer to kobject
- * @of: open file
- * @buf: data buffer for file
- * @off: file offset to write to
- * @count: number of bytes
- *
- * Get the correct pointers for the kobject and the attribute we're dealing
- * with, then call the store() method for it with @buf.
- */
-static int flush_write_buffer(struct sysfs_open_file *of, char *buf, loff_t off,
-                             size_t count)
+/* kernfs write callback for regular sysfs files */
+static ssize_t sysfs_kf_write(struct sysfs_open_file *of, char *buf,
+                             size_t count, loff_t pos)
 {
-       struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
-       int rc = 0;
-
-       /*
-        * Need @of->sd for attr and ops, its parent for kobj.  @of->mutex
-        * nests outside active ref and is just to ensure that the ops
-        * aren't called concurrently for the same open file.
-        */
-       mutex_lock(&of->mutex);
-       if (!sysfs_get_active(of->sd)) {
-               mutex_unlock(&of->mutex);
-               return -ENODEV;
-       }
-
-       if (sysfs_is_bin(of->sd)) {
-               struct bin_attribute *battr = of->sd->s_attr.bin_attr;
+       const struct sysfs_ops *ops = sysfs_file_ops(of->sd);
+       struct kobject *kobj = of->sd->s_parent->priv;
 
-               rc = -EIO;
-               if (battr->write)
-                       rc = battr->write(of->file, kobj, battr, buf, off,
-                                         count);
-       } else {
-               const struct sysfs_ops *ops = sysfs_file_ops(of->sd);
-
-               rc = ops->store(kobj, of->sd->s_attr.attr, buf, count);
-       }
-
-       sysfs_put_active(of->sd);
-       mutex_unlock(&of->mutex);
+       if (!count)
+               return 0;
 
-       return rc;
+       return ops->store(kobj, of->sd->priv, buf, count);
 }
 
-/**
- * sysfs_write_file - write an attribute
- * @file: file pointer
- * @user_buf: data to write
- * @count: number of bytes
- * @ppos: starting offset
- *
- * Copy data in from userland and pass it to the matching
- * sysfs_ops->store() by invoking flush_write_buffer().
- *
- * There is no easy way for us to know if userspace is only doing a partial
- * write, so we don't support them. We expect the entire buffer to come on
- * the first write.  Hint: if you're writing a value, first read the file,
- * modify only the the value you're changing, then write entire buffer
- * back.
- */
-static ssize_t sysfs_write_file(struct file *file, const char __user *user_buf,
-                               size_t count, loff_t *ppos)
+/* kernfs write callback for bin sysfs files */
+static ssize_t sysfs_kf_bin_write(struct sysfs_open_file *of, char *buf,
+                                 size_t count, loff_t pos)
 {
-       struct sysfs_open_file *of = sysfs_of(file);
-       ssize_t len = min_t(size_t, count, PAGE_SIZE);
-       loff_t size = file_inode(file)->i_size;
-       char *buf;
+       struct bin_attribute *battr = of->sd->priv;
+       struct kobject *kobj = of->sd->s_parent->priv;
+       loff_t size = file_inode(of->file)->i_size;
 
-       if (sysfs_is_bin(of->sd) && size) {
-               if (size <= *ppos)
+       if (size) {
+               if (size <= pos)
                        return 0;
-               len = min_t(ssize_t, len, size - *ppos);
+               count = min_t(ssize_t, count, size - pos);
        }
-
-       if (!len)
+       if (!count)
                return 0;
 
-       buf = kmalloc(len + 1, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
+       if (!battr->write)
+               return -EIO;
 
-       if (copy_from_user(buf, user_buf, len)) {
-               len = -EFAULT;
-               goto out_free;
-       }
-       buf[len] = '\0';        /* guarantee string termination */
-
-       len = flush_write_buffer(of, buf, *ppos, len);
-       if (len > 0)
-               *ppos += len;
-out_free:
-       kfree(buf);
-       return len;
+       return battr->write(of->file, kobj, battr, buf, pos, count);
 }
 
-static void sysfs_bin_vma_open(struct vm_area_struct *vma)
+static int sysfs_kf_bin_mmap(struct sysfs_open_file *of,
+                            struct vm_area_struct *vma)
 {
-       struct file *file = vma->vm_file;
-       struct sysfs_open_file *of = sysfs_of(file);
-
-       if (!of->vm_ops)
-               return;
-
-       if (!sysfs_get_active(of->sd))
-               return;
-
-       if (of->vm_ops->open)
-               of->vm_ops->open(vma);
-
-       sysfs_put_active(of->sd);
-}
-
-static int sysfs_bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-       struct file *file = vma->vm_file;
-       struct sysfs_open_file *of = sysfs_of(file);
-       int ret;
-
-       if (!of->vm_ops)
-               return VM_FAULT_SIGBUS;
-
-       if (!sysfs_get_active(of->sd))
-               return VM_FAULT_SIGBUS;
-
-       ret = VM_FAULT_SIGBUS;
-       if (of->vm_ops->fault)
-               ret = of->vm_ops->fault(vma, vmf);
-
-       sysfs_put_active(of->sd);
-       return ret;
-}
-
-static int sysfs_bin_page_mkwrite(struct vm_area_struct *vma,
-                                 struct vm_fault *vmf)
-{
-       struct file *file = vma->vm_file;
-       struct sysfs_open_file *of = sysfs_of(file);
-       int ret;
-
-       if (!of->vm_ops)
-               return VM_FAULT_SIGBUS;
-
-       if (!sysfs_get_active(of->sd))
-               return VM_FAULT_SIGBUS;
-
-       ret = 0;
-       if (of->vm_ops->page_mkwrite)
-               ret = of->vm_ops->page_mkwrite(vma, vmf);
-       else
-               file_update_time(file);
-
-       sysfs_put_active(of->sd);
-       return ret;
-}
-
-static int sysfs_bin_access(struct vm_area_struct *vma, unsigned long addr,
-                           void *buf, int len, int write)
-{
-       struct file *file = vma->vm_file;
-       struct sysfs_open_file *of = sysfs_of(file);
-       int ret;
-
-       if (!of->vm_ops)
-               return -EINVAL;
-
-       if (!sysfs_get_active(of->sd))
-               return -EINVAL;
-
-       ret = -EINVAL;
-       if (of->vm_ops->access)
-               ret = of->vm_ops->access(vma, addr, buf, len, write);
-
-       sysfs_put_active(of->sd);
-       return ret;
-}
-
-#ifdef CONFIG_NUMA
-static int sysfs_bin_set_policy(struct vm_area_struct *vma,
-                               struct mempolicy *new)
-{
-       struct file *file = vma->vm_file;
-       struct sysfs_open_file *of = sysfs_of(file);
-       int ret;
-
-       if (!of->vm_ops)
-               return 0;
-
-       if (!sysfs_get_active(of->sd))
-               return -EINVAL;
-
-       ret = 0;
-       if (of->vm_ops->set_policy)
-               ret = of->vm_ops->set_policy(vma, new);
-
-       sysfs_put_active(of->sd);
-       return ret;
-}
-
-static struct mempolicy *sysfs_bin_get_policy(struct vm_area_struct *vma,
-                                             unsigned long addr)
-{
-       struct file *file = vma->vm_file;
-       struct sysfs_open_file *of = sysfs_of(file);
-       struct mempolicy *pol;
-
-       if (!of->vm_ops)
-               return vma->vm_policy;
-
-       if (!sysfs_get_active(of->sd))
-               return vma->vm_policy;
-
-       pol = vma->vm_policy;
-       if (of->vm_ops->get_policy)
-               pol = of->vm_ops->get_policy(vma, addr);
-
-       sysfs_put_active(of->sd);
-       return pol;
-}
-
-static int sysfs_bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
-                            const nodemask_t *to, unsigned long flags)
-{
-       struct file *file = vma->vm_file;
-       struct sysfs_open_file *of = sysfs_of(file);
-       int ret;
-
-       if (!of->vm_ops)
-               return 0;
-
-       if (!sysfs_get_active(of->sd))
-               return 0;
-
-       ret = 0;
-       if (of->vm_ops->migrate)
-               ret = of->vm_ops->migrate(vma, from, to, flags);
-
-       sysfs_put_active(of->sd);
-       return ret;
-}
-#endif
-
-static const struct vm_operations_struct sysfs_bin_vm_ops = {
-       .open           = sysfs_bin_vma_open,
-       .fault          = sysfs_bin_fault,
-       .page_mkwrite   = sysfs_bin_page_mkwrite,
-       .access         = sysfs_bin_access,
-#ifdef CONFIG_NUMA
-       .set_policy     = sysfs_bin_set_policy,
-       .get_policy     = sysfs_bin_get_policy,
-       .migrate        = sysfs_bin_migrate,
-#endif
-};
-
-static int sysfs_bin_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct sysfs_open_file *of = sysfs_of(file);
-       struct bin_attribute *battr = of->sd->s_attr.bin_attr;
-       struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
-       int rc;
-
-       mutex_lock(&of->mutex);
-
-       /* need of->sd for battr, its parent for kobj */
-       rc = -ENODEV;
-       if (!sysfs_get_active(of->sd))
-               goto out_unlock;
+       struct bin_attribute *battr = of->sd->priv;
+       struct kobject *kobj = of->sd->s_parent->priv;
 
        if (!battr->mmap)
-               goto out_put;
-
-       rc = battr->mmap(file, kobj, battr, vma);
-       if (rc)
-               goto out_put;
-
-       /*
-        * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup()
-        * to satisfy versions of X which crash if the mmap fails: that
-        * substitutes a new vm_file, and we don't then want bin_vm_ops.
-        */
-       if (vma->vm_file != file)
-               goto out_put;
-
-       rc = -EINVAL;
-       if (of->mmapped && of->vm_ops != vma->vm_ops)
-               goto out_put;
-
-       /*
-        * It is not possible to successfully wrap close.
-        * So error if someone is trying to use close.
-        */
-       rc = -EINVAL;
-       if (vma->vm_ops && vma->vm_ops->close)
-               goto out_put;
-
-       rc = 0;
-       of->mmapped = 1;
-       of->vm_ops = vma->vm_ops;
-       vma->vm_ops = &sysfs_bin_vm_ops;
-out_put:
-       sysfs_put_active(of->sd);
-out_unlock:
-       mutex_unlock(&of->mutex);
-
-       return rc;
-}
-
-/**
- *     sysfs_get_open_dirent - get or create sysfs_open_dirent
- *     @sd: target sysfs_dirent
- *     @of: sysfs_open_file for this instance of open
- *
- *     If @sd->s_attr.open exists, increment its reference count;
- *     otherwise, create one.  @of is chained to the files list.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).
- *
- *     RETURNS:
- *     0 on success, -errno on failure.
- */
-static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
-                                struct sysfs_open_file *of)
-{
-       struct sysfs_open_dirent *od, *new_od = NULL;
-
- retry:
-       mutex_lock(&sysfs_open_file_mutex);
-       spin_lock_irq(&sysfs_open_dirent_lock);
-
-       if (!sd->s_attr.open && new_od) {
-               sd->s_attr.open = new_od;
-               new_od = NULL;
-       }
-
-       od = sd->s_attr.open;
-       if (od) {
-               atomic_inc(&od->refcnt);
-               list_add_tail(&of->list, &od->files);
-       }
-
-       spin_unlock_irq(&sysfs_open_dirent_lock);
-       mutex_unlock(&sysfs_open_file_mutex);
-
-       if (od) {
-               kfree(new_od);
-               return 0;
-       }
-
-       /* not there, initialize a new one and retry */
-       new_od = kmalloc(sizeof(*new_od), GFP_KERNEL);
-       if (!new_od)
-               return -ENOMEM;
+               return -ENODEV;
 
-       atomic_set(&new_od->refcnt, 0);
-       atomic_set(&new_od->event, 1);
-       init_waitqueue_head(&new_od->poll);
-       INIT_LIST_HEAD(&new_od->files);
-       goto retry;
+       return battr->mmap(of->file, kobj, battr, vma);
 }
 
-/**
- *     sysfs_put_open_dirent - put sysfs_open_dirent
- *     @sd: target sysfs_dirent
- *     @of: associated sysfs_open_file
- *
- *     Put @sd->s_attr.open and unlink @of from the files list.  If
- *     reference count reaches zero, disassociate and free it.
- *
- *     LOCKING:
- *     None.
- */
-static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
-                                 struct sysfs_open_file *of)
+void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
 {
-       struct sysfs_open_dirent *od = sd->s_attr.open;
-       unsigned long flags;
-
-       mutex_lock(&sysfs_open_file_mutex);
-       spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
+       struct sysfs_dirent *sd = k->sd, *tmp;
 
-       if (of)
-               list_del(&of->list);
-
-       if (atomic_dec_and_test(&od->refcnt))
-               sd->s_attr.open = NULL;
+       if (sd && dir)
+               sd = kernfs_find_and_get(sd, dir);
        else
-               od = NULL;
-
-       spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
-       mutex_unlock(&sysfs_open_file_mutex);
-
-       kfree(od);
-}
-
-static int sysfs_open_file(struct inode *inode, struct file *file)
-{
-       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
-       struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
-       struct sysfs_open_file *of;
-       bool has_read, has_write;
-       int error = -EACCES;
-
-       /* need attr_sd for attr and ops, its parent for kobj */
-       if (!sysfs_get_active(attr_sd))
-               return -ENODEV;
-
-       if (sysfs_is_bin(attr_sd)) {
-               struct bin_attribute *battr = attr_sd->s_attr.bin_attr;
-
-               has_read = battr->read || battr->mmap;
-               has_write = battr->write || battr->mmap;
-       } else {
-               const struct sysfs_ops *ops = sysfs_file_ops(attr_sd);
+               kernfs_get(sd);
 
-               /* every kobject with an attribute needs a ktype assigned */
-               if (WARN(!ops, KERN_ERR
-                        "missing sysfs attribute operations for kobject: %s\n",
-                        kobject_name(kobj)))
-                       goto err_out;
-
-               has_read = ops->show;
-               has_write = ops->store;
+       if (sd && attr) {
+               tmp = kernfs_find_and_get(sd, attr);
+               kernfs_put(sd);
+               sd = tmp;
        }
 
-       /* check perms and supported operations */
-       if ((file->f_mode & FMODE_WRITE) &&
-           (!(inode->i_mode & S_IWUGO) || !has_write))
-               goto err_out;
-
-       if ((file->f_mode & FMODE_READ) &&
-           (!(inode->i_mode & S_IRUGO) || !has_read))
-               goto err_out;
-
-       /* allocate a sysfs_open_file for the file */
-       error = -ENOMEM;
-       of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL);
-       if (!of)
-               goto err_out;
-
-       mutex_init(&of->mutex);
-       of->sd = attr_sd;
-       of->file = file;
-
-       /*
-        * Always instantiate seq_file even if read access doesn't use
-        * seq_file or is not requested.  This unifies private data access
-        * and readable regular files are the vast majority anyway.
-        */
-       if (sysfs_is_bin(attr_sd))
-               error = single_open(file, NULL, of);
-       else
-               error = single_open(file, sysfs_seq_show, of);
-       if (error)
-               goto err_free;
-
-       /* seq_file clears PWRITE unconditionally, restore it if WRITE */
-       if (file->f_mode & FMODE_WRITE)
-               file->f_mode |= FMODE_PWRITE;
-
-       /* make sure we have open dirent struct */
-       error = sysfs_get_open_dirent(attr_sd, of);
-       if (error)
-               goto err_close;
-
-       /* open succeeded, put active references */
-       sysfs_put_active(attr_sd);
-       return 0;
-
-err_close:
-       single_release(inode, file);
-err_free:
-       kfree(of);
-err_out:
-       sysfs_put_active(attr_sd);
-       return error;
-}
-
-static int sysfs_release(struct inode *inode, struct file *filp)
-{
-       struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata;
-       struct sysfs_open_file *of = sysfs_of(filp);
-
-       sysfs_put_open_dirent(sd, of);
-       single_release(inode, filp);
-       kfree(of);
-
-       return 0;
-}
-
-void sysfs_unmap_bin_file(struct sysfs_dirent *sd)
-{
-       struct sysfs_open_dirent *od;
-       struct sysfs_open_file *of;
-
-       if (!sysfs_is_bin(sd))
-               return;
-
-       spin_lock_irq(&sysfs_open_dirent_lock);
-       od = sd->s_attr.open;
-       if (od)
-               atomic_inc(&od->refcnt);
-       spin_unlock_irq(&sysfs_open_dirent_lock);
-       if (!od)
-               return;
-
-       mutex_lock(&sysfs_open_file_mutex);
-       list_for_each_entry(of, &od->files, list) {
-               struct inode *inode = file_inode(of->file);
-               unmap_mapping_range(inode->i_mapping, 0, 0, 1);
+       if (sd) {
+               kernfs_notify(sd);
+               kernfs_put(sd);
        }
-       mutex_unlock(&sysfs_open_file_mutex);
-
-       sysfs_put_open_dirent(sd, NULL);
 }
+EXPORT_SYMBOL_GPL(sysfs_notify);
 
-/* Sysfs attribute files are pollable.  The idea is that you read
- * the content and then you use 'poll' or 'select' to wait for
- * the content to change.  When the content changes (assuming the
- * manager for the kobject supports notification), poll will
- * return POLLERR|POLLPRI, and select will return the fd whether
- * it is waiting for read, write, or exceptions.
- * Once poll/select indicates that the value has changed, you
- * need to close and re-open the file, or seek to 0 and read again.
- * Reminder: this only works for attributes which actively support
- * it, and it is not possible to test an attribute from userspace
- * to see if it supports poll (Neither 'poll' nor 'select' return
- * an appropriate error code).  When in doubt, set a suitable timeout value.
- */
-static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
-{
-       struct sysfs_open_file *of = sysfs_of(filp);
-       struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
-       struct sysfs_open_dirent *od = attr_sd->s_attr.open;
-
-       /* need parent for the kobj, grab both */
-       if (!sysfs_get_active(attr_sd))
-               goto trigger;
-
-       poll_wait(filp, &od->poll, wait);
-
-       sysfs_put_active(attr_sd);
-
-       if (of->event != atomic_read(&od->event))
-               goto trigger;
-
-       return DEFAULT_POLLMASK;
-
- trigger:
-       return DEFAULT_POLLMASK|POLLERR|POLLPRI;
-}
-
-void sysfs_notify_dirent(struct sysfs_dirent *sd)
-{
-       struct sysfs_open_dirent *od;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
-
-       if (!WARN_ON(sysfs_type(sd) != SYSFS_KOBJ_ATTR)) {
-               od = sd->s_attr.open;
-               if (od) {
-                       atomic_inc(&od->event);
-                       wake_up_interruptible(&od->poll);
-               }
-       }
-
-       spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
-}
-EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
+static const struct kernfs_ops sysfs_file_kfops_empty = {
+};
 
-void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
-{
-       struct sysfs_dirent *sd = k->sd;
+static const struct kernfs_ops sysfs_file_kfops_ro = {
+       .seq_show       = sysfs_kf_seq_show,
+};
 
-       mutex_lock(&sysfs_mutex);
+static const struct kernfs_ops sysfs_file_kfops_wo = {
+       .write          = sysfs_kf_write,
+};
 
-       if (sd && dir)
-               sd = sysfs_find_dirent(sd, dir, NULL);
-       if (sd && attr)
-               sd = sysfs_find_dirent(sd, attr, NULL);
-       if (sd)
-               sysfs_notify_dirent(sd);
+static const struct kernfs_ops sysfs_file_kfops_rw = {
+       .seq_show       = sysfs_kf_seq_show,
+       .write          = sysfs_kf_write,
+};
 
-       mutex_unlock(&sysfs_mutex);
-}
-EXPORT_SYMBOL_GPL(sysfs_notify);
+static const struct kernfs_ops sysfs_bin_kfops_ro = {
+       .read           = sysfs_kf_bin_read,
+};
 
-const struct file_operations sysfs_file_operations = {
-       .read           = seq_read,
-       .write          = sysfs_write_file,
-       .llseek         = generic_file_llseek,
-       .open           = sysfs_open_file,
-       .release        = sysfs_release,
-       .poll           = sysfs_poll,
+static const struct kernfs_ops sysfs_bin_kfops_wo = {
+       .write          = sysfs_kf_bin_write,
 };
 
-const struct file_operations sysfs_bin_operations = {
-       .read           = sysfs_bin_read,
-       .write          = sysfs_write_file,
-       .llseek         = generic_file_llseek,
-       .mmap           = sysfs_bin_mmap,
-       .open           = sysfs_open_file,
-       .release        = sysfs_release,
-       .poll           = sysfs_poll,
+static const struct kernfs_ops sysfs_bin_kfops_rw = {
+       .read           = sysfs_kf_bin_read,
+       .write          = sysfs_kf_bin_write,
+       .mmap           = sysfs_kf_bin_mmap,
 };
 
 int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
-                          const struct attribute *attr, int type,
-                          umode_t amode, const void *ns)
+                          const struct attribute *attr, bool is_bin,
+                          umode_t mode, const void *ns)
 {
-       umode_t mode = (amode & S_IALLUGO) | S_IFREG;
-       struct sysfs_addrm_cxt acxt;
+       struct lock_class_key *key = NULL;
+       const struct kernfs_ops *ops;
        struct sysfs_dirent *sd;
-       int rc;
-
-       sd = sysfs_new_dirent(attr->name, mode, type);
-       if (!sd)
-               return -ENOMEM;
+       loff_t size;
 
-       sd->s_ns = ns;
-       sd->s_attr.attr = (void *)attr;
-       sysfs_dirent_init_lockdep(sd);
+       if (!is_bin) {
+               struct kobject *kobj = dir_sd->priv;
+               const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops;
 
-       sysfs_addrm_start(&acxt);
-       rc = sysfs_add_one(&acxt, sd, dir_sd);
-       sysfs_addrm_finish(&acxt);
-
-       if (rc)
-               sysfs_put(sd);
+               /* every kobject with an attribute needs a ktype assigned */
+               if (WARN(!sysfs_ops, KERN_ERR
+                        "missing sysfs attribute operations for kobject: %s\n",
+                        kobject_name(kobj)))
+                       return -EINVAL;
+
+               if (sysfs_ops->show && sysfs_ops->store)
+                       ops = &sysfs_file_kfops_rw;
+               else if (sysfs_ops->show)
+                       ops = &sysfs_file_kfops_ro;
+               else if (sysfs_ops->store)
+                       ops = &sysfs_file_kfops_wo;
+               else
+                       ops = &sysfs_file_kfops_empty;
+
+               size = PAGE_SIZE;
+       } else {
+               struct bin_attribute *battr = (void *)attr;
+
+               if ((battr->read && battr->write) || battr->mmap)
+                       ops = &sysfs_bin_kfops_rw;
+               else if (battr->read)
+                       ops = &sysfs_bin_kfops_ro;
+               else if (battr->write)
+                       ops = &sysfs_bin_kfops_wo;
+               else
+                       ops = &sysfs_file_kfops_empty;
+
+               size = battr->size;
+       }
 
-       return rc;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       if (!attr->ignore_lockdep)
+               key = attr->key ?: (struct lock_class_key *)&attr->skey;
+#endif
+       sd = kernfs_create_file_ns_key(dir_sd, attr->name, mode, size,
+                                      ops, (void *)attr, ns, key);
+       if (IS_ERR(sd)) {
+               if (PTR_ERR(sd) == -EEXIST)
+                       sysfs_warn_dup(dir_sd, attr->name);
+               return PTR_ERR(sd);
+       }
+       return 0;
 }
 
-
 int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
-                  int type)
+                  bool is_bin)
 {
-       return sysfs_add_file_mode_ns(dir_sd, attr, type, attr->mode, NULL);
+       return sysfs_add_file_mode_ns(dir_sd, attr, is_bin, attr->mode, NULL);
 }
 
 /**
@@ -861,8 +275,7 @@ int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
 {
        BUG_ON(!kobj || !kobj->sd || !attr);
 
-       return sysfs_add_file_mode_ns(kobj->sd, attr, SYSFS_KOBJ_ATTR,
-                                     attr->mode, ns);
+       return sysfs_add_file_mode_ns(kobj->sd, attr, false, attr->mode, ns);
 
 }
 EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
@@ -893,16 +306,18 @@ int sysfs_add_file_to_group(struct kobject *kobj,
        struct sysfs_dirent *dir_sd;
        int error;
 
-       if (group)
-               dir_sd = sysfs_get_dirent(kobj->sd, group);
-       else
-               dir_sd = sysfs_get(kobj->sd);
+       if (group) {
+               dir_sd = kernfs_find_and_get(kobj->sd, group);
+       } else {
+               dir_sd = kobj->sd;
+               kernfs_get(dir_sd);
+       }
 
        if (!dir_sd)
                return -ENOENT;
 
-       error = sysfs_add_file(dir_sd, attr, SYSFS_KOBJ_ATTR);
-       sysfs_put(dir_sd);
+       error = sysfs_add_file(dir_sd, attr, false);
+       kernfs_put(dir_sd);
 
        return error;
 }
@@ -922,19 +337,16 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
        struct iattr newattrs;
        int rc;
 
-       mutex_lock(&sysfs_mutex);
-
-       rc = -ENOENT;
-       sd = sysfs_find_dirent(kobj->sd, attr->name, NULL);
+       sd = kernfs_find_and_get(kobj->sd, attr->name);
        if (!sd)
-               goto out;
+               return -ENOENT;
 
        newattrs.ia_mode = (mode & S_IALLUGO) | (sd->s_mode & ~S_IALLUGO);
        newattrs.ia_valid = ATTR_MODE;
-       rc = sysfs_sd_setattr(sd, &newattrs);
 
- out:
-       mutex_unlock(&sysfs_mutex);
+       rc = kernfs_setattr(sd, &newattrs);
+
+       kernfs_put(sd);
        return rc;
 }
 EXPORT_SYMBOL_GPL(sysfs_chmod_file);
@@ -952,7 +364,7 @@ void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
 {
        struct sysfs_dirent *dir_sd = kobj->sd;
 
-       sysfs_hash_and_remove(dir_sd, attr->name, ns);
+       kernfs_remove_by_name_ns(dir_sd, attr->name, ns);
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
 
@@ -975,13 +387,16 @@ void sysfs_remove_file_from_group(struct kobject *kobj,
 {
        struct sysfs_dirent *dir_sd;
 
-       if (group)
-               dir_sd = sysfs_get_dirent(kobj->sd, group);
-       else
-               dir_sd = sysfs_get(kobj->sd);
+       if (group) {
+               dir_sd = kernfs_find_and_get(kobj->sd, group);
+       } else {
+               dir_sd = kobj->sd;
+               kernfs_get(dir_sd);
+       }
+
        if (dir_sd) {
-               sysfs_hash_and_remove(dir_sd, attr->name, NULL);
-               sysfs_put(dir_sd);
+               kernfs_remove_by_name(dir_sd, attr->name);
+               kernfs_put(dir_sd);
        }
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
@@ -996,7 +411,7 @@ int sysfs_create_bin_file(struct kobject *kobj,
 {
        BUG_ON(!kobj || !kobj->sd || !attr);
 
-       return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
+       return sysfs_add_file(kobj->sd, &attr->attr, true);
 }
 EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
 
@@ -1008,7 +423,7 @@ EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
 void sysfs_remove_bin_file(struct kobject *kobj,
                           const struct bin_attribute *attr)
 {
-       sysfs_hash_and_remove(kobj->sd, attr->attr.name, NULL);
+       kernfs_remove_by_name(kobj->sd, attr->attr.name);
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
 
index 1898a10e38ce8ccef26a687882c637f349ac5b29..7177532b8f7bfa7d2e683dd41da3d7e79a6876f3 100644 (file)
@@ -26,7 +26,7 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
 
        if (grp->attrs)
                for (attr = grp->attrs; *attr; attr++)
-                       sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL);
+                       kernfs_remove_by_name(dir_sd, (*attr)->name);
        if (grp->bin_attrs)
                for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++)
                        sysfs_remove_bin_file(kobj, *bin_attr);
@@ -49,15 +49,13 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
                         * re-adding (if required) the file.
                         */
                        if (update)
-                               sysfs_hash_and_remove(dir_sd, (*attr)->name,
-                                                     NULL);
+                               kernfs_remove_by_name(dir_sd, (*attr)->name);
                        if (grp->is_visible) {
                                mode = grp->is_visible(kobj, *attr, i);
                                if (!mode)
                                        continue;
                        }
-                       error = sysfs_add_file_mode_ns(dir_sd, *attr,
-                                                      SYSFS_KOBJ_ATTR,
+                       error = sysfs_add_file_mode_ns(dir_sd, *attr, false,
                                                       (*attr)->mode | mode,
                                                       NULL);
                        if (unlikely(error))
@@ -102,18 +100,21 @@ static int internal_create_group(struct kobject *kobj, int update,
                return -EINVAL;
        }
        if (grp->name) {
-               error = sysfs_create_subdir(kobj, grp->name, &sd);
-               if (error)
-                       return error;
+               sd = kernfs_create_dir(kobj->sd, grp->name, kobj);
+               if (IS_ERR(sd)) {
+                       if (PTR_ERR(sd) == -EEXIST)
+                               sysfs_warn_dup(kobj->sd, grp->name);
+                       return PTR_ERR(sd);
+               }
        } else
                sd = kobj->sd;
-       sysfs_get(sd);
+       kernfs_get(sd);
        error = create_files(sd, kobj, grp, update);
        if (error) {
                if (grp->name)
-                       sysfs_remove(sd);
+                       kernfs_remove(sd);
        }
-       sysfs_put(sd);
+       kernfs_put(sd);
        return error;
 }
 
@@ -207,21 +208,23 @@ void sysfs_remove_group(struct kobject *kobj,
        struct sysfs_dirent *sd;
 
        if (grp->name) {
-               sd = sysfs_get_dirent(dir_sd, grp->name);
+               sd = kernfs_find_and_get(dir_sd, grp->name);
                if (!sd) {
                        WARN(!sd, KERN_WARNING
                             "sysfs group %p not found for kobject '%s'\n",
                             grp, kobject_name(kobj));
                        return;
                }
-       } else
-               sd = sysfs_get(dir_sd);
+       } else {
+               sd = dir_sd;
+               kernfs_get(sd);
+       }
 
        remove_files(sd, kobj, grp);
        if (grp->name)
-               sysfs_remove(sd);
+               kernfs_remove(sd);
 
-       sysfs_put(sd);
+       kernfs_put(sd);
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_group);
 
@@ -262,17 +265,17 @@ int sysfs_merge_group(struct kobject *kobj,
        struct attribute *const *attr;
        int i;
 
-       dir_sd = sysfs_get_dirent(kobj->sd, grp->name);
+       dir_sd = kernfs_find_and_get(kobj->sd, grp->name);
        if (!dir_sd)
                return -ENOENT;
 
        for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr))
-               error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
+               error = sysfs_add_file(dir_sd, *attr, false);
        if (error) {
                while (--i >= 0)
-                       sysfs_hash_and_remove(dir_sd, (*--attr)->name, NULL);
+                       kernfs_remove_by_name(dir_sd, (*--attr)->name);
        }
-       sysfs_put(dir_sd);
+       kernfs_put(dir_sd);
 
        return error;
 }
@@ -289,11 +292,11 @@ void sysfs_unmerge_group(struct kobject *kobj,
        struct sysfs_dirent *dir_sd;
        struct attribute *const *attr;
 
-       dir_sd = sysfs_get_dirent(kobj->sd, grp->name);
+       dir_sd = kernfs_find_and_get(kobj->sd, grp->name);
        if (dir_sd) {
                for (attr = grp->attrs; *attr; ++attr)
-                       sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL);
-               sysfs_put(dir_sd);
+                       kernfs_remove_by_name(dir_sd, (*attr)->name);
+               kernfs_put(dir_sd);
        }
 }
 EXPORT_SYMBOL_GPL(sysfs_unmerge_group);
@@ -311,12 +314,12 @@ int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name,
        struct sysfs_dirent *dir_sd;
        int error = 0;
 
-       dir_sd = sysfs_get_dirent(kobj->sd, group_name);
+       dir_sd = kernfs_find_and_get(kobj->sd, group_name);
        if (!dir_sd)
                return -ENOENT;
 
        error = sysfs_create_link_sd(dir_sd, target, link_name);
-       sysfs_put(dir_sd);
+       kernfs_put(dir_sd);
 
        return error;
 }
@@ -333,10 +336,10 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
 {
        struct sysfs_dirent *dir_sd;
 
-       dir_sd = sysfs_get_dirent(kobj->sd, group_name);
+       dir_sd = kernfs_find_and_get(kobj->sd, group_name);
        if (dir_sd) {
-               sysfs_hash_and_remove(dir_sd, link_name, NULL);
-               sysfs_put(dir_sd);
+               kernfs_remove_by_name(dir_sd, link_name);
+               kernfs_put(dir_sd);
        }
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group);
index 834ec2cdb7a37e070b7e5ed04ec684ba46cb2093..e7e3aa8e7b78663561738347b1ff78572cb3f6a1 100644 (file)
 
 #include <linux/fs.h>
 #include <linux/mount.h>
-#include <linux/pagemap.h>
 #include <linux/init.h>
-#include <linux/module.h>
-#include <linux/magic.h>
-#include <linux/slab.h>
 #include <linux/user_namespace.h>
 
 #include "sysfs.h"
 
-
-static struct vfsmount *sysfs_mnt;
-struct kmem_cache *sysfs_dir_cachep;
-
-static const struct super_operations sysfs_ops = {
-       .statfs         = simple_statfs,
-       .drop_inode     = generic_delete_inode,
-       .evict_inode    = sysfs_evict_inode,
-};
-
-struct sysfs_dirent sysfs_root = {
-       .s_name         = "",
-       .s_count        = ATOMIC_INIT(1),
-       .s_flags        = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT),
-       .s_mode         = S_IFDIR | S_IRUGO | S_IXUGO,
-       .s_ino          = 1,
-};
-
-static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-       struct inode *inode;
-       struct dentry *root;
-
-       sb->s_blocksize = PAGE_CACHE_SIZE;
-       sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-       sb->s_magic = SYSFS_MAGIC;
-       sb->s_op = &sysfs_ops;
-       sb->s_time_gran = 1;
-
-       /* get root inode, initialize and unlock it */
-       mutex_lock(&sysfs_mutex);
-       inode = sysfs_get_inode(sb, &sysfs_root);
-       mutex_unlock(&sysfs_mutex);
-       if (!inode) {
-               pr_debug("sysfs: could not get root inode\n");
-               return -ENOMEM;
-       }
-
-       /* instantiate and link root dentry */
-       root = d_make_root(inode);
-       if (!root) {
-               pr_debug("%s: could not get root dentry!\n", __func__);
-               return -ENOMEM;
-       }
-       root->d_fsdata = &sysfs_root;
-       sb->s_root = root;
-       sb->s_d_op = &sysfs_dentry_ops;
-       return 0;
-}
-
-static int sysfs_test_super(struct super_block *sb, void *data)
-{
-       struct sysfs_super_info *sb_info = sysfs_info(sb);
-       struct sysfs_super_info *info = data;
-       enum kobj_ns_type type;
-       int found = 1;
-
-       for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) {
-               if (sb_info->ns[type] != info->ns[type])
-                       found = 0;
-       }
-       return found;
-}
-
-static int sysfs_set_super(struct super_block *sb, void *data)
-{
-       int error;
-       error = set_anon_super(sb, data);
-       if (!error)
-               sb->s_fs_info = data;
-       return error;
-}
-
-static void free_sysfs_super_info(struct sysfs_super_info *info)
-{
-       int type;
-       for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
-               kobj_ns_drop(type, info->ns[type]);
-       kfree(info);
-}
+static struct kernfs_root *sysfs_root;
+struct sysfs_dirent *sysfs_root_sd;
 
 static struct dentry *sysfs_mount(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data)
 {
-       struct sysfs_super_info *info;
-       enum kobj_ns_type type;
-       struct super_block *sb;
-       int error;
+       struct dentry *root;
+       void *ns;
 
        if (!(flags & MS_KERNMOUNT)) {
                if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
                        return ERR_PTR(-EPERM);
 
-               for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) {
-                       if (!kobj_ns_current_may_mount(type))
-                               return ERR_PTR(-EPERM);
-               }
-       }
-
-       info = kzalloc(sizeof(*info), GFP_KERNEL);
-       if (!info)
-               return ERR_PTR(-ENOMEM);
-
-       for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
-               info->ns[type] = kobj_ns_grab_current(type);
-
-       sb = sget(fs_type, sysfs_test_super, sysfs_set_super, flags, info);
-       if (IS_ERR(sb) || sb->s_fs_info != info)
-               free_sysfs_super_info(info);
-       if (IS_ERR(sb))
-               return ERR_CAST(sb);
-       if (!sb->s_root) {
-               error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
-               if (error) {
-                       deactivate_locked_super(sb);
-                       return ERR_PTR(error);
-               }
-               sb->s_flags |= MS_ACTIVE;
+               if (!kobj_ns_current_may_mount(KOBJ_NS_TYPE_NET))
+                       return ERR_PTR(-EPERM);
        }
 
-       return dget(sb->s_root);
+       ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET);
+       root = kernfs_mount_ns(fs_type, flags, sysfs_root, ns);
+       if (IS_ERR(root))
+               kobj_ns_drop(KOBJ_NS_TYPE_NET, ns);
+       return root;
 }
 
 static void sysfs_kill_sb(struct super_block *sb)
 {
-       struct sysfs_super_info *info = sysfs_info(sb);
-       /* Remove the superblock from fs_supers/s_instances
-        * so we can't find it, before freeing sysfs_super_info.
-        */
-       kill_anon_super(sb);
-       free_sysfs_super_info(info);
+       kernfs_kill_sb(sb);
+       kobj_ns_drop(KOBJ_NS_TYPE_NET, (void *)kernfs_super_ns(sb));
 }
 
 static struct file_system_type sysfs_fs_type = {
@@ -165,48 +58,19 @@ static struct file_system_type sysfs_fs_type = {
 
 int __init sysfs_init(void)
 {
-       int err = -ENOMEM;
+       int err;
 
-       sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
-                                             sizeof(struct sysfs_dirent),
-                                             0, 0, NULL);
-       if (!sysfs_dir_cachep)
-               goto out;
+       sysfs_root = kernfs_create_root(NULL);
+       if (IS_ERR(sysfs_root))
+               return PTR_ERR(sysfs_root);
 
-       err = sysfs_inode_init();
-       if (err)
-               goto out_err;
+       sysfs_root_sd = sysfs_root->sd;
 
        err = register_filesystem(&sysfs_fs_type);
-       if (!err) {
-               sysfs_mnt = kern_mount(&sysfs_fs_type);
-               if (IS_ERR(sysfs_mnt)) {
-                       printk(KERN_ERR "sysfs: could not mount!\n");
-                       err = PTR_ERR(sysfs_mnt);
-                       sysfs_mnt = NULL;
-                       unregister_filesystem(&sysfs_fs_type);
-                       goto out_err;
-               }
-       } else
-               goto out_err;
-out:
-       return err;
-out_err:
-       kmem_cache_destroy(sysfs_dir_cachep);
-       sysfs_dir_cachep = NULL;
-       goto out;
-}
-
-#undef sysfs_get
-struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
-{
-       return __sysfs_get(sd);
-}
-EXPORT_SYMBOL_GPL(sysfs_get);
+       if (err) {
+               kernfs_destroy_root(sysfs_root);
+               return err;
+       }
 
-#undef sysfs_put
-void sysfs_put(struct sysfs_dirent *sd)
-{
-       __sysfs_put(sd);
+       return 0;
 }
-EXPORT_SYMBOL_GPL(sysfs_put);
index 3ae3f1bf1a0957075bec9d36d8834550000c3b14..1b8c9ed8511a7b2687097a2954c90f4bf6d8d8de 100644 (file)
  */
 
 #include <linux/fs.h>
-#include <linux/gfp.h>
-#include <linux/mount.h>
 #include <linux/module.h>
 #include <linux/kobject.h>
-#include <linux/namei.h>
 #include <linux/mutex.h>
 #include <linux/security.h>
 
@@ -25,11 +22,7 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd,
                                   struct kobject *target,
                                   const char *name, int warn)
 {
-       struct sysfs_dirent *target_sd = NULL;
-       struct sysfs_dirent *sd = NULL;
-       struct sysfs_addrm_cxt acxt;
-       enum kobj_ns_type ns_type;
-       int error;
+       struct sysfs_dirent *sd, *target_sd = NULL;
 
        BUG_ON(!name || !parent_sd);
 
@@ -39,53 +32,24 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd,
         * sysfs_remove_dir() for details.
         */
        spin_lock(&sysfs_symlink_target_lock);
-       if (target->sd)
-               target_sd = sysfs_get(target->sd);
+       if (target->sd) {
+               target_sd = target->sd;
+               kernfs_get(target_sd);
+       }
        spin_unlock(&sysfs_symlink_target_lock);
 
-       error = -ENOENT;
        if (!target_sd)
-               goto out_put;
-
-       error = -ENOMEM;
-       sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
-       if (!sd)
-               goto out_put;
+               return -ENOENT;
 
-       ns_type = sysfs_ns_type(parent_sd);
-       if (ns_type)
-               sd->s_ns = target_sd->s_ns;
-       sd->s_symlink.target_sd = target_sd;
-       target_sd = NULL;       /* reference is now owned by the symlink */
-
-       sysfs_addrm_start(&acxt);
-       /* Symlinks must be between directories with the same ns_type */
-       if (!ns_type ||
-           (ns_type == sysfs_ns_type(sd->s_symlink.target_sd->s_parent))) {
-               if (warn)
-                       error = sysfs_add_one(&acxt, sd, parent_sd);
-               else
-                       error = __sysfs_add_one(&acxt, sd, parent_sd);
-       } else {
-               error = -EINVAL;
-               WARN(1, KERN_WARNING
-                       "sysfs: symlink across ns_types %s/%s -> %s/%s\n",
-                       parent_sd->s_name,
-                       sd->s_name,
-                       sd->s_symlink.target_sd->s_parent->s_name,
-                       sd->s_symlink.target_sd->s_name);
-       }
-       sysfs_addrm_finish(&acxt);
+       sd = kernfs_create_link(parent_sd, name, target_sd);
+       kernfs_put(target_sd);
 
-       if (error)
-               goto out_put;
+       if (!IS_ERR(sd))
+               return 0;
 
-       return 0;
-
- out_put:
-       sysfs_put(target_sd);
-       sysfs_put(sd);
-       return error;
+       if (warn && PTR_ERR(sd) == -EEXIST)
+               sysfs_warn_dup(parent_sd, name);
+       return PTR_ERR(sd);
 }
 
 /**
@@ -106,7 +70,7 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
        struct sysfs_dirent *parent_sd = NULL;
 
        if (!kobj)
-               parent_sd = &sysfs_root;
+               parent_sd = sysfs_root_sd;
        else
                parent_sd = kobj->sd;
 
@@ -164,10 +128,10 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ,
         * sysfs_remove_dir() for details.
         */
        spin_lock(&sysfs_symlink_target_lock);
-       if (targ->sd && sysfs_ns_type(kobj->sd))
+       if (targ->sd && kernfs_ns_enabled(kobj->sd))
                ns = targ->sd->s_ns;
        spin_unlock(&sysfs_symlink_target_lock);
-       sysfs_hash_and_remove(kobj->sd, name, ns);
+       kernfs_remove_by_name_ns(kobj->sd, name, ns);
 }
 
 /**
@@ -180,11 +144,11 @@ void sysfs_remove_link(struct kobject *kobj, const char *name)
        struct sysfs_dirent *parent_sd = NULL;
 
        if (!kobj)
-               parent_sd = &sysfs_root;
+               parent_sd = sysfs_root_sd;
        else
                parent_sd = kobj->sd;
 
-       sysfs_hash_and_remove(parent_sd, name, NULL);
+       kernfs_remove_by_name(parent_sd, name);
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_link);
 
@@ -206,7 +170,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ,
        int result;
 
        if (!kobj)
-               parent_sd = &sysfs_root;
+               parent_sd = sysfs_root_sd;
        else
                parent_sd = kobj->sd;
 
@@ -214,117 +178,20 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ,
                old_ns = targ->sd->s_ns;
 
        result = -ENOENT;
-       sd = sysfs_get_dirent_ns(parent_sd, old, old_ns);
+       sd = kernfs_find_and_get_ns(parent_sd, old, old_ns);
        if (!sd)
                goto out;
 
        result = -EINVAL;
        if (sysfs_type(sd) != SYSFS_KOBJ_LINK)
                goto out;
-       if (sd->s_symlink.target_sd->s_dir.kobj != targ)
+       if (sd->s_symlink.target_sd->priv != targ)
                goto out;
 
-       result = sysfs_rename(sd, parent_sd, new, new_ns);
+       result = kernfs_rename_ns(sd, parent_sd, new, new_ns);
 
 out:
-       sysfs_put(sd);
+       kernfs_put(sd);
        return result;
 }
 EXPORT_SYMBOL_GPL(sysfs_rename_link_ns);
-
-static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
-                                struct sysfs_dirent *target_sd, char *path)
-{
-       struct sysfs_dirent *base, *sd;
-       char *s = path;
-       int len = 0;
-
-       /* go up to the root, stop at the base */
-       base = parent_sd;
-       while (base->s_parent) {
-               sd = target_sd->s_parent;
-               while (sd->s_parent && base != sd)
-                       sd = sd->s_parent;
-
-               if (base == sd)
-                       break;
-
-               strcpy(s, "../");
-               s += 3;
-               base = base->s_parent;
-       }
-
-       /* determine end of target string for reverse fillup */
-       sd = target_sd;
-       while (sd->s_parent && sd != base) {
-               len += strlen(sd->s_name) + 1;
-               sd = sd->s_parent;
-       }
-
-       /* check limits */
-       if (len < 2)
-               return -EINVAL;
-       len--;
-       if ((s - path) + len > PATH_MAX)
-               return -ENAMETOOLONG;
-
-       /* reverse fillup of target string from target to base */
-       sd = target_sd;
-       while (sd->s_parent && sd != base) {
-               int slen = strlen(sd->s_name);
-
-               len -= slen;
-               strncpy(s + len, sd->s_name, slen);
-               if (len)
-                       s[--len] = '/';
-
-               sd = sd->s_parent;
-       }
-
-       return 0;
-}
-
-static int sysfs_getlink(struct dentry *dentry, char *path)
-{
-       struct sysfs_dirent *sd = dentry->d_fsdata;
-       struct sysfs_dirent *parent_sd = sd->s_parent;
-       struct sysfs_dirent *target_sd = sd->s_symlink.target_sd;
-       int error;
-
-       mutex_lock(&sysfs_mutex);
-       error = sysfs_get_target_path(parent_sd, target_sd, path);
-       mutex_unlock(&sysfs_mutex);
-
-       return error;
-}
-
-static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
-       int error = -ENOMEM;
-       unsigned long page = get_zeroed_page(GFP_KERNEL);
-       if (page) {
-               error = sysfs_getlink(dentry, (char *) page);
-               if (error < 0)
-                       free_page((unsigned long)page);
-       }
-       nd_set_link(nd, error ? ERR_PTR(error) : (char *)page);
-       return NULL;
-}
-
-static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd,
-                          void *cookie)
-{
-       char *page = nd_get_link(nd);
-       if (!IS_ERR(page))
-               free_page((unsigned long)page);
-}
-
-const struct inode_operations sysfs_symlink_inode_operations = {
-       .setxattr       = sysfs_setxattr,
-       .readlink       = generic_readlink,
-       .follow_link    = sysfs_follow_link,
-       .put_link       = sysfs_put_link,
-       .setattr        = sysfs_setattr,
-       .getattr        = sysfs_getattr,
-       .permission     = sysfs_permission,
-};
index 0af09fbfb3f6abc112581638bf401b4b562430e8..c8e395b49330b0939eabd41cb61acfdfa549b8cd 100644 (file)
  * This file is released under the GPLv2.
  */
 
-#include <linux/lockdep.h>
-#include <linux/kobject_ns.h>
-#include <linux/fs.h>
-#include <linux/rbtree.h>
+#ifndef __SYSFS_INTERNAL_H
+#define __SYSFS_INTERNAL_H
 
-struct sysfs_open_dirent;
-
-/* type-specific structures for sysfs_dirent->s_* union members */
-struct sysfs_elem_dir {
-       struct kobject          *kobj;
-
-       unsigned long           subdirs;
-       /* children rbtree starts here and goes through sd->s_rb */
-       struct rb_root          children;
-};
-
-struct sysfs_elem_symlink {
-       struct sysfs_dirent     *target_sd;
-};
-
-struct sysfs_elem_attr {
-       union {
-               struct attribute        *attr;
-               struct bin_attribute    *bin_attr;
-       };
-       struct sysfs_open_dirent *open;
-};
-
-struct sysfs_inode_attrs {
-       struct iattr    ia_iattr;
-       void            *ia_secdata;
-       u32             ia_secdata_len;
-};
-
-/*
- * sysfs_dirent - the building block of sysfs hierarchy.  Each and
- * every sysfs node is represented by single sysfs_dirent.
- *
- * As long as s_count reference is held, the sysfs_dirent itself is
- * accessible.  Dereferencing s_elem or any other outer entity
- * requires s_active reference.
- */
-struct sysfs_dirent {
-       atomic_t                s_count;
-       atomic_t                s_active;
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-       struct lockdep_map      dep_map;
-#endif
-       struct sysfs_dirent     *s_parent;
-       const char              *s_name;
-
-       struct rb_node          s_rb;
-
-       union {
-               struct completion       *completion;
-               struct sysfs_dirent     *removed_list;
-       } u;
-
-       const void              *s_ns; /* namespace tag */
-       unsigned int            s_hash; /* ns + name hash */
-       union {
-               struct sysfs_elem_dir           s_dir;
-               struct sysfs_elem_symlink       s_symlink;
-               struct sysfs_elem_attr          s_attr;
-       };
-
-       unsigned short          s_flags;
-       umode_t                 s_mode;
-       unsigned int            s_ino;
-       struct sysfs_inode_attrs *s_iattr;
-};
-
-#define SD_DEACTIVATED_BIAS            INT_MIN
-
-#define SYSFS_TYPE_MASK                        0x00ff
-#define SYSFS_DIR                      0x0001
-#define SYSFS_KOBJ_ATTR                        0x0002
-#define SYSFS_KOBJ_BIN_ATTR            0x0004
-#define SYSFS_KOBJ_LINK                        0x0008
-#define SYSFS_COPY_NAME                        (SYSFS_DIR | SYSFS_KOBJ_LINK)
-#define SYSFS_ACTIVE_REF               (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR)
-
-/* identify any namespace tag on sysfs_dirents */
-#define SYSFS_NS_TYPE_MASK             0xf00
-#define SYSFS_NS_TYPE_SHIFT            8
-
-#define SYSFS_FLAG_MASK                        ~(SYSFS_NS_TYPE_MASK|SYSFS_TYPE_MASK)
-#define SYSFS_FLAG_REMOVED             0x02000
-
-static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
-{
-       return sd->s_flags & SYSFS_TYPE_MASK;
-}
-
-/*
- * Return any namespace tags on this dirent.
- * enum kobj_ns_type is defined in linux/kobject.h
- */
-static inline enum kobj_ns_type sysfs_ns_type(struct sysfs_dirent *sd)
-{
-       return (sd->s_flags & SYSFS_NS_TYPE_MASK) >> SYSFS_NS_TYPE_SHIFT;
-}
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-
-#define sysfs_dirent_init_lockdep(sd)                          \
-do {                                                           \
-       struct attribute *attr = sd->s_attr.attr;               \
-       struct lock_class_key *key = attr->key;                 \
-       if (!key)                                               \
-               key = &attr->skey;                              \
-                                                               \
-       lockdep_init_map(&sd->dep_map, "s_active", key, 0);     \
-} while (0)
-
-/* Test for attributes that want to ignore lockdep for read-locking */
-static inline bool sysfs_ignore_lockdep(struct sysfs_dirent *sd)
-{
-       int type = sysfs_type(sd);
-
-       return (type == SYSFS_KOBJ_ATTR || type == SYSFS_KOBJ_BIN_ATTR) &&
-               sd->s_attr.attr->ignore_lockdep;
-}
-
-#else
-
-#define sysfs_dirent_init_lockdep(sd) do {} while (0)
-
-static inline bool sysfs_ignore_lockdep(struct sysfs_dirent *sd)
-{
-       return true;
-}
-
-#endif
-
-/*
- * Context structure to be used while adding/removing nodes.
- */
-struct sysfs_addrm_cxt {
-       struct sysfs_dirent     *removed;
-};
+#include <linux/sysfs.h>
 
 /*
  * mount.c
  */
-
-/*
- * Each sb is associated with a set of namespace tags (i.e.
- * the network namespace of the task which mounted this sysfs
- * instance).
- */
-struct sysfs_super_info {
-       void *ns[KOBJ_NS_TYPES];
-};
-#define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info))
-extern struct sysfs_dirent sysfs_root;
-extern struct kmem_cache *sysfs_dir_cachep;
+extern struct sysfs_dirent *sysfs_root_sd;
 
 /*
  * dir.c
  */
-extern struct mutex sysfs_mutex;
 extern spinlock_t sysfs_symlink_target_lock;
-extern const struct dentry_operations sysfs_dentry_ops;
-
-extern const struct file_operations sysfs_dir_operations;
-extern const struct inode_operations sysfs_dir_inode_operations;
 
-struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
-void sysfs_put_active(struct sysfs_dirent *sd);
-void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt);
 void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name);
-int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
-                   struct sysfs_dirent *parent_sd);
-int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
-                 struct sysfs_dirent *parent_sd);
-void sysfs_remove(struct sysfs_dirent *sd);
-int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name,
-                         const void *ns);
-void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
-
-struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
-                                      const unsigned char *name,
-                                      const void *ns);
-struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type);
-
-void release_sysfs_dirent(struct sysfs_dirent *sd);
-
-int sysfs_create_subdir(struct kobject *kobj, const char *name,
-                       struct sysfs_dirent **p_sd);
-
-int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,
-                const char *new_name, const void *new_ns);
-
-static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
-{
-       if (sd) {
-               WARN_ON(!atomic_read(&sd->s_count));
-               atomic_inc(&sd->s_count);
-       }
-       return sd;
-}
-#define sysfs_get(sd) __sysfs_get(sd)
-
-static inline void __sysfs_put(struct sysfs_dirent *sd)
-{
-       if (sd && atomic_dec_and_test(&sd->s_count))
-               release_sysfs_dirent(sd);
-}
-#define sysfs_put(sd) __sysfs_put(sd)
-
-/*
- * inode.c
- */
-struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd);
-void sysfs_evict_inode(struct inode *inode);
-int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
-int sysfs_permission(struct inode *inode, int mask);
-int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
-int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                 struct kstat *stat);
-int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
-                  size_t size, int flags);
-int sysfs_inode_init(void);
 
 /*
  * file.c
  */
-extern const struct file_operations sysfs_file_operations;
-extern const struct file_operations sysfs_bin_operations;
-
 int sysfs_add_file(struct sysfs_dirent *dir_sd,
-                  const struct attribute *attr, int type);
-
+                  const struct attribute *attr, bool is_bin);
 int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
-                          const struct attribute *attr, int type,
+                          const struct attribute *attr, bool is_bin,
                           umode_t amode, const void *ns);
-void sysfs_unmap_bin_file(struct sysfs_dirent *sd);
 
 /*
  * symlink.c
  */
-extern const struct inode_operations sysfs_symlink_inode_operations;
 int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target,
                         const char *name);
+
+#endif /* __SYSFS_INTERNAL_H */
index 71c8c9d2b8826a0ed22d886fb3327d2ff0784fc3..1b19b9cd692ad8ff4d73259f7353b1e6a86477ad 100644 (file)
@@ -407,7 +407,7 @@ xfs_alloc_ioend_bio(
        struct bio              *bio = bio_alloc(GFP_NOIO, nvecs);
 
        ASSERT(bio->bi_private == NULL);
-       bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
+       bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9);
        bio->bi_bdev = bh->b_bdev;
        return bio;
 }
index c7f0b77dcb0090046b84eda27c68d870af25d45a..5f3ea443ebbe34950123246533058eb83c7f30c4 100644 (file)
@@ -1255,7 +1255,7 @@ next_chunk:
 
        bio = bio_alloc(GFP_NOIO, nr_pages);
        bio->bi_bdev = bp->b_target->bt_bdev;
-       bio->bi_sector = sector;
+       bio->bi_iter.bi_sector = sector;
        bio->bi_end_io = xfs_buf_bio_end_io;
        bio->bi_private = bp;
 
@@ -1277,7 +1277,7 @@ next_chunk:
                total_nr_pages--;
        }
 
-       if (likely(bio->bi_size)) {
+       if (likely(bio->bi_iter.bi_size)) {
                if (xfs_buf_is_vmapped(bp)) {
                        flush_kernel_vmap_range(bp->b_addr,
                                                xfs_buf_vmap_len(bp));
index d98c67001840b705db746e4a1bc89ccba209652b..3ea214cff349c87482d4d3a29b0370bb6c90cd42 100644 (file)
@@ -83,7 +83,9 @@
  * Should the subsystem abort the loading of an ACPI table if the
  * table checksum is incorrect?
  */
+#ifndef ACPI_CHECKSUM_ABORT
 #define ACPI_CHECKSUM_ABORT             FALSE
+#endif
 
 /*
  * Generate a version of ACPICA that only supports "reduced hardware"
index 7b2de026a4f3db11c730d9d3abfa8b903ba5713f..7135fe3d6daa6ee76bca6238a63a1ba6be949d5b 100644 (file)
@@ -28,8 +28,6 @@
 
 #include <linux/device.h>
 
-#include <acpi/acpi.h>
-
 /* TBD: Make dynamic */
 #define ACPI_MAX_HANDLES       10
 struct acpi_handle_list {
@@ -91,16 +89,10 @@ struct acpi_device;
  * -----------------
  */
 
-enum acpi_hotplug_mode {
-       AHM_GENERIC = 0,
-       AHM_CONTAINER,
-       AHM_COUNT
-};
-
 struct acpi_hotplug_profile {
        struct kobject kobj;
        bool enabled:1;
-       enum acpi_hotplug_mode mode;
+       int (*scan_dependent)(struct acpi_device *adev);
 };
 
 static inline struct acpi_hotplug_profile *to_acpi_hotplug_profile(
@@ -168,7 +160,9 @@ struct acpi_device_flags {
        u32 ejectable:1;
        u32 power_manageable:1;
        u32 match_driver:1;
-       u32 reserved:27;
+       u32 initialized:1;
+       u32 visited:1;
+       u32 reserved:25;
 };
 
 /* File System */
@@ -298,6 +292,7 @@ struct acpi_device {
        struct list_head children;
        struct list_head node;
        struct list_head wakeup_list;
+       struct list_head del_list;
        struct acpi_device_status status;
        struct acpi_device_flags flags;
        struct acpi_device_pnp pnp;
@@ -323,6 +318,11 @@ static inline void *acpi_driver_data(struct acpi_device *d)
 #define to_acpi_device(d)      container_of(d, struct acpi_device, dev)
 #define to_acpi_driver(d)      container_of(d, struct acpi_driver, drv)
 
+static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta)
+{
+       *((u32 *)&adev->status) = sta;
+}
+
 /* acpi_device.dev.bus == &acpi_bus_type */
 extern struct bus_type acpi_bus_type;
 
@@ -384,6 +384,11 @@ int acpi_match_device_ids(struct acpi_device *device,
 int acpi_create_dir(struct acpi_device *);
 void acpi_remove_dir(struct acpi_device *);
 
+static inline bool acpi_device_enumerated(struct acpi_device *adev)
+{
+       return adev && adev->flags.initialized && adev->flags.visited;
+}
+
 typedef void (*acpi_hp_callback)(void *data, u32 src);
 
 acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src);
@@ -407,7 +412,7 @@ struct acpi_bus_type {
        struct list_head list;
        const char *name;
        bool (*match)(struct device *dev);
-       int (*find_device) (struct device *, acpi_handle *);
+       struct acpi_device * (*find_companion)(struct device *);
        void (*setup)(struct device *);
        void (*cleanup)(struct device *);
 };
@@ -426,12 +431,9 @@ struct acpi_pci_root {
 };
 
 /* helper */
-acpi_handle acpi_find_child(acpi_handle, u64, bool);
-static inline acpi_handle acpi_get_child(acpi_handle handle, u64 addr)
-{
-       return acpi_find_child(handle, addr, false);
-}
-void acpi_preset_companion(struct device *dev, acpi_handle parent, u64 addr);
+
+struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
+                                          u64 address, bool check_children);
 int acpi_is_root_bridge(acpi_handle);
 struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
 
index 1cedfcb1bd8878ff7466e4ab6d9285e3a811a90a..b124fdb260469bfa07dbc14fa511cb7dbd0240e2 100644 (file)
@@ -26,9 +26,6 @@
 #ifndef __ACPI_DRIVERS_H__
 #define __ACPI_DRIVERS_H__
 
-#include <linux/acpi.h>
-#include <acpi/acpi_bus.h>
-
 #define ACPI_MAX_STRING                        80
 
 /*
index d8f9457755b4168787a66f903c15cb9d6506af25..4278aba9650381c932a687ca871a47f874b6aa1e 100644 (file)
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20130927
+#define ACPI_CA_VERSION                 0x20131115
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
diff --git a/include/asm-generic/simd.h b/include/asm-generic/simd.h
new file mode 100644 (file)
index 0000000..f57eb7b
--- /dev/null
@@ -0,0 +1,14 @@
+
+#include <linux/hardirq.h>
+
+/*
+ * may_use_simd - whether it is allowable at this time to issue SIMD
+ *                instructions or access the SIMD register file
+ *
+ * As architectures typically don't preserve the SIMD register file when
+ * taking an interrupt, !in_interrupt() should be a reasonable default.
+ */
+static __must_check inline bool may_use_simd(void)
+{
+       return !in_interrupt();
+}
index 418d270e18063517750f39c68490f56fb7cd24c3..e73c19e90e38f49e9ebdff10bfed3cdca90a9f9a 100644 (file)
@@ -386,5 +386,21 @@ static inline int crypto_requires_sync(u32 type, u32 mask)
        return (type ^ CRYPTO_ALG_ASYNC) & mask & CRYPTO_ALG_ASYNC;
 }
 
-#endif /* _CRYPTO_ALGAPI_H */
+noinline unsigned long __crypto_memneq(const void *a, const void *b, size_t size);
+
+/**
+ * crypto_memneq - Compare two areas of memory without leaking
+ *                timing information.
+ *
+ * @a: One area of memory
+ * @b: Another area of memory
+ * @size: The size of the area.
+ *
+ * Returns 0 when data is equal, 1 otherwise.
+ */
+static inline int crypto_memneq(const void *a, const void *b, size_t size)
+{
+       return __crypto_memneq(a, b, size) != 0UL ? 1 : 0;
+}
 
+#endif /* _CRYPTO_ALGAPI_H */
index e47b044929a84b7cd1e54fb17b8e87de3020d7b6..6775059539b56f2ffe870d28c4d2ab35821c013a 100644 (file)
@@ -23,5 +23,15 @@ struct crypto_authenc_key_param {
        __be32 enckeylen;
 };
 
-#endif /* _CRYPTO_AUTHENC_H */
+struct crypto_authenc_keys {
+       const u8 *authkey;
+       const u8 *enckey;
+
+       unsigned int authkeylen;
+       unsigned int enckeylen;
+};
 
+int crypto_authenc_extractkeys(struct crypto_authenc_keys *keys, const u8 *key,
+                              unsigned int keylen);
+
+#endif /* _CRYPTO_AUTHENC_H */
index 13621cc8cf4c454f546a6fbb33fb5e85e8b1b1aa..64ebede184f10d588ab251a11efe8df9f016d358 100644 (file)
@@ -36,6 +36,7 @@ static inline void scatterwalk_sg_chain(struct scatterlist *sg1, int num,
 {
        sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0);
        sg1[num - 1].page_link &= ~0x02;
+       sg1[num - 1].page_link |= 0x01;
 }
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
diff --git a/include/dt-bindings/clock/imx5-clock.h b/include/dt-bindings/clock/imx5-clock.h
new file mode 100644 (file)
index 0000000..5f2667e
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2013 Lucas Stach, Pengutronix <l.stach@pengutronix.de>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX5_H
+#define __DT_BINDINGS_CLOCK_IMX5_H
+
+#define IMX5_CLK_DUMMY                 0
+#define IMX5_CLK_CKIL                  1
+#define IMX5_CLK_OSC                   2
+#define IMX5_CLK_CKIH1                 3
+#define IMX5_CLK_CKIH2                 4
+#define IMX5_CLK_AHB                   5
+#define IMX5_CLK_IPG                   6
+#define IMX5_CLK_AXI_A                 7
+#define IMX5_CLK_AXI_B                 8
+#define IMX5_CLK_UART_PRED             9
+#define IMX5_CLK_UART_ROOT             10
+#define IMX5_CLK_ESDHC_A_PRED          11
+#define IMX5_CLK_ESDHC_B_PRED          12
+#define IMX5_CLK_ESDHC_C_SEL           13
+#define IMX5_CLK_ESDHC_D_SEL           14
+#define IMX5_CLK_EMI_SEL               15
+#define IMX5_CLK_EMI_SLOW_PODF         16
+#define IMX5_CLK_NFC_PODF              17
+#define IMX5_CLK_ECSPI_PRED            18
+#define IMX5_CLK_ECSPI_PODF            19
+#define IMX5_CLK_USBOH3_PRED           20
+#define IMX5_CLK_USBOH3_PODF           21
+#define IMX5_CLK_USB_PHY_PRED          22
+#define IMX5_CLK_USB_PHY_PODF          23
+#define IMX5_CLK_CPU_PODF              24
+#define IMX5_CLK_DI_PRED               25
+#define IMX5_CLK_TVE_SEL               27
+#define IMX5_CLK_UART1_IPG_GATE                28
+#define IMX5_CLK_UART1_PER_GATE                29
+#define IMX5_CLK_UART2_IPG_GATE                30
+#define IMX5_CLK_UART2_PER_GATE                31
+#define IMX5_CLK_UART3_IPG_GATE                32
+#define IMX5_CLK_UART3_PER_GATE                33
+#define IMX5_CLK_I2C1_GATE             34
+#define IMX5_CLK_I2C2_GATE             35
+#define IMX5_CLK_GPT_IPG_GATE          36
+#define IMX5_CLK_PWM1_IPG_GATE         37
+#define IMX5_CLK_PWM1_HF_GATE          38
+#define IMX5_CLK_PWM2_IPG_GATE         39
+#define IMX5_CLK_PWM2_HF_GATE          40
+#define IMX5_CLK_GPT_HF_GATE           41
+#define IMX5_CLK_FEC_GATE              42
+#define IMX5_CLK_USBOH3_PER_GATE       43
+#define IMX5_CLK_ESDHC1_IPG_GATE       44
+#define IMX5_CLK_ESDHC2_IPG_GATE       45
+#define IMX5_CLK_ESDHC3_IPG_GATE       46
+#define IMX5_CLK_ESDHC4_IPG_GATE       47
+#define IMX5_CLK_SSI1_IPG_GATE         48
+#define IMX5_CLK_SSI2_IPG_GATE         49
+#define IMX5_CLK_SSI3_IPG_GATE         50
+#define IMX5_CLK_ECSPI1_IPG_GATE       51
+#define IMX5_CLK_ECSPI1_PER_GATE       52
+#define IMX5_CLK_ECSPI2_IPG_GATE       53
+#define IMX5_CLK_ECSPI2_PER_GATE       54
+#define IMX5_CLK_CSPI_IPG_GATE         55
+#define IMX5_CLK_SDMA_GATE             56
+#define IMX5_CLK_EMI_SLOW_GATE         57
+#define IMX5_CLK_IPU_SEL               58
+#define IMX5_CLK_IPU_GATE              59
+#define IMX5_CLK_NFC_GATE              60
+#define IMX5_CLK_IPU_DI1_GATE          61
+#define IMX5_CLK_VPU_SEL               62
+#define IMX5_CLK_VPU_GATE              63
+#define IMX5_CLK_VPU_REFERENCE_GATE    64
+#define IMX5_CLK_UART4_IPG_GATE                65
+#define IMX5_CLK_UART4_PER_GATE                66
+#define IMX5_CLK_UART5_IPG_GATE                67
+#define IMX5_CLK_UART5_PER_GATE                68
+#define IMX5_CLK_TVE_GATE              69
+#define IMX5_CLK_TVE_PRED              70
+#define IMX5_CLK_ESDHC1_PER_GATE       71
+#define IMX5_CLK_ESDHC2_PER_GATE       72
+#define IMX5_CLK_ESDHC3_PER_GATE       73
+#define IMX5_CLK_ESDHC4_PER_GATE       74
+#define IMX5_CLK_USB_PHY_GATE          75
+#define IMX5_CLK_HSI2C_GATE            76
+#define IMX5_CLK_MIPI_HSC1_GATE                77
+#define IMX5_CLK_MIPI_HSC2_GATE                78
+#define IMX5_CLK_MIPI_ESC_GATE         79
+#define IMX5_CLK_MIPI_HSP_GATE         80
+#define IMX5_CLK_LDB_DI1_DIV_3_5       81
+#define IMX5_CLK_LDB_DI1_DIV           82
+#define IMX5_CLK_LDB_DI0_DIV_3_5       83
+#define IMX5_CLK_LDB_DI0_DIV           84
+#define IMX5_CLK_LDB_DI1_GATE          85
+#define IMX5_CLK_CAN2_SERIAL_GATE      86
+#define IMX5_CLK_CAN2_IPG_GATE         87
+#define IMX5_CLK_I2C3_GATE             88
+#define IMX5_CLK_LP_APM                        89
+#define IMX5_CLK_PERIPH_APM            90
+#define IMX5_CLK_MAIN_BUS              91
+#define IMX5_CLK_AHB_MAX               92
+#define IMX5_CLK_AIPS_TZ1              93
+#define IMX5_CLK_AIPS_TZ2              94
+#define IMX5_CLK_TMAX1                 95
+#define IMX5_CLK_TMAX2                 96
+#define IMX5_CLK_TMAX3                 97
+#define IMX5_CLK_SPBA                  98
+#define IMX5_CLK_UART_SEL              99
+#define IMX5_CLK_ESDHC_A_SEL           100
+#define IMX5_CLK_ESDHC_B_SEL           101
+#define IMX5_CLK_ESDHC_A_PODF          102
+#define IMX5_CLK_ESDHC_B_PODF          103
+#define IMX5_CLK_ECSPI_SEL             104
+#define IMX5_CLK_USBOH3_SEL            105
+#define IMX5_CLK_USB_PHY_SEL           106
+#define IMX5_CLK_IIM_GATE              107
+#define IMX5_CLK_USBOH3_GATE           108
+#define IMX5_CLK_EMI_FAST_GATE         109
+#define IMX5_CLK_IPU_DI0_GATE          110
+#define IMX5_CLK_GPC_DVFS              111
+#define IMX5_CLK_PLL1_SW               112
+#define IMX5_CLK_PLL2_SW               113
+#define IMX5_CLK_PLL3_SW               114
+#define IMX5_CLK_IPU_DI0_SEL           115
+#define IMX5_CLK_IPU_DI1_SEL           116
+#define IMX5_CLK_TVE_EXT_SEL           117
+#define IMX5_CLK_MX51_MIPI             118
+#define IMX5_CLK_PLL4_SW               119
+#define IMX5_CLK_LDB_DI1_SEL           120
+#define IMX5_CLK_DI_PLL4_PODF          121
+#define IMX5_CLK_LDB_DI0_SEL           122
+#define IMX5_CLK_LDB_DI0_GATE          123
+#define IMX5_CLK_USB_PHY1_GATE         124
+#define IMX5_CLK_USB_PHY2_GATE         125
+#define IMX5_CLK_PER_LP_APM            126
+#define IMX5_CLK_PER_PRED1             127
+#define IMX5_CLK_PER_PRED2             128
+#define IMX5_CLK_PER_PODF              129
+#define IMX5_CLK_PER_ROOT              130
+#define IMX5_CLK_SSI_APM               131
+#define IMX5_CLK_SSI1_ROOT_SEL         132
+#define IMX5_CLK_SSI2_ROOT_SEL         133
+#define IMX5_CLK_SSI3_ROOT_SEL         134
+#define IMX5_CLK_SSI_EXT1_SEL          135
+#define IMX5_CLK_SSI_EXT2_SEL          136
+#define IMX5_CLK_SSI_EXT1_COM_SEL      137
+#define IMX5_CLK_SSI_EXT2_COM_SEL      138
+#define IMX5_CLK_SSI1_ROOT_PRED                139
+#define IMX5_CLK_SSI1_ROOT_PODF                140
+#define IMX5_CLK_SSI2_ROOT_PRED                141
+#define IMX5_CLK_SSI2_ROOT_PODF                142
+#define IMX5_CLK_SSI_EXT1_PRED         143
+#define IMX5_CLK_SSI_EXT1_PODF         144
+#define IMX5_CLK_SSI_EXT2_PRED         145
+#define IMX5_CLK_SSI_EXT2_PODF         146
+#define IMX5_CLK_SSI1_ROOT_GATE                147
+#define IMX5_CLK_SSI2_ROOT_GATE                148
+#define IMX5_CLK_SSI3_ROOT_GATE                149
+#define IMX5_CLK_SSI_EXT1_GATE         150
+#define IMX5_CLK_SSI_EXT2_GATE         151
+#define IMX5_CLK_EPIT1_IPG_GATE                152
+#define IMX5_CLK_EPIT1_HF_GATE         153
+#define IMX5_CLK_EPIT2_IPG_GATE                154
+#define IMX5_CLK_EPIT2_HF_GATE         155
+#define IMX5_CLK_CAN_SEL               156
+#define IMX5_CLK_CAN1_SERIAL_GATE      157
+#define IMX5_CLK_CAN1_IPG_GATE         158
+#define IMX5_CLK_OWIRE_GATE            159
+#define IMX5_CLK_GPU3D_SEL             160
+#define IMX5_CLK_GPU2D_SEL             161
+#define IMX5_CLK_GPU3D_GATE            162
+#define IMX5_CLK_GPU2D_GATE            163
+#define IMX5_CLK_GARB_GATE             164
+#define IMX5_CLK_CKO1_SEL              165
+#define IMX5_CLK_CKO1_PODF             166
+#define IMX5_CLK_CKO1                  167
+#define IMX5_CLK_CKO2_SEL              168
+#define IMX5_CLK_CKO2_PODF             169
+#define IMX5_CLK_CKO2                  170
+#define IMX5_CLK_SRTC_GATE             171
+#define IMX5_CLK_PATA_GATE             172
+#define IMX5_CLK_SATA_GATE             173
+#define IMX5_CLK_SPDIF_XTAL_SEL                174
+#define IMX5_CLK_SPDIF0_SEL            175
+#define IMX5_CLK_SPDIF1_SEL            176
+#define IMX5_CLK_SPDIF0_PRED           177
+#define IMX5_CLK_SPDIF0_PODF           178
+#define IMX5_CLK_SPDIF1_PRED           179
+#define IMX5_CLK_SPDIF1_PODF           180
+#define IMX5_CLK_SPDIF0_COM_SEL                181
+#define IMX5_CLK_SPDIF1_COM_SEL                182
+#define IMX5_CLK_SPDIF0_GATE           183
+#define IMX5_CLK_SPDIF1_GATE           184
+#define IMX5_CLK_SPDIF_IPG_GATE                185
+#define IMX5_CLK_OCRAM                 186
+#define IMX5_CLK_SAHARA_IPG_GATE       187
+#define IMX5_CLK_SATA_REF              188
+#define IMX5_CLK_END                   189
+
+#endif /* __DT_BINDINGS_CLOCK_IMX5_H */
index 7fcdf90879f25b23e9dadd28399dd7e8112022e9..46f7495ae3870c12a511b558b7970b8b4151e538 100644 (file)
 #define IMX6SL_CLK_USDHC2              130
 #define IMX6SL_CLK_USDHC3              131
 #define IMX6SL_CLK_USDHC4              132
-#define IMX6SL_CLK_CLK_END             133
+#define IMX6SL_CLK_END                 133
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
index 4aa2b48cd15183e457a3eb96288dca81039cef37..a91602951d3d3c018218c37889b7ae9338191948 100644 (file)
 #define VF610_CLK_GPU2D                        147
 #define VF610_CLK_ENET0                        148
 #define VF610_CLK_ENET1                        149
-#define VF610_CLK_END                  150
+#define VF610_CLK_DMAMUX0              150
+#define VF610_CLK_DMAMUX1              151
+#define VF610_CLK_DMAMUX2              152
+#define VF610_CLK_DMAMUX3              153
+#define VF610_CLK_END                  154
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
index d9099b15b4726404343308a39e5e55d39a16aa05..115c610324d1ec6b9ecc8aa3a67d839636ca35bf 100644 (file)
@@ -53,6 +53,12 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
 #define ACPI_COMPANION_SET(dev, adev)  ACPI_COMPANION(dev) = (adev)
 #define ACPI_HANDLE(dev)               acpi_device_handle(ACPI_COMPANION(dev))
 
+static inline void acpi_preset_companion(struct device *dev,
+                                        struct acpi_device *parent, u64 addr)
+{
+       ACPI_COMPANION_SET(dev, acpi_find_child_device(parent, addr, NULL));
+}
+
 static inline const char *acpi_dev_name(struct acpi_device *adev)
 {
        return dev_name(&adev->dev);
index b0ffa219993ec2be82a01854718d5e1269ef05bb..ded96fed8f18f12cbf536bbdd0627de7316af2e5 100644 (file)
@@ -2,7 +2,7 @@
 #define _ACPI_IO_H_
 
 #include <linux/io.h>
-#include <acpi/acpi.h>
+#include <linux/acpi.h>
 
 static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
                                            acpi_size size)
index 060ff695085c596f2ddcd2166e7825290d75bd3d..70654521dab69fb03443723550e9b9f8c64a6533 100644 (file)
  * various member access, note that bio_data should of course not be used
  * on highmem page vectors
  */
-#define bio_iovec_idx(bio, idx)        (&((bio)->bi_io_vec[(idx)]))
-#define bio_iovec(bio)         bio_iovec_idx((bio), (bio)->bi_idx)
-#define bio_page(bio)          bio_iovec((bio))->bv_page
-#define bio_offset(bio)                bio_iovec((bio))->bv_offset
-#define bio_segments(bio)      ((bio)->bi_vcnt - (bio)->bi_idx)
-#define bio_sectors(bio)       ((bio)->bi_size >> 9)
-#define bio_end_sector(bio)    ((bio)->bi_sector + bio_sectors((bio)))
+#define __bvec_iter_bvec(bvec, iter)   (&(bvec)[(iter).bi_idx])
+
+#define bvec_iter_page(bvec, iter)                             \
+       (__bvec_iter_bvec((bvec), (iter))->bv_page)
+
+#define bvec_iter_len(bvec, iter)                              \
+       min((iter).bi_size,                                     \
+           __bvec_iter_bvec((bvec), (iter))->bv_len - (iter).bi_bvec_done)
+
+#define bvec_iter_offset(bvec, iter)                           \
+       (__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
+
+#define bvec_iter_bvec(bvec, iter)                             \
+((struct bio_vec) {                                            \
+       .bv_page        = bvec_iter_page((bvec), (iter)),       \
+       .bv_len         = bvec_iter_len((bvec), (iter)),        \
+       .bv_offset      = bvec_iter_offset((bvec), (iter)),     \
+})
+
+#define bio_iter_iovec(bio, iter)                              \
+       bvec_iter_bvec((bio)->bi_io_vec, (iter))
+
+#define bio_iter_page(bio, iter)                               \
+       bvec_iter_page((bio)->bi_io_vec, (iter))
+#define bio_iter_len(bio, iter)                                        \
+       bvec_iter_len((bio)->bi_io_vec, (iter))
+#define bio_iter_offset(bio, iter)                             \
+       bvec_iter_offset((bio)->bi_io_vec, (iter))
+
+#define bio_page(bio)          bio_iter_page((bio), (bio)->bi_iter)
+#define bio_offset(bio)                bio_iter_offset((bio), (bio)->bi_iter)
+#define bio_iovec(bio)         bio_iter_iovec((bio), (bio)->bi_iter)
+
+#define bio_multiple_segments(bio)                             \
+       ((bio)->bi_iter.bi_size != bio_iovec(bio).bv_len)
+#define bio_sectors(bio)       ((bio)->bi_iter.bi_size >> 9)
+#define bio_end_sector(bio)    ((bio)->bi_iter.bi_sector + bio_sectors((bio)))
+
+/*
+ * Check whether this bio carries any data or not. A NULL bio is allowed.
+ */
+static inline bool bio_has_data(struct bio *bio)
+{
+       if (bio &&
+           bio->bi_iter.bi_size &&
+           !(bio->bi_rw & REQ_DISCARD))
+               return true;
+
+       return false;
+}
+
+static inline bool bio_is_rw(struct bio *bio)
+{
+       if (!bio_has_data(bio))
+               return false;
+
+       if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
+               return false;
+
+       return true;
+}
+
+static inline bool bio_mergeable(struct bio *bio)
+{
+       if (bio->bi_rw & REQ_NOMERGE_FLAGS)
+               return false;
+
+       return true;
+}
 
 static inline unsigned int bio_cur_bytes(struct bio *bio)
 {
-       if (bio->bi_vcnt)
-               return bio_iovec(bio)->bv_len;
+       if (bio_has_data(bio))
+               return bio_iovec(bio).bv_len;
        else /* dataless requests such as discard */
-               return bio->bi_size;
+               return bio->bi_iter.bi_size;
 }
 
 static inline void *bio_data(struct bio *bio)
 {
-       if (bio->bi_vcnt)
+       if (bio_has_data(bio))
                return page_address(bio_page(bio)) + bio_offset(bio);
 
        return NULL;
@@ -97,19 +159,16 @@ static inline void *bio_data(struct bio *bio)
  * permanent PIO fall back, user is probably better off disabling highmem
  * I/O completely on that queue (see ide-dma for example)
  */
-#define __bio_kmap_atomic(bio, idx)                            \
-       (kmap_atomic(bio_iovec_idx((bio), (idx))->bv_page) +    \
-               bio_iovec_idx((bio), (idx))->bv_offset)
+#define __bio_kmap_atomic(bio, iter)                           \
+       (kmap_atomic(bio_iter_iovec((bio), (iter)).bv_page) +   \
+               bio_iter_iovec((bio), (iter)).bv_offset)
 
-#define __bio_kunmap_atomic(addr) kunmap_atomic(addr)
+#define __bio_kunmap_atomic(addr)      kunmap_atomic(addr)
 
 /*
  * merge helpers etc
  */
 
-#define __BVEC_END(bio)                bio_iovec_idx((bio), (bio)->bi_vcnt - 1)
-#define __BVEC_START(bio)      bio_iovec_idx((bio), (bio)->bi_idx)
-
 /* Default implementation of BIOVEC_PHYS_MERGEABLE */
 #define __BIOVEC_PHYS_MERGEABLE(vec1, vec2)    \
        ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
@@ -126,33 +185,76 @@ static inline void *bio_data(struct bio *bio)
        (((addr1) | (mask)) == (((addr2) - 1) | (mask)))
 #define BIOVEC_SEG_BOUNDARY(q, b1, b2) \
        __BIO_SEG_BOUNDARY(bvec_to_phys((b1)), bvec_to_phys((b2)) + (b2)->bv_len, queue_segment_boundary((q)))
-#define BIO_SEG_BOUNDARY(q, b1, b2) \
-       BIOVEC_SEG_BOUNDARY((q), __BVEC_END((b1)), __BVEC_START((b2)))
 
 #define bio_io_error(bio) bio_endio((bio), -EIO)
 
-/*
- * drivers should not use the __ version unless they _really_ know what
- * they're doing
- */
-#define __bio_for_each_segment(bvl, bio, i, start_idx)                 \
-       for (bvl = bio_iovec_idx((bio), (start_idx)), i = (start_idx);  \
-            i < (bio)->bi_vcnt;                                        \
-            bvl++, i++)
-
 /*
  * drivers should _never_ use the all version - the bio may have been split
  * before it got to the driver and the driver won't own all of it
  */
 #define bio_for_each_segment_all(bvl, bio, i)                          \
-       for (i = 0;                                                     \
-            bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt;       \
-            i++)
+       for (i = 0, bvl = (bio)->bi_io_vec; i < (bio)->bi_vcnt; i++, bvl++)
+
+static inline void bvec_iter_advance(struct bio_vec *bv, struct bvec_iter *iter,
+                                    unsigned bytes)
+{
+       WARN_ONCE(bytes > iter->bi_size,
+                 "Attempted to advance past end of bvec iter\n");
+
+       while (bytes) {
+               unsigned len = min(bytes, bvec_iter_len(bv, *iter));
+
+               bytes -= len;
+               iter->bi_size -= len;
+               iter->bi_bvec_done += len;
+
+               if (iter->bi_bvec_done == __bvec_iter_bvec(bv, *iter)->bv_len) {
+                       iter->bi_bvec_done = 0;
+                       iter->bi_idx++;
+               }
+       }
+}
+
+#define for_each_bvec(bvl, bio_vec, iter, start)                       \
+       for ((iter) = start;                                            \
+            (bvl) = bvec_iter_bvec((bio_vec), (iter)),                 \
+               (iter).bi_size;                                         \
+            bvec_iter_advance((bio_vec), &(iter), (bvl).bv_len))
+
+
+static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
+                                   unsigned bytes)
+{
+       iter->bi_sector += bytes >> 9;
+
+       if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
+               iter->bi_size -= bytes;
+       else
+               bvec_iter_advance(bio->bi_io_vec, iter, bytes);
+}
 
-#define bio_for_each_segment(bvl, bio, i)                              \
-       for (i = (bio)->bi_idx;                                         \
-            bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt;       \
-            i++)
+#define __bio_for_each_segment(bvl, bio, iter, start)                  \
+       for (iter = (start);                                            \
+            (iter).bi_size &&                                          \
+               ((bvl = bio_iter_iovec((bio), (iter))), 1);             \
+            bio_advance_iter((bio), &(iter), (bvl).bv_len))
+
+#define bio_for_each_segment(bvl, bio, iter)                           \
+       __bio_for_each_segment(bvl, bio, iter, (bio)->bi_iter)
+
+#define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
+
+static inline unsigned bio_segments(struct bio *bio)
+{
+       unsigned segs = 0;
+       struct bio_vec bv;
+       struct bvec_iter iter;
+
+       bio_for_each_segment(bv, bio, iter)
+               segs++;
+
+       return segs;
+}
 
 /*
  * get a reference to a bio, so it won't disappear. the intended use is
@@ -177,16 +279,15 @@ static inline void *bio_data(struct bio *bio)
 struct bio_integrity_payload {
        struct bio              *bip_bio;       /* parent bio */
 
-       sector_t                bip_sector;     /* virtual start sector */
+       struct bvec_iter        bip_iter;
 
+       /* kill - should just use bip_vec */
        void                    *bip_buf;       /* generated integrity data */
-       bio_end_io_t            *bip_end_io;    /* saved I/O completion fn */
 
-       unsigned int            bip_size;
+       bio_end_io_t            *bip_end_io;    /* saved I/O completion fn */
 
        unsigned short          bip_slab;       /* slab the bip came from */
        unsigned short          bip_vcnt;       /* # of integrity bio_vecs */
-       unsigned short          bip_idx;        /* current bip_vec index */
        unsigned                bip_owns_buf:1; /* should free bip_buf */
 
        struct work_struct      bip_work;       /* I/O completion */
@@ -196,29 +297,28 @@ struct bio_integrity_payload {
 };
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
 
-/*
- * A bio_pair is used when we need to split a bio.
- * This can only happen for a bio that refers to just one
- * page of data, and in the unusual situation when the
- * page crosses a chunk/device boundary
+extern void bio_trim(struct bio *bio, int offset, int size);
+extern struct bio *bio_split(struct bio *bio, int sectors,
+                            gfp_t gfp, struct bio_set *bs);
+
+/**
+ * bio_next_split - get next @sectors from a bio, splitting if necessary
+ * @bio:       bio to split
+ * @sectors:   number of sectors to split from the front of @bio
+ * @gfp:       gfp mask
+ * @bs:                bio set to allocate from
  *
- * The address of the master bio is stored in bio1.bi_private
- * The address of the pool the pair was allocated from is stored
- *   in bio2.bi_private
+ * Returns a bio representing the next @sectors of @bio - if the bio is smaller
+ * than @sectors, returns the original bio unchanged.
  */
-struct bio_pair {
-       struct bio                      bio1, bio2;
-       struct bio_vec                  bv1, bv2;
-#if defined(CONFIG_BLK_DEV_INTEGRITY)
-       struct bio_integrity_payload    bip1, bip2;
-       struct bio_vec                  iv1, iv2;
-#endif
-       atomic_t                        cnt;
-       int                             error;
-};
-extern struct bio_pair *bio_split(struct bio *bi, int first_sectors);
-extern void bio_pair_release(struct bio_pair *dbio);
-extern void bio_trim(struct bio *bio, int offset, int size);
+static inline struct bio *bio_next_split(struct bio *bio, int sectors,
+                                        gfp_t gfp, struct bio_set *bs)
+{
+       if (sectors >= bio_sectors(bio))
+               return bio;
+
+       return bio_split(bio, sectors, gfp, bs);
+}
 
 extern struct bio_set *bioset_create(unsigned int, unsigned int);
 extern void bioset_free(struct bio_set *);
@@ -227,7 +327,8 @@ extern mempool_t *biovec_create_pool(struct bio_set *bs, int pool_entries);
 extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *);
 extern void bio_put(struct bio *);
 
-extern void __bio_clone(struct bio *, struct bio *);
+extern void __bio_clone_fast(struct bio *, struct bio *);
+extern struct bio *bio_clone_fast(struct bio *, gfp_t, struct bio_set *);
 extern struct bio *bio_clone_bioset(struct bio *, gfp_t, struct bio_set *bs);
 
 extern struct bio_set *fs_bio_set;
@@ -254,6 +355,7 @@ static inline struct bio *bio_clone_kmalloc(struct bio *bio, gfp_t gfp_mask)
 }
 
 extern void bio_endio(struct bio *, int);
+extern void bio_endio_nodec(struct bio *, int);
 struct request_queue;
 extern int bio_phys_segments(struct request_queue *, struct bio *);
 
@@ -262,12 +364,12 @@ extern void bio_advance(struct bio *, unsigned);
 
 extern void bio_init(struct bio *);
 extern void bio_reset(struct bio *);
+void bio_chain(struct bio *, struct bio *);
 
 extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
 extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
                           unsigned int, unsigned int);
 extern int bio_get_nr_vecs(struct block_device *);
-extern sector_t bio_sector_offset(struct bio *, unsigned short, unsigned int);
 extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
                                unsigned long, unsigned int, int, gfp_t);
 struct sg_iovec;
@@ -357,47 +459,17 @@ static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
 }
 #endif
 
-static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
+static inline char *__bio_kmap_irq(struct bio *bio, struct bvec_iter iter,
                                   unsigned long *flags)
 {
-       return bvec_kmap_irq(bio_iovec_idx(bio, idx), flags);
+       return bvec_kmap_irq(&bio_iter_iovec(bio, iter), flags);
 }
 #define __bio_kunmap_irq(buf, flags)   bvec_kunmap_irq(buf, flags)
 
 #define bio_kmap_irq(bio, flags) \
-       __bio_kmap_irq((bio), (bio)->bi_idx, (flags))
+       __bio_kmap_irq((bio), (bio)->bi_iter, (flags))
 #define bio_kunmap_irq(buf,flags)      __bio_kunmap_irq(buf, flags)
 
-/*
- * Check whether this bio carries any data or not. A NULL bio is allowed.
- */
-static inline bool bio_has_data(struct bio *bio)
-{
-       if (bio && bio->bi_vcnt)
-               return true;
-
-       return false;
-}
-
-static inline bool bio_is_rw(struct bio *bio)
-{
-       if (!bio_has_data(bio))
-               return false;
-
-       if (bio->bi_rw & REQ_WRITE_SAME)
-               return false;
-
-       return true;
-}
-
-static inline bool bio_mergeable(struct bio *bio)
-{
-       if (bio->bi_rw & REQ_NOMERGE_FLAGS)
-               return false;
-
-       return true;
-}
-
 /*
  * BIO list management for use by remapping drivers (e.g. DM or MD) and loop.
  *
@@ -559,16 +631,12 @@ struct biovec_slab {
 
 #if defined(CONFIG_BLK_DEV_INTEGRITY)
 
-#define bip_vec_idx(bip, idx)  (&(bip->bip_vec[(idx)]))
-#define bip_vec(bip)           bip_vec_idx(bip, 0)
 
-#define __bip_for_each_vec(bvl, bip, i, start_idx)                     \
-       for (bvl = bip_vec_idx((bip), (start_idx)), i = (start_idx);    \
-            i < (bip)->bip_vcnt;                                       \
-            bvl++, i++)
 
-#define bip_for_each_vec(bvl, bip, i)                                  \
-       __bip_for_each_vec(bvl, bip, i, (bip)->bip_idx)
+#define bip_vec_idx(bip, idx)  (&(bip->bip_vec[(idx)]))
+
+#define bip_for_each_vec(bvl, bip, iter)                               \
+       for_each_bvec(bvl, (bip)->bip_vec, iter, (bip)->bip_iter)
 
 #define bio_for_each_integrity_vec(_bvl, _bio, _iter)                  \
        for_each_bio(_bio)                                              \
@@ -586,7 +654,6 @@ extern int bio_integrity_prep(struct bio *);
 extern void bio_integrity_endio(struct bio *, int);
 extern void bio_integrity_advance(struct bio *, unsigned int);
 extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int);
-extern void bio_integrity_split(struct bio *, struct bio_pair *, int);
 extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t);
 extern int bioset_integrity_create(struct bio_set *, int);
 extern void bioset_integrity_free(struct bio_set *);
@@ -630,12 +697,6 @@ static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
        return 0;
 }
 
-static inline void bio_integrity_split(struct bio *bio, struct bio_pair *bp,
-                                      int sectors)
-{
-       return;
-}
-
 static inline void bio_integrity_advance(struct bio *bio,
                                         unsigned int bytes_done)
 {
index 238ef0ed62f85f18085b6446bc681d8c18d674dc..bbc3a6c88fce3410b954b6c91c407297e2f03e7f 100644 (file)
@@ -28,13 +28,22 @@ struct bio_vec {
        unsigned int    bv_offset;
 };
 
+struct bvec_iter {
+       sector_t                bi_sector;      /* device address in 512 byte
+                                                  sectors */
+       unsigned int            bi_size;        /* residual I/O count */
+
+       unsigned int            bi_idx;         /* current index into bvl_vec */
+
+       unsigned int            bi_bvec_done;   /* number of bytes completed in
+                                                  current bvec */
+};
+
 /*
  * main unit of I/O for the block layer and lower layers (ie drivers and
  * stacking drivers)
  */
 struct bio {
-       sector_t                bi_sector;      /* device address in 512 byte
-                                                  sectors */
        struct bio              *bi_next;       /* request queue link */
        struct block_device     *bi_bdev;
        unsigned long           bi_flags;       /* status, command, etc */
@@ -42,16 +51,13 @@ struct bio {
                                                 * top bits priority
                                                 */
 
-       unsigned short          bi_vcnt;        /* how many bio_vec's */
-       unsigned short          bi_idx;         /* current index into bvl_vec */
+       struct bvec_iter        bi_iter;
 
        /* Number of segments in this BIO after
         * physical address coalescing is performed.
         */
        unsigned int            bi_phys_segments;
 
-       unsigned int            bi_size;        /* residual I/O count */
-
        /*
         * To keep track of the max segment size, we account for the
         * sizes of the first and last mergeable segments in this bio.
@@ -59,6 +65,8 @@ struct bio {
        unsigned int            bi_seg_front_size;
        unsigned int            bi_seg_back_size;
 
+       atomic_t                bi_remaining;
+
        bio_end_io_t            *bi_end_io;
 
        void                    *bi_private;
@@ -74,11 +82,13 @@ struct bio {
        struct bio_integrity_payload *bi_integrity;  /* data integrity */
 #endif
 
+       unsigned short          bi_vcnt;        /* how many bio_vec's */
+
        /*
         * Everything starting with bi_max_vecs will be preserved by bio_reset()
         */
 
-       unsigned int            bi_max_vecs;    /* max bvl_vecs we can hold */
+       unsigned short          bi_max_vecs;    /* max bvl_vecs we can hold */
 
        atomic_t                bi_cnt;         /* pin count */
 
index 1b135d49b27985d3243cdbf92d6002ce5eea8597..02cb6f0ea71d52a09c3b2147f2bbc91997904650 100644 (file)
@@ -735,7 +735,7 @@ struct rq_map_data {
 };
 
 struct req_iterator {
-       int i;
+       struct bvec_iter iter;
        struct bio *bio;
 };
 
@@ -748,10 +748,11 @@ struct req_iterator {
 
 #define rq_for_each_segment(bvl, _rq, _iter)                   \
        __rq_for_each_bio(_iter.bio, _rq)                       \
-               bio_for_each_segment(bvl, _iter.bio, _iter.i)
+               bio_for_each_segment(bvl, _iter.bio, _iter.iter)
 
-#define rq_iter_last(rq, _iter)                                        \
-               (_iter.bio->bi_next == NULL && _iter.i == _iter.bio->bi_vcnt-1)
+#define rq_iter_last(bvec, _iter)                              \
+               (_iter.bio->bi_next == NULL &&                  \
+                bio_iter_last(bvec, _iter.iter))
 
 #ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
 # error        "You should define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE for your platform"
index 7c1420bb1dcef40e6f8e4cc571ef5ea2c25df913..091fdb600d55bbde721ef15d06cbb5494e322ebc 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __FS_CEPH_MESSENGER_H
 #define __FS_CEPH_MESSENGER_H
 
+#include <linux/blk_types.h>
 #include <linux/kref.h>
 #include <linux/mutex.h>
 #include <linux/net.h>
@@ -119,8 +120,7 @@ struct ceph_msg_data_cursor {
 #ifdef CONFIG_BLOCK
                struct {                                /* bio */
                        struct bio      *bio;           /* bio from list */
-                       unsigned int    vector_index;   /* vector from bio */
-                       unsigned int    vector_offset;  /* bytes from vector */
+                       struct bvec_iter bvec_iter;
                };
 #endif /* CONFIG_BLOCK */
                struct {                                /* pages */
index 39c1d946967778d29df5399d5ad222ff7a2ee2b8..50d8cc37498b35a42a3c474a93c55f556e464fcb 100644 (file)
@@ -29,7 +29,6 @@ struct cgroup_subsys;
 struct inode;
 struct cgroup;
 struct css_id;
-struct eventfd_ctx;
 
 extern int cgroup_init_early(void);
 extern int cgroup_init(void);
@@ -239,10 +238,6 @@ struct cgroup {
        struct rcu_head rcu_head;
        struct work_struct destroy_work;
 
-       /* List of events which userspace want to receive */
-       struct list_head event_list;
-       spinlock_t event_list_lock;
-
        /* directory xattrs */
        struct simple_xattrs xattrs;
 };
@@ -280,6 +275,9 @@ enum {
         * - "tasks" is removed.  Everything should be at process
         *   granularity.  Use "cgroup.procs" instead.
         *
+        * - "cgroup.procs" is not sorted.  pids will be unique unless they
+        *   got recycled inbetween reads.
+        *
         * - "release_agent" and "notify_on_release" are removed.
         *   Replacement notification mechanism will be implemented.
         *
@@ -504,27 +502,6 @@ struct cftype {
         * kick type for multiplexing.
         */
        int (*trigger)(struct cgroup_subsys_state *css, unsigned int event);
-
-       int (*release)(struct inode *inode, struct file *file);
-
-       /*
-        * register_event() callback will be used to add new userspace
-        * waiter for changes related to the cftype. Implement it if
-        * you want to provide this functionality. Use eventfd_signal()
-        * on eventfd to send notification to userspace.
-        */
-       int (*register_event)(struct cgroup_subsys_state *css,
-                             struct cftype *cft, struct eventfd_ctx *eventfd,
-                             const char *args);
-       /*
-        * unregister_event() callback will be called when userspace
-        * closes the eventfd or on cgroup removing.
-        * This callback must be implemented, if you want provide
-        * notification functionality.
-        */
-       void (*unregister_event)(struct cgroup_subsys_state *css,
-                                struct cftype *cft,
-                                struct eventfd_ctx *eventfd);
 };
 
 /*
index dc196bbcf227288bce4d4d3e2db60dae5cde3dec..ee5fe9d77ae8ef400031978a3990430b7aa57f4a 100644 (file)
@@ -280,6 +280,14 @@ cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy)
                        policy->cpuinfo.max_freq);
 }
 
+#ifdef CONFIG_CPU_FREQ
+void cpufreq_suspend(void);
+void cpufreq_resume(void);
+#else
+static inline void cpufreq_suspend(void) {}
+static inline void cpufreq_resume(void) {}
+#endif
+
 /*********************************************************************
  *                     CPUFREQ NOTIFIER INTERFACE                    *
  *********************************************************************/
index f4b0aa3126f5deae8ff8908375a9da1eca790ecf..a68cbe59e6ad190023e410cb32784b1fb6a67d2a 100644 (file)
@@ -29,7 +29,7 @@ typedef void (*io_notify_fn)(unsigned long error, void *context);
 
 enum dm_io_mem_type {
        DM_IO_PAGE_LIST,/* Page list */
-       DM_IO_BVEC,     /* Bio vector */
+       DM_IO_BIO,      /* Bio vector */
        DM_IO_VMA,      /* Virtual memory area */
        DM_IO_KMEM,     /* Kernel memory */
 };
@@ -41,7 +41,7 @@ struct dm_io_memory {
 
        union {
                struct page_list *pl;
-               struct bio_vec *bvec;
+               struct bio *bio;
                void *vma;
                void *addr;
        } ptr;
index bc5687d0f3157c9d8d39342d4e69db1734baff16..49ece2ca3c570a2f589ef94588e031bbeb6654ce 100644 (file)
@@ -653,6 +653,7 @@ extern int __init efi_setup_pcdp_console(char *);
 #define EFI_RUNTIME_SERVICES   3       /* Can we use runtime services? */
 #define EFI_MEMMAP             4       /* Can we use EFI memory map? */
 #define EFI_64BIT              5       /* Is the firmware 64-bit? */
+#define EFI_ARCH_1             6       /* First arch-specific bit */
 
 #ifdef CONFIG_EFI
 # ifdef CONFIG_X86
@@ -801,6 +802,8 @@ struct efivar_entry {
        struct efi_variable var;
        struct list_head list;
        struct kobject kobj;
+       bool scanning;
+       bool deleting;
 };
 
 
@@ -866,6 +869,8 @@ void efivar_run_worker(void);
 #if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE)
 int efivars_sysfs_init(void);
 
+#define EFIVARS_DATA_SIZE_MAX 1024
+
 #endif /* CONFIG_EFI_VARS */
 
 #endif /* _LINUX_EFI_H */
index bb942f6d5702912218abfc43134660dc0b4ea21f..aea5eedbb1ca042314fc9c422b420324bacdf063 100644 (file)
@@ -153,6 +153,14 @@ struct f2fs_extent {
 #define        NODE_DIND_BLOCK         (DEF_ADDRS_PER_INODE + 5)
 
 #define F2FS_INLINE_XATTR      0x01    /* file inline xattr flag */
+#define F2FS_INLINE_DATA       0x02    /* file inline data flag */
+
+
+#define MAX_INLINE_DATA                (sizeof(__le32) * (DEF_ADDRS_PER_INODE - \
+                                               F2FS_INLINE_XATTR_ADDRS - 1))
+
+#define INLINE_DATA_OFFSET     (PAGE_CACHE_SIZE - sizeof(struct node_footer) \
+                               - sizeof(__le32)*(DEF_ADDRS_PER_INODE + 5 - 1))
 
 struct f2fs_inode {
        __le16 i_mode;                  /* file mode */
index 9abbe630c456775b19cc999f36887efa94bbdd41..8c9b7a1c4138b87a79833bc400370a13e94cf270 100644 (file)
@@ -248,6 +248,9 @@ struct ftrace_event_call {
 #ifdef CONFIG_PERF_EVENTS
        int                             perf_refcount;
        struct hlist_head __percpu      *perf_events;
+
+       int     (*perf_perm)(struct ftrace_event_call *,
+                            struct perf_event *);
 #endif
 };
 
@@ -317,6 +320,19 @@ struct ftrace_event_file {
        }                                                               \
        early_initcall(trace_init_flags_##name);
 
+#define __TRACE_EVENT_PERF_PERM(name, expr...)                         \
+       static int perf_perm_##name(struct ftrace_event_call *tp_event, \
+                                   struct perf_event *p_event)         \
+       {                                                               \
+               return ({ expr; });                                     \
+       }                                                               \
+       static int __init trace_init_perf_perm_##name(void)             \
+       {                                                               \
+               event_##name.perf_perm = &perf_perm_##name;             \
+               return 0;                                               \
+       }                                                               \
+       early_initcall(trace_init_perf_perm_##name);
+
 #define PERF_MAX_TRACE_SIZE    2048
 
 #define MAX_FILTER_STR_VAL     256     /* Should handle KSYM_SYMBOL_LEN */
index 656a27efb2c8cdd755cd78e20a36e5dd028e5310..82eac610ce1a77ba944ee99d4afe6c921690b3c5 100644 (file)
@@ -125,6 +125,13 @@ extern struct gpio_chip *gpiochip_find(void *data,
 int gpiod_lock_as_irq(struct gpio_desc *desc);
 void gpiod_unlock_as_irq(struct gpio_desc *desc);
 
+enum gpio_lookup_flags {
+       GPIO_ACTIVE_HIGH = (0 << 0),
+       GPIO_ACTIVE_LOW = (1 << 0),
+       GPIO_OPEN_DRAIN = (1 << 1),
+       GPIO_OPEN_SOURCE = (1 << 2),
+};
+
 /**
  * Lookup table for associating GPIOs to specific devices and functions using
  * platform data.
@@ -152,9 +159,9 @@ struct gpiod_lookup {
         */
        unsigned int idx;
        /*
-        * mask of GPIOF_* values
+        * mask of GPIO_* values
         */
-       unsigned long flags;
+       enum gpio_lookup_flags flags;
 };
 
 /*
index a265af294ea49a28c0384af71aa5ee1a249b3be8..206a2af6b62b176fbbb16e2cca923053edc5877a 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <linux/hid.h>
 #include <linux/hid-sensor-ids.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
 
 /**
  * struct hid_sensor_hub_attribute_info - Attribute info
@@ -184,6 +186,7 @@ struct hid_sensor_common {
        struct platform_device *pdev;
        unsigned usage_id;
        bool data_ready;
+       struct iio_trigger *trigger;
        struct hid_sensor_hub_attribute_info poll;
        struct hid_sensor_hub_attribute_info report_state;
        struct hid_sensor_hub_attribute_info power_state;
index 4f945d3ed49fc7a511affdc307ea84aff60565cb..4cc165887b091685d5ada87624156c2dc0b98626 100644 (file)
 
 /* Accel 3D (200073) */
 #define HID_USAGE_SENSOR_ACCEL_3D                              0x200073
+#define HID_USAGE_SENSOR_DATA_ACCELERATION                     0x200452
 #define HID_USAGE_SENSOR_ACCEL_X_AXIS                          0x200453
 #define HID_USAGE_SENSOR_ACCEL_Y_AXIS                          0x200454
 #define HID_USAGE_SENSOR_ACCEL_Z_AXIS                          0x200455
 
 /* ALS (200041) */
 #define HID_USAGE_SENSOR_ALS                                   0x200041
+#define HID_USAGE_SENSOR_DATA_LIGHT                            0x2004d0
 #define HID_USAGE_SENSOR_LIGHT_ILLUM                           0x2004d1
 
 /* Gyro 3D: (200076) */
 #define HID_USAGE_SENSOR_GYRO_3D                               0x200076
+#define HID_USAGE_SENSOR_DATA_ANGL_VELOCITY                    0x200456
 #define HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS                  0x200457
 #define HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS                  0x200458
 #define HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS                  0x200459
 
 /* ORIENTATION: Compass 3D: (200083) */
 #define HID_USAGE_SENSOR_COMPASS_3D                            0x200083
+#define HID_USAGE_SENSOR_DATA_ORIENTATION                      0x200470
 #define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING                   0x200471
 #define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING_X                 0x200472
 #define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING_Y                 0x200473
 #define HID_USAGE_SENSOR_PROP_REPORT_STATE                     0x200316
 #define HID_USAGE_SENSOR_PROY_POWER_STATE                      0x200319
 
+/* Per data field properties */
+#define HID_USAGE_SENSOR_DATA_MOD_NONE                                 0x00
+#define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS               0x1000
+
 #endif
index 506a9f7af51e6a5dc4766f62d19dda5279d06e7e..4f35b6ad3889fac069910379c48b149dea413358 100644 (file)
@@ -7,16 +7,14 @@ struct tsc2007_platform_data {
        u16     model;                          /* 2007. */
        u16     x_plate_ohms;   /* must be non-zero value */
        u16     max_rt; /* max. resistance above which samples are ignored */
-       unsigned long poll_delay; /* delay (in ms) after pen-down event
-                                    before polling starts */
        unsigned long poll_period; /* time (in ms) between samples */
        int     fuzzx; /* fuzz factor for X, Y and pressure axes */
        int     fuzzy;
        int     fuzzz;
 
-       int     (*get_pendown_state)(void);
-       void    (*clear_penirq)(void);          /* If needed, clear 2nd level
-                                                  interrupt source */
+       int     (*get_pendown_state)(struct device *);
+       /* If needed, clear 2nd level interrupt source */
+       void    (*clear_penirq)(void);
        int     (*init_platform_hw)(void);
        void    (*exit_platform_hw)(void);
 };
index 46a14229a162cf2bc5cc5e5b096c10c120766d8d..93b5ca754b5b4c4931aa2b3f66cf246312cedbd8 100644 (file)
 #include <linux/completion.h>
 #include <linux/pm.h>
 #include <linux/mutex.h>
-#ifdef CONFIG_BLK_DEV_IDEACPI
-#include <acpi/acpi.h>
-#endif
-#include <asm/byteorder.h>
-#include <asm/io.h>
-
 /* for request_sense */
 #include <linux/cdrom.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
 
 #if defined(CONFIG_CRIS) || defined(CONFIG_FRV) || defined(CONFIG_MN10300)
 # define SUPPORT_VLB_SYNC 0
index 256a90a1bea681fde6473e2d5d74bc93ea868a87..5b125fd554e42dcf70fb27defd8dbfa752ab82b5 100644 (file)
@@ -490,32 +490,12 @@ struct iio_dev {
 #endif
 };
 
-/**
- * iio_find_channel_from_si() - get channel from its scan index
- * @indio_dev:         device
- * @si:                        scan index to match
- */
 const struct iio_chan_spec
 *iio_find_channel_from_si(struct iio_dev *indio_dev, int si);
-
-/**
- * iio_device_register() - register a device with the IIO subsystem
- * @indio_dev:         Device structure filled by the device driver
- **/
 int iio_device_register(struct iio_dev *indio_dev);
-
-/**
- * iio_device_unregister() - unregister a device from the IIO subsystem
- * @indio_dev:         Device structure representing the device.
- **/
 void iio_device_unregister(struct iio_dev *indio_dev);
-
-/**
- * iio_push_event() - try to add event to the list for userspace reading
- * @indio_dev:         IIO device structure
- * @ev_code:           What event
- * @timestamp:         When the event occurred
- **/
+int devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev);
+void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev);
 int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp);
 
 extern struct bus_type iio_bus_type;
@@ -579,10 +559,6 @@ static inline void *iio_device_get_drvdata(struct iio_dev *indio_dev)
 
 /* Can we make this smaller? */
 #define IIO_ALIGN L1_CACHE_BYTES
-/**
- * iio_device_alloc() - allocate an iio_dev from a driver
- * @sizeof_priv:       Space to allocate for private structure.
- **/
 struct iio_dev *iio_device_alloc(int sizeof_priv);
 
 static inline void *iio_priv(const struct iio_dev *indio_dev)
@@ -596,64 +572,11 @@ static inline struct iio_dev *iio_priv_to_dev(void *priv)
                                  ALIGN(sizeof(struct iio_dev), IIO_ALIGN));
 }
 
-/**
- * iio_device_free() - free an iio_dev from a driver
- * @indio_dev:                 the iio_dev associated with the device
- **/
 void iio_device_free(struct iio_dev *indio_dev);
-
-/**
- * devm_iio_device_alloc - Resource-managed iio_device_alloc()
- * @dev:               Device to allocate iio_dev for
- * @sizeof_priv:       Space to allocate for private structure.
- *
- * Managed iio_device_alloc.  iio_dev allocated with this function is
- * automatically freed on driver detach.
- *
- * If an iio_dev allocated with this function needs to be freed separately,
- * devm_iio_device_free() must be used.
- *
- * RETURNS:
- * Pointer to allocated iio_dev on success, NULL on failure.
- */
 struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv);
-
-/**
- * devm_iio_device_free - Resource-managed iio_device_free()
- * @dev:               Device this iio_dev belongs to
- * @indio_dev:                 the iio_dev associated with the device
- *
- * Free iio_dev allocated with devm_iio_device_alloc().
- */
 void devm_iio_device_free(struct device *dev, struct iio_dev *indio_dev);
-
-/**
- * devm_iio_trigger_alloc - Resource-managed iio_trigger_alloc()
- * @dev:               Device to allocate iio_trigger for
- * @fmt:               trigger name format. If it includes format
- *                     specifiers, the additional arguments following
- *                     format are formatted and inserted in the resulting
- *                     string replacing their respective specifiers.
- *
- * Managed iio_trigger_alloc.  iio_trigger allocated with this function is
- * automatically freed on driver detach.
- *
- * If an iio_trigger allocated with this function needs to be freed separately,
- * devm_iio_trigger_free() must be used.
- *
- * RETURNS:
- * Pointer to allocated iio_trigger on success, NULL on failure.
- */
 struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
                                                const char *fmt, ...);
-
-/**
- * devm_iio_trigger_free - Resource-managed iio_trigger_free()
- * @dev:               Device this iio_dev belongs to
- * @iio_trig:          the iio_trigger associated with the device
- *
- * Free iio_trigger allocated with devm_iio_trigger_alloc().
- */
 void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig);
 
 /**
diff --git a/include/linux/irqchip/xtensa-mx.h b/include/linux/irqchip/xtensa-mx.h
new file mode 100644 (file)
index 0000000..9c3b6ec
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Xtensa MX interrupt distributor
+ *
+ * Copyright (C) 2002 - 2013 Tensilica, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __LINUX_IRQCHIP_XTENSA_MX_H
+#define __LINUX_IRQCHIP_XTENSA_MX_H
+
+struct device_node;
+int xtensa_mx_init_legacy(struct device_node *interrupt_parent);
+
+#endif /* __LINUX_IRQCHIP_XTENSA_MX_H */
diff --git a/include/linux/irqchip/xtensa-pic.h b/include/linux/irqchip/xtensa-pic.h
new file mode 100644 (file)
index 0000000..48718ae
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Xtensa built-in interrupt controller
+ *
+ * Copyright (C) 2002 - 2013 Tensilica, Inc.
+ * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __LINUX_IRQCHIP_XTENSA_PIC_H
+#define __LINUX_IRQCHIP_XTENSA_PIC_H
+
+struct device_node;
+int xtensa_pic_init_legacy(struct device_node *interrupt_parent);
+
+#endif /* __LINUX_IRQCHIP_XTENSA_PIC_H */
index 714ba08dc09265922fe8ab81dee1caadc12a9100..e374e369fb2f4c9eb5ace48679376550d5ee633c 100644 (file)
@@ -14,6 +14,6 @@ enum irqreturn {
 };
 
 typedef enum irqreturn irqreturn_t;
-#define IRQ_RETVAL(x)  ((x) != IRQ_NONE)
+#define IRQ_RETVAL(x)  ((x) ? IRQ_HANDLED : IRQ_NONE)
 
 #endif
index 8ba7e5b9d62cb466f60cced5c8340261acf9fc4f..605cc5c333d968f7ff2074cd9ab6d21d6b9bbc7e 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef ISCSI_IBFT_H
 #define ISCSI_IBFT_H
 
-#include <acpi/acpi.h>
+#include <linux/acpi.h>
 
 /*
  * Logical location of iSCSI Boot Format Table.
index d4e98d13eff4bda01b08313986b63135cc80ee2b..2ac02772a86e3c1db0be81c7fb68d331aba02977 100644 (file)
@@ -393,6 +393,15 @@ extern int panic_on_oops;
 extern int panic_on_unrecovered_nmi;
 extern int panic_on_io_nmi;
 extern int sysctl_panic_on_stackoverflow;
+/*
+ * Only to be used by arch init code. If the user over-wrote the default
+ * CONFIG_PANIC_TIMEOUT, honor it.
+ */
+static inline void set_arch_panic_timeout(int timeout, int arch_default_timeout)
+{
+       if (panic_timeout == arch_default_timeout)
+               panic_timeout = timeout;
+}
 extern const char *print_tainted(void);
 enum lockdep_ok {
        LOCKDEP_STILL_OK,
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
new file mode 100644 (file)
index 0000000..d655413
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * kernfs.h - pseudo filesystem decoupled from vfs locking
+ *
+ * This file is released under the GPLv2.
+ */
+
+#ifndef __LINUX_KERNFS_H
+#define __LINUX_KERNFS_H
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/idr.h>
+#include <linux/lockdep.h>
+#include <linux/rbtree.h>
+#include <linux/atomic.h>
+#include <linux/completion.h>
+
+struct file;
+struct iattr;
+struct seq_file;
+struct vm_area_struct;
+struct super_block;
+struct file_system_type;
+
+struct sysfs_open_dirent;
+struct sysfs_inode_attrs;
+
+enum kernfs_node_type {
+       SYSFS_DIR               = 0x0001,
+       SYSFS_KOBJ_ATTR         = 0x0002,
+       SYSFS_KOBJ_LINK         = 0x0004,
+};
+
+#define SYSFS_TYPE_MASK                0x000f
+#define SYSFS_COPY_NAME                (SYSFS_DIR | SYSFS_KOBJ_LINK)
+#define SYSFS_ACTIVE_REF       SYSFS_KOBJ_ATTR
+#define SYSFS_FLAG_MASK                ~SYSFS_TYPE_MASK
+
+enum kernfs_node_flag {
+       SYSFS_FLAG_REMOVED      = 0x0010,
+       SYSFS_FLAG_NS           = 0x0020,
+       SYSFS_FLAG_HAS_SEQ_SHOW = 0x0040,
+       SYSFS_FLAG_HAS_MMAP     = 0x0080,
+       SYSFS_FLAG_LOCKDEP      = 0x0100,
+};
+
+/* type-specific structures for sysfs_dirent->s_* union members */
+struct sysfs_elem_dir {
+       unsigned long           subdirs;
+       /* children rbtree starts here and goes through sd->s_rb */
+       struct rb_root          children;
+
+       /*
+        * The kernfs hierarchy this directory belongs to.  This fits
+        * better directly in sysfs_dirent but is here to save space.
+        */
+       struct kernfs_root      *root;
+};
+
+struct sysfs_elem_symlink {
+       struct sysfs_dirent     *target_sd;
+};
+
+struct sysfs_elem_attr {
+       const struct kernfs_ops *ops;
+       struct sysfs_open_dirent *open;
+       loff_t                  size;
+};
+
+/*
+ * sysfs_dirent - the building block of sysfs hierarchy.  Each and every
+ * sysfs node is represented by single sysfs_dirent.  Most fields are
+ * private to kernfs and shouldn't be accessed directly by kernfs users.
+ *
+ * As long as s_count reference is held, the sysfs_dirent itself is
+ * accessible.  Dereferencing s_elem or any other outer entity
+ * requires s_active reference.
+ */
+struct sysfs_dirent {
+       atomic_t                s_count;
+       atomic_t                s_active;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       struct lockdep_map      dep_map;
+#endif
+       /* the following two fields are published */
+       struct sysfs_dirent     *s_parent;
+       const char              *s_name;
+
+       struct rb_node          s_rb;
+
+       union {
+               struct completion       *completion;
+               struct sysfs_dirent     *removed_list;
+       } u;
+
+       const void              *s_ns; /* namespace tag */
+       unsigned int            s_hash; /* ns + name hash */
+       union {
+               struct sysfs_elem_dir           s_dir;
+               struct sysfs_elem_symlink       s_symlink;
+               struct sysfs_elem_attr          s_attr;
+       };
+
+       void                    *priv;
+
+       unsigned short          s_flags;
+       umode_t                 s_mode;
+       unsigned int            s_ino;
+       struct sysfs_inode_attrs *s_iattr;
+};
+
+struct kernfs_root {
+       /* published fields */
+       struct sysfs_dirent     *sd;
+
+       /* private fields, do not use outside kernfs proper */
+       struct ida              ino_ida;
+};
+
+struct sysfs_open_file {
+       /* published fields */
+       struct sysfs_dirent     *sd;
+       struct file             *file;
+
+       /* private fields, do not use outside kernfs proper */
+       struct mutex            mutex;
+       int                     event;
+       struct list_head        list;
+
+       bool                    mmapped;
+       const struct vm_operations_struct *vm_ops;
+};
+
+struct kernfs_ops {
+       /*
+        * Read is handled by either seq_file or raw_read().
+        *
+        * If seq_show() is present, seq_file path is active.  Other seq
+        * operations are optional and if not implemented, the behavior is
+        * equivalent to single_open().  @sf->private points to the
+        * associated sysfs_open_file.
+        *
+        * read() is bounced through kernel buffer and a read larger than
+        * PAGE_SIZE results in partial operation of PAGE_SIZE.
+        */
+       int (*seq_show)(struct seq_file *sf, void *v);
+
+       void *(*seq_start)(struct seq_file *sf, loff_t *ppos);
+       void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos);
+       void (*seq_stop)(struct seq_file *sf, void *v);
+
+       ssize_t (*read)(struct sysfs_open_file *of, char *buf, size_t bytes,
+                       loff_t off);
+
+       /*
+        * write() is bounced through kernel buffer and a write larger than
+        * PAGE_SIZE results in partial operation of PAGE_SIZE.
+        */
+       ssize_t (*write)(struct sysfs_open_file *of, char *buf, size_t bytes,
+                        loff_t off);
+
+       int (*mmap)(struct sysfs_open_file *of, struct vm_area_struct *vma);
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       struct lock_class_key   lockdep_key;
+#endif
+};
+
+#ifdef CONFIG_SYSFS
+
+static inline enum kernfs_node_type sysfs_type(struct sysfs_dirent *sd)
+{
+       return sd->s_flags & SYSFS_TYPE_MASK;
+}
+
+/**
+ * kernfs_enable_ns - enable namespace under a directory
+ * @sd: directory of interest, should be empty
+ *
+ * This is to be called right after @sd is created to enable namespace
+ * under it.  All children of @sd must have non-NULL namespace tags and
+ * only the ones which match the super_block's tag will be visible.
+ */
+static inline void kernfs_enable_ns(struct sysfs_dirent *sd)
+{
+       WARN_ON_ONCE(sysfs_type(sd) != SYSFS_DIR);
+       WARN_ON_ONCE(!RB_EMPTY_ROOT(&sd->s_dir.children));
+       sd->s_flags |= SYSFS_FLAG_NS;
+}
+
+/**
+ * kernfs_ns_enabled - test whether namespace is enabled
+ * @sd: the node to test
+ *
+ * Test whether namespace filtering is enabled for the children of @ns.
+ */
+static inline bool kernfs_ns_enabled(struct sysfs_dirent *sd)
+{
+       return sd->s_flags & SYSFS_FLAG_NS;
+}
+
+struct sysfs_dirent *kernfs_find_and_get_ns(struct sysfs_dirent *parent,
+                                           const char *name, const void *ns);
+void kernfs_get(struct sysfs_dirent *sd);
+void kernfs_put(struct sysfs_dirent *sd);
+
+struct kernfs_root *kernfs_create_root(void *priv);
+void kernfs_destroy_root(struct kernfs_root *root);
+
+struct sysfs_dirent *kernfs_create_dir_ns(struct sysfs_dirent *parent,
+                                         const char *name, void *priv,
+                                         const void *ns);
+struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent,
+                                              const char *name,
+                                              umode_t mode, loff_t size,
+                                              const struct kernfs_ops *ops,
+                                              void *priv, const void *ns,
+                                              struct lock_class_key *key);
+struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent,
+                                       const char *name,
+                                       struct sysfs_dirent *target);
+void kernfs_remove(struct sysfs_dirent *sd);
+int kernfs_remove_by_name_ns(struct sysfs_dirent *parent, const char *name,
+                            const void *ns);
+int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent,
+                    const char *new_name, const void *new_ns);
+int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr);
+void kernfs_notify(struct sysfs_dirent *sd);
+
+const void *kernfs_super_ns(struct super_block *sb);
+struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags,
+                              struct kernfs_root *root, const void *ns);
+void kernfs_kill_sb(struct super_block *sb);
+
+void kernfs_init(void);
+
+#else  /* CONFIG_SYSFS */
+
+static inline enum kernfs_node_type sysfs_type(struct sysfs_dirent *sd)
+{ return 0; }  /* whatever */
+
+static inline void kernfs_enable_ns(struct sysfs_dirent *sd) { }
+
+static inline bool kernfs_ns_enabled(struct sysfs_dirent *sd)
+{ return false; }
+
+static inline struct sysfs_dirent *
+kernfs_find_and_get_ns(struct sysfs_dirent *parent, const char *name,
+                      const void *ns)
+{ return NULL; }
+
+static inline void kernfs_get(struct sysfs_dirent *sd) { }
+static inline void kernfs_put(struct sysfs_dirent *sd) { }
+
+static inline struct kernfs_root *kernfs_create_root(void *priv)
+{ return ERR_PTR(-ENOSYS); }
+
+static inline void kernfs_destroy_root(struct kernfs_root *root) { }
+
+static inline struct sysfs_dirent *
+kernfs_create_dir_ns(struct sysfs_dirent *parent, const char *name, void *priv,
+                    const void *ns)
+{ return ERR_PTR(-ENOSYS); }
+
+static inline struct sysfs_dirent *
+kernfs_create_file_ns_key(struct sysfs_dirent *parent, const char *name,
+                         umode_t mode, loff_t size,
+                         const struct kernfs_ops *ops, void *priv,
+                         const void *ns, struct lock_class_key *key)
+{ return ERR_PTR(-ENOSYS); }
+
+static inline struct sysfs_dirent *
+kernfs_create_link(struct sysfs_dirent *parent, const char *name,
+                  struct sysfs_dirent *target)
+{ return ERR_PTR(-ENOSYS); }
+
+static inline void kernfs_remove(struct sysfs_dirent *sd) { }
+
+static inline int kernfs_remove_by_name_ns(struct sysfs_dirent *parent,
+                                          const char *name, const void *ns)
+{ return -ENOSYS; }
+
+static inline int kernfs_rename_ns(struct sysfs_dirent *sd,
+                                  struct sysfs_dirent *new_parent,
+                                  const char *new_name, const void *new_ns)
+{ return -ENOSYS; }
+
+static inline int kernfs_setattr(struct sysfs_dirent *sd,
+                                const struct iattr *iattr)
+{ return -ENOSYS; }
+
+static inline void kernfs_notify(struct sysfs_dirent *sd) { }
+
+static inline const void *kernfs_super_ns(struct super_block *sb)
+{ return NULL; }
+
+static inline struct dentry *
+kernfs_mount_ns(struct file_system_type *fs_type, int flags,
+               struct kernfs_root *root, const void *ns)
+{ return ERR_PTR(-ENOSYS); }
+
+static inline void kernfs_kill_sb(struct super_block *sb) { }
+
+static inline void kernfs_init(void) { }
+
+#endif /* CONFIG_SYSFS */
+
+static inline struct sysfs_dirent *
+kernfs_find_and_get(struct sysfs_dirent *sd, const char *name)
+{
+       return kernfs_find_and_get_ns(sd, name, NULL);
+}
+
+static inline struct sysfs_dirent *
+kernfs_create_dir(struct sysfs_dirent *parent, const char *name, void *priv)
+{
+       return kernfs_create_dir_ns(parent, name, priv, NULL);
+}
+
+static inline struct sysfs_dirent *
+kernfs_create_file_ns(struct sysfs_dirent *parent, const char *name,
+                     umode_t mode, loff_t size, const struct kernfs_ops *ops,
+                     void *priv, const void *ns)
+{
+       struct lock_class_key *key = NULL;
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       key = (struct lock_class_key *)&ops->lockdep_key;
+#endif
+       return kernfs_create_file_ns_key(parent, name, mode, size, ops, priv,
+                                        ns, key);
+}
+
+static inline struct sysfs_dirent *
+kernfs_create_file(struct sysfs_dirent *parent, const char *name, umode_t mode,
+                  loff_t size, const struct kernfs_ops *ops, void *priv)
+{
+       return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL);
+}
+
+static inline int kernfs_remove_by_name(struct sysfs_dirent *parent,
+                                       const char *name)
+{
+       return kernfs_remove_by_name_ns(parent, name, NULL);
+}
+
+static inline struct dentry *
+kernfs_mount(struct file_system_type *fs_type, int flags,
+            struct kernfs_root *root)
+{
+       return kernfs_mount_ns(fs_type, flags, root, NULL);
+}
+
+#endif /* __LINUX_KERNFS_H */
index cb49417f8ba9261ba436fef11851274f9df977d0..89878149a43f60d78de29c23de76ca47f8b5a006 100644 (file)
 #define ARIZONA_INPUT_ENABLES_STATUS             0x301
 #define ARIZONA_INPUT_RATE                       0x308
 #define ARIZONA_INPUT_VOLUME_RAMP                0x309
+#define ARIZONA_HPF_CONTROL                      0x30C
 #define ARIZONA_IN1L_CONTROL                     0x310
 #define ARIZONA_ADC_DIGITAL_VOLUME_1L            0x311
 #define ARIZONA_DMIC1L_CONTROL                   0x312
 #define ARIZONA_IN4L_CONTROL                     0x328
 #define ARIZONA_ADC_DIGITAL_VOLUME_4L            0x329
 #define ARIZONA_DMIC4L_CONTROL                   0x32A
+#define ARIZONA_IN4R_CONTROL                     0x32C
 #define ARIZONA_ADC_DIGITAL_VOLUME_4R            0x32D
 #define ARIZONA_DMIC4R_CONTROL                   0x32E
 #define ARIZONA_OUTPUT_ENABLES_1                 0x400
 #define ARIZONA_AIF2TX2MIX_INPUT_3_VOLUME        0x74D
 #define ARIZONA_AIF2TX2MIX_INPUT_4_SOURCE        0x74E
 #define ARIZONA_AIF2TX2MIX_INPUT_4_VOLUME        0x74F
+#define ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE        0x750
+#define ARIZONA_AIF2TX3MIX_INPUT_1_VOLUME        0x751
+#define ARIZONA_AIF2TX3MIX_INPUT_2_SOURCE        0x752
+#define ARIZONA_AIF2TX3MIX_INPUT_2_VOLUME        0x753
+#define ARIZONA_AIF2TX3MIX_INPUT_3_SOURCE        0x754
+#define ARIZONA_AIF2TX3MIX_INPUT_3_VOLUME        0x755
+#define ARIZONA_AIF2TX3MIX_INPUT_4_SOURCE        0x756
+#define ARIZONA_AIF2TX3MIX_INPUT_4_VOLUME        0x757
+#define ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE        0x758
+#define ARIZONA_AIF2TX4MIX_INPUT_1_VOLUME        0x759
+#define ARIZONA_AIF2TX4MIX_INPUT_2_SOURCE        0x75A
+#define ARIZONA_AIF2TX4MIX_INPUT_2_VOLUME        0x75B
+#define ARIZONA_AIF2TX4MIX_INPUT_3_SOURCE        0x75C
+#define ARIZONA_AIF2TX4MIX_INPUT_3_VOLUME        0x75D
+#define ARIZONA_AIF2TX4MIX_INPUT_4_SOURCE        0x75E
+#define ARIZONA_AIF2TX4MIX_INPUT_4_VOLUME        0x75F
+#define ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE        0x760
+#define ARIZONA_AIF2TX5MIX_INPUT_1_VOLUME        0x761
+#define ARIZONA_AIF2TX5MIX_INPUT_2_SOURCE        0x762
+#define ARIZONA_AIF2TX5MIX_INPUT_2_VOLUME        0x763
+#define ARIZONA_AIF2TX5MIX_INPUT_3_SOURCE        0x764
+#define ARIZONA_AIF2TX5MIX_INPUT_3_VOLUME        0x765
+#define ARIZONA_AIF2TX5MIX_INPUT_4_SOURCE        0x766
+#define ARIZONA_AIF2TX5MIX_INPUT_4_VOLUME        0x767
+#define ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE        0x768
+#define ARIZONA_AIF2TX6MIX_INPUT_1_VOLUME        0x769
+#define ARIZONA_AIF2TX6MIX_INPUT_2_SOURCE        0x76A
+#define ARIZONA_AIF2TX6MIX_INPUT_2_VOLUME        0x76B
+#define ARIZONA_AIF2TX6MIX_INPUT_3_SOURCE        0x76C
+#define ARIZONA_AIF2TX6MIX_INPUT_3_VOLUME        0x76D
+#define ARIZONA_AIF2TX6MIX_INPUT_4_SOURCE        0x76E
+#define ARIZONA_AIF2TX6MIX_INPUT_4_VOLUME        0x76F
 #define ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE        0x780
 #define ARIZONA_AIF3TX1MIX_INPUT_1_VOLUME        0x781
 #define ARIZONA_AIF3TX1MIX_INPUT_2_SOURCE        0x782
 #define ARIZONA_IN_VI_RAMP_SHIFT                      0  /* IN_VI_RAMP - [2:0] */
 #define ARIZONA_IN_VI_RAMP_WIDTH                      3  /* IN_VI_RAMP - [2:0] */
 
+/*
+ * R780 (0x30C) - HPF Control
+ */
+#define ARIZONA_IN_HPF_CUT_MASK                  0x0007  /* IN_HPF_CUT [2:0] */
+#define ARIZONA_IN_HPF_CUT_SHIFT                      0  /* IN_HPF_CUT [2:0] */
+#define ARIZONA_IN_HPF_CUT_WIDTH                      3  /* IN_HPF_CUT [2:0] */
+
 /*
  * R784 (0x310) - IN1L Control
  */
+#define ARIZONA_IN1L_HPF_MASK                    0x8000  /* IN1L_HPF - [15] */
+#define ARIZONA_IN1L_HPF_SHIFT                       15  /* IN1L_HPF - [15] */
+#define ARIZONA_IN1L_HPF_WIDTH                        1  /* IN1L_HPF - [15] */
 #define ARIZONA_IN1_OSR_MASK                     0x6000  /* IN1_OSR - [14:13] */
 #define ARIZONA_IN1_OSR_SHIFT                        13  /* IN1_OSR - [14:13] */
 #define ARIZONA_IN1_OSR_WIDTH                         2  /* IN1_OSR - [14:13] */
 /*
  * R788 (0x314) - IN1R Control
  */
+#define ARIZONA_IN1R_HPF_MASK                    0x8000  /* IN1R_HPF - [15] */
+#define ARIZONA_IN1R_HPF_SHIFT                       15  /* IN1R_HPF - [15] */
+#define ARIZONA_IN1R_HPF_WIDTH                        1  /* IN1R_HPF - [15] */
 #define ARIZONA_IN1R_PGA_VOL_MASK                0x00FE  /* IN1R_PGA_VOL - [7:1] */
 #define ARIZONA_IN1R_PGA_VOL_SHIFT                    1  /* IN1R_PGA_VOL - [7:1] */
 #define ARIZONA_IN1R_PGA_VOL_WIDTH                    7  /* IN1R_PGA_VOL - [7:1] */
 /*
  * R792 (0x318) - IN2L Control
  */
+#define ARIZONA_IN2L_HPF_MASK                    0x8000  /* IN2L_HPF - [15] */
+#define ARIZONA_IN2L_HPF_SHIFT                       15  /* IN2L_HPF - [15] */
+#define ARIZONA_IN2L_HPF_WIDTH                        1  /* IN2L_HPF - [15] */
 #define ARIZONA_IN2_OSR_MASK                     0x6000  /* IN2_OSR - [14:13] */
 #define ARIZONA_IN2_OSR_SHIFT                        13  /* IN2_OSR - [14:13] */
 #define ARIZONA_IN2_OSR_WIDTH                         2  /* IN2_OSR - [14:13] */
 /*
  * R796 (0x31C) - IN2R Control
  */
+#define ARIZONA_IN2R_HPF_MASK                    0x8000  /* IN2R_HPF - [15] */
+#define ARIZONA_IN2R_HPF_SHIFT                       15  /* IN2R_HPF - [15] */
+#define ARIZONA_IN2R_HPF_WIDTH                        1  /* IN2R_HPF - [15] */
 #define ARIZONA_IN2R_PGA_VOL_MASK                0x00FE  /* IN2R_PGA_VOL - [7:1] */
 #define ARIZONA_IN2R_PGA_VOL_SHIFT                    1  /* IN2R_PGA_VOL - [7:1] */
 #define ARIZONA_IN2R_PGA_VOL_WIDTH                    7  /* IN2R_PGA_VOL - [7:1] */
 /*
  * R800 (0x320) - IN3L Control
  */
+#define ARIZONA_IN3L_HPF_MASK                    0x8000  /* IN3L_HPF - [15] */
+#define ARIZONA_IN3L_HPF_SHIFT                       15  /* IN3L_HPF - [15] */
+#define ARIZONA_IN3L_HPF_WIDTH                        1  /* IN3L_HPF - [15] */
 #define ARIZONA_IN3_OSR_MASK                     0x6000  /* IN3_OSR - [14:13] */
 #define ARIZONA_IN3_OSR_SHIFT                        13  /* IN3_OSR - [14:13] */
 #define ARIZONA_IN3_OSR_WIDTH                         2  /* IN3_OSR - [14:13] */
 /*
  * R804 (0x324) - IN3R Control
  */
+#define ARIZONA_IN3R_HPF_MASK                    0x8000  /* IN3R_HPF - [15] */
+#define ARIZONA_IN3R_HPF_SHIFT                       15  /* IN3R_HPF - [15] */
+#define ARIZONA_IN3R_HPF_WIDTH                        1  /* IN3R_HPF - [15] */
 #define ARIZONA_IN3R_PGA_VOL_MASK                0x00FE  /* IN3R_PGA_VOL - [7:1] */
 #define ARIZONA_IN3R_PGA_VOL_SHIFT                    1  /* IN3R_PGA_VOL - [7:1] */
 #define ARIZONA_IN3R_PGA_VOL_WIDTH                    7  /* IN3R_PGA_VOL - [7:1] */
 /*
  * R808 (0x328) - IN4 Control
  */
+#define ARIZONA_IN4L_HPF_MASK                    0x8000  /* IN4L_HPF - [15] */
+#define ARIZONA_IN4L_HPF_SHIFT                       15  /* IN4L_HPF - [15] */
+#define ARIZONA_IN4L_HPF_WIDTH                        1  /* IN4L_HPF - [15] */
 #define ARIZONA_IN4_OSR_MASK                     0x6000  /* IN4_OSR - [14:13] */
 #define ARIZONA_IN4_OSR_SHIFT                        13  /* IN4_OSR - [14:13] */
 #define ARIZONA_IN4_OSR_WIDTH                         2  /* IN4_OSR - [14:13] */
 #define ARIZONA_IN4L_DMIC_DLY_SHIFT                   0  /* IN4L_DMIC_DLY - [5:0] */
 #define ARIZONA_IN4L_DMIC_DLY_WIDTH                   6  /* IN4L_DMIC_DLY - [5:0] */
 
+/*
+ * R812 (0x32C) - IN4R Control
+ */
+#define ARIZONA_IN4R_HPF_MASK                    0x8000  /* IN4R_HPF - [15] */
+#define ARIZONA_IN4R_HPF_SHIFT                       15  /* IN4R_HPF - [15] */
+#define ARIZONA_IN4R_HPF_WIDTH                        1  /* IN4R_HPF - [15] */
+
 /*
  * R813 (0x32D) - ADC Digital Volume 4R
  */
 #define ARIZONA_AIF2TX2_SLOT_SHIFT                    0  /* AIF2TX2_SLOT - [5:0] */
 #define ARIZONA_AIF2TX2_SLOT_WIDTH                    6  /* AIF2TX2_SLOT - [5:0] */
 
+/*
+ * R1355 (0x54B) - AIF2 Frame Ctrl 5
+ */
+#define ARIZONA_AIF2TX3_SLOT_MASK                0x003F  /* AIF2TX3_SLOT - [5:0] */
+#define ARIZONA_AIF2TX3_SLOT_SHIFT                    0  /* AIF2TX3_SLOT - [5:0] */
+#define ARIZONA_AIF2TX3_SLOT_WIDTH                    6  /* AIF2TX3_SLOT - [5:0] */
+
+/*
+ * R1356 (0x54C) - AIF2 Frame Ctrl 6
+ */
+#define ARIZONA_AIF2TX4_SLOT_MASK                0x003F  /* AIF2TX4_SLOT - [5:0] */
+#define ARIZONA_AIF2TX4_SLOT_SHIFT                    0  /* AIF2TX4_SLOT - [5:0] */
+#define ARIZONA_AIF2TX4_SLOT_WIDTH                    6  /* AIF2TX4_SLOT - [5:0] */
+
+
+/*
+ * R1357 (0x54D) - AIF2 Frame Ctrl 7
+ */
+#define ARIZONA_AIF2TX5_SLOT_MASK                0x003F  /* AIF2TX5_SLOT - [5:0] */
+#define ARIZONA_AIF2TX5_SLOT_SHIFT                    0  /* AIF2TX5_SLOT - [5:0] */
+#define ARIZONA_AIF2TX5_SLOT_WIDTH                    6  /* AIF2TX5_SLOT - [5:0] */
+
+/*
+ * R1358 (0x54E) - AIF2 Frame Ctrl 8
+ */
+#define ARIZONA_AIF2TX6_SLOT_MASK                0x003F  /* AIF2TX6_SLOT - [5:0] */
+#define ARIZONA_AIF2TX6_SLOT_SHIFT                    0  /* AIF2TX6_SLOT - [5:0] */
+#define ARIZONA_AIF2TX6_SLOT_WIDTH                    6  /* AIF2TX6_SLOT - [5:0] */
+
 /*
  * R1361 (0x551) - AIF2 Frame Ctrl 11
  */
 #define ARIZONA_AIF2RX2_SLOT_SHIFT                    0  /* AIF2RX2_SLOT - [5:0] */
 #define ARIZONA_AIF2RX2_SLOT_WIDTH                    6  /* AIF2RX2_SLOT - [5:0] */
 
+/*
+ * R1363 (0x553) - AIF2 Frame Ctrl 13
+ */
+#define ARIZONA_AIF2RX3_SLOT_MASK                0x003F  /* AIF2RX3_SLOT - [5:0] */
+#define ARIZONA_AIF2RX3_SLOT_SHIFT                    0  /* AIF2RX3_SLOT - [5:0] */
+#define ARIZONA_AIF2RX3_SLOT_WIDTH                    6  /* AIF2RX3_SLOT - [5:0] */
+
+/*
+ * R1364 (0x554) - AIF2 Frame Ctrl 14
+ */
+#define ARIZONA_AIF2RX4_SLOT_MASK                0x003F  /* AIF2RX4_SLOT - [5:0] */
+#define ARIZONA_AIF2RX4_SLOT_SHIFT                    0  /* AIF2RX4_SLOT - [5:0] */
+#define ARIZONA_AIF2RX4_SLOT_WIDTH                    6  /* AIF2RX4_SLOT - [5:0] */
+
+/*
+ * R1365 (0x555) - AIF2 Frame Ctrl 15
+ */
+#define ARIZONA_AIF2RX5_SLOT_MASK                0x003F  /* AIF2RX5_SLOT - [5:0] */
+#define ARIZONA_AIF2RX5_SLOT_SHIFT                    0  /* AIF2RX5_SLOT - [5:0] */
+#define ARIZONA_AIF2RX5_SLOT_WIDTH                    6  /* AIF2RX5_SLOT - [5:0] */
+
+/*
+ * R1366 (0x556) - AIF2 Frame Ctrl 16
+ */
+#define ARIZONA_AIF2RX6_SLOT_MASK                0x003F  /* AIF2RX6_SLOT - [5:0] */
+#define ARIZONA_AIF2RX6_SLOT_SHIFT                    0  /* AIF2RX6_SLOT - [5:0] */
+#define ARIZONA_AIF2RX6_SLOT_WIDTH                    6  /* AIF2RX6_SLOT - [5:0] */
+
 /*
  * R1369 (0x559) - AIF2 Tx Enables
  */
+#define ARIZONA_AIF2TX6_ENA                      0x0020  /* AIF2TX6_ENA */
+#define ARIZONA_AIF2TX6_ENA_MASK                 0x0020  /* AIF2TX6_ENA */
+#define ARIZONA_AIF2TX6_ENA_SHIFT                     5  /* AIF2TX6_ENA */
+#define ARIZONA_AIF2TX6_ENA_WIDTH                     1  /* AIF2TX6_ENA */
+#define ARIZONA_AIF2TX5_ENA                      0x0010  /* AIF2TX5_ENA */
+#define ARIZONA_AIF2TX5_ENA_MASK                 0x0010  /* AIF2TX5_ENA */
+#define ARIZONA_AIF2TX5_ENA_SHIFT                     4  /* AIF2TX5_ENA */
+#define ARIZONA_AIF2TX5_ENA_WIDTH                     1  /* AIF2TX5_ENA */
+#define ARIZONA_AIF2TX4_ENA                      0x0008  /* AIF2TX4_ENA */
+#define ARIZONA_AIF2TX4_ENA_MASK                 0x0008  /* AIF2TX4_ENA */
+#define ARIZONA_AIF2TX4_ENA_SHIFT                     3  /* AIF2TX4_ENA */
+#define ARIZONA_AIF2TX4_ENA_WIDTH                     1  /* AIF2TX4_ENA */
+#define ARIZONA_AIF2TX3_ENA                      0x0004  /* AIF2TX3_ENA */
+#define ARIZONA_AIF2TX3_ENA_MASK                 0x0004  /* AIF2TX3_ENA */
+#define ARIZONA_AIF2TX3_ENA_SHIFT                     2  /* AIF2TX3_ENA */
+#define ARIZONA_AIF2TX3_ENA_WIDTH                     1  /* AIF2TX3_ENA */
 #define ARIZONA_AIF2TX2_ENA                      0x0002  /* AIF2TX2_ENA */
 #define ARIZONA_AIF2TX2_ENA_MASK                 0x0002  /* AIF2TX2_ENA */
 #define ARIZONA_AIF2TX2_ENA_SHIFT                     1  /* AIF2TX2_ENA */
 /*
  * R1370 (0x55A) - AIF2 Rx Enables
  */
+#define ARIZONA_AIF2RX6_ENA                      0x0020  /* AIF2RX6_ENA */
+#define ARIZONA_AIF2RX6_ENA_MASK                 0x0020  /* AIF2RX6_ENA */
+#define ARIZONA_AIF2RX6_ENA_SHIFT                     5  /* AIF2RX6_ENA */
+#define ARIZONA_AIF2RX6_ENA_WIDTH                     1  /* AIF2RX6_ENA */
+#define ARIZONA_AIF2RX5_ENA                      0x0010  /* AIF2RX5_ENA */
+#define ARIZONA_AIF2RX5_ENA_MASK                 0x0010  /* AIF2RX5_ENA */
+#define ARIZONA_AIF2RX5_ENA_SHIFT                     4  /* AIF2RX5_ENA */
+#define ARIZONA_AIF2RX5_ENA_WIDTH                     1  /* AIF2RX5_ENA */
+#define ARIZONA_AIF2RX4_ENA                      0x0008  /* AIF2RX4_ENA */
+#define ARIZONA_AIF2RX4_ENA_MASK                 0x0008  /* AIF2RX4_ENA */
+#define ARIZONA_AIF2RX4_ENA_SHIFT                     3  /* AIF2RX4_ENA */
+#define ARIZONA_AIF2RX4_ENA_WIDTH                     1  /* AIF2RX4_ENA */
+#define ARIZONA_AIF2RX3_ENA                      0x0004  /* AIF2RX3_ENA */
+#define ARIZONA_AIF2RX3_ENA_MASK                 0x0004  /* AIF2RX3_ENA */
+#define ARIZONA_AIF2RX3_ENA_SHIFT                     2  /* AIF2RX3_ENA */
+#define ARIZONA_AIF2RX3_ENA_WIDTH                     1  /* AIF2RX3_ENA */
 #define ARIZONA_AIF2RX2_ENA                      0x0002  /* AIF2RX2_ENA */
 #define ARIZONA_AIF2RX2_ENA_MASK                 0x0002  /* AIF2RX2_ENA */
 #define ARIZONA_AIF2RX2_ENA_SHIFT                     1  /* AIF2RX2_ENA */
diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h
new file mode 100644 (file)
index 0000000..a3d0185
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * max14577-private.h - Common API for the Maxim 14577 internal sub chip
+ *
+ * Copyright (C) 2013 Samsung Electrnoics
+ * Chanwoo Choi <cw00.choi@samsung.com>
+ * Krzysztof Kozlowski <k.kozlowski@samsung.com>
+ *
+ * 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.
+ */
+
+#ifndef __MAX14577_PRIVATE_H__
+#define __MAX14577_PRIVATE_H__
+
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+
+#define MAX14577_REG_INVALID           (0xff)
+
+/* Slave addr = 0x4A: Interrupt */
+enum max14577_reg {
+       MAX14577_REG_DEVICEID           = 0x00,
+       MAX14577_REG_INT1               = 0x01,
+       MAX14577_REG_INT2               = 0x02,
+       MAX14577_REG_INT3               = 0x03,
+       MAX14577_REG_STATUS1            = 0x04,
+       MAX14577_REG_STATUS2            = 0x05,
+       MAX14577_REG_STATUS3            = 0x06,
+       MAX14577_REG_INTMASK1           = 0x07,
+       MAX14577_REG_INTMASK2           = 0x08,
+       MAX14577_REG_INTMASK3           = 0x09,
+       MAX14577_REG_CDETCTRL1          = 0x0A,
+       MAX14577_REG_RFU                = 0x0B,
+       MAX14577_REG_CONTROL1           = 0x0C,
+       MAX14577_REG_CONTROL2           = 0x0D,
+       MAX14577_REG_CONTROL3           = 0x0E,
+       MAX14577_REG_CHGCTRL1           = 0x0F,
+       MAX14577_REG_CHGCTRL2           = 0x10,
+       MAX14577_REG_CHGCTRL3           = 0x11,
+       MAX14577_REG_CHGCTRL4           = 0x12,
+       MAX14577_REG_CHGCTRL5           = 0x13,
+       MAX14577_REG_CHGCTRL6           = 0x14,
+       MAX14577_REG_CHGCTRL7           = 0x15,
+
+       MAX14577_REG_END,
+};
+
+/* Slave addr = 0x4A: MUIC */
+enum max14577_muic_reg {
+       MAX14577_MUIC_REG_STATUS1       = 0x04,
+       MAX14577_MUIC_REG_STATUS2       = 0x05,
+       MAX14577_MUIC_REG_CONTROL1      = 0x0C,
+       MAX14577_MUIC_REG_CONTROL3      = 0x0E,
+
+       MAX14577_MUIC_REG_END,
+};
+
+enum max14577_muic_charger_type {
+       MAX14577_CHARGER_TYPE_NONE = 0,
+       MAX14577_CHARGER_TYPE_USB,
+       MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT,
+       MAX14577_CHARGER_TYPE_DEDICATED_CHG,
+       MAX14577_CHARGER_TYPE_SPECIAL_500MA,
+       MAX14577_CHARGER_TYPE_SPECIAL_1A,
+       MAX14577_CHARGER_TYPE_RESERVED,
+       MAX14577_CHARGER_TYPE_DEAD_BATTERY = 7,
+};
+
+/* MAX14577 interrupts */
+#define INT1_ADC_MASK                  (0x1 << 0)
+#define INT1_ADCLOW_MASK               (0x1 << 1)
+#define INT1_ADCERR_MASK               (0x1 << 2)
+
+#define INT2_CHGTYP_MASK               (0x1 << 0)
+#define INT2_CHGDETRUN_MASK            (0x1 << 1)
+#define INT2_DCDTMR_MASK               (0x1 << 2)
+#define INT2_DBCHG_MASK                        (0x1 << 3)
+#define INT2_VBVOLT_MASK               (0x1 << 4)
+
+#define INT3_EOC_MASK                  (0x1 << 0)
+#define INT3_CGMBC_MASK                        (0x1 << 1)
+#define INT3_OVP_MASK                  (0x1 << 2)
+#define INT3_MBCCHGERR_MASK            (0x1 << 3)
+
+/* MAX14577 DEVICE ID register */
+#define DEVID_VENDORID_SHIFT           0
+#define DEVID_DEVICEID_SHIFT           3
+#define DEVID_VENDORID_MASK            (0x07 << DEVID_VENDORID_SHIFT)
+#define DEVID_DEVICEID_MASK            (0x1f << DEVID_DEVICEID_SHIFT)
+
+/* MAX14577 STATUS1 register */
+#define STATUS1_ADC_SHIFT              0
+#define STATUS1_ADCLOW_SHIFT           5
+#define STATUS1_ADCERR_SHIFT           6
+#define STATUS1_ADC_MASK               (0x1f << STATUS1_ADC_SHIFT)
+#define STATUS1_ADCLOW_MASK            (0x1 << STATUS1_ADCLOW_SHIFT)
+#define STATUS1_ADCERR_MASK            (0x1 << STATUS1_ADCERR_SHIFT)
+
+/* MAX14577 STATUS2 register */
+#define STATUS2_CHGTYP_SHIFT           0
+#define STATUS2_CHGDETRUN_SHIFT                3
+#define STATUS2_DCDTMR_SHIFT           4
+#define STATUS2_DBCHG_SHIFT            5
+#define STATUS2_VBVOLT_SHIFT           6
+#define STATUS2_CHGTYP_MASK            (0x7 << STATUS2_CHGTYP_SHIFT)
+#define STATUS2_CHGDETRUN_MASK         (0x1 << STATUS2_CHGDETRUN_SHIFT)
+#define STATUS2_DCDTMR_MASK            (0x1 << STATUS2_DCDTMR_SHIFT)
+#define STATUS2_DBCHG_MASK             (0x1 << STATUS2_DBCHG_SHIFT)
+#define STATUS2_VBVOLT_MASK            (0x1 << STATUS2_VBVOLT_SHIFT)
+
+/* MAX14577 CONTROL1 register */
+#define COMN1SW_SHIFT                  0
+#define COMP2SW_SHIFT                  3
+#define MICEN_SHIFT                    6
+#define IDBEN_SHIFT                    7
+#define COMN1SW_MASK                   (0x7 << COMN1SW_SHIFT)
+#define COMP2SW_MASK                   (0x7 << COMP2SW_SHIFT)
+#define MICEN_MASK                     (0x1 << MICEN_SHIFT)
+#define IDBEN_MASK                     (0x1 << IDBEN_SHIFT)
+#define CLEAR_IDBEN_MICEN_MASK         (COMN1SW_MASK | COMP2SW_MASK)
+#define CTRL1_SW_USB                   ((1 << COMP2SW_SHIFT) \
+                                               | (1 << COMN1SW_SHIFT))
+#define CTRL1_SW_AUDIO                 ((2 << COMP2SW_SHIFT) \
+                                               | (2 << COMN1SW_SHIFT))
+#define CTRL1_SW_UART                  ((3 << COMP2SW_SHIFT) \
+                                               | (3 << COMN1SW_SHIFT))
+#define CTRL1_SW_OPEN                  ((0 << COMP2SW_SHIFT) \
+                                               | (0 << COMN1SW_SHIFT))
+
+/* MAX14577 CONTROL2 register */
+#define CTRL2_LOWPWR_SHIFT             (0)
+#define CTRL2_ADCEN_SHIFT              (1)
+#define CTRL2_CPEN_SHIFT               (2)
+#define CTRL2_SFOUTASRT_SHIFT          (3)
+#define CTRL2_SFOUTORD_SHIFT           (4)
+#define CTRL2_ACCDET_SHIFT             (5)
+#define CTRL2_USBCPINT_SHIFT           (6)
+#define CTRL2_RCPS_SHIFT               (7)
+#define CTRL2_LOWPWR_MASK              (0x1 << CTRL2_LOWPWR_SHIFT)
+#define CTRL2_ADCEN_MASK               (0x1 << CTRL2_ADCEN_SHIFT)
+#define CTRL2_CPEN_MASK                        (0x1 << CTRL2_CPEN_SHIFT)
+#define CTRL2_SFOUTASRT_MASK           (0x1 << CTRL2_SFOUTASRT_SHIFT)
+#define CTRL2_SFOUTORD_MASK            (0x1 << CTRL2_SFOUTORD_SHIFT)
+#define CTRL2_ACCDET_MASK              (0x1 << CTRL2_ACCDET_SHIFT)
+#define CTRL2_USBCPINT_MASK            (0x1 << CTRL2_USBCPINT_SHIFT)
+#define CTRL2_RCPS_MASK                        (0x1 << CTR2_RCPS_SHIFT)
+
+#define CTRL2_CPEN1_LOWPWR0 ((1 << CTRL2_CPEN_SHIFT) | \
+                               (0 << CTRL2_LOWPWR_SHIFT))
+#define CTRL2_CPEN0_LOWPWR1 ((0 << CTRL2_CPEN_SHIFT) | \
+                               (1 << CTRL2_LOWPWR_SHIFT))
+
+/* MAX14577 CONTROL3 register */
+#define CTRL3_JIGSET_SHIFT             0
+#define CTRL3_BOOTSET_SHIFT            2
+#define CTRL3_ADCDBSET_SHIFT           4
+#define CTRL3_JIGSET_MASK              (0x3 << CTRL3_JIGSET_SHIFT)
+#define CTRL3_BOOTSET_MASK             (0x3 << CTRL3_BOOTSET_SHIFT)
+#define CTRL3_ADCDBSET_MASK            (0x3 << CTRL3_ADCDBSET_SHIFT)
+
+/* Slave addr = 0x4A: Charger */
+enum max14577_charger_reg {
+       MAX14577_CHG_REG_STATUS3        = 0x06,
+       MAX14577_CHG_REG_CHG_CTRL1      = 0x0F,
+       MAX14577_CHG_REG_CHG_CTRL2      = 0x10,
+       MAX14577_CHG_REG_CHG_CTRL3      = 0x11,
+       MAX14577_CHG_REG_CHG_CTRL4      = 0x12,
+       MAX14577_CHG_REG_CHG_CTRL5      = 0x13,
+       MAX14577_CHG_REG_CHG_CTRL6      = 0x14,
+       MAX14577_CHG_REG_CHG_CTRL7      = 0x15,
+
+       MAX14577_CHG_REG_END,
+};
+
+/* MAX14577 STATUS3 register */
+#define STATUS3_EOC_SHIFT              0
+#define STATUS3_CGMBC_SHIFT            1
+#define STATUS3_OVP_SHIFT              2
+#define STATUS3_MBCCHGERR_SHIFT                3
+#define STATUS3_EOC_MASK               (0x1 << STATUS3_EOC_SHIFT)
+#define STATUS3_CGMBC_MASK             (0x1 << STATUS3_CGMBC_SHIFT)
+#define STATUS3_OVP_MASK               (0x1 << STATUS3_OVP_SHIFT)
+#define STATUS3_MBCCHGERR_MASK         (0x1 << STATUS3_MBCCHGERR_SHIFT)
+
+/* MAX14577 CDETCTRL1 register */
+#define CDETCTRL1_CHGDETEN_SHIFT       0
+#define CDETCTRL1_CHGTYPMAN_SHIFT      1
+#define CDETCTRL1_DCDEN_SHIFT          2
+#define CDETCTRL1_DCD2SCT_SHIFT                3
+#define CDETCTRL1_DCHKTM_SHIFT         4
+#define CDETCTRL1_DBEXIT_SHIFT         5
+#define CDETCTRL1_DBIDLE_SHIFT         6
+#define CDETCTRL1_CDPDET_SHIFT         7
+#define CDETCTRL1_CHGDETEN_MASK                (0x1 << CDETCTRL1_CHGDETEN_SHIFT)
+#define CDETCTRL1_CHGTYPMAN_MASK       (0x1 << CDETCTRL1_CHGTYPMAN_SHIFT)
+#define CDETCTRL1_DCDEN_MASK           (0x1 << CDETCTRL1_DCDEN_SHIFT)
+#define CDETCTRL1_DCD2SCT_MASK         (0x1 << CDETCTRL1_DCD2SCT_SHIFT)
+#define CDETCTRL1_DCHKTM_MASK          (0x1 << CDETCTRL1_DCHKTM_SHIFT)
+#define CDETCTRL1_DBEXIT_MASK          (0x1 << CDETCTRL1_DBEXIT_SHIFT)
+#define CDETCTRL1_DBIDLE_MASK          (0x1 << CDETCTRL1_DBIDLE_SHIFT)
+#define CDETCTRL1_CDPDET_MASK          (0x1 << CDETCTRL1_CDPDET_SHIFT)
+
+/* MAX14577 CHGCTRL1 register */
+#define CHGCTRL1_TCHW_SHIFT            4
+#define CHGCTRL1_TCHW_MASK             (0x7 << CHGCTRL1_TCHW_SHIFT)
+
+/* MAX14577 CHGCTRL2 register */
+#define CHGCTRL2_MBCHOSTEN_SHIFT       6
+#define CHGCTRL2_MBCHOSTEN_MASK                (0x1 << CHGCTRL2_MBCHOSTEN_SHIFT)
+#define CHGCTRL2_VCHGR_RC_SHIFT                7
+#define CHGCTRL2_VCHGR_RC_MASK         (0x1 << CHGCTRL2_VCHGR_RC_SHIFT)
+
+/* MAX14577 CHGCTRL3 register */
+#define CHGCTRL3_MBCCVWRC_SHIFT                0
+#define CHGCTRL3_MBCCVWRC_MASK         (0xf << CHGCTRL3_MBCCVWRC_SHIFT)
+
+/* MAX14577 CHGCTRL4 register */
+#define CHGCTRL4_MBCICHWRCH_SHIFT      0
+#define CHGCTRL4_MBCICHWRCH_MASK       (0xf << CHGCTRL4_MBCICHWRCH_SHIFT)
+#define CHGCTRL4_MBCICHWRCL_SHIFT      4
+#define CHGCTRL4_MBCICHWRCL_MASK       (0x1 << CHGCTRL4_MBCICHWRCL_SHIFT)
+
+/* MAX14577 CHGCTRL5 register */
+#define CHGCTRL5_EOCS_SHIFT            0
+#define CHGCTRL5_EOCS_MASK             (0xf << CHGCTRL5_EOCS_SHIFT)
+
+/* MAX14577 CHGCTRL6 register */
+#define CHGCTRL6_AUTOSTOP_SHIFT                5
+#define CHGCTRL6_AUTOSTOP_MASK         (0x1 << CHGCTRL6_AUTOSTOP_SHIFT)
+
+/* MAX14577 CHGCTRL7 register */
+#define CHGCTRL7_OTPCGHCVS_SHIFT       0
+#define CHGCTRL7_OTPCGHCVS_MASK                (0x3 << CHGCTRL7_OTPCGHCVS_SHIFT)
+
+/* MAX14577 regulator current limits (as in CHGCTRL4 register), uA */
+#define MAX14577_REGULATOR_CURRENT_LIMIT_MIN            90000
+#define MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START    200000
+#define MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP      50000
+#define MAX14577_REGULATOR_CURRENT_LIMIT_MAX           950000
+
+/* MAX14577 regulator SFOUT LDO voltage, fixed, uV */
+#define MAX14577_REGULATOR_SAFEOUT_VOLTAGE             4900000
+
+enum max14577_irq_source {
+       MAX14577_IRQ_INT1 = 0,
+       MAX14577_IRQ_INT2,
+       MAX14577_IRQ_INT3,
+
+       MAX14577_IRQ_REGS_NUM,
+};
+
+enum max14577_irq {
+       /* INT1 */
+       MAX14577_IRQ_INT1_ADC,
+       MAX14577_IRQ_INT1_ADCLOW,
+       MAX14577_IRQ_INT1_ADCERR,
+
+       /* INT2 */
+       MAX14577_IRQ_INT2_CHGTYP,
+       MAX14577_IRQ_INT2_CHGDETRUN,
+       MAX14577_IRQ_INT2_DCDTMR,
+       MAX14577_IRQ_INT2_DBCHG,
+       MAX14577_IRQ_INT2_VBVOLT,
+
+       /* INT3 */
+       MAX14577_IRQ_INT3_EOC,
+       MAX14577_IRQ_INT3_CGMBC,
+       MAX14577_IRQ_INT3_OVP,
+       MAX14577_IRQ_INT3_MBCCHGERR,
+
+       MAX14577_IRQ_NUM,
+};
+
+struct max14577 {
+       struct device *dev;
+       struct i2c_client *i2c; /* Slave addr = 0x4A */
+
+       struct regmap *regmap;
+
+       struct regmap_irq_chip_data *irq_data;
+       int irq;
+
+       /* Device ID */
+       u8 vendor_id;   /* Vendor Identification */
+       u8 device_id;   /* Chip Version */
+};
+
+/* MAX14577 shared regmap API function */
+static inline int max14577_read_reg(struct regmap *map, u8 reg, u8 *dest)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(map, reg, &val);
+       *dest = val;
+
+       return ret;
+}
+
+static inline int max14577_bulk_read(struct regmap *map, u8 reg, u8 *buf,
+               int count)
+{
+       return regmap_bulk_read(map, reg, buf, count);
+}
+
+static inline int max14577_write_reg(struct regmap *map, u8 reg, u8 value)
+{
+       return regmap_write(map, reg, value);
+}
+
+static inline int max14577_bulk_write(struct regmap *map, u8 reg, u8 *buf,
+               int count)
+{
+       return regmap_bulk_write(map, reg, buf, count);
+}
+
+static inline int max14577_update_reg(struct regmap *map, u8 reg, u8 mask,
+               u8 val)
+{
+       return regmap_update_bits(map, reg, mask, val);
+}
+
+#endif /* __MAX14577_PRIVATE_H__ */
diff --git a/include/linux/mfd/max14577.h b/include/linux/mfd/max14577.h
new file mode 100644 (file)
index 0000000..247b021
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * max14577.h - Driver for the Maxim 14577
+ *
+ * Copyright (C) 2013 Samsung Electrnoics
+ * Chanwoo Choi <cw00.choi@samsung.com>
+ * Krzysztof Kozlowski <k.kozlowski@samsung.com>
+ *
+ * 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.
+ *
+ * This driver is based on max8997.h
+ *
+ * MAX14577 has MUIC, Charger devices.
+ * The devices share the same I2C bus and interrupt line
+ * included in this mfd driver.
+ */
+
+#ifndef __MAX14577_H__
+#define __MAX14577_H__
+
+#include <linux/mfd/max14577-private.h>
+#include <linux/regulator/consumer.h>
+
+/*
+ * MAX14577 Regulator
+ */
+
+/* MAX14577 regulator IDs */
+enum max14577_regulators {
+       MAX14577_SAFEOUT = 0,
+       MAX14577_CHARGER,
+
+       MAX14577_REG_MAX,
+};
+
+struct max14577_regulator_platform_data {
+       int id;
+       struct regulator_init_data *initdata;
+       struct device_node *of_node;
+};
+
+/*
+ * MAX14577 MFD platform data
+ */
+struct max14577_platform_data {
+       /* IRQ */
+       int irq_base;
+
+       /* current control GPIOs */
+       int gpio_pogo_vbatt_en;
+       int gpio_pogo_vbus_en;
+
+       /* current control GPIO control function */
+       int (*set_gpio_pogo_vbatt_en) (int gpio_val);
+       int (*set_gpio_pogo_vbus_en) (int gpio_val);
+
+       int (*set_gpio_pogo_cb) (int new_dev);
+
+       struct max14577_regulator_platform_data *regulators;
+};
+
+#endif /* __MAX14577_H__ */
index 1f8d24bdafdac2bc28789c777315068311368765..335ffca10c10c01d82e9a2304d9d21afba3b47c2 100644 (file)
@@ -37,7 +37,7 @@
  */
 
 struct mtd_partition {
-       char *name;                     /* identifier string */
+       const char *name;               /* identifier string */
        uint64_t size;                  /* partition size */
        uint64_t offset;                /* offset within the master MTD space */
        uint32_t mask_flags;            /* master MTD flags to mask out for this partition */
@@ -80,7 +80,7 @@ extern int register_mtd_parser(struct mtd_part_parser *parser);
 extern int deregister_mtd_parser(struct mtd_part_parser *parser);
 
 int mtd_is_partition(const struct mtd_info *mtd);
-int mtd_add_partition(struct mtd_info *master, char *name,
+int mtd_add_partition(struct mtd_info *master, const char *name,
                      long long offset, long long length);
 int mtd_del_partition(struct mtd_info *master, int partno);
 uint64_t mtd_get_device_size(const struct mtd_info *mtd);
index c1637062c1ce138129a87dd571a5ea7cd2b53abd..12c2cb947df579bca8e55c46c5a58cf449f084fb 100644 (file)
@@ -413,16 +413,6 @@ enum lock_type4 {
 #define NFS4_VERSION 4
 #define NFS4_MINOR_VERSION 0
 
-#if defined(CONFIG_NFS_V4_2)
-#define NFS4_MAX_MINOR_VERSION 2
-#else
-#if defined(CONFIG_NFS_V4_1)
-#define NFS4_MAX_MINOR_VERSION 1
-#else
-#define NFS4_MAX_MINOR_VERSION 0
-#endif /* CONFIG_NFS_V4_1 */
-#endif /* CONFIG_NFS_V4_2 */
-
 #define NFS4_DEBUG 1
 
 /* Index of predefined Linux client operations */
index 14a48207a304ec65dda6ac8af22e0e0825b8fa6b..48997374eaf04eac0d52b8bf8d60c61c35944df3 100644 (file)
@@ -506,24 +506,6 @@ extern const struct inode_operations nfs_referral_inode_operations;
 extern int nfs_mountpoint_expiry_timeout;
 extern void nfs_release_automount_timer(void);
 
-/*
- * linux/fs/nfs/nfs4proc.c
- */
-#ifdef CONFIG_NFS_V4_SECURITY_LABEL
-extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags);
-static inline void nfs4_label_free(struct nfs4_label *label)
-{
-       if (label) {
-               kfree(label->label);
-               kfree(label);
-       }
-       return;
-}
-#else
-static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
-static inline void nfs4_label_free(void *label) {}
-#endif
-
 /*
  * linux/fs/nfs/unlink.c
  */
index 86292beebfe2b910e28491dfd0e9c2343428000d..438694650471cc66b62cb7890e19fde5799314f7 100644 (file)
@@ -129,10 +129,9 @@ struct parallel_data {
        struct padata_serial_queue      __percpu *squeue;
        atomic_t                        reorder_objects;
        atomic_t                        refcnt;
+       atomic_t                        seq_nr;
        struct padata_cpumask           cpumask;
        spinlock_t                      lock ____cacheline_aligned;
-       spinlock_t                      seq_lock;
-       unsigned int                    seq_nr;
        unsigned int                    processed;
        struct timer_list               timer;
 };
index a2e2f1d17e164c00b190d6515ec90950ef288e17..5f2e559af6b0a7a6ea07247ab405ea48407d4e72 100644 (file)
@@ -175,8 +175,7 @@ struct hotplug_params {
 };
 
 #ifdef CONFIG_ACPI
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
+#include <linux/acpi.h>
 int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp);
 int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags);
 int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle);
index 2e069d1288df5f04e6982243d7cac0f7455cd31d..8f4a70f2eca8bd0a3f55c572ad967ca516a2d8e1 100644 (file)
@@ -319,7 +319,10 @@ struct perf_event {
         */
        struct list_head                migrate_entry;
 
-       struct hlist_node               hlist_entry;
+       union {
+               struct hlist_node       hlist_entry;
+               struct list_head        active_entry;
+       };
        int                             nr_siblings;
        int                             group_flags;
        struct perf_event               *group_leader;
index 3a3942823c209163501b1dcd49a550d1664c56da..eabac4e2fc993b114ae940b1be960f04015ade0f 100644 (file)
@@ -43,6 +43,11 @@ struct sdma_script_start_addrs {
        s32 dptc_dvfs_addr;
        s32 utra_addr;
        s32 ram_code_start_addr;
+       /* End of v1 array */
+       s32 mcu_2_ssish_addr;
+       s32 ssish_2_mcu_addr;
+       s32 hdmi_dma_addr;
+       /* End of v2 array */
 };
 
 /**
index beac6b8b6a7b3846cf3925cab343da187fc686e1..bcbc6c3c14c0da82547b861e7108ccee41351f71 100644 (file)
@@ -39,6 +39,7 @@ enum sdma_peripheral_type {
        IMX_DMATYPE_IPU_MEMORY, /* IPU Memory */
        IMX_DMATYPE_ASRC,       /* ASRC */
        IMX_DMATYPE_ESAI,       /* ESAI */
+       IMX_DMATYPE_SSI_DUAL,   /* SSI Dual FIFO */
 };
 
 enum imx_dma_prio {
index ffb801998e5dfa10c450f99b2dbb943e8f7a05d4..a941471249299c842a7cfea12de9a4091d2e44e2 100644 (file)
@@ -55,6 +55,9 @@ struct pxa3xx_nand_platform_data {
        /* indicate how many chip selects will be used */
        int     num_cs;
 
+       /* use an flash-based bad block table */
+       bool    flash_bbt;
+
        const struct mtd_partition              *parts[NUM_CHIP_SELECT];
        unsigned int                            nr_parts[NUM_CHIP_SELECT];
 
index 5c2600630dc99ace79f3d001416db6d37f568806..3e28fe188d171a11f224fcdc36975a031c7146b2 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/workqueue.h>
 #include <linux/leds.h>
 #include <linux/spinlock.h>
+#include <linux/notifier.h>
 
 struct device;
 
@@ -158,6 +159,10 @@ enum power_supply_type {
        POWER_SUPPLY_TYPE_USB_ACA,      /* Accessory Charger Adapters */
 };
 
+enum power_supply_notifier_events {
+       PSY_EVENT_PROP_CHANGED,
+};
+
 union power_supply_propval {
        int intval;
        const char *strval;
@@ -235,6 +240,9 @@ struct power_supply_info {
        int use_for_apm;
 };
 
+extern struct atomic_notifier_head power_supply_notifier;
+extern int power_supply_reg_notifier(struct notifier_block *nb);
+extern void power_supply_unreg_notifier(struct notifier_block *nb);
 extern struct power_supply *power_supply_get_by_name(const char *name);
 extern void power_supply_changed(struct power_supply *psy);
 extern int power_supply_am_i_supplied(struct power_supply *psy);
index 7e35d4b9e14a45cba37fd8a7f234e5a3a50ec4b5..bf14c215af1e820eb2395950701fc5b5831aa2c8 100644 (file)
@@ -168,7 +168,6 @@ extern char ___assert_task_state[1 - 2*!!(
 
 #define task_is_traced(task)   ((task->state & __TASK_TRACED) != 0)
 #define task_is_stopped(task)  ((task->state & __TASK_STOPPED) != 0)
-#define task_is_dead(task)     ((task)->exit_state != 0)
 #define task_is_stopped_or_traced(task)        \
                        ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
 #define task_contributes_to_load(task) \
@@ -831,8 +830,6 @@ struct sched_domain {
        unsigned int balance_interval;  /* initialise to 1. units in ms. */
        unsigned int nr_balance_failed; /* initialise to 0 */
 
-       u64 last_update;
-
        /* idle_balance() stats */
        u64 max_newidle_lb_cost;
        unsigned long next_decay_max_lb_cost;
index 50fe651da965933f416b3cc6a5a0080942ac107e..3dbdf7e53dcc0942153be0a59cdeebd73caa0973 100644 (file)
 #define SCIx_NOT_SUPPORTED     (-1)
 
 enum {
+       SCBRR_ALGO_INVALID,
+
        SCBRR_ALGO_1,           /* ((clk + 16 * bps) / (16 * bps) - 1) */
        SCBRR_ALGO_2,           /* ((clk + 16 * bps) / (32 * bps) - 1) */
        SCBRR_ALGO_3,           /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */
        SCBRR_ALGO_4,           /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */
        SCBRR_ALGO_5,           /* (((clk * 1000 / 32) / bps) - 1) */
        SCBRR_ALGO_6,           /* HSCIF variable sample rate algorithm */
+
+       SCBRR_NR_ALGOS,
 };
 
 #define SCSCR_TIE      (1 << 7)
index 631af63af42ddbaaabf6f8debcda035821cc71dc..c9cab828cb9001116e014d05db86567d1936e47e 100644 (file)
@@ -60,7 +60,7 @@
 #define _LINUX_SFI_ACPI_H
 
 #ifdef CONFIG_SFI
-#include <acpi/acpi.h>         /* struct acpi_table_header */
+#include <linux/acpi.h>
 
 extern int sfi_acpi_table_parse(char *signature, char *oem_id,
                                char *oem_table_id,
index c2bba248fa63d46024930f5b4d6c47b652a51dc6..1e2f4fe12773bdaf9c5ffddd9b5eb77d42b665a0 100644 (file)
@@ -388,10 +388,55 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
 /**
  * kmalloc - allocate memory
  * @size: how many bytes of memory are required.
- * @flags: the type of memory to allocate (see kcalloc).
+ * @flags: the type of memory to allocate.
  *
  * kmalloc is the normal method of allocating memory
  * for objects smaller than page size in the kernel.
+ *
+ * The @flags argument may be one of:
+ *
+ * %GFP_USER - Allocate memory on behalf of user.  May sleep.
+ *
+ * %GFP_KERNEL - Allocate normal kernel ram.  May sleep.
+ *
+ * %GFP_ATOMIC - Allocation will not sleep.  May use emergency pools.
+ *   For example, use this inside interrupt handlers.
+ *
+ * %GFP_HIGHUSER - Allocate pages from high memory.
+ *
+ * %GFP_NOIO - Do not do any I/O at all while trying to get memory.
+ *
+ * %GFP_NOFS - Do not make any fs calls while trying to get memory.
+ *
+ * %GFP_NOWAIT - Allocation will not sleep.
+ *
+ * %GFP_THISNODE - Allocate node-local memory only.
+ *
+ * %GFP_DMA - Allocation suitable for DMA.
+ *   Should only be used for kmalloc() caches. Otherwise, use a
+ *   slab created with SLAB_DMA.
+ *
+ * Also it is possible to set different flags by OR'ing
+ * in one or more of the following additional @flags:
+ *
+ * %__GFP_COLD - Request cache-cold pages instead of
+ *   trying to return cache-warm pages.
+ *
+ * %__GFP_HIGH - This allocation has high priority and may use emergency pools.
+ *
+ * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail
+ *   (think twice before using).
+ *
+ * %__GFP_NORETRY - If memory is not immediately available,
+ *   then give up at once.
+ *
+ * %__GFP_NOWARN - If allocation fails, don't issue any warnings.
+ *
+ * %__GFP_REPEAT - If allocation fails initially, try once more before failing.
+ *
+ * There are other flags available as well, but these are not intended
+ * for general use, and so are not documented here. For a full list of
+ * potential flags, always refer to linux/gfp.h.
  */
 static __always_inline void *kmalloc(size_t size, gfp_t flags)
 {
@@ -501,61 +546,6 @@ struct seq_file;
 int cache_show(struct kmem_cache *s, struct seq_file *m);
 void print_slabinfo_header(struct seq_file *m);
 
-/**
- * kmalloc - allocate memory
- * @size: how many bytes of memory are required.
- * @flags: the type of memory to allocate.
- *
- * The @flags argument may be one of:
- *
- * %GFP_USER - Allocate memory on behalf of user.  May sleep.
- *
- * %GFP_KERNEL - Allocate normal kernel ram.  May sleep.
- *
- * %GFP_ATOMIC - Allocation will not sleep.  May use emergency pools.
- *   For example, use this inside interrupt handlers.
- *
- * %GFP_HIGHUSER - Allocate pages from high memory.
- *
- * %GFP_NOIO - Do not do any I/O at all while trying to get memory.
- *
- * %GFP_NOFS - Do not make any fs calls while trying to get memory.
- *
- * %GFP_NOWAIT - Allocation will not sleep.
- *
- * %GFP_THISNODE - Allocate node-local memory only.
- *
- * %GFP_DMA - Allocation suitable for DMA.
- *   Should only be used for kmalloc() caches. Otherwise, use a
- *   slab created with SLAB_DMA.
- *
- * Also it is possible to set different flags by OR'ing
- * in one or more of the following additional @flags:
- *
- * %__GFP_COLD - Request cache-cold pages instead of
- *   trying to return cache-warm pages.
- *
- * %__GFP_HIGH - This allocation has high priority and may use emergency pools.
- *
- * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail
- *   (think twice before using).
- *
- * %__GFP_NORETRY - If memory is not immediately available,
- *   then give up at once.
- *
- * %__GFP_NOWARN - If allocation fails, don't issue any warnings.
- *
- * %__GFP_REPEAT - If allocation fails initially, try once more before failing.
- *
- * There are other flags available as well, but these are not intended
- * for general use, and so are not documented here. For a full list of
- * potential flags, always refer to linux/gfp.h.
- *
- * kmalloc is the normal method of allocating memory
- * in the kernel.
- */
-static __always_inline void *kmalloc(size_t size, gfp_t flags);
-
 /**
  * kmalloc_array - allocate memory for an array.
  * @n: number of elements.
index 6695040a031713ee257130e7295be38cc6aff293..cd8f90bf51a724c6510a1f5b51739d6842ba326d 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _SYSFS_H_
 #define _SYSFS_H_
 
+#include <linux/kernfs.h>
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/list.h>
@@ -175,8 +176,6 @@ struct sysfs_ops {
        ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
 };
 
-struct sysfs_dirent;
-
 #ifdef CONFIG_SYSFS
 
 int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
@@ -244,12 +243,6 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
                                  const char *link_name);
 
 void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
-void sysfs_notify_dirent(struct sysfs_dirent *sd);
-struct sysfs_dirent *sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd,
-                                        const unsigned char *name,
-                                        const void *ns);
-struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd);
-void sysfs_put(struct sysfs_dirent *sd);
 
 int __must_check sysfs_init(void);
 
@@ -419,22 +412,6 @@ static inline void sysfs_notify(struct kobject *kobj, const char *dir,
                                const char *attr)
 {
 }
-static inline void sysfs_notify_dirent(struct sysfs_dirent *sd)
-{
-}
-static inline struct sysfs_dirent *
-sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd, const unsigned char *name,
-                   const void *ns)
-{
-       return NULL;
-}
-static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
-{
-       return NULL;
-}
-static inline void sysfs_put(struct sysfs_dirent *sd)
-{
-}
 
 static inline int __must_check sysfs_init(void)
 {
@@ -461,10 +438,26 @@ static inline int sysfs_rename_link(struct kobject *kobj, struct kobject *target
        return sysfs_rename_link_ns(kobj, target, old_name, new_name, NULL);
 }
 
+static inline void sysfs_notify_dirent(struct sysfs_dirent *sd)
+{
+       kernfs_notify(sd);
+}
+
 static inline struct sysfs_dirent *
 sysfs_get_dirent(struct sysfs_dirent *parent_sd, const unsigned char *name)
 {
-       return sysfs_get_dirent_ns(parent_sd, name, NULL);
+       return kernfs_find_and_get(parent_sd, name);
+}
+
+static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+{
+       kernfs_get(sd);
+       return sd;
+}
+
+static inline void sysfs_put(struct sysfs_dirent *sd)
+{
+       kernfs_put(sd);
 }
 
 #endif /* _SYSFS_H_ */
index c75128bed5fa39116952fd148ff01374993b8f44..9a54b331f938fcfc02d66a22873b8d735369d8ad 100644 (file)
@@ -34,7 +34,7 @@ enum {
 };
 
 #ifdef CONFIG_INTEL_TXT
-#include <acpi/acpi.h>
+#include <linux/acpi.h>
 /* used to communicate between tboot and the launched kernel */
 
 #define TB_KEY_SIZE             64   /* 512 bits */
index c98cfa40695248d16ab3ee91891c33334239c252..fd4498329c7c509b3614ad820c7c717d976afa2f 100644 (file)
@@ -45,6 +45,7 @@ struct clk;
 
 #define TEGRA_POWERGATE_3D0    TEGRA_POWERGATE_3D
 
+#ifdef CONFIG_ARCH_TEGRA
 int tegra_powergate_is_powered(int id);
 int tegra_powergate_power_on(int id);
 int tegra_powergate_power_off(int id);
@@ -52,5 +53,31 @@ int tegra_powergate_remove_clamping(int id);
 
 /* Must be called with clk disabled, and returns with clk enabled */
 int tegra_powergate_sequence_power_up(int id, struct clk *clk);
+#else
+static inline int tegra_powergate_is_powered(int id)
+{
+       return -ENOSYS;
+}
+
+static inline int tegra_powergate_power_on(int id)
+{
+       return -ENOSYS;
+}
+
+static inline int tegra_powergate_power_off(int id)
+{
+       return -ENOSYS;
+}
+
+static inline int tegra_powergate_remove_clamping(int id)
+{
+       return -ENOSYS;
+}
+
+static inline int tegra_powergate_sequence_power_up(int id, struct clk *clk)
+{
+       return -ENOSYS;
+}
+#endif
 
 #endif /* _MACH_TEGRA_POWERGATE_H_ */
index ebeab360d851c1ece4952b3f5f4f294aa9673db0..f16dc0a4004976376c9036a244e1121ed52ed020 100644 (file)
@@ -267,6 +267,8 @@ static inline void tracepoint_synchronize_unregister(void)
 
 #define TRACE_EVENT_FLAGS(event, flag)
 
+#define TRACE_EVENT_PERF_PERM(event, expr...)
+
 #endif /* DECLARE_TRACE */
 
 #ifndef TRACE_EVENT
@@ -399,4 +401,6 @@ static inline void tracepoint_synchronize_unregister(void)
 
 #define TRACE_EVENT_FLAGS(event, flag)
 
+#define TRACE_EVENT_PERF_PERM(event, expr...)
+
 #endif /* ifdef TRACE_EVENT (see note above) */
index 319eae70fe8415f774e57c4861b98688fb81bb4c..e32251e00e62f0b2629c0ef7658d1445e6647586 100644 (file)
 
 #include <linux/errno.h>
 #include <linux/rbtree.h>
+#include <linux/types.h>
 
 struct vm_area_struct;
 struct mm_struct;
 struct inode;
 struct notifier_block;
 
-#ifdef CONFIG_ARCH_SUPPORTS_UPROBES
-# include <asm/uprobes.h>
-#endif
-
 #define UPROBE_HANDLER_REMOVE          1
 #define UPROBE_HANDLER_MASK            1
 
@@ -60,6 +57,8 @@ struct uprobe_consumer {
 };
 
 #ifdef CONFIG_UPROBES
+#include <asm/uprobes.h>
+
 enum uprobe_task_state {
        UTASK_RUNNING,
        UTASK_SSTEP,
@@ -72,35 +71,28 @@ enum uprobe_task_state {
  */
 struct uprobe_task {
        enum uprobe_task_state          state;
-       struct arch_uprobe_task         autask;
 
-       struct return_instance          *return_instances;
-       unsigned int                    depth;
-       struct uprobe                   *active_uprobe;
+       union {
+               struct {
+                       struct arch_uprobe_task autask;
+                       unsigned long           vaddr;
+               };
 
+               struct {
+                       struct callback_head    dup_xol_work;
+                       unsigned long           dup_xol_addr;
+               };
+       };
+
+       struct uprobe                   *active_uprobe;
        unsigned long                   xol_vaddr;
-       unsigned long                   vaddr;
-};
 
-/*
- * On a breakpoint hit, thread contests for a slot.  It frees the
- * slot after singlestep. Currently a fixed number of slots are
- * allocated.
- */
-struct xol_area {
-       wait_queue_head_t       wq;             /* if all slots are busy */
-       atomic_t                slot_count;     /* number of in-use slots */
-       unsigned long           *bitmap;        /* 0 = free slot */
-       struct page             *page;
-
-       /*
-        * We keep the vma's vm_start rather than a pointer to the vma
-        * itself.  The probed process or a naughty kernel module could make
-        * the vma go away, and we must handle that reasonably gracefully.
-        */
-       unsigned long           vaddr;          /* Page(s) of instruction slots */
+       struct return_instance          *return_instances;
+       unsigned int                    depth;
 };
 
+struct xol_area;
+
 struct uprobes_state {
        struct xol_area         *xol_area;
 };
@@ -109,6 +101,7 @@ extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsign
 extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
 extern bool __weak is_swbp_insn(uprobe_opcode_t *insn);
 extern bool __weak is_trap_insn(uprobe_opcode_t *insn);
+extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs);
 extern int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t);
 extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
 extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool);
@@ -120,7 +113,6 @@ extern void uprobe_end_dup_mmap(void);
 extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm);
 extern void uprobe_free_utask(struct task_struct *t);
 extern void uprobe_copy_process(struct task_struct *t, unsigned long flags);
-extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs);
 extern int uprobe_post_sstep_notifier(struct pt_regs *regs);
 extern int uprobe_pre_sstep_notifier(struct pt_regs *regs);
 extern void uprobe_notify_resume(struct pt_regs *regs);
@@ -176,10 +168,6 @@ static inline bool uprobe_deny_signal(void)
 {
        return false;
 }
-static inline unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
-{
-       return 0;
-}
 static inline void uprobe_free_utask(struct task_struct *t)
 {
 }
index 3f3788d4936292ce150a6cb4b56036a58c541128..3e4535876d37493e590d43a687aa980646dab0c4 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/gfp.h>
 #include <linux/types.h>
 #include <linux/cgroup.h>
+#include <linux/eventfd.h>
 
 struct vmpressure {
        unsigned long scanned;
@@ -33,13 +34,10 @@ extern void vmpressure_init(struct vmpressure *vmpr);
 extern void vmpressure_cleanup(struct vmpressure *vmpr);
 extern struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg);
 extern struct cgroup_subsys_state *vmpressure_to_css(struct vmpressure *vmpr);
-extern struct vmpressure *css_to_vmpressure(struct cgroup_subsys_state *css);
-extern int vmpressure_register_event(struct cgroup_subsys_state *css,
-                                    struct cftype *cft,
+extern int vmpressure_register_event(struct mem_cgroup *memcg,
                                     struct eventfd_ctx *eventfd,
                                     const char *args);
-extern void vmpressure_unregister_event(struct cgroup_subsys_state *css,
-                                       struct cftype *cft,
+extern void vmpressure_unregister_event(struct mem_cgroup *memcg,
                                        struct eventfd_ctx *eventfd);
 #else
 static inline void vmpressure(gfp_t gfp, struct mem_cgroup *memcg,
index dff42025649b32cb03f84d359c0c213ec5617569..63fbba0740c2c2bfb35b4a29f6c146b0137f695d 100644 (file)
 #ifndef _LINUX_ZORRO_H
 #define _LINUX_ZORRO_H
 
-#include <linux/device.h>
-
-
-    /*
-     *  Each Zorro board has a 32-bit ID of the form
-     *
-     *      mmmmmmmmmmmmmmmmppppppppeeeeeeee
-     *
-     *  with
-     *
-     *      mmmmmmmmmmmmmmmm   16-bit Manufacturer ID (assigned by CBM (sigh))
-     *      pppppppp           8-bit Product ID (assigned by manufacturer)
-     *      eeeeeeee           8-bit Extended Product ID (currently only used
-     *                         for some GVP boards)
-     */
-
-
-#define ZORRO_MANUF(id)                ((id) >> 16)
-#define ZORRO_PROD(id)         (((id) >> 8) & 0xff)
-#define ZORRO_EPC(id)          ((id) & 0xff)
-
-#define ZORRO_ID(manuf, prod, epc) \
-    ((ZORRO_MANUF_##manuf << 16) | ((prod) << 8) | (epc))
-
-typedef __u32 zorro_id;
-
-
-/* Include the ID list */
-#include <linux/zorro_ids.h>
-
 
-    /*
-     *  GVP identifies most of its products through the 'extended product code'
-     *  (epc). The epc has to be ANDed with the GVP_PRODMASK before the
-     *  identification.
-     */
-
-#define GVP_PRODMASK                   (0xf8)
-#define GVP_SCSICLKMASK                        (0x01)
-
-enum GVP_flags {
-    GVP_IO             = 0x01,
-    GVP_ACCEL          = 0x02,
-    GVP_SCSI           = 0x04,
-    GVP_24BITDMA       = 0x08,
-    GVP_25BITDMA       = 0x10,
-    GVP_NOBANK         = 0x20,
-    GVP_14MHZ          = 0x40,
-};
-
-
-struct Node {
-    struct  Node *ln_Succ;     /* Pointer to next (successor) */
-    struct  Node *ln_Pred;     /* Pointer to previous (predecessor) */
-    __u8    ln_Type;
-    __s8    ln_Pri;            /* Priority, for sorting */
-    __s8    *ln_Name;          /* ID string, null terminated */
-} __attribute__ ((packed));
-
-struct ExpansionRom {
-    /* -First 16 bytes of the expansion ROM */
-    __u8  er_Type;             /* Board type, size and flags */
-    __u8  er_Product;          /* Product number, assigned by manufacturer */
-    __u8  er_Flags;            /* Flags */
-    __u8  er_Reserved03;       /* Must be zero ($ff inverted) */
-    __u16 er_Manufacturer;     /* Unique ID, ASSIGNED BY COMMODORE-AMIGA! */
-    __u32 er_SerialNumber;     /* Available for use by manufacturer */
-    __u16 er_InitDiagVec;      /* Offset to optional "DiagArea" structure */
-    __u8  er_Reserved0c;
-    __u8  er_Reserved0d;
-    __u8  er_Reserved0e;
-    __u8  er_Reserved0f;
-} __attribute__ ((packed));
-
-/* er_Type board type bits */
-#define ERT_TYPEMASK   0xc0
-#define ERT_ZORROII    0xc0
-#define ERT_ZORROIII   0x80
-
-/* other bits defined in er_Type */
-#define ERTB_MEMLIST   5               /* Link RAM into free memory list */
-#define ERTF_MEMLIST   (1<<5)
-
-struct ConfigDev {
-    struct Node                cd_Node;
-    __u8               cd_Flags;       /* (read/write) */
-    __u8               cd_Pad;         /* reserved */
-    struct ExpansionRom cd_Rom;                /* copy of board's expansion ROM */
-    void               *cd_BoardAddr;  /* where in memory the board was placed */
-    __u32              cd_BoardSize;   /* size of board in bytes */
-    __u16              cd_SlotAddr;    /* which slot number (PRIVATE) */
-    __u16              cd_SlotSize;    /* number of slots (PRIVATE) */
-    void               *cd_Driver;     /* pointer to node of driver */
-    struct ConfigDev   *cd_NextCD;     /* linked list of drivers to config */
-    __u32              cd_Unused[4];   /* for whatever the driver wants */
-} __attribute__ ((packed));
-
-#define ZORRO_NUM_AUTO         16
-
-#ifdef __KERNEL__
+#include <uapi/linux/zorro.h>
 
+#include <linux/device.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/mod_devicetable.h>
@@ -175,7 +78,23 @@ static inline struct zorro_driver *zorro_dev_driver(const struct zorro_dev *z)
 
 
 extern unsigned int zorro_num_autocon; /* # of autoconfig devices found */
-extern struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
+extern struct zorro_dev *zorro_autocon;
+
+
+    /*
+     * Minimal information about a Zorro device, passed from bootinfo
+     * Only available temporarily, i.e. until initmem has been freed!
+     */
+
+struct zorro_dev_init {
+       struct ExpansionRom rom;
+       u16 slotaddr;
+       u16 slotsize;
+       u32 boardaddr;
+       u32 boardsize;
+};
+
+extern struct zorro_dev_init zorro_autocon_init[ZORRO_NUM_AUTO] __initdata;
 
 
     /*
@@ -229,6 +148,4 @@ extern DECLARE_BITMAP(zorro_unused_z2ram, 128);
 #define Z2RAM_CHUNKSHIFT       (16)
 
 
-#endif /* __KERNEL__ */
-
 #endif /* _LINUX_ZORRO_H */
index bd8218b15009a810af8abd5df5a4bcad31dfdb20..941055e9d125af3bfe5a6915ff551e0bb1532445 100644 (file)
@@ -83,7 +83,7 @@ struct vb2_fileio_data;
 struct vb2_mem_ops {
        void            *(*alloc)(void *alloc_ctx, unsigned long size, gfp_t gfp_flags);
        void            (*put)(void *buf_priv);
-       struct dma_buf *(*get_dmabuf)(void *buf_priv);
+       struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags);
 
        void            *(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
                                        unsigned long size, int write);
index 217bc5bfc6c6e99cf52117312ceda95c98f005a6..5a25f36fe3a7cb50a388e309df9b5905f013b6b4 100644 (file)
@@ -473,7 +473,7 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
 int ip_ra_control(struct sock *sk, unsigned char on,
                  void (*destructor)(struct sock *));
 
-int ip_recv_error(struct sock *sk, struct msghdr *msg, int len);
+int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len);
 void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
                   u32 info, u8 *payload);
 void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
index 2a5f668cd6836fae6ff45e551f8dacfd93dacd8e..eb198acaac1d5f42b53ac97838511563fe7e874b 100644 (file)
@@ -776,8 +776,10 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
 
 int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len);
 
-int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
-int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);
+int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
+                   int *addr_len);
+int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
+                    int *addr_len);
 void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
                     u32 info, u8 *payload);
 void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
index 3f67704f3747281b3ad0852fd5d69dcd49c9b01c..90f48417b03dac91259aefe18d79c63145a23849 100644 (file)
@@ -31,7 +31,8 @@
 
 /* Compatibility glue so we can support IPv6 when it's compiled as a module */
 struct pingv6_ops {
-       int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len);
+       int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len,
+                              int *addr_len);
        int (*ip6_datagram_recv_ctl)(struct sock *sk, struct msghdr *msg,
                                     struct sk_buff *skb);
        int (*icmpv6_err_convert)(u8 type, u8 code, int *err);
index 2174d8da0770a5285d3d937a1174eb9e52dd2a27..ea0ca5f6e629cc8eb2e05e53b1531379617b3b79 100644 (file)
@@ -629,6 +629,7 @@ struct sctp_chunk {
 #define SCTP_NEED_FRTX 0x1
 #define SCTP_DONT_FRTX 0x2
        __u16   rtt_in_progress:1,      /* This chunk used for RTT calc? */
+               resent:1,               /* Has this chunk ever been resent. */
                has_tsn:1,              /* Does this chunk have a TSN yet? */
                has_ssn:1,              /* Does this chunk have a SSN yet? */
                singleton:1,            /* Only chunk in the packet? */
index 5d6ed6cf12cc8c2c984e2565b028a55bedb001d8..a572083c77cbf854e4328c178af2db7e3697bff7 100644 (file)
@@ -311,6 +311,7 @@ enum iscsi_param_type {
        ISCSI_NET_PARAM,        /* iscsi_net_param */
        ISCSI_FLASHNODE_PARAM,  /* iscsi_flashnode_param */
        ISCSI_CHAP_PARAM,       /* iscsi_chap_param */
+       ISCSI_IFACE_PARAM,      /* iscsi_iface_param */
 };
 
 /* structure for minimalist usecase */
@@ -383,28 +384,106 @@ struct iscsi_path {
 #define ISCSI_VLAN_DISABLE     0x01
 #define ISCSI_VLAN_ENABLE      0x02
 
+/* iscsi generic enable/disabled setting for various features */
+#define ISCSI_NET_PARAM_DISABLE                0x01
+#define ISCSI_NET_PARAM_ENABLE         0x02
+
 /* iSCSI network params */
 enum iscsi_net_param {
        ISCSI_NET_PARAM_IPV4_ADDR               = 1,
-       ISCSI_NET_PARAM_IPV4_SUBNET             = 2,
-       ISCSI_NET_PARAM_IPV4_GW                 = 3,
-       ISCSI_NET_PARAM_IPV4_BOOTPROTO          = 4,
-       ISCSI_NET_PARAM_MAC                     = 5,
-       ISCSI_NET_PARAM_IPV6_LINKLOCAL          = 6,
-       ISCSI_NET_PARAM_IPV6_ADDR               = 7,
-       ISCSI_NET_PARAM_IPV6_ROUTER             = 8,
-       ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG       = 9,
-       ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG  = 10,
-       ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG     = 11,
-       ISCSI_NET_PARAM_IFACE_ENABLE            = 12,
-       ISCSI_NET_PARAM_VLAN_ID                 = 13,
-       ISCSI_NET_PARAM_VLAN_PRIORITY           = 14,
-       ISCSI_NET_PARAM_VLAN_ENABLED            = 15,
-       ISCSI_NET_PARAM_VLAN_TAG                = 16,
-       ISCSI_NET_PARAM_IFACE_TYPE              = 17,
-       ISCSI_NET_PARAM_IFACE_NAME              = 18,
-       ISCSI_NET_PARAM_MTU                     = 19,
-       ISCSI_NET_PARAM_PORT                    = 20,
+       ISCSI_NET_PARAM_IPV4_SUBNET,
+       ISCSI_NET_PARAM_IPV4_GW,
+       ISCSI_NET_PARAM_IPV4_BOOTPROTO,
+       ISCSI_NET_PARAM_MAC,
+       ISCSI_NET_PARAM_IPV6_LINKLOCAL,
+       ISCSI_NET_PARAM_IPV6_ADDR,
+       ISCSI_NET_PARAM_IPV6_ROUTER,
+       ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG,
+       ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG,
+       ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG,
+       ISCSI_NET_PARAM_IFACE_ENABLE,
+       ISCSI_NET_PARAM_VLAN_ID,
+       ISCSI_NET_PARAM_VLAN_PRIORITY,
+       ISCSI_NET_PARAM_VLAN_ENABLED,
+       ISCSI_NET_PARAM_VLAN_TAG,
+       ISCSI_NET_PARAM_IFACE_TYPE,
+       ISCSI_NET_PARAM_IFACE_NAME,
+       ISCSI_NET_PARAM_MTU,
+       ISCSI_NET_PARAM_PORT,
+       ISCSI_NET_PARAM_IPADDR_STATE,
+       ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE,
+       ISCSI_NET_PARAM_IPV6_ROUTER_STATE,
+       ISCSI_NET_PARAM_DELAYED_ACK_EN,
+       ISCSI_NET_PARAM_TCP_NAGLE_DISABLE,
+       ISCSI_NET_PARAM_TCP_WSF_DISABLE,
+       ISCSI_NET_PARAM_TCP_WSF,
+       ISCSI_NET_PARAM_TCP_TIMER_SCALE,
+       ISCSI_NET_PARAM_TCP_TIMESTAMP_EN,
+       ISCSI_NET_PARAM_CACHE_ID,
+       ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN,
+       ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN,
+       ISCSI_NET_PARAM_IPV4_TOS_EN,
+       ISCSI_NET_PARAM_IPV4_TOS,
+       ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN,
+       ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN,
+       ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID,
+       ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN,
+       ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN,
+       ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID,
+       ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN,
+       ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE,
+       ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN,
+       ISCSI_NET_PARAM_IPV4_TTL,
+       ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN,
+       ISCSI_NET_PARAM_IPV6_MLD_EN,
+       ISCSI_NET_PARAM_IPV6_FLOW_LABEL,
+       ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS,
+       ISCSI_NET_PARAM_IPV6_HOP_LIMIT,
+       ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO,
+       ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME,
+       ISCSI_NET_PARAM_IPV6_ND_STALE_TMO,
+       ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT,
+       ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU,
+       ISCSI_NET_PARAM_REDIRECT_EN,
+};
+
+enum iscsi_ipaddress_state {
+       ISCSI_IPDDRESS_STATE_UNCONFIGURED,
+       ISCSI_IPDDRESS_STATE_ACQUIRING,
+       ISCSI_IPDDRESS_STATE_TENTATIVE,
+       ISCSI_IPDDRESS_STATE_VALID,
+       ISCSI_IPDDRESS_STATE_DISABLING,
+       ISCSI_IPDDRESS_STATE_INVALID,
+       ISCSI_IPDDRESS_STATE_DEPRECATED,
+};
+
+enum iscsi_router_state {
+       ISCSI_ROUTER_STATE_UNKNOWN,
+       ISCSI_ROUTER_STATE_ADVERTISED,
+       ISCSI_ROUTER_STATE_MANUAL,
+       ISCSI_ROUTER_STATE_STALE,
+};
+
+/* iSCSI specific settings params for iface */
+enum iscsi_iface_param {
+       ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO,
+       ISCSI_IFACE_PARAM_HDRDGST_EN,
+       ISCSI_IFACE_PARAM_DATADGST_EN,
+       ISCSI_IFACE_PARAM_IMM_DATA_EN,
+       ISCSI_IFACE_PARAM_INITIAL_R2T_EN,
+       ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN,
+       ISCSI_IFACE_PARAM_PDU_INORDER_EN,
+       ISCSI_IFACE_PARAM_ERL,
+       ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH,
+       ISCSI_IFACE_PARAM_FIRST_BURST,
+       ISCSI_IFACE_PARAM_MAX_R2T,
+       ISCSI_IFACE_PARAM_MAX_BURST,
+       ISCSI_IFACE_PARAM_CHAP_AUTH_EN,
+       ISCSI_IFACE_PARAM_BIDI_CHAP_EN,
+       ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL,
+       ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN,
+       ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN,
+       ISCSI_IFACE_PARAM_INITIATOR_NAME,
 };
 
 enum iscsi_conn_state {
index 546084964d554fc8e463e9244558fce4e4eb8563..fe3b58e836c881b7598d37c46d56cbd6d1b81b6e 100644 (file)
@@ -475,6 +475,9 @@ struct scsi_host_template {
         */
        unsigned ordered_tag:1;
 
+       /* True if the controller does not support WRITE SAME */
+       unsigned no_write_same:1;
+
        /*
         * Countdown for host blocking with no commands outstanding.
         */
@@ -677,6 +680,9 @@ struct Scsi_Host {
        /* Don't resume host in EH */
        unsigned eh_noresume:1;
 
+       /* The controller does not support WRITE SAME */
+       unsigned no_write_same:1;
+
        /*
         * Optional work queue to be utilized by the transport
         */
index fe7c8f3e93f81dad733c6cc6a08c2d8a65c3a8df..2ac11feab6f39f8a65653fdc54d397c036f51e30 100644 (file)
@@ -478,4 +478,7 @@ iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
 extern struct device *
 iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess);
 
+extern char *
+iscsi_get_ipaddress_state_name(enum iscsi_ipaddress_state port_state);
+extern char *iscsi_get_router_state_name(enum iscsi_router_state router_state);
 #endif
index 7c2be4a51894484e8a05fe08d11751c1cc7e04ab..bbabf84bdb443114fcd33d4b3a4bbc3172385a8b 100644 (file)
@@ -16,17 +16,11 @@ struct cs42l52_platform_data {
        /* MICBIAS Level. Check datasheet Pg48 */
        unsigned int micbias_lvl;
 
-       /* MICA mode selection 0=Single 1=Differential */
-       unsigned int mica_cfg;
+       /* MICA mode selection Differential or Single-ended */
+       bool mica_diff_cfg;
 
-       /* MICB mode selection 0=Single 1=Differential */
-       unsigned int micb_cfg;
-
-       /* MICA Select 0=MIC1A 1=MIC2A */
-       unsigned int mica_sel;
-
-       /* MICB Select 0=MIC2A 1=MIC2B */
-       unsigned int micb_sel;
+       /* MICB mode selection Differential or Single-ended */
+       bool micb_diff_cfg;
 
        /* Charge Pump Freq. Check datasheet Pg73 */
        unsigned int chgfreq;
index 15017311f2e9f0c9c2dba9bf41c00f01763cee0f..4ef986cab182ec62565ced32541c5f301058c2c7 100644 (file)
@@ -140,6 +140,10 @@ int snd_dmaengine_pcm_register(struct device *dev,
        unsigned int flags);
 void snd_dmaengine_pcm_unregister(struct device *dev);
 
+int devm_snd_dmaengine_pcm_register(struct device *dev,
+       const struct snd_dmaengine_pcm_config *config,
+       unsigned int flags);
+
 int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct dma_slave_config *slave_config);
index 12afab18945d056709df7495b75b0da6c0155426..a818ff76b1384ced8e4e6be85b6d0a6786f557e9 100644 (file)
@@ -18,7 +18,7 @@
 #define RSND_GEN1_ADG  1
 #define RSND_GEN1_SSI  2
 
-#define RSND_GEN2_SRU  0
+#define RSND_GEN2_SCU  0
 #define RSND_GEN2_ADG  1
 #define RSND_GEN2_SSIU 2
 #define RSND_GEN2_SSI  3
index 800c101bb096fd6f5c1170ebbdce1ab06cead062..243d3b689699791ae257b5edc48f5c6bb9f34bfd 100644 (file)
@@ -220,6 +220,8 @@ struct snd_soc_dai_driver {
        struct snd_soc_pcm_stream capture;
        struct snd_soc_pcm_stream playback;
        unsigned int symmetric_rates:1;
+       unsigned int symmetric_channels:1;
+       unsigned int symmetric_samplebits:1;
 
        /* probe ordering - for components with runtime dependencies */
        int probe_order;
@@ -244,6 +246,8 @@ struct snd_soc_dai {
        unsigned int capture_active:1;          /* stream is in use */
        unsigned int playback_active:1;         /* stream is in use */
        unsigned int symmetric_rates:1;
+       unsigned int symmetric_channels:1;
+       unsigned int symmetric_samplebits:1;
        struct snd_pcm_runtime *runtime;
        unsigned int active;
        unsigned char probed:1;
@@ -258,6 +262,8 @@ struct snd_soc_dai {
 
        /* Symmetry data - only valid if symmetry is being enforced */
        unsigned int rate;
+       unsigned int channels;
+       unsigned int sample_bits;
 
        /* parent platform/codec */
        struct snd_soc_platform *platform;
index 2037c45adfe648e907fa86290f7dfea847989c20..56ebdfca627375b1a7ec7d5ce5606bc124ecdf42 100644 (file)
@@ -104,7 +104,8 @@ struct device;
        SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
        .kcontrol_news = wcontrols, .num_kcontrols = 1}
 #define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
-{      .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, \
+{      .id = snd_soc_dapm_mux, .name = wname, \
+       SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
        .kcontrol_news = wcontrols, .num_kcontrols = 1}
 #define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \
 {      .id = snd_soc_dapm_virt_mux, .name = wname, \
index 1f741cb24f337c3e4662c2ff2cd45f78985c54c1..5a049d969c59cd0712940501974e4b23292f0b9c 100644 (file)
@@ -334,9 +334,7 @@ struct snd_soc_jack_pin;
 #include <sound/soc-dapm.h>
 #include <sound/soc-dpcm.h>
 
-#ifdef CONFIG_GPIOLIB
 struct snd_soc_jack_gpio;
-#endif
 
 typedef int (*hw_write_t)(void *,const char* ,int);
 
@@ -446,6 +444,17 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
                        struct snd_soc_jack_gpio *gpios);
 void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
                        struct snd_soc_jack_gpio *gpios);
+#else
+static inline int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
+                                        struct snd_soc_jack_gpio *gpios)
+{
+       return 0;
+}
+
+static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
+                                          struct snd_soc_jack_gpio *gpios)
+{
+}
 #endif
 
 /* codec register bit access */
@@ -580,7 +589,6 @@ struct snd_soc_jack_zone {
  *                    to provide more complex checks (eg, reading an
  *                    ADC).
  */
-#ifdef CONFIG_GPIOLIB
 struct snd_soc_jack_gpio {
        unsigned int gpio;
        const char *name;
@@ -594,7 +602,6 @@ struct snd_soc_jack_gpio {
 
        int (*jack_status_check)(void);
 };
-#endif
 
 struct snd_soc_jack {
        struct mutex mutex;
@@ -879,6 +886,8 @@ struct snd_soc_dai_link {
 
        /* Symmetry requirements */
        unsigned int symmetric_rates:1;
+       unsigned int symmetric_channels:1;
+       unsigned int symmetric_samplebits:1;
 
        /* Do not create a PCM for this DAI link (Backend link) */
        unsigned int no_pcm:1;
index e2b9576d00e24772580a601a268e42bdc46e349e..095c6e4fe1e87ea02e3c6d9eeecdb66ddc1a1367 100644 (file)
@@ -24,10 +24,10 @@ DECLARE_EVENT_CLASS(bcache_request,
                __entry->dev            = bio->bi_bdev->bd_dev;
                __entry->orig_major     = d->disk->major;
                __entry->orig_minor     = d->disk->first_minor;
-               __entry->sector         = bio->bi_sector;
-               __entry->orig_sector    = bio->bi_sector - 16;
-               __entry->nr_sector      = bio->bi_size >> 9;
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               __entry->sector         = bio->bi_iter.bi_sector;
+               __entry->orig_sector    = bio->bi_iter.bi_sector - 16;
+               __entry->nr_sector      = bio->bi_iter.bi_size >> 9;
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
        ),
 
        TP_printk("%d,%d %s %llu + %u (from %d,%d @ %llu)",
@@ -99,9 +99,9 @@ DECLARE_EVENT_CLASS(bcache_bio,
 
        TP_fast_assign(
                __entry->dev            = bio->bi_bdev->bd_dev;
-               __entry->sector         = bio->bi_sector;
-               __entry->nr_sector      = bio->bi_size >> 9;
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               __entry->sector         = bio->bi_iter.bi_sector;
+               __entry->nr_sector      = bio->bi_iter.bi_size >> 9;
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
        ),
 
        TP_printk("%d,%d  %s %llu + %u",
@@ -134,9 +134,9 @@ TRACE_EVENT(bcache_read,
 
        TP_fast_assign(
                __entry->dev            = bio->bi_bdev->bd_dev;
-               __entry->sector         = bio->bi_sector;
-               __entry->nr_sector      = bio->bi_size >> 9;
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               __entry->sector         = bio->bi_iter.bi_sector;
+               __entry->nr_sector      = bio->bi_iter.bi_size >> 9;
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
                __entry->cache_hit = hit;
                __entry->bypass = bypass;
        ),
@@ -162,9 +162,9 @@ TRACE_EVENT(bcache_write,
 
        TP_fast_assign(
                __entry->dev            = bio->bi_bdev->bd_dev;
-               __entry->sector         = bio->bi_sector;
-               __entry->nr_sector      = bio->bi_size >> 9;
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               __entry->sector         = bio->bi_iter.bi_sector;
+               __entry->nr_sector      = bio->bi_iter.bi_size >> 9;
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
                __entry->writeback = writeback;
                __entry->bypass = bypass;
        ),
index 4c2301d2ef1aa979ea0d6594ad1b6404368b920b..e76ae19a8d6fe65705e48104bb8212ed8bddb546 100644 (file)
@@ -243,9 +243,9 @@ TRACE_EVENT(block_bio_bounce,
        TP_fast_assign(
                __entry->dev            = bio->bi_bdev ?
                                          bio->bi_bdev->bd_dev : 0;
-               __entry->sector         = bio->bi_sector;
+               __entry->sector         = bio->bi_iter.bi_sector;
                __entry->nr_sector      = bio_sectors(bio);
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
                memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
        ),
 
@@ -280,10 +280,10 @@ TRACE_EVENT(block_bio_complete,
 
        TP_fast_assign(
                __entry->dev            = bio->bi_bdev->bd_dev;
-               __entry->sector         = bio->bi_sector;
+               __entry->sector         = bio->bi_iter.bi_sector;
                __entry->nr_sector      = bio_sectors(bio);
                __entry->error          = error;
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
        ),
 
        TP_printk("%d,%d %s %llu + %u [%d]",
@@ -308,9 +308,9 @@ DECLARE_EVENT_CLASS(block_bio_merge,
 
        TP_fast_assign(
                __entry->dev            = bio->bi_bdev->bd_dev;
-               __entry->sector         = bio->bi_sector;
+               __entry->sector         = bio->bi_iter.bi_sector;
                __entry->nr_sector      = bio_sectors(bio);
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
                memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
        ),
 
@@ -375,9 +375,9 @@ TRACE_EVENT(block_bio_queue,
 
        TP_fast_assign(
                __entry->dev            = bio->bi_bdev->bd_dev;
-               __entry->sector         = bio->bi_sector;
+               __entry->sector         = bio->bi_iter.bi_sector;
                __entry->nr_sector      = bio_sectors(bio);
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
                memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
        ),
 
@@ -403,7 +403,7 @@ DECLARE_EVENT_CLASS(block_get_rq,
 
        TP_fast_assign(
                __entry->dev            = bio ? bio->bi_bdev->bd_dev : 0;
-               __entry->sector         = bio ? bio->bi_sector : 0;
+               __entry->sector         = bio ? bio->bi_iter.bi_sector : 0;
                __entry->nr_sector      = bio ? bio_sectors(bio) : 0;
                blk_fill_rwbs(__entry->rwbs,
                              bio ? bio->bi_rw : 0, __entry->nr_sector);
@@ -538,9 +538,9 @@ TRACE_EVENT(block_split,
 
        TP_fast_assign(
                __entry->dev            = bio->bi_bdev->bd_dev;
-               __entry->sector         = bio->bi_sector;
+               __entry->sector         = bio->bi_iter.bi_sector;
                __entry->new_sector     = new_sector;
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
                memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
        ),
 
@@ -579,11 +579,11 @@ TRACE_EVENT(block_bio_remap,
 
        TP_fast_assign(
                __entry->dev            = bio->bi_bdev->bd_dev;
-               __entry->sector         = bio->bi_sector;
+               __entry->sector         = bio->bi_iter.bi_sector;
                __entry->nr_sector      = bio_sectors(bio);
                __entry->old_dev        = dev;
                __entry->old_sector     = from;
-               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+               blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
        ),
 
        TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
index e0dc355fa3179658a2b99660fd6fca0ca0a80937..67f38faac589ad52ac5850e5af602799753b8d29 100644 (file)
                { META,         "META" },                               \
                { META_FLUSH,   "META_FLUSH" })
 
-#define show_bio_type(type)                                            \
-       __print_symbolic(type,                                          \
-               { READ,         "READ" },                               \
-               { READA,        "READAHEAD" },                          \
-               { READ_SYNC,    "READ_SYNC" },                          \
-               { WRITE,        "WRITE" },                              \
-               { WRITE_SYNC,   "WRITE_SYNC" },                         \
-               { WRITE_FLUSH,  "WRITE_FLUSH" },                        \
-               { WRITE_FUA,    "WRITE_FUA" })
+#define F2FS_BIO_MASK(t)       (t & (READA | WRITE_FLUSH_FUA))
+#define F2FS_BIO_EXTRA_MASK(t) (t & (REQ_META | REQ_PRIO))
+
+#define show_bio_type(type)    show_bio_base(type), show_bio_extra(type)
+
+#define show_bio_base(type)                                            \
+       __print_symbolic(F2FS_BIO_MASK(type),                           \
+               { READ,                 "READ" },                       \
+               { READA,                "READAHEAD" },                  \
+               { READ_SYNC,            "READ_SYNC" },                  \
+               { WRITE,                "WRITE" },                      \
+               { WRITE_SYNC,           "WRITE_SYNC" },                 \
+               { WRITE_FLUSH,          "WRITE_FLUSH" },                \
+               { WRITE_FUA,            "WRITE_FUA" },                  \
+               { WRITE_FLUSH_FUA,      "WRITE_FLUSH_FUA" })
+
+#define show_bio_extra(type)                                           \
+       __print_symbolic(F2FS_BIO_EXTRA_MASK(type),                     \
+               { REQ_META,             "(M)" },                        \
+               { REQ_PRIO,             "(P)" },                        \
+               { REQ_META | REQ_PRIO,  "(MP)" },                       \
+               { 0, " \b" })
 
 #define show_data_type(type)                                           \
        __print_symbolic(type,                                          \
@@ -421,7 +434,7 @@ TRACE_EVENT(f2fs_truncate_partial_nodes,
                __entry->err)
 );
 
-TRACE_EVENT_CONDITION(f2fs_readpage,
+TRACE_EVENT_CONDITION(f2fs_submit_page_bio,
 
        TP_PROTO(struct page *page, sector_t blkaddr, int type),
 
@@ -446,7 +459,7 @@ TRACE_EVENT_CONDITION(f2fs_readpage,
        ),
 
        TP_printk("dev = (%d,%d), ino = %lu, page_index = 0x%lx, "
-               "blkaddr = 0x%llx, bio_type = %s",
+               "blkaddr = 0x%llx, bio_type = %s%s",
                show_dev_ino(__entry),
                (unsigned long)__entry->index,
                (unsigned long long)__entry->blkaddr,
@@ -598,36 +611,54 @@ TRACE_EVENT(f2fs_reserve_new_block,
                __entry->ofs_in_node)
 );
 
-TRACE_EVENT(f2fs_do_submit_bio,
+DECLARE_EVENT_CLASS(f2fs__submit_bio,
 
-       TP_PROTO(struct super_block *sb, int btype, bool sync, struct bio *bio),
+       TP_PROTO(struct super_block *sb, int rw, int type, struct bio *bio),
 
-       TP_ARGS(sb, btype, sync, bio),
+       TP_ARGS(sb, rw, type, bio),
 
        TP_STRUCT__entry(
                __field(dev_t,  dev)
-               __field(int,    btype)
-               __field(bool,   sync)
+               __field(int,    rw)
+               __field(int,    type)
                __field(sector_t,       sector)
                __field(unsigned int,   size)
        ),
 
        TP_fast_assign(
                __entry->dev            = sb->s_dev;
-               __entry->btype          = btype;
-               __entry->sync           = sync;
-               __entry->sector         = bio->bi_sector;
-               __entry->size           = bio->bi_size;
+               __entry->rw             = rw;
+               __entry->type           = type;
+               __entry->sector         = bio->bi_iter.bi_sector;
+               __entry->size           = bio->bi_iter.bi_size;
        ),
 
-       TP_printk("dev = (%d,%d), type = %s, io = %s, sector = %lld, size = %u",
+       TP_printk("dev = (%d,%d), %s%s, %s, sector = %lld, size = %u",
                show_dev(__entry),
-               show_block_type(__entry->btype),
-               __entry->sync ? "sync" : "no sync",
+               show_bio_type(__entry->rw),
+               show_block_type(__entry->type),
                (unsigned long long)__entry->sector,
                __entry->size)
 );
 
+DEFINE_EVENT_CONDITION(f2fs__submit_bio, f2fs_submit_write_bio,
+
+       TP_PROTO(struct super_block *sb, int rw, int type, struct bio *bio),
+
+       TP_ARGS(sb, rw, type, bio),
+
+       TP_CONDITION(bio)
+);
+
+DEFINE_EVENT_CONDITION(f2fs__submit_bio, f2fs_submit_read_bio,
+
+       TP_PROTO(struct super_block *sb, int rw, int type, struct bio *bio),
+
+       TP_ARGS(sb, rw, type, bio),
+
+       TP_CONDITION(bio)
+);
+
 DECLARE_EVENT_CLASS(f2fs__page,
 
        TP_PROTO(struct page *page, int type),
@@ -674,15 +705,16 @@ DEFINE_EVENT(f2fs__page, f2fs_vm_page_mkwrite,
        TP_ARGS(page, type)
 );
 
-TRACE_EVENT(f2fs_submit_write_page,
+TRACE_EVENT(f2fs_submit_page_mbio,
 
-       TP_PROTO(struct page *page, block_t blk_addr, int type),
+       TP_PROTO(struct page *page, int rw, int type, block_t blk_addr),
 
-       TP_ARGS(page, blk_addr, type),
+       TP_ARGS(page, rw, type, blk_addr),
 
        TP_STRUCT__entry(
                __field(dev_t,  dev)
                __field(ino_t,  ino)
+               __field(int, rw)
                __field(int, type)
                __field(pgoff_t, index)
                __field(block_t, block)
@@ -691,13 +723,15 @@ TRACE_EVENT(f2fs_submit_write_page,
        TP_fast_assign(
                __entry->dev    = page->mapping->host->i_sb->s_dev;
                __entry->ino    = page->mapping->host->i_ino;
+               __entry->rw     = rw;
                __entry->type   = type;
                __entry->index  = page->index;
                __entry->block  = blk_addr;
        ),
 
-       TP_printk("dev = (%d,%d), ino = %lu, %s, index = %lu, blkaddr = 0x%llx",
+       TP_printk("dev = (%d,%d), ino = %lu, %s%s, %s, index = %lu, blkaddr = 0x%llx",
                show_dev_ino(__entry),
+               show_bio_type(__entry->rw),
                show_block_type(__entry->type),
                (unsigned long)__entry->index,
                (unsigned long long)__entry->block)
@@ -727,6 +761,29 @@ TRACE_EVENT(f2fs_write_checkpoint,
                __entry->msg)
 );
 
+TRACE_EVENT(f2fs_issue_discard,
+
+       TP_PROTO(struct super_block *sb, block_t blkstart, block_t blklen),
+
+       TP_ARGS(sb, blkstart, blklen),
+
+       TP_STRUCT__entry(
+               __field(dev_t,  dev)
+               __field(block_t, blkstart)
+               __field(block_t, blklen)
+       ),
+
+       TP_fast_assign(
+               __entry->dev    = sb->s_dev;
+               __entry->blkstart = blkstart;
+               __entry->blklen = blklen;
+       ),
+
+       TP_printk("dev = (%d,%d), blkstart = 0x%llx, blklen = 0x%llx",
+               show_dev(__entry),
+               (unsigned long long)__entry->blkstart,
+               (unsigned long long)__entry->blklen)
+);
 #endif /* _TRACE_F2FS_H */
 
  /* This part must be outside protection */
index 52594b20179e0d8459a0810c7fbcc75fceda84ff..5c38606613d89a06c361a56054e97031c391c2d3 100644 (file)
 #define TRACE_EVENT_FLAGS(name, value)                                 \
        __TRACE_EVENT_FLAGS(name, value)
 
+#undef TRACE_EVENT_PERF_PERM
+#define TRACE_EVENT_PERF_PERM(name, expr...)                           \
+       __TRACE_EVENT_PERF_PERM(name, expr)
+
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
 
 #undef TRACE_EVENT_FLAGS
 #define TRACE_EVENT_FLAGS(event, flag)
 
+#undef TRACE_EVENT_PERF_PERM
+#define TRACE_EVENT_PERF_PERM(event, expr...)
+
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
 /*
@@ -372,7 +379,8 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call)   \
        __data_size += (len) * sizeof(type);
 
 #undef __string
-#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1)
+#define __string(item, src) __dynamic_array(char, item,                        \
+                   strlen((src) ? (const char *)(src) : "(null)") + 1)
 
 #undef DECLARE_EVENT_CLASS
 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
@@ -501,7 +509,7 @@ static inline notrace int ftrace_get_offsets_##call(                        \
 
 #undef __assign_str
 #define __assign_str(dst, src)                                         \
-       strcpy(__get_str(dst), src);
+       strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)");
 
 #undef TP_fast_assign
 #define TP_fast_assign(args...) args
index 3a4e97bd860771b6ad8e3b5d026a35200fcad4d3..52aed893710a126e979cec558239e55c76cb2c59 100644 (file)
@@ -222,6 +222,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_GEM_SET_CACHING       0x2f
 #define DRM_I915_GEM_GET_CACHING       0x30
 #define DRM_I915_REG_READ              0x31
+#define DRM_I915_GET_RESET_STATS       0x32
 
 #define DRM_IOCTL_I915_INIT            DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH           DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -271,6 +272,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_CONTEXT_CREATE      DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
 #define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY     DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
 #define DRM_IOCTL_I915_REG_READ                        DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
+#define DRM_IOCTL_I915_GET_RESET_STATS         DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -1030,4 +1032,21 @@ struct drm_i915_reg_read {
        __u64 offset;
        __u64 val; /* Return value */
 };
+
+struct drm_i915_reset_stats {
+       __u32 ctx_id;
+       __u32 flags;
+
+       /* All resets since boot/module reload, for all contexts */
+       __u32 reset_count;
+
+       /* Number of batches lost when active in GPU, for this context */
+       __u32 batch_active;
+
+       /* Number of batches lost pending for execution, for this context */
+       __u32 batch_pending;
+
+       __u32 pad;
+};
+
 #endif /* _UAPI_I915_DRM_H_ */
index 33d2b8fe166dafcd8dd39c5b7a092b8b3d5befa6..3ce25b5d75a9facfd047a526d3c3af618169e488 100644 (file)
@@ -426,3 +426,5 @@ header-y += x25.h
 header-y += xattr.h
 header-y += xfrm.h
 header-y += hw_breakpoint.h
+header-y += zorro.h
+header-y += zorro_ids.h
index 1af72d8228e04db8c1d6de05cacfa1bfd4a577b7..c3363ba1ae057f66dc5b878ee9fde7899857c450 100644 (file)
@@ -28,6 +28,7 @@ struct genlmsghdr {
 #define GENL_ID_GENERATE       0
 #define GENL_ID_CTRL           NLMSG_MIN_TYPE
 #define GENL_ID_VFS_DQUOT      (NLMSG_MIN_TYPE + 1)
+#define GENL_ID_PMCRAID                (NLMSG_MIN_TYPE + 2)
 
 /**************************************************************************
  * Controller
index b78566f59abaa54528ed86acf85eb7e7b3f305fa..6db460121f84845d4026420cdc2fd12fc4f1497e 100644 (file)
@@ -488,7 +488,9 @@ enum {
        IFLA_HSR_UNSPEC,
        IFLA_HSR_SLAVE1,
        IFLA_HSR_SLAVE2,
-       IFLA_HSR_MULTICAST_SPEC,
+       IFLA_HSR_MULTICAST_SPEC,        /* Last byte of supervision addr */
+       IFLA_HSR_SUPERVISION_ADDR,      /* Supervision frame multicast addr */
+       IFLA_HSR_SEQ_NR,
        __IFLA_HSR_MAX,
 };
 
index a3726275876dc509bfa99a01b8113385c1fb2d2f..7bacdb514377d28b2a77ec200bef2a8a27034fa9 100644 (file)
@@ -719,6 +719,8 @@ struct input_keymap_entry {
 #define BTN_DPAD_LEFT          0x222
 #define BTN_DPAD_RIGHT         0x223
 
+#define KEY_ALS_TOGGLE         0x230   /* Ambient light sensor */
+
 #define BTN_TRIGGER_HAPPY              0x2c0
 #define BTN_TRIGGER_HAPPY1             0x2c0
 #define BTN_TRIGGER_HAPPY2             0x2c1
index 17e7d95e4f536b883cf98ebe363ed3734e9db958..6eb40244e0194110ce6c7e3878f738227ddfb013 100644 (file)
 
 #include <linux/virtio_ring.h>
 
-#ifndef __KERNEL__
-#define ALIGN(a, x)    (((a) + (x) - 1) & ~((x) - 1))
-#define __aligned(x)   __attribute__ ((aligned(x)))
-#endif
-
-#define mic_aligned_size(x) ALIGN(sizeof(x), 8)
+#define __mic_align(a, x) (((a) + (x) - 1) & ~((x) - 1))
 
 /**
  * struct mic_device_desc: Virtio device information shared between the
@@ -48,8 +43,8 @@ struct mic_device_desc {
        __u8 feature_len;
        __u8 config_len;
        __u8 status;
-       __u64 config[0];
-} __aligned(8);
+       __le64 config[0];
+} __attribute__ ((aligned(8)));
 
 /**
  * struct mic_device_ctrl: Per virtio device information in the device page
@@ -66,7 +61,7 @@ struct mic_device_desc {
  * @h2c_vdev_db: The doorbell number to be used by host. Set by guest.
  */
 struct mic_device_ctrl {
-       __u64 vdev;
+       __le64 vdev;
        __u8 config_change;
        __u8 vdev_reset;
        __u8 guest_ack;
@@ -74,7 +69,7 @@ struct mic_device_ctrl {
        __u8 used_address_updated;
        __s8 c2h_vdev_db;
        __s8 h2c_vdev_db;
-} __aligned(8);
+} __attribute__ ((aligned(8)));
 
 /**
  * struct mic_bootparam: Virtio device independent information in device page
@@ -87,13 +82,13 @@ struct mic_device_ctrl {
  * @shutdown_card: Set to 1 by the host when a card shutdown is initiated
  */
 struct mic_bootparam {
-       __u32 magic;
+       __le32 magic;
        __s8 c2h_shutdown_db;
        __s8 h2c_shutdown_db;
        __s8 h2c_config_db;
        __u8 shutdown_status;
        __u8 shutdown_card;
-} __aligned(8);
+} __attribute__ ((aligned(8)));
 
 /**
  * struct mic_device_page: High level representation of the device page
@@ -116,10 +111,10 @@ struct mic_device_page {
  * @num: The number of entries in the virtio_ring
  */
 struct mic_vqconfig {
-       __u64 address;
-       __u64 used_address;
-       __u16 num;
-} __aligned(8);
+       __le64 address;
+       __le64 used_address;
+       __le16 num;
+} __attribute__ ((aligned(8)));
 
 /*
  * The alignment to use between consumer and producer parts of vring.
@@ -154,7 +149,7 @@ struct mic_vqconfig {
  */
 struct _mic_vring_info {
        __u16 avail_idx;
-       int magic;
+       __le32 magic;
 };
 
 /**
@@ -173,15 +168,13 @@ struct mic_vring {
        int len;
 };
 
-#define mic_aligned_desc_size(d) ALIGN(mic_desc_size(d), 8)
+#define mic_aligned_desc_size(d) __mic_align(mic_desc_size(d), 8)
 
 #ifndef INTEL_MIC_CARD
 static inline unsigned mic_desc_size(const struct mic_device_desc *desc)
 {
-       return mic_aligned_size(*desc)
-               + desc->num_vq * mic_aligned_size(struct mic_vqconfig)
-               + desc->feature_len * 2
-               + desc->config_len;
+       return sizeof(*desc) + desc->num_vq * sizeof(struct mic_vqconfig)
+               + desc->feature_len * 2 + desc->config_len;
 }
 
 static inline struct mic_vqconfig *
@@ -201,8 +194,7 @@ static inline __u8 *mic_vq_configspace(const struct mic_device_desc *desc)
 }
 static inline unsigned mic_total_desc_size(struct mic_device_desc *desc)
 {
-       return mic_aligned_desc_size(desc) +
-               mic_aligned_size(struct mic_device_ctrl);
+       return mic_aligned_desc_size(desc) + sizeof(struct mic_device_ctrl);
 }
 #endif
 
index 4e31db4eea412dcfc3c56364d734b420f36afaef..f2159d30d1f5a24c76d6e939318603e72faa2637 100644 (file)
@@ -33,6 +33,7 @@ struct netlink_diag_ring {
 };
 
 enum {
+       /* NETLINK_DIAG_NONE, standard nl API requires this attribute!  */
        NETLINK_DIAG_MEMINFO,
        NETLINK_DIAG_GROUPS,
        NETLINK_DIAG_RX_RING,
index b2cc0cd9c4d9782433b4203e24480267257071ce..d08c63f3dd6ff47c7cf090927e91f27cfc0d767f 100644 (file)
@@ -29,6 +29,7 @@ struct packet_diag_msg {
 };
 
 enum {
+       /* PACKET_DIAG_NONE, standard nl API requires this attribute!  */
        PACKET_DIAG_INFO,
        PACKET_DIAG_MCLIST,
        PACKET_DIAG_RX_RING,
index b9e2a6a7446f077e528dd15fac8e8d97f0d9a232..1eb0b8dd18308481313b9d13b284f897a56188aa 100644 (file)
@@ -31,6 +31,7 @@ struct unix_diag_msg {
 };
 
 enum {
+       /* UNIX_DIAG_NONE, standard nl API requires this attribute!  */
        UNIX_DIAG_NAME,
        UNIX_DIAG_VFS,
        UNIX_DIAG_PEER,
diff --git a/include/uapi/linux/zorro.h b/include/uapi/linux/zorro.h
new file mode 100644 (file)
index 0000000..59d021b
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  linux/zorro.h -- Amiga AutoConfig (Zorro) Bus Definitions
+ *
+ *  Copyright (C) 1995--2003 Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive
+ *  for more details.
+ */
+
+#ifndef _UAPI_LINUX_ZORRO_H
+#define _UAPI_LINUX_ZORRO_H
+
+#include <linux/types.h>
+
+
+    /*
+     *  Each Zorro board has a 32-bit ID of the form
+     *
+     *      mmmmmmmmmmmmmmmmppppppppeeeeeeee
+     *
+     *  with
+     *
+     *      mmmmmmmmmmmmmmmm   16-bit Manufacturer ID (assigned by CBM (sigh))
+     *      pppppppp           8-bit Product ID (assigned by manufacturer)
+     *      eeeeeeee           8-bit Extended Product ID (currently only used
+     *                         for some GVP boards)
+     */
+
+
+#define ZORRO_MANUF(id)                ((id) >> 16)
+#define ZORRO_PROD(id)         (((id) >> 8) & 0xff)
+#define ZORRO_EPC(id)          ((id) & 0xff)
+
+#define ZORRO_ID(manuf, prod, epc) \
+       ((ZORRO_MANUF_##manuf << 16) | ((prod) << 8) | (epc))
+
+typedef __u32 zorro_id;
+
+
+/* Include the ID list */
+#include <linux/zorro_ids.h>
+
+
+    /*
+     *  GVP identifies most of its products through the 'extended product code'
+     *  (epc). The epc has to be ANDed with the GVP_PRODMASK before the
+     *  identification.
+     */
+
+#define GVP_PRODMASK           (0xf8)
+#define GVP_SCSICLKMASK                (0x01)
+
+enum GVP_flags {
+       GVP_IO                  = 0x01,
+       GVP_ACCEL               = 0x02,
+       GVP_SCSI                = 0x04,
+       GVP_24BITDMA            = 0x08,
+       GVP_25BITDMA            = 0x10,
+       GVP_NOBANK              = 0x20,
+       GVP_14MHZ               = 0x40,
+};
+
+
+struct Node {
+       __be32 ln_Succ;         /* Pointer to next (successor) */
+       __be32 ln_Pred;         /* Pointer to previous (predecessor) */
+       __u8   ln_Type;
+       __s8   ln_Pri;          /* Priority, for sorting */
+       __be32 ln_Name;         /* ID string, null terminated */
+} __packed;
+
+struct ExpansionRom {
+       /* -First 16 bytes of the expansion ROM */
+       __u8   er_Type;         /* Board type, size and flags */
+       __u8   er_Product;      /* Product number, assigned by manufacturer */
+       __u8   er_Flags;                /* Flags */
+       __u8   er_Reserved03;   /* Must be zero ($ff inverted) */
+       __be16 er_Manufacturer; /* Unique ID, ASSIGNED BY COMMODORE-AMIGA! */
+       __be32 er_SerialNumber; /* Available for use by manufacturer */
+       __be16 er_InitDiagVec;  /* Offset to optional "DiagArea" structure */
+       __u8   er_Reserved0c;
+       __u8   er_Reserved0d;
+       __u8   er_Reserved0e;
+       __u8   er_Reserved0f;
+} __packed;
+
+/* er_Type board type bits */
+#define ERT_TYPEMASK   0xc0
+#define ERT_ZORROII    0xc0
+#define ERT_ZORROIII   0x80
+
+/* other bits defined in er_Type */
+#define ERTB_MEMLIST   5               /* Link RAM into free memory list */
+#define ERTF_MEMLIST   (1<<5)
+
+struct ConfigDev {
+       struct Node     cd_Node;
+       __u8            cd_Flags;       /* (read/write) */
+       __u8            cd_Pad;         /* reserved */
+       struct ExpansionRom cd_Rom;     /* copy of board's expansion ROM */
+       __be32          cd_BoardAddr;   /* where in memory the board was placed */
+       __be32          cd_BoardSize;   /* size of board in bytes */
+       __be16          cd_SlotAddr;    /* which slot number (PRIVATE) */
+       __be16          cd_SlotSize;    /* number of slots (PRIVATE) */
+       __be32          cd_Driver;      /* pointer to node of driver */
+       __be32          cd_NextCD;      /* linked list of drivers to config */
+       __be32          cd_Unused[4];   /* for whatever the driver wants */
+} __packed;
+
+#define ZORRO_NUM_AUTO         16
+
+#endif /* _UAPI_LINUX_ZORRO_H */
index 79383d3aa5dc5f7fe64abdcaf7d511144ca016e5..93f344337172c44bc7d43fcf3a5241d1eca923c8 100644 (file)
@@ -848,7 +848,6 @@ config NUMA_BALANCING
 
 menuconfig CGROUPS
        boolean "Control Group support"
-       depends on EVENTFD
        help
          This option adds support for grouping sets of processes together, for
          use with process control subsystems such as Cpusets, CFS, memory
@@ -915,6 +914,7 @@ config MEMCG
        bool "Memory Resource Controller for Control Groups"
        depends on RESOURCE_COUNTERS
        select MM_OWNER
+       select EVENTFD
        help
          Provides a memory resource controller that manages both anonymous
          memory and page cache. (See Documentation/cgroups/memory.txt)
@@ -1154,7 +1154,6 @@ config UIDGID_STRICT_TYPE_CHECKS
 
 config SCHED_AUTOGROUP
        bool "Automatic process group scheduling"
-       select EVENTFD
        select CGROUPS
        select CGROUP_SCHED
        select FAIR_GROUP_SCHED
index 4c62513fe19fc8c4b938aeb8b3acb5158da2f976..f9f5fe3526acd69c0a1373e767d1cc725172f474 100644 (file)
 #include <linux/pid_namespace.h>
 #include <linux/idr.h>
 #include <linux/vmalloc.h> /* TODO: replace with more sophisticated array */
-#include <linux/eventfd.h>
-#include <linux/poll.h>
 #include <linux/flex_array.h> /* used in cgroup_attach_task */
 #include <linux/kthread.h>
-#include <linux/file.h>
 
 #include <linux/atomic.h>
 
+/*
+ * pidlists linger the following amount before being destroyed.  The goal
+ * is avoiding frequent destruction in the middle of consecutive read calls
+ * Expiring in the middle is a performance problem not a correctness one.
+ * 1 sec should be enough.
+ */
+#define CGROUP_PIDLIST_DESTROY_DELAY   HZ
+
 /*
  * cgroup_mutex is the master lock.  Any modification to cgroup or its
  * hierarchy must be performed while holding it.
@@ -89,6 +94,20 @@ static DEFINE_MUTEX(cgroup_mutex);
 
 static DEFINE_MUTEX(cgroup_root_mutex);
 
+/*
+ * cgroup destruction makes heavy use of work items and there can be a lot
+ * of concurrent destructions.  Use a separate workqueue so that cgroup
+ * destruction work items don't end up filling up max_active of system_wq
+ * which may lead to deadlock.
+ */
+static struct workqueue_struct *cgroup_destroy_wq;
+
+/*
+ * pidlist destructions need to be flushed on cgroup destruction.  Use a
+ * separate workqueue as flush domain.
+ */
+static struct workqueue_struct *cgroup_pidlist_destroy_wq;
+
 /*
  * Generate an array of cgroup subsystem pointers. At boot time, this is
  * populated with the built in subsystems, and modular subsystems are
@@ -124,36 +143,6 @@ struct cfent {
        struct simple_xattrs            xattrs;
 };
 
-/*
- * cgroup_event represents events which userspace want to receive.
- */
-struct cgroup_event {
-       /*
-        * css which the event belongs to.
-        */
-       struct cgroup_subsys_state *css;
-       /*
-        * Control file which the event associated.
-        */
-       struct cftype *cft;
-       /*
-        * eventfd to signal userspace about the event.
-        */
-       struct eventfd_ctx *eventfd;
-       /*
-        * Each of these stored in a list by the cgroup.
-        */
-       struct list_head list;
-       /*
-        * All fields below needed to unregister event when
-        * userspace closes eventfd.
-        */
-       poll_table pt;
-       wait_queue_head_t *wqh;
-       wait_queue_t wait;
-       struct work_struct remove;
-};
-
 /* The list of hierarchy roots */
 
 static LIST_HEAD(cgroup_roots);
@@ -191,6 +180,8 @@ static void cgroup_destroy_css_killed(struct cgroup *cgrp);
 static int cgroup_destroy_locked(struct cgroup *cgrp);
 static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],
                              bool is_add);
+static int cgroup_file_release(struct inode *inode, struct file *file);
+static void cgroup_pidlist_destroy_all(struct cgroup *cgrp);
 
 /**
  * cgroup_css - obtain a cgroup's css for the specified subsystem
@@ -854,11 +845,7 @@ static void cgroup_free_fn(struct work_struct *work)
         */
        deactivate_super(cgrp->root->sb);
 
-       /*
-        * if we're getting rid of the cgroup, refcount should ensure
-        * that there are no pidlists left.
-        */
-       BUG_ON(!list_empty(&cgrp->pidlists));
+       cgroup_pidlist_destroy_all(cgrp);
 
        simple_xattrs_free(&cgrp->xattrs);
 
@@ -871,7 +858,7 @@ static void cgroup_free_rcu(struct rcu_head *head)
        struct cgroup *cgrp = container_of(head, struct cgroup, rcu_head);
 
        INIT_WORK(&cgrp->destroy_work, cgroup_free_fn);
-       schedule_work(&cgrp->destroy_work);
+       queue_work(cgroup_destroy_wq, &cgrp->destroy_work);
 }
 
 static void cgroup_diput(struct dentry *dentry, struct inode *inode)
@@ -1343,8 +1330,6 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp)
        INIT_LIST_HEAD(&cgrp->pidlists);
        mutex_init(&cgrp->pidlist_mutex);
        cgrp->dummy_css.cgroup = cgrp;
-       INIT_LIST_HEAD(&cgrp->event_list);
-       spin_lock_init(&cgrp->event_list_lock);
        simple_xattrs_init(&cgrp->xattrs);
 }
 
@@ -2421,7 +2406,7 @@ static const struct file_operations cgroup_seqfile_operations = {
        .read = seq_read,
        .write = cgroup_file_write,
        .llseek = seq_lseek,
-       .release = single_release,
+       .release = cgroup_file_release,
 };
 
 static int cgroup_file_open(struct inode *inode, struct file *file)
@@ -2474,15 +2459,13 @@ static int cgroup_file_open(struct inode *inode, struct file *file)
 static int cgroup_file_release(struct inode *inode, struct file *file)
 {
        struct cfent *cfe = __d_cfe(file->f_dentry);
-       struct cftype *cft = __d_cft(file->f_dentry);
        struct cgroup_subsys_state *css = cfe->css;
-       int ret = 0;
 
-       if (cft->release)
-               ret = cft->release(inode, file);
        if (css->ss)
                css_put(css);
-       return ret;
+       if (file->f_op == &cgroup_seqfile_operations)
+               single_release(inode, file);
+       return 0;
 }
 
 /*
@@ -2618,16 +2601,6 @@ static const struct inode_operations cgroup_dir_inode_operations = {
        .removexattr = cgroup_removexattr,
 };
 
-/*
- * Check if a file is a control file
- */
-static inline struct cftype *__file_cft(struct file *file)
-{
-       if (file_inode(file)->i_fop != &cgroup_file_operations)
-               return ERR_PTR(-EINVAL);
-       return __d_cft(file->f_dentry);
-}
-
 static int cgroup_create_file(struct dentry *dentry, umode_t mode,
                                struct super_block *sb)
 {
@@ -3483,14 +3456,19 @@ struct cgroup_pidlist {
        pid_t *list;
        /* how many elements the above list has */
        int length;
-       /* how many files are using the current array */
-       int use_count;
        /* each of these stored in a list by its cgroup */
        struct list_head links;
        /* pointer to the cgroup we belong to, for list removal purposes */
        struct cgroup *owner;
-       /* protects the other fields */
-       struct rw_semaphore rwsem;
+       /* for delayed destruction */
+       struct delayed_work destroy_dwork;
+};
+
+/* seq_file->private points to the following */
+struct cgroup_pidlist_open_file {
+       enum cgroup_filetype            type;
+       struct cgroup                   *cgrp;
+       struct cgroup_pidlist           *pidlist;
 };
 
 /*
@@ -3506,6 +3484,7 @@ static void *pidlist_allocate(int count)
        else
                return kmalloc(count * sizeof(pid_t), GFP_KERNEL);
 }
+
 static void pidlist_free(void *p)
 {
        if (is_vmalloc_addr(p))
@@ -3514,6 +3493,47 @@ static void pidlist_free(void *p)
                kfree(p);
 }
 
+/*
+ * Used to destroy all pidlists lingering waiting for destroy timer.  None
+ * should be left afterwards.
+ */
+static void cgroup_pidlist_destroy_all(struct cgroup *cgrp)
+{
+       struct cgroup_pidlist *l, *tmp_l;
+
+       mutex_lock(&cgrp->pidlist_mutex);
+       list_for_each_entry_safe(l, tmp_l, &cgrp->pidlists, links)
+               mod_delayed_work(cgroup_pidlist_destroy_wq, &l->destroy_dwork, 0);
+       mutex_unlock(&cgrp->pidlist_mutex);
+
+       flush_workqueue(cgroup_pidlist_destroy_wq);
+       BUG_ON(!list_empty(&cgrp->pidlists));
+}
+
+static void cgroup_pidlist_destroy_work_fn(struct work_struct *work)
+{
+       struct delayed_work *dwork = to_delayed_work(work);
+       struct cgroup_pidlist *l = container_of(dwork, struct cgroup_pidlist,
+                                               destroy_dwork);
+       struct cgroup_pidlist *tofree = NULL;
+
+       mutex_lock(&l->owner->pidlist_mutex);
+
+       /*
+        * Destroy iff we didn't get queued again.  The state won't change
+        * as destroy_dwork can only be queued while locked.
+        */
+       if (!delayed_work_pending(dwork)) {
+               list_del(&l->links);
+               pidlist_free(l->list);
+               put_pid_ns(l->key.ns);
+               tofree = l;
+       }
+
+       mutex_unlock(&l->owner->pidlist_mutex);
+       kfree(tofree);
+}
+
 /*
  * pidlist_uniq - given a kmalloc()ed list, strip out all duplicate entries
  * Returns the number of unique elements.
@@ -3544,52 +3564,92 @@ after:
        return dest;
 }
 
+/*
+ * The two pid files - task and cgroup.procs - guaranteed that the result
+ * is sorted, which forced this whole pidlist fiasco.  As pid order is
+ * different per namespace, each namespace needs differently sorted list,
+ * making it impossible to use, for example, single rbtree of member tasks
+ * sorted by task pointer.  As pidlists can be fairly large, allocating one
+ * per open file is dangerous, so cgroup had to implement shared pool of
+ * pidlists keyed by cgroup and namespace.
+ *
+ * All this extra complexity was caused by the original implementation
+ * committing to an entirely unnecessary property.  In the long term, we
+ * want to do away with it.  Explicitly scramble sort order if
+ * sane_behavior so that no such expectation exists in the new interface.
+ *
+ * Scrambling is done by swapping every two consecutive bits, which is
+ * non-identity one-to-one mapping which disturbs sort order sufficiently.
+ */
+static pid_t pid_fry(pid_t pid)
+{
+       unsigned a = pid & 0x55555555;
+       unsigned b = pid & 0xAAAAAAAA;
+
+       return (a << 1) | (b >> 1);
+}
+
+static pid_t cgroup_pid_fry(struct cgroup *cgrp, pid_t pid)
+{
+       if (cgroup_sane_behavior(cgrp))
+               return pid_fry(pid);
+       else
+               return pid;
+}
+
 static int cmppid(const void *a, const void *b)
 {
        return *(pid_t *)a - *(pid_t *)b;
 }
 
+static int fried_cmppid(const void *a, const void *b)
+{
+       return pid_fry(*(pid_t *)a) - pid_fry(*(pid_t *)b);
+}
+
+static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp,
+                                                 enum cgroup_filetype type)
+{
+       struct cgroup_pidlist *l;
+       /* don't need task_nsproxy() if we're looking at ourself */
+       struct pid_namespace *ns = task_active_pid_ns(current);
+
+       lockdep_assert_held(&cgrp->pidlist_mutex);
+
+       list_for_each_entry(l, &cgrp->pidlists, links)
+               if (l->key.type == type && l->key.ns == ns)
+                       return l;
+       return NULL;
+}
+
 /*
  * find the appropriate pidlist for our purpose (given procs vs tasks)
  * returns with the lock on that pidlist already held, and takes care
  * of the use count, or returns NULL with no locks held if we're out of
  * memory.
  */
-static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp,
-                                                 enum cgroup_filetype type)
+static struct cgroup_pidlist *cgroup_pidlist_find_create(struct cgroup *cgrp,
+                                               enum cgroup_filetype type)
 {
        struct cgroup_pidlist *l;
-       /* don't need task_nsproxy() if we're looking at ourself */
-       struct pid_namespace *ns = task_active_pid_ns(current);
 
-       /*
-        * We can't drop the pidlist_mutex before taking the l->rwsem in case
-        * the last ref-holder is trying to remove l from the list at the same
-        * time. Holding the pidlist_mutex precludes somebody taking whichever
-        * list we find out from under us - compare release_pid_array().
-        */
-       mutex_lock(&cgrp->pidlist_mutex);
-       list_for_each_entry(l, &cgrp->pidlists, links) {
-               if (l->key.type == type && l->key.ns == ns) {
-                       /* make sure l doesn't vanish out from under us */
-                       down_write(&l->rwsem);
-                       mutex_unlock(&cgrp->pidlist_mutex);
-                       return l;
-               }
-       }
+       lockdep_assert_held(&cgrp->pidlist_mutex);
+
+       l = cgroup_pidlist_find(cgrp, type);
+       if (l)
+               return l;
+
        /* entry not found; create a new one */
        l = kzalloc(sizeof(struct cgroup_pidlist), GFP_KERNEL);
-       if (!l) {
-               mutex_unlock(&cgrp->pidlist_mutex);
+       if (!l)
                return l;
-       }
-       init_rwsem(&l->rwsem);
-       down_write(&l->rwsem);
+
+       INIT_DELAYED_WORK(&l->destroy_dwork, cgroup_pidlist_destroy_work_fn);
        l->key.type = type;
-       l->key.ns = get_pid_ns(ns);
+       /* don't need task_nsproxy() if we're looking at ourself */
+       l->key.ns = get_pid_ns(task_active_pid_ns(current));
        l->owner = cgrp;
        list_add(&l->links, &cgrp->pidlists);
-       mutex_unlock(&cgrp->pidlist_mutex);
        return l;
 }
 
@@ -3606,6 +3666,8 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type,
        struct task_struct *tsk;
        struct cgroup_pidlist *l;
 
+       lockdep_assert_held(&cgrp->pidlist_mutex);
+
        /*
         * If cgroup gets more users after we read count, we won't have
         * enough space - tough.  This race is indistinguishable to the
@@ -3632,20 +3694,24 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type,
        css_task_iter_end(&it);
        length = n;
        /* now sort & (if procs) strip out duplicates */
-       sort(array, length, sizeof(pid_t), cmppid, NULL);
+       if (cgroup_sane_behavior(cgrp))
+               sort(array, length, sizeof(pid_t), fried_cmppid, NULL);
+       else
+               sort(array, length, sizeof(pid_t), cmppid, NULL);
        if (type == CGROUP_FILE_PROCS)
                length = pidlist_uniq(array, length);
-       l = cgroup_pidlist_find(cgrp, type);
+
+       l = cgroup_pidlist_find_create(cgrp, type);
        if (!l) {
+               mutex_unlock(&cgrp->pidlist_mutex);
                pidlist_free(array);
                return -ENOMEM;
        }
-       /* store array, freeing old if necessary - lock already held */
+
+       /* store array, freeing old if necessary */
        pidlist_free(l->list);
        l->list = array;
        l->length = length;
-       l->use_count++;
-       up_write(&l->rwsem);
        *lp = l;
        return 0;
 }
@@ -3719,20 +3785,43 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
         * after a seek to the start). Use a binary-search to find the
         * next pid to display, if any
         */
-       struct cgroup_pidlist *l = s->private;
+       struct cgroup_pidlist_open_file *of = s->private;
+       struct cgroup *cgrp = of->cgrp;
+       struct cgroup_pidlist *l;
        int index = 0, pid = *pos;
-       int *iter;
+       int *iter, ret;
+
+       mutex_lock(&cgrp->pidlist_mutex);
+
+       /*
+        * !NULL @of->pidlist indicates that this isn't the first start()
+        * after open.  If the matching pidlist is around, we can use that.
+        * Look for it.  Note that @of->pidlist can't be used directly.  It
+        * could already have been destroyed.
+        */
+       if (of->pidlist)
+               of->pidlist = cgroup_pidlist_find(cgrp, of->type);
+
+       /*
+        * Either this is the first start() after open or the matching
+        * pidlist has been destroyed inbetween.  Create a new one.
+        */
+       if (!of->pidlist) {
+               ret = pidlist_array_load(of->cgrp, of->type, &of->pidlist);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+       l = of->pidlist;
 
-       down_read(&l->rwsem);
        if (pid) {
                int end = l->length;
 
                while (index < end) {
                        int mid = (index + end) / 2;
-                       if (l->list[mid] == pid) {
+                       if (cgroup_pid_fry(cgrp, l->list[mid]) == pid) {
                                index = mid;
                                break;
-                       } else if (l->list[mid] <= pid)
+                       } else if (cgroup_pid_fry(cgrp, l->list[mid]) <= pid)
                                index = mid + 1;
                        else
                                end = mid;
@@ -3743,19 +3832,25 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
                return NULL;
        /* Update the abstract position to be the actual pid that we found */
        iter = l->list + index;
-       *pos = *iter;
+       *pos = cgroup_pid_fry(cgrp, *iter);
        return iter;
 }
 
 static void cgroup_pidlist_stop(struct seq_file *s, void *v)
 {
-       struct cgroup_pidlist *l = s->private;
-       up_read(&l->rwsem);
+       struct cgroup_pidlist_open_file *of = s->private;
+
+       if (of->pidlist)
+               mod_delayed_work(cgroup_pidlist_destroy_wq,
+                                &of->pidlist->destroy_dwork,
+                                CGROUP_PIDLIST_DESTROY_DELAY);
+       mutex_unlock(&of->cgrp->pidlist_mutex);
 }
 
 static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
 {
-       struct cgroup_pidlist *l = s->private;
+       struct cgroup_pidlist_open_file *of = s->private;
+       struct cgroup_pidlist *l = of->pidlist;
        pid_t *p = v;
        pid_t *end = l->list + l->length;
        /*
@@ -3766,7 +3861,7 @@ static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
        if (p >= end) {
                return NULL;
        } else {
-               *pos = *p;
+               *pos = cgroup_pid_fry(of->cgrp, *p);
                return p;
        }
 }
@@ -3787,50 +3882,11 @@ static const struct seq_operations cgroup_pidlist_seq_operations = {
        .show = cgroup_pidlist_show,
 };
 
-static void cgroup_release_pid_array(struct cgroup_pidlist *l)
-{
-       /*
-        * the case where we're the last user of this particular pidlist will
-        * have us remove it from the cgroup's list, which entails taking the
-        * mutex. since in pidlist_find the pidlist->lock depends on cgroup->
-        * pidlist_mutex, we have to take pidlist_mutex first.
-        */
-       mutex_lock(&l->owner->pidlist_mutex);
-       down_write(&l->rwsem);
-       BUG_ON(!l->use_count);
-       if (!--l->use_count) {
-               /* we're the last user if refcount is 0; remove and free */
-               list_del(&l->links);
-               mutex_unlock(&l->owner->pidlist_mutex);
-               pidlist_free(l->list);
-               put_pid_ns(l->key.ns);
-               up_write(&l->rwsem);
-               kfree(l);
-               return;
-       }
-       mutex_unlock(&l->owner->pidlist_mutex);
-       up_write(&l->rwsem);
-}
-
-static int cgroup_pidlist_release(struct inode *inode, struct file *file)
-{
-       struct cgroup_pidlist *l;
-       if (!(file->f_mode & FMODE_READ))
-               return 0;
-       /*
-        * the seq_file will only be initialized if the file was opened for
-        * reading; hence we check if it's not null only in that case.
-        */
-       l = ((struct seq_file *)file->private_data)->private;
-       cgroup_release_pid_array(l);
-       return seq_release(inode, file);
-}
-
 static const struct file_operations cgroup_pidlist_operations = {
        .read = seq_read,
        .llseek = seq_lseek,
        .write = cgroup_file_write,
-       .release = cgroup_pidlist_release,
+       .release = seq_release_private,
 };
 
 /*
@@ -3842,26 +3898,18 @@ static const struct file_operations cgroup_pidlist_operations = {
 static int cgroup_pidlist_open(struct file *file, enum cgroup_filetype type)
 {
        struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
-       struct cgroup_pidlist *l;
-       int retval;
-
-       /* Nothing to do for write-only files */
-       if (!(file->f_mode & FMODE_READ))
-               return 0;
+       struct cgroup_pidlist_open_file *of;
 
-       /* have the array populated */
-       retval = pidlist_array_load(cgrp, type, &l);
-       if (retval)
-               return retval;
        /* configure file information */
        file->f_op = &cgroup_pidlist_operations;
 
-       retval = seq_open(file, &cgroup_pidlist_seq_operations);
-       if (retval) {
-               cgroup_release_pid_array(l);
-               return retval;
-       }
-       ((struct seq_file *)file->private_data)->private = l;
+       of = __seq_open_private(file, &cgroup_pidlist_seq_operations,
+                               sizeof(*of));
+       if (!of)
+               return -ENOMEM;
+
+       of->type = type;
+       of->cgrp = cgrp;
        return 0;
 }
 static int cgroup_tasks_open(struct inode *unused, struct file *file)
@@ -3907,202 +3955,6 @@ static void cgroup_dput(struct cgroup *cgrp)
        deactivate_super(sb);
 }
 
-/*
- * Unregister event and free resources.
- *
- * Gets called from workqueue.
- */
-static void cgroup_event_remove(struct work_struct *work)
-{
-       struct cgroup_event *event = container_of(work, struct cgroup_event,
-                       remove);
-       struct cgroup_subsys_state *css = event->css;
-
-       remove_wait_queue(event->wqh, &event->wait);
-
-       event->cft->unregister_event(css, event->cft, event->eventfd);
-
-       /* Notify userspace the event is going away. */
-       eventfd_signal(event->eventfd, 1);
-
-       eventfd_ctx_put(event->eventfd);
-       kfree(event);
-       css_put(css);
-}
-
-/*
- * Gets called on POLLHUP on eventfd when user closes it.
- *
- * Called with wqh->lock held and interrupts disabled.
- */
-static int cgroup_event_wake(wait_queue_t *wait, unsigned mode,
-               int sync, void *key)
-{
-       struct cgroup_event *event = container_of(wait,
-                       struct cgroup_event, wait);
-       struct cgroup *cgrp = event->css->cgroup;
-       unsigned long flags = (unsigned long)key;
-
-       if (flags & POLLHUP) {
-               /*
-                * If the event has been detached at cgroup removal, we
-                * can simply return knowing the other side will cleanup
-                * for us.
-                *
-                * We can't race against event freeing since the other
-                * side will require wqh->lock via remove_wait_queue(),
-                * which we hold.
-                */
-               spin_lock(&cgrp->event_list_lock);
-               if (!list_empty(&event->list)) {
-                       list_del_init(&event->list);
-                       /*
-                        * We are in atomic context, but cgroup_event_remove()
-                        * may sleep, so we have to call it in workqueue.
-                        */
-                       schedule_work(&event->remove);
-               }
-               spin_unlock(&cgrp->event_list_lock);
-       }
-
-       return 0;
-}
-
-static void cgroup_event_ptable_queue_proc(struct file *file,
-               wait_queue_head_t *wqh, poll_table *pt)
-{
-       struct cgroup_event *event = container_of(pt,
-                       struct cgroup_event, pt);
-
-       event->wqh = wqh;
-       add_wait_queue(wqh, &event->wait);
-}
-
-/*
- * Parse input and register new cgroup event handler.
- *
- * Input must be in format '<event_fd> <control_fd> <args>'.
- * Interpretation of args is defined by control file implementation.
- */
-static int cgroup_write_event_control(struct cgroup_subsys_state *dummy_css,
-                                     struct cftype *cft, const char *buffer)
-{
-       struct cgroup *cgrp = dummy_css->cgroup;
-       struct cgroup_event *event;
-       struct cgroup_subsys_state *cfile_css;
-       unsigned int efd, cfd;
-       struct fd efile;
-       struct fd cfile;
-       char *endp;
-       int ret;
-
-       efd = simple_strtoul(buffer, &endp, 10);
-       if (*endp != ' ')
-               return -EINVAL;
-       buffer = endp + 1;
-
-       cfd = simple_strtoul(buffer, &endp, 10);
-       if ((*endp != ' ') && (*endp != '\0'))
-               return -EINVAL;
-       buffer = endp + 1;
-
-       event = kzalloc(sizeof(*event), GFP_KERNEL);
-       if (!event)
-               return -ENOMEM;
-
-       INIT_LIST_HEAD(&event->list);
-       init_poll_funcptr(&event->pt, cgroup_event_ptable_queue_proc);
-       init_waitqueue_func_entry(&event->wait, cgroup_event_wake);
-       INIT_WORK(&event->remove, cgroup_event_remove);
-
-       efile = fdget(efd);
-       if (!efile.file) {
-               ret = -EBADF;
-               goto out_kfree;
-       }
-
-       event->eventfd = eventfd_ctx_fileget(efile.file);
-       if (IS_ERR(event->eventfd)) {
-               ret = PTR_ERR(event->eventfd);
-               goto out_put_efile;
-       }
-
-       cfile = fdget(cfd);
-       if (!cfile.file) {
-               ret = -EBADF;
-               goto out_put_eventfd;
-       }
-
-       /* the process need read permission on control file */
-       /* AV: shouldn't we check that it's been opened for read instead? */
-       ret = inode_permission(file_inode(cfile.file), MAY_READ);
-       if (ret < 0)
-               goto out_put_cfile;
-
-       event->cft = __file_cft(cfile.file);
-       if (IS_ERR(event->cft)) {
-               ret = PTR_ERR(event->cft);
-               goto out_put_cfile;
-       }
-
-       if (!event->cft->ss) {
-               ret = -EBADF;
-               goto out_put_cfile;
-       }
-
-       /*
-        * Determine the css of @cfile, verify it belongs to the same
-        * cgroup as cgroup.event_control, and associate @event with it.
-        * Remaining events are automatically removed on cgroup destruction
-        * but the removal is asynchronous, so take an extra ref.
-        */
-       rcu_read_lock();
-
-       ret = -EINVAL;
-       event->css = cgroup_css(cgrp, event->cft->ss);
-       cfile_css = css_from_dir(cfile.file->f_dentry->d_parent, event->cft->ss);
-       if (event->css && event->css == cfile_css && css_tryget(event->css))
-               ret = 0;
-
-       rcu_read_unlock();
-       if (ret)
-               goto out_put_cfile;
-
-       if (!event->cft->register_event || !event->cft->unregister_event) {
-               ret = -EINVAL;
-               goto out_put_css;
-       }
-
-       ret = event->cft->register_event(event->css, event->cft,
-                       event->eventfd, buffer);
-       if (ret)
-               goto out_put_css;
-
-       efile.file->f_op->poll(efile.file, &event->pt);
-
-       spin_lock(&cgrp->event_list_lock);
-       list_add(&event->list, &cgrp->event_list);
-       spin_unlock(&cgrp->event_list_lock);
-
-       fdput(cfile);
-       fdput(efile);
-
-       return 0;
-
-out_put_css:
-       css_put(event->css);
-out_put_cfile:
-       fdput(cfile);
-out_put_eventfd:
-       eventfd_ctx_put(event->eventfd);
-out_put_efile:
-       fdput(efile);
-out_kfree:
-       kfree(event);
-
-       return ret;
-}
-
 static u64 cgroup_clone_children_read(struct cgroup_subsys_state *css,
                                      struct cftype *cft)
 {
@@ -4124,14 +3976,8 @@ static struct cftype cgroup_base_files[] = {
                .name = "cgroup.procs",
                .open = cgroup_procs_open,
                .write_u64 = cgroup_procs_write,
-               .release = cgroup_pidlist_release,
                .mode = S_IRUGO | S_IWUSR,
        },
-       {
-               .name = "cgroup.event_control",
-               .write_string = cgroup_write_event_control,
-               .mode = S_IWUGO,
-       },
        {
                .name = "cgroup.clone_children",
                .flags = CFTYPE_INSANE,
@@ -4154,7 +4000,6 @@ static struct cftype cgroup_base_files[] = {
                .flags = CFTYPE_INSANE,         /* use "procs" instead */
                .open = cgroup_tasks_open,
                .write_u64 = cgroup_tasks_write,
-               .release = cgroup_pidlist_release,
                .mode = S_IRUGO | S_IWUSR,
        },
        {
@@ -4249,7 +4094,7 @@ static void css_free_rcu_fn(struct rcu_head *rcu_head)
         * css_put().  dput() requires process context which we don't have.
         */
        INIT_WORK(&css->destroy_work, css_free_work_fn);
-       schedule_work(&css->destroy_work);
+       queue_work(cgroup_destroy_wq, &css->destroy_work);
 }
 
 static void css_release(struct percpu_ref *ref)
@@ -4539,7 +4384,7 @@ static void css_killed_ref_fn(struct percpu_ref *ref)
                container_of(ref, struct cgroup_subsys_state, refcnt);
 
        INIT_WORK(&css->destroy_work, css_killed_work_fn);
-       schedule_work(&css->destroy_work);
+       queue_work(cgroup_destroy_wq, &css->destroy_work);
 }
 
 /**
@@ -4602,7 +4447,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
        __releases(&cgroup_mutex) __acquires(&cgroup_mutex)
 {
        struct dentry *d = cgrp->dentry;
-       struct cgroup_event *event, *tmp;
        struct cgroup_subsys *ss;
        struct cgroup *child;
        bool empty;
@@ -4677,18 +4521,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
        dget(d);
        cgroup_d_remove_dir(d);
 
-       /*
-        * Unregister events and notify userspace.
-        * Notify userspace about cgroup removing only after rmdir of cgroup
-        * directory to avoid race between userspace and kernelspace.
-        */
-       spin_lock(&cgrp->event_list_lock);
-       list_for_each_entry_safe(event, tmp, &cgrp->event_list, list) {
-               list_del_init(&event->list);
-               schedule_work(&event->remove);
-       }
-       spin_unlock(&cgrp->event_list_lock);
-
        return 0;
 };
 
@@ -5063,6 +4895,31 @@ out:
        return err;
 }
 
+static int __init cgroup_wq_init(void)
+{
+       /*
+        * There isn't much point in executing destruction path in
+        * parallel.  Good chunk is serialized with cgroup_mutex anyway.
+        * Use 1 for @max_active.
+        *
+        * We would prefer to do this in cgroup_init() above, but that
+        * is called before init_workqueues(): so leave this until after.
+        */
+       cgroup_destroy_wq = alloc_workqueue("cgroup_destroy", 0, 1);
+       BUG_ON(!cgroup_destroy_wq);
+
+       /*
+        * Used to destroy pidlists and separate to serve as flush domain.
+        * Cap @max_active to 1 too.
+        */
+       cgroup_pidlist_destroy_wq = alloc_workqueue("cgroup_pidlist_destroy",
+                                                   0, 1);
+       BUG_ON(!cgroup_pidlist_destroy_wq);
+
+       return 0;
+}
+core_initcall(cgroup_wq_init);
+
 /*
  * proc_cgroup_show()
  *  - Print task's cgroup paths into seq_file, one line for each hierarchy
index 6bf981e13c437ff81979f4c9f08f69998c8ca45a..4772034b4b17062a4506bc4f437c599b8d5f2ac3 100644 (file)
@@ -1033,8 +1033,10 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk,
        need_loop = task_has_mempolicy(tsk) ||
                        !nodes_intersects(*newmems, tsk->mems_allowed);
 
-       if (need_loop)
+       if (need_loop) {
+               local_irq_disable();
                write_seqcount_begin(&tsk->mems_allowed_seq);
+       }
 
        nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems);
        mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1);
@@ -1042,8 +1044,10 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk,
        mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP2);
        tsk->mems_allowed = *newmems;
 
-       if (need_loop)
+       if (need_loop) {
                write_seqcount_end(&tsk->mems_allowed_seq);
+               local_irq_enable();
+       }
 
        task_unlock(tsk);
 }
index d724e7757cd1ec2df7a9c2ac9be1b0c23f6e4e71..403b781daafb694ef9baa94e5a176212a23678e1 100644 (file)
@@ -5680,11 +5680,6 @@ static void swevent_hlist_put(struct perf_event *event)
 {
        int cpu;
 
-       if (event->cpu != -1) {
-               swevent_hlist_put_cpu(event, event->cpu);
-               return;
-       }
-
        for_each_possible_cpu(cpu)
                swevent_hlist_put_cpu(event, cpu);
 }
@@ -5718,9 +5713,6 @@ static int swevent_hlist_get(struct perf_event *event)
        int err;
        int cpu, failed_cpu;
 
-       if (event->cpu != -1)
-               return swevent_hlist_get_cpu(event, event->cpu);
-
        get_online_cpus();
        for_each_possible_cpu(cpu) {
                err = swevent_hlist_get_cpu(event, cpu);
@@ -6663,6 +6655,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
        INIT_LIST_HEAD(&event->event_entry);
        INIT_LIST_HEAD(&event->sibling_list);
        INIT_LIST_HEAD(&event->rb_entry);
+       INIT_LIST_HEAD(&event->active_entry);
 
        init_waitqueue_head(&event->waitq);
        init_irq_work(&event->pending, perf_pending_event);
index 24b7d6ca871b632f2e35912e720bfc0162c939c5..b886a5e7d4ff4a5d1c7b240a63aed39538926de4 100644 (file)
@@ -73,6 +73,17 @@ struct uprobe {
        struct inode            *inode;         /* Also hold a ref to inode */
        loff_t                  offset;
        unsigned long           flags;
+
+       /*
+        * The generic code assumes that it has two members of unknown type
+        * owned by the arch-specific code:
+        *
+        *      insn -  copy_insn() saves the original instruction here for
+        *              arch_uprobe_analyze_insn().
+        *
+        *      ixol -  potentially modified instruction to execute out of
+        *              line, copied to xol_area by xol_get_insn_slot().
+        */
        struct arch_uprobe      arch;
 };
 
@@ -85,6 +96,29 @@ struct return_instance {
        struct return_instance  *next;          /* keep as stack */
 };
 
+/*
+ * Execute out of line area: anonymous executable mapping installed
+ * by the probed task to execute the copy of the original instruction
+ * mangled by set_swbp().
+ *
+ * On a breakpoint hit, thread contests for a slot.  It frees the
+ * slot after singlestep. Currently a fixed number of slots are
+ * allocated.
+ */
+struct xol_area {
+       wait_queue_head_t       wq;             /* if all slots are busy */
+       atomic_t                slot_count;     /* number of in-use slots */
+       unsigned long           *bitmap;        /* 0 = free slot */
+       struct page             *page;
+
+       /*
+        * We keep the vma's vm_start rather than a pointer to the vma
+        * itself.  The probed process or a naughty kernel module could make
+        * the vma go away, and we must handle that reasonably gracefully.
+        */
+       unsigned long           vaddr;          /* Page(s) of instruction slots */
+};
+
 /*
  * valid_vma: Verify if the specified vma is an executable vma
  * Relax restrictions while unregistering: vm_flags might have
@@ -330,7 +364,7 @@ int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned
 int __weak
 set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
 {
-       return uprobe_write_opcode(mm, vaddr, *(uprobe_opcode_t *)auprobe->insn);
+       return uprobe_write_opcode(mm, vaddr, *(uprobe_opcode_t *)&auprobe->insn);
 }
 
 static int match_uprobe(struct uprobe *l, struct uprobe *r)
@@ -529,8 +563,8 @@ static int copy_insn(struct uprobe *uprobe, struct file *filp)
 {
        struct address_space *mapping = uprobe->inode->i_mapping;
        loff_t offs = uprobe->offset;
-       void *insn = uprobe->arch.insn;
-       int size = MAX_UINSN_BYTES;
+       void *insn = &uprobe->arch.insn;
+       int size = sizeof(uprobe->arch.insn);
        int len, err = -EIO;
 
        /* Copy only available bytes, -EIO if nothing was read */
@@ -569,7 +603,7 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
                goto out;
 
        ret = -ENOTSUPP;
-       if (is_trap_insn((uprobe_opcode_t *)uprobe->arch.insn))
+       if (is_trap_insn((uprobe_opcode_t *)&uprobe->arch.insn))
                goto out;
 
        ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr);
@@ -1264,7 +1298,7 @@ static unsigned long xol_get_insn_slot(struct uprobe *uprobe)
 
        /* Initialize the slot */
        copy_to_page(area->page, xol_vaddr,
-                       uprobe->arch.ixol, sizeof(uprobe->arch.ixol));
+                       &uprobe->arch.ixol, sizeof(uprobe->arch.ixol));
        /*
         * We probably need flush_icache_user_range() but it needs vma.
         * This should work on supported architectures too.
@@ -1403,12 +1437,10 @@ static void uprobe_warn(struct task_struct *t, const char *msg)
 
 static void dup_xol_work(struct callback_head *work)
 {
-       kfree(work);
-
        if (current->flags & PF_EXITING)
                return;
 
-       if (!__create_xol_area(current->utask->vaddr))
+       if (!__create_xol_area(current->utask->dup_xol_addr))
                uprobe_warn(current, "dup xol area");
 }
 
@@ -1419,7 +1451,6 @@ void uprobe_copy_process(struct task_struct *t, unsigned long flags)
 {
        struct uprobe_task *utask = current->utask;
        struct mm_struct *mm = current->mm;
-       struct callback_head *work;
        struct xol_area *area;
 
        t->utask = NULL;
@@ -1441,14 +1472,9 @@ void uprobe_copy_process(struct task_struct *t, unsigned long flags)
        if (mm == t->mm)
                return;
 
-       /* TODO: move it into the union in uprobe_task */
-       work = kmalloc(sizeof(*work), GFP_KERNEL);
-       if (!work)
-               return uprobe_warn(t, "dup xol area");
-
-       t->utask->vaddr = area->vaddr;
-       init_task_work(work, dup_xol_work);
-       task_work_add(t, work, true);
+       t->utask->dup_xol_addr = area->vaddr;
+       init_task_work(&t->utask->dup_xol_work, dup_xol_work);
+       task_work_add(t, &t->utask->dup_xol_work, true);
 }
 
 /*
index 832cb28105bbb7900a6c1342a095179303734215..763faf037ec1cccb135b98d1deccf339f69cd2e5 100644 (file)
@@ -61,7 +61,7 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr)
 static inline int init_kernel_text(unsigned long addr)
 {
        if (addr >= (unsigned long)_sinittext &&
-           addr <= (unsigned long)_einittext)
+           addr < (unsigned long)_einittext)
                return 1;
        return 0;
 }
@@ -69,7 +69,7 @@ static inline int init_kernel_text(unsigned long addr)
 int core_kernel_text(unsigned long addr)
 {
        if (addr >= (unsigned long)_stext &&
-           addr <= (unsigned long)_etext)
+           addr < (unsigned long)_etext)
                return 1;
 
        if (system_state == SYSTEM_BOOTING &&
index 728d5be9548ce61913c85e14303248363eae0a31..b3080823a24d08d875da78af3f05b8d6cd72456a 100644 (file)
@@ -1402,13 +1402,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
                p->tgid = p->pid;
        }
 
-       p->pdeath_signal = 0;
-       p->exit_state = 0;
-
        p->nr_dirtied = 0;
        p->nr_dirtied_pause = 128 >> (PAGE_SHIFT - 10);
        p->dirty_paused_when = 0;
 
+       p->pdeath_signal = 0;
        INIT_LIST_HEAD(&p->thread_group);
        p->task_works = NULL;
 
index cb228bf217603d6e841c1028dd610598ae133bff..abcd6ca86cb76b56e5979613a1964c0db743b5d0 100644 (file)
@@ -50,7 +50,7 @@ static void resume_irqs(bool want_early)
                bool is_early = desc->action &&
                        desc->action->flags & IRQF_EARLY_RESUME;
 
-               if (is_early != want_early)
+               if (!is_early && want_early)
                        continue;
 
                raw_spin_lock_irqsave(&desc->lock, flags);
index 576ba756a32d9c80948c72e31700738bcfc5ee06..eb8a54783fa0f47bb9b51568ec9dfed3d51cc48d 100644 (file)
@@ -590,6 +590,7 @@ static int very_verbose(struct lock_class *class)
 /*
  * Is this the address of a static object:
  */
+#ifdef __KERNEL__
 static int static_obj(void *obj)
 {
        unsigned long start = (unsigned long) &_stext,
@@ -616,6 +617,7 @@ static int static_obj(void *obj)
         */
        return is_module_address(addr) || is_module_percpu_address(addr);
 }
+#endif
 
 /*
  * To make lock name printouts unique, we calculate a unique
@@ -4115,6 +4117,7 @@ void debug_check_no_locks_held(void)
 }
 EXPORT_SYMBOL_GPL(debug_check_no_locks_held);
 
+#ifdef __KERNEL__
 void debug_show_all_locks(void)
 {
        struct task_struct *g, *p;
@@ -4172,6 +4175,7 @@ retry:
                read_unlock(&tasklist_lock);
 }
 EXPORT_SYMBOL_GPL(debug_show_all_locks);
+#endif
 
 /*
  * Careful: only use this function if you are sure that
index 07af2c95dcfeea37f855db214e8e3405274bddb6..2abd25d79cc87bfc171f491c595d500e161f2de3 100644 (file)
@@ -46,6 +46,7 @@ static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index)
 
 static int padata_cpu_hash(struct parallel_data *pd)
 {
+       unsigned int seq_nr;
        int cpu_index;
 
        /*
@@ -53,10 +54,8 @@ static int padata_cpu_hash(struct parallel_data *pd)
         * seq_nr mod. number of cpus in use.
         */
 
-       spin_lock(&pd->seq_lock);
-       cpu_index =  pd->seq_nr % cpumask_weight(pd->cpumask.pcpu);
-       pd->seq_nr++;
-       spin_unlock(&pd->seq_lock);
+       seq_nr = atomic_inc_return(&pd->seq_nr);
+       cpu_index = seq_nr % cpumask_weight(pd->cpumask.pcpu);
 
        return padata_index_to_cpu(pd, cpu_index);
 }
@@ -429,7 +428,7 @@ static struct parallel_data *padata_alloc_pd(struct padata_instance *pinst,
        padata_init_pqueues(pd);
        padata_init_squeues(pd);
        setup_timer(&pd->timer, padata_reorder_timer, (unsigned long)pd);
-       pd->seq_nr = 0;
+       atomic_set(&pd->seq_nr, -1);
        atomic_set(&pd->reorder_objects, 0);
        atomic_set(&pd->refcnt, 0);
        pd->pinst = pinst;
index c00b4ceb39e8b151aab790e6b498247ea53a4aa6..6d6300375090e7b2345353174d85ed09f6f35ce4 100644 (file)
@@ -33,7 +33,7 @@ static int pause_on_oops;
 static int pause_on_oops_flag;
 static DEFINE_SPINLOCK(pause_on_oops_lock);
 
-int panic_timeout;
+int panic_timeout = CONFIG_PANIC_TIMEOUT;
 EXPORT_SYMBOL_GPL(panic_timeout);
 
 ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
index d09dd10c5a5efc2c206a85bd31a431268e37cc7f..9a58bc2588105900d79ec27c46bdcb8374c32cbc 100644 (file)
@@ -32,7 +32,7 @@ static int submit(int rw, struct block_device *bdev, sector_t sector,
        struct bio *bio;
 
        bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1);
-       bio->bi_sector = sector;
+       bio->bi_iter.bi_sector = sector;
        bio->bi_bdev = bdev;
        bio->bi_end_io = end_swap_bio_read;
 
index 0121dab83f43d82ddfb620f7423d6c9728f8b01b..bc13d087ea14e3a69074ba67f00d68cb9a8ba4d2 100644 (file)
@@ -82,6 +82,7 @@ void hibernation_set_ops(const struct platform_hibernation_ops *ops)
 
        unlock_system_sleep();
 }
+EXPORT_SYMBOL_GPL(hibernation_set_ops);
 
 static bool entering_platform_hibernation;
 
index 6abb03dff5c053f44ef5dbc28f7bf754e5669e78..08a7652324321b132e3fca0f27f7285a609660dc 100644 (file)
@@ -1632,7 +1632,7 @@ module_param(rcu_idle_gp_delay, int, 0644);
 static int rcu_idle_lazy_gp_delay = RCU_IDLE_LAZY_GP_DELAY;
 module_param(rcu_idle_lazy_gp_delay, int, 0644);
 
-extern int tick_nohz_enabled;
+extern int tick_nohz_active;
 
 /*
  * Try to advance callbacks for all flavors of RCU on the current CPU, but
@@ -1729,7 +1729,7 @@ static void rcu_prepare_for_idle(int cpu)
        int tne;
 
        /* Handle nohz enablement switches conservatively. */
-       tne = ACCESS_ONCE(tick_nohz_enabled);
+       tne = ACCESS_ONCE(tick_nohz_active);
        if (tne != rdtp->tick_nohz_enabled_snap) {
                if (rcu_cpu_has_callbacks(cpu, NULL))
                        invoke_rcu_core(); /* force nohz to see update. */
index c1808606ee5f0f4e48e2fc51380369ba248bd9fe..87c3bc47d99d80a214af07bfa84f7cf7b15e6e8e 100644 (file)
@@ -2003,6 +2003,9 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
        if (unlikely(prev_state == TASK_DEAD)) {
                task_numa_free(prev);
 
+               if (prev->sched_class->task_dead)
+                       prev->sched_class->task_dead(prev);
+
                /*
                 * Remove function-return probe instances associated with this
                 * task and put them back on the free list.
@@ -2414,10 +2417,10 @@ static inline void schedule_debug(struct task_struct *prev)
 {
        /*
         * Test if we are atomic. Since do_exit() needs to call into
-        * schedule() atomically, we ignore that path for now.
-        * Otherwise, whine if we are scheduling when we should not be.
+        * schedule() atomically, we ignore that path. Otherwise whine
+        * if we are scheduling when we should not.
         */
-       if (unlikely(in_atomic_preempt_off() && !prev->exit_state))
+       if (unlikely(in_atomic_preempt_off() && prev->state != TASK_DEAD))
                __schedule_bug(prev);
        rcu_sleep_check();
 
@@ -2660,6 +2663,7 @@ asmlinkage void __sched notrace preempt_schedule(void)
        } while (need_resched());
 }
 EXPORT_SYMBOL(preempt_schedule);
+#endif /* CONFIG_PREEMPT */
 
 /*
  * this is the entry point to schedule() from kernel preemption
@@ -2693,8 +2697,6 @@ asmlinkage void __sched preempt_schedule_irq(void)
        exception_exit(prev_state);
 }
 
-#endif /* CONFIG_PREEMPT */
-
 int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags,
                          void *key)
 {
@@ -3654,7 +3656,7 @@ again:
        }
 
        double_rq_lock(rq, p_rq);
-       while (task_rq(p) != p_rq) {
+       if (task_rq(p) != p_rq) {
                double_rq_unlock(rq, p_rq);
                goto again;
        }
@@ -4762,7 +4764,7 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd)
                cpumask_clear_cpu(rq->cpu, old_rd->span);
 
                /*
-                * If we dont want to free the old_rt yet then
+                * If we dont want to free the old_rd yet then
                 * set old_rd to NULL to skip the freeing later
                 * in this function:
                 */
@@ -4910,8 +4912,9 @@ static void update_top_cache_domain(int cpu)
        if (sd) {
                id = cpumask_first(sched_domain_span(sd));
                size = cpumask_weight(sched_domain_span(sd));
-               rcu_assign_pointer(per_cpu(sd_busy, cpu), sd->parent);
+               sd = sd->parent; /* sd_busy */
        }
+       rcu_assign_pointer(per_cpu(sd_busy, cpu), sd);
 
        rcu_assign_pointer(per_cpu(sd_llc, cpu), sd);
        per_cpu(sd_llc_size, cpu) = size;
index e8b652ebe027c481e87122f629a300058cf82679..0de52f4f7717ad71d863ed82ecdba61c13e77766 100644 (file)
@@ -4110,12 +4110,16 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
  */
 static struct sched_group *
 find_idlest_group(struct sched_domain *sd, struct task_struct *p,
-                 int this_cpu, int load_idx)
+                 int this_cpu, int sd_flag)
 {
        struct sched_group *idlest = NULL, *group = sd->groups;
        unsigned long min_load = ULONG_MAX, this_load = 0;
+       int load_idx = sd->forkexec_idx;
        int imbalance = 100 + (sd->imbalance_pct-100)/2;
 
+       if (sd_flag & SD_BALANCE_WAKE)
+               load_idx = sd->wake_idx;
+
        do {
                unsigned long load, avg_load;
                int local_group;
@@ -4283,7 +4287,6 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
        }
 
        while (sd) {
-               int load_idx = sd->forkexec_idx;
                struct sched_group *group;
                int weight;
 
@@ -4292,10 +4295,7 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
                        continue;
                }
 
-               if (sd_flag & SD_BALANCE_WAKE)
-                       load_idx = sd->wake_idx;
-
-               group = find_idlest_group(sd, p, cpu, load_idx);
+               group = find_idlest_group(sd, p, cpu, sd_flag);
                if (!group) {
                        sd = sd->child;
                        continue;
@@ -5379,10 +5379,31 @@ void update_group_power(struct sched_domain *sd, int cpu)
                 */
 
                for_each_cpu(cpu, sched_group_cpus(sdg)) {
-                       struct sched_group *sg = cpu_rq(cpu)->sd->groups;
+                       struct sched_group_power *sgp;
+                       struct rq *rq = cpu_rq(cpu);
 
-                       power_orig += sg->sgp->power_orig;
-                       power += sg->sgp->power;
+                       /*
+                        * build_sched_domains() -> init_sched_groups_power()
+                        * gets here before we've attached the domains to the
+                        * runqueues.
+                        *
+                        * Use power_of(), which is set irrespective of domains
+                        * in update_cpu_power().
+                        *
+                        * This avoids power/power_orig from being 0 and
+                        * causing divide-by-zero issues on boot.
+                        *
+                        * Runtime updates will correct power_orig.
+                        */
+                       if (unlikely(!rq->sd)) {
+                               power_orig += power_of(cpu);
+                               power += power_of(cpu);
+                               continue;
+                       }
+
+                       sgp = rq->sd->groups->sgp;
+                       power_orig += sgp->power_orig;
+                       power += sgp->power;
                }
        } else  {
                /*
@@ -5500,7 +5521,6 @@ static inline void update_sg_lb_stats(struct lb_env *env,
                        struct sched_group *group, int load_idx,
                        int local_group, struct sg_lb_stats *sgs)
 {
-       unsigned long nr_running;
        unsigned long load;
        int i;
 
@@ -5509,8 +5529,6 @@ static inline void update_sg_lb_stats(struct lb_env *env,
        for_each_cpu_and(i, sched_group_cpus(group), env->cpus) {
                struct rq *rq = cpu_rq(i);
 
-               nr_running = rq->nr_running;
-
                /* Bias balancing toward cpus of our domain */
                if (local_group)
                        load = target_load(i, load_idx);
@@ -5518,7 +5536,7 @@ static inline void update_sg_lb_stats(struct lb_env *env,
                        load = source_load(i, load_idx);
 
                sgs->group_load += load;
-               sgs->sum_nr_running += nr_running;
+               sgs->sum_nr_running += rq->nr_running;
 #ifdef CONFIG_NUMA_BALANCING
                sgs->nr_numa_running += rq->nr_numa_running;
                sgs->nr_preferred_running += rq->nr_preferred_running;
index 88c85b21d63346f4ba82e00962486445c9fdb410..b3b4a4953efcdae925c77e44fcf2798c69edd040 100644 (file)
@@ -1023,6 +1023,7 @@ struct sched_class {
        void (*set_curr_task) (struct rq *rq);
        void (*task_tick) (struct rq *rq, struct task_struct *p, int queued);
        void (*task_fork) (struct task_struct *p);
+       void (*task_dead) (struct task_struct *p);
 
        void (*switched_from) (struct rq *this_rq, struct task_struct *task);
        void (*switched_to) (struct rq *this_rq, struct task_struct *task);
index 11025ccc06dd1e2211ca62dcbcea7ce1b05418dd..9a4500e4c1893ec22e17c4ac98a1d34cc6a0b6cf 100644 (file)
@@ -211,14 +211,48 @@ EXPORT_SYMBOL(local_bh_enable_ip);
 #define MAX_SOFTIRQ_TIME  msecs_to_jiffies(2)
 #define MAX_SOFTIRQ_RESTART 10
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+/*
+ * When we run softirqs from irq_exit() and thus on the hardirq stack we need
+ * to keep the lockdep irq context tracking as tight as possible in order to
+ * not miss-qualify lock contexts and miss possible deadlocks.
+ */
+
+static inline bool lockdep_softirq_start(void)
+{
+       bool in_hardirq = false;
+
+       if (trace_hardirq_context(current)) {
+               in_hardirq = true;
+               trace_hardirq_exit();
+       }
+
+       lockdep_softirq_enter();
+
+       return in_hardirq;
+}
+
+static inline void lockdep_softirq_end(bool in_hardirq)
+{
+       lockdep_softirq_exit();
+
+       if (in_hardirq)
+               trace_hardirq_enter();
+}
+#else
+static inline bool lockdep_softirq_start(void) { return false; }
+static inline void lockdep_softirq_end(bool in_hardirq) { }
+#endif
+
 asmlinkage void __do_softirq(void)
 {
-       struct softirq_action *h;
-       __u32 pending;
        unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
-       int cpu;
        unsigned long old_flags = current->flags;
        int max_restart = MAX_SOFTIRQ_RESTART;
+       struct softirq_action *h;
+       bool in_hardirq;
+       __u32 pending;
+       int cpu;
 
        /*
         * Mask out PF_MEMALLOC s current task context is borrowed for the
@@ -231,7 +265,7 @@ asmlinkage void __do_softirq(void)
        account_irq_enter_time(current);
 
        __local_bh_disable(_RET_IP_, SOFTIRQ_OFFSET);
-       lockdep_softirq_enter();
+       in_hardirq = lockdep_softirq_start();
 
        cpu = smp_processor_id();
 restart:
@@ -278,16 +312,13 @@ restart:
                wakeup_softirqd();
        }
 
-       lockdep_softirq_exit();
-
+       lockdep_softirq_end(in_hardirq);
        account_irq_exit_time(current);
        __local_bh_enable(SOFTIRQ_OFFSET);
        WARN_ON_ONCE(in_interrupt());
        tsk_restore_flags(current, old_flags, PF_MEMALLOC);
 }
 
-
-
 asmlinkage void do_softirq(void)
 {
        __u32 pending;
@@ -375,13 +406,13 @@ void irq_exit(void)
 #endif
 
        account_irq_exit_time(current);
-       trace_hardirq_exit();
        preempt_count_sub(HARDIRQ_OFFSET);
        if (!in_interrupt() && local_softirq_pending())
                invoke_softirq();
 
        tick_irq_exit();
        rcu_irq_exit();
+       trace_hardirq_exit(); /* must be last! */
 }
 
 /*
index 64522ecdfe0e868420acdd7b47a65de99b847748..162b03ab0ad2ed16e3654f7006aae6f88c1886cf 100644 (file)
@@ -33,6 +33,21 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
  */
 ktime_t tick_next_period;
 ktime_t tick_period;
+
+/*
+ * tick_do_timer_cpu is a timer core internal variable which holds the CPU NR
+ * which is responsible for calling do_timer(), i.e. the timekeeping stuff. This
+ * variable has two functions:
+ *
+ * 1) Prevent a thundering herd issue of a gazillion of CPUs trying to grab the
+ *    timekeeping lock all at once. Only the CPU which is assigned to do the
+ *    update is handling it.
+ *
+ * 2) Hand off the duty in the NOHZ idle case by setting the value to
+ *    TICK_DO_TIMER_NONE, i.e. a non existing CPU. So the next cpu which looks
+ *    at it will take over and keep the time keeping alive.  The handover
+ *    procedure also covers cpu hotplug.
+ */
 int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT;
 
 /*
index 3612fc77f834372c0d5d674f3bc5ae609dd64635..ea20f7d1ac2c4f91af4dd8dd4db3b01b5c6ae4b7 100644 (file)
@@ -361,8 +361,8 @@ void __init tick_nohz_init(void)
 /*
  * NO HZ enabled ?
  */
-int tick_nohz_enabled __read_mostly  = 1;
-
+static int tick_nohz_enabled __read_mostly  = 1;
+int tick_nohz_active  __read_mostly;
 /*
  * Enable / Disable tickless mode
  */
@@ -465,7 +465,7 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
        ktime_t now, idle;
 
-       if (!tick_nohz_enabled)
+       if (!tick_nohz_active)
                return -1;
 
        now = ktime_get();
@@ -506,7 +506,7 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
        ktime_t now, iowait;
 
-       if (!tick_nohz_enabled)
+       if (!tick_nohz_active)
                return -1;
 
        now = ktime_get();
@@ -711,8 +711,10 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
                return false;
        }
 
-       if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
+       if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) {
+               ts->sleep_length = (ktime_t) { .tv64 = NSEC_PER_SEC/HZ };
                return false;
+       }
 
        if (need_resched())
                return false;
@@ -799,11 +801,6 @@ void tick_nohz_idle_enter(void)
        local_irq_disable();
 
        ts = &__get_cpu_var(tick_cpu_sched);
-       /*
-        * set ts->inidle unconditionally. even if the system did not
-        * switch to nohz mode the cpu frequency governers rely on the
-        * update of the idle time accounting in tick_nohz_start_idle().
-        */
        ts->inidle = 1;
        __tick_nohz_idle_enter(ts);
 
@@ -973,7 +970,7 @@ static void tick_nohz_switch_to_nohz(void)
        struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
        ktime_t next;
 
-       if (!tick_nohz_enabled)
+       if (!tick_nohz_active)
                return;
 
        local_irq_disable();
@@ -981,7 +978,7 @@ static void tick_nohz_switch_to_nohz(void)
                local_irq_enable();
                return;
        }
-
+       tick_nohz_active = 1;
        ts->nohz_mode = NOHZ_MODE_LOWRES;
 
        /*
@@ -1139,8 +1136,10 @@ void tick_setup_sched_timer(void)
        }
 
 #ifdef CONFIG_NO_HZ_COMMON
-       if (tick_nohz_enabled)
+       if (tick_nohz_enabled) {
                ts->nohz_mode = NOHZ_MODE_HIGHRES;
+               tick_nohz_active = 1;
+       }
 #endif
 }
 #endif /* HIGH_RES_TIMERS */
index 3abf53418b67c6ee92c16522299a8821856b749d..87b4f00284c9e21f420d0865af937b03eb286f33 100644 (file)
@@ -1347,7 +1347,7 @@ static inline void old_vsyscall_fixup(struct timekeeper *tk)
        tk->xtime_nsec -= remainder;
        tk->xtime_nsec += 1ULL << tk->shift;
        tk->ntp_error += remainder << tk->ntp_error_shift;
-
+       tk->ntp_error -= (1ULL << tk->shift) << tk->ntp_error_shift;
 }
 #else
 #define old_vsyscall_fixup(tk)
index 6582b82fa966d6ba503a7361f8f89f699f4de04d..accfd241b9e5d5c67040407dfa4f3d8603851de2 100644 (file)
@@ -1518,9 +1518,8 @@ static int init_timers_cpu(int cpu)
                        /*
                         * The APs use this path later in boot
                         */
-                       base = kmalloc_node(sizeof(*base),
-                                               GFP_KERNEL | __GFP_ZERO,
-                                               cpu_to_node(cpu));
+                       base = kzalloc_node(sizeof(*base), GFP_KERNEL,
+                                           cpu_to_node(cpu));
                        if (!base)
                                return -ENOMEM;
 
index f785aef65799cdb0068f0016bb0183a3bfe312a6..b418cb0d72424ab454e66e3cde881784ce1f0fad 100644 (file)
@@ -781,8 +781,8 @@ static void blk_add_trace_bio(struct request_queue *q, struct bio *bio,
        if (!error && !bio_flagged(bio, BIO_UPTODATE))
                error = EIO;
 
-       __blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw, what,
-                       error, 0, NULL);
+       __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
+                       bio->bi_rw, what, error, 0, NULL);
 }
 
 static void blk_add_trace_bio_bounce(void *ignore,
@@ -885,8 +885,9 @@ static void blk_add_trace_split(void *ignore,
        if (bt) {
                __be64 rpdu = cpu_to_be64(pdu);
 
-               __blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw,
-                               BLK_TA_SPLIT, !bio_flagged(bio, BIO_UPTODATE),
+               __blk_add_trace(bt, bio->bi_iter.bi_sector,
+                               bio->bi_iter.bi_size, bio->bi_rw, BLK_TA_SPLIT,
+                               !bio_flagged(bio, BIO_UPTODATE),
                                sizeof(rpdu), &rpdu);
        }
 }
@@ -918,9 +919,9 @@ static void blk_add_trace_bio_remap(void *ignore,
        r.device_to   = cpu_to_be32(bio->bi_bdev->bd_dev);
        r.sector_from = cpu_to_be64(from);
 
-       __blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw,
-                       BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE),
-                       sizeof(r), &r);
+       __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
+                       bio->bi_rw, BLK_TA_REMAP,
+                       !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r);
 }
 
 /**
index 22fa556967609465a0dbd98e238ee1d14b52e328..0e9f9eaade2f6a2dd0e729cd2d3bb38b4f6f8ec0 100644 (file)
@@ -367,9 +367,6 @@ static int remove_ftrace_list_ops(struct ftrace_ops **list,
 
 static int __register_ftrace_function(struct ftrace_ops *ops)
 {
-       if (unlikely(ftrace_disabled))
-               return -ENODEV;
-
        if (FTRACE_WARN_ON(ops == &global_ops))
                return -EINVAL;
 
@@ -428,9 +425,6 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
 {
        int ret;
 
-       if (ftrace_disabled)
-               return -ENODEV;
-
        if (WARN_ON(!(ops->flags & FTRACE_OPS_FL_ENABLED)))
                return -EBUSY;
 
@@ -2088,10 +2082,15 @@ static void ftrace_startup_enable(int command)
 static int ftrace_startup(struct ftrace_ops *ops, int command)
 {
        bool hash_enable = true;
+       int ret;
 
        if (unlikely(ftrace_disabled))
                return -ENODEV;
 
+       ret = __register_ftrace_function(ops);
+       if (ret)
+               return ret;
+
        ftrace_start_up++;
        command |= FTRACE_UPDATE_CALLS;
 
@@ -2113,12 +2112,17 @@ static int ftrace_startup(struct ftrace_ops *ops, int command)
        return 0;
 }
 
-static void ftrace_shutdown(struct ftrace_ops *ops, int command)
+static int ftrace_shutdown(struct ftrace_ops *ops, int command)
 {
        bool hash_disable = true;
+       int ret;
 
        if (unlikely(ftrace_disabled))
-               return;
+               return -ENODEV;
+
+       ret = __unregister_ftrace_function(ops);
+       if (ret)
+               return ret;
 
        ftrace_start_up--;
        /*
@@ -2153,9 +2157,10 @@ static void ftrace_shutdown(struct ftrace_ops *ops, int command)
        }
 
        if (!command || !ftrace_enabled)
-               return;
+               return 0;
 
        ftrace_run_update_code(command);
+       return 0;
 }
 
 static void ftrace_startup_sysctl(void)
@@ -3060,16 +3065,13 @@ static void __enable_ftrace_function_probe(void)
        if (i == FTRACE_FUNC_HASHSIZE)
                return;
 
-       ret = __register_ftrace_function(&trace_probe_ops);
-       if (!ret)
-               ret = ftrace_startup(&trace_probe_ops, 0);
+       ret = ftrace_startup(&trace_probe_ops, 0);
 
        ftrace_probe_registered = 1;
 }
 
 static void __disable_ftrace_function_probe(void)
 {
-       int ret;
        int i;
 
        if (!ftrace_probe_registered)
@@ -3082,9 +3084,7 @@ static void __disable_ftrace_function_probe(void)
        }
 
        /* no more funcs left */
-       ret = __unregister_ftrace_function(&trace_probe_ops);
-       if (!ret)
-               ftrace_shutdown(&trace_probe_ops, 0);
+       ftrace_shutdown(&trace_probe_ops, 0);
 
        ftrace_probe_registered = 0;
 }
@@ -4366,12 +4366,15 @@ core_initcall(ftrace_nodyn_init);
 static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
 static inline void ftrace_startup_enable(int command) { }
 /* Keep as macros so we do not need to define the commands */
-# define ftrace_startup(ops, command)                  \
-       ({                                              \
-               (ops)->flags |= FTRACE_OPS_FL_ENABLED;  \
-               0;                                      \
+# define ftrace_startup(ops, command)                                  \
+       ({                                                              \
+               int ___ret = __register_ftrace_function(ops);           \
+               if (!___ret)                                            \
+                       (ops)->flags |= FTRACE_OPS_FL_ENABLED;          \
+               ___ret;                                                 \
        })
-# define ftrace_shutdown(ops, command) do { } while (0)
+# define ftrace_shutdown(ops, command) __unregister_ftrace_function(ops)
+
 # define ftrace_startup_sysctl()       do { } while (0)
 # define ftrace_shutdown_sysctl()      do { } while (0)
 
@@ -4780,9 +4783,7 @@ int register_ftrace_function(struct ftrace_ops *ops)
 
        mutex_lock(&ftrace_lock);
 
-       ret = __register_ftrace_function(ops);
-       if (!ret)
-               ret = ftrace_startup(ops, 0);
+       ret = ftrace_startup(ops, 0);
 
        mutex_unlock(&ftrace_lock);
 
@@ -4801,9 +4802,7 @@ int unregister_ftrace_function(struct ftrace_ops *ops)
        int ret;
 
        mutex_lock(&ftrace_lock);
-       ret = __unregister_ftrace_function(ops);
-       if (!ret)
-               ftrace_shutdown(ops, 0);
+       ret = ftrace_shutdown(ops, 0);
        mutex_unlock(&ftrace_lock);
 
        return ret;
@@ -4997,6 +4996,13 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
        return NOTIFY_DONE;
 }
 
+/* Just a place holder for function graph */
+static struct ftrace_ops fgraph_ops __read_mostly = {
+       .func           = ftrace_stub,
+       .flags          = FTRACE_OPS_FL_STUB | FTRACE_OPS_FL_GLOBAL |
+                               FTRACE_OPS_FL_RECURSION_SAFE,
+};
+
 int register_ftrace_graph(trace_func_graph_ret_t retfunc,
                        trace_func_graph_ent_t entryfunc)
 {
@@ -5023,7 +5029,7 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
        ftrace_graph_return = retfunc;
        ftrace_graph_entry = entryfunc;
 
-       ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET);
+       ret = ftrace_startup(&fgraph_ops, FTRACE_START_FUNC_RET);
 
 out:
        mutex_unlock(&ftrace_lock);
@@ -5040,7 +5046,7 @@ void unregister_ftrace_graph(void)
        ftrace_graph_active--;
        ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
        ftrace_graph_entry = ftrace_graph_entry_stub;
-       ftrace_shutdown(&global_ops, FTRACE_STOP_FUNC_RET);
+       ftrace_shutdown(&fgraph_ops, FTRACE_STOP_FUNC_RET);
        unregister_pm_notifier(&ftrace_suspend_notifier);
        unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL);
 
index 78e27e3b52ac2ee0b9e86f544b77a45e12865d95..e854f420e033eb65a2bca233bb8df2e42778faf7 100644 (file)
@@ -24,6 +24,12 @@ static int   total_ref_count;
 static int perf_trace_event_perm(struct ftrace_event_call *tp_event,
                                 struct perf_event *p_event)
 {
+       if (tp_event->perf_perm) {
+               int ret = tp_event->perf_perm(tp_event, p_event);
+               if (ret)
+                       return ret;
+       }
+
        /* The ftrace function trace is allowed only for root. */
        if (ftrace_event_is_function(tp_event) &&
            perf_paranoid_tracepoint_raw() && !capable(CAP_SYS_ADMIN))
@@ -173,7 +179,7 @@ static int perf_trace_event_init(struct ftrace_event_call *tp_event,
 int perf_trace_init(struct perf_event *p_event)
 {
        struct ftrace_event_call *tp_event;
-       int event_id = p_event->attr.config;
+       u64 event_id = p_event->attr.config;
        int ret = -EINVAL;
 
        mutex_lock(&event_mutex);
index 987293d03ebcf0e6bf1c6b81e8a4e68c7965e903..b010eac595d20eece261310cc4acb629ad70b92b 100644 (file)
@@ -305,6 +305,9 @@ static DEFINE_HASHTABLE(unbound_pool_hash, UNBOUND_POOL_HASH_ORDER);
 /* I: attributes used when instantiating standard unbound pools on demand */
 static struct workqueue_attrs *unbound_std_wq_attrs[NR_STD_WORKER_POOLS];
 
+/* I: attributes used when instantiating ordered pools on demand */
+static struct workqueue_attrs *ordered_wq_attrs[NR_STD_WORKER_POOLS];
+
 struct workqueue_struct *system_wq __read_mostly;
 EXPORT_SYMBOL(system_wq);
 struct workqueue_struct *system_highpri_wq __read_mostly;
@@ -518,14 +521,21 @@ static inline void debug_work_activate(struct work_struct *work) { }
 static inline void debug_work_deactivate(struct work_struct *work) { }
 #endif
 
-/* allocate ID and assign it to @pool */
+/**
+ * worker_pool_assign_id - allocate ID and assing it to @pool
+ * @pool: the pool pointer of interest
+ *
+ * Returns 0 if ID in [0, WORK_OFFQ_POOL_NONE) is allocated and assigned
+ * successfully, -errno on failure.
+ */
 static int worker_pool_assign_id(struct worker_pool *pool)
 {
        int ret;
 
        lockdep_assert_held(&wq_pool_mutex);
 
-       ret = idr_alloc(&worker_pool_idr, pool, 0, 0, GFP_KERNEL);
+       ret = idr_alloc(&worker_pool_idr, pool, 0, WORK_OFFQ_POOL_NONE,
+                       GFP_KERNEL);
        if (ret >= 0) {
                pool->id = ret;
                return 0;
@@ -1320,7 +1330,7 @@ static void __queue_work(int cpu, struct workqueue_struct *wq,
 
        debug_work_activate(work);
 
-       /* if dying, only works from the same workqueue are allowed */
+       /* if draining, only works from the same workqueue are allowed */
        if (unlikely(wq->flags & __WQ_DRAINING) &&
            WARN_ON_ONCE(!is_chained_work(wq)))
                return;
@@ -1736,16 +1746,17 @@ static struct worker *create_worker(struct worker_pool *pool)
        if (IS_ERR(worker->task))
                goto fail;
 
+       set_user_nice(worker->task, pool->attrs->nice);
+
+       /* prevent userland from meddling with cpumask of workqueue workers */
+       worker->task->flags |= PF_NO_SETAFFINITY;
+
        /*
         * set_cpus_allowed_ptr() will fail if the cpumask doesn't have any
         * online CPUs.  It'll be re-applied when any of the CPUs come up.
         */
-       set_user_nice(worker->task, pool->attrs->nice);
        set_cpus_allowed_ptr(worker->task, pool->attrs->cpumask);
 
-       /* prevent userland from meddling with cpumask of workqueue workers */
-       worker->task->flags |= PF_NO_SETAFFINITY;
-
        /*
         * The caller is responsible for ensuring %POOL_DISASSOCIATED
         * remains stable across this function.  See the comments above the
@@ -2840,19 +2851,6 @@ already_gone:
        return false;
 }
 
-static bool __flush_work(struct work_struct *work)
-{
-       struct wq_barrier barr;
-
-       if (start_flush_work(work, &barr)) {
-               wait_for_completion(&barr.done);
-               destroy_work_on_stack(&barr.work);
-               return true;
-       } else {
-               return false;
-       }
-}
-
 /**
  * flush_work - wait for a work to finish executing the last queueing instance
  * @work: the work to flush
@@ -2866,10 +2864,18 @@ static bool __flush_work(struct work_struct *work)
  */
 bool flush_work(struct work_struct *work)
 {
+       struct wq_barrier barr;
+
        lock_map_acquire(&work->lockdep_map);
        lock_map_release(&work->lockdep_map);
 
-       return __flush_work(work);
+       if (start_flush_work(work, &barr)) {
+               wait_for_completion(&barr.done);
+               destroy_work_on_stack(&barr.work);
+               return true;
+       } else {
+               return false;
+       }
 }
 EXPORT_SYMBOL_GPL(flush_work);
 
@@ -4106,7 +4112,7 @@ out_unlock:
 static int alloc_and_link_pwqs(struct workqueue_struct *wq)
 {
        bool highpri = wq->flags & WQ_HIGHPRI;
-       int cpu;
+       int cpu, ret;
 
        if (!(wq->flags & WQ_UNBOUND)) {
                wq->cpu_pwqs = alloc_percpu(struct pool_workqueue);
@@ -4126,6 +4132,13 @@ static int alloc_and_link_pwqs(struct workqueue_struct *wq)
                        mutex_unlock(&wq->mutex);
                }
                return 0;
+       } else if (wq->flags & __WQ_ORDERED) {
+               ret = apply_workqueue_attrs(wq, ordered_wq_attrs[highpri]);
+               /* there should only be single pwq for ordering guarantee */
+               WARN(!ret && (wq->pwqs.next != &wq->dfl_pwq->pwqs_node ||
+                             wq->pwqs.prev != &wq->dfl_pwq->pwqs_node),
+                    "ordering guarantee broken for workqueue %s\n", wq->name);
+               return ret;
        } else {
                return apply_workqueue_attrs(wq, unbound_std_wq_attrs[highpri]);
        }
@@ -4814,14 +4827,7 @@ long work_on_cpu(int cpu, long (*fn)(void *), void *arg)
 
        INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn);
        schedule_work_on(cpu, &wfc.work);
-
-       /*
-        * The work item is on-stack and can't lead to deadlock through
-        * flushing.  Use __flush_work() to avoid spurious lockdep warnings
-        * when work_on_cpu()s are nested.
-        */
-       __flush_work(&wfc.work);
-
+       flush_work(&wfc.work);
        return wfc.ret;
 }
 EXPORT_SYMBOL_GPL(work_on_cpu);
@@ -5009,10 +5015,6 @@ static int __init init_workqueues(void)
        int std_nice[NR_STD_WORKER_POOLS] = { 0, HIGHPRI_NICE_LEVEL };
        int i, cpu;
 
-       /* make sure we have enough bits for OFFQ pool ID */
-       BUILD_BUG_ON((1LU << (BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT)) <
-                    WORK_CPU_END * NR_STD_WORKER_POOLS);
-
        WARN_ON(__alignof__(struct pool_workqueue) < __alignof__(long long));
 
        pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC);
@@ -5051,13 +5053,23 @@ static int __init init_workqueues(void)
                }
        }
 
-       /* create default unbound wq attrs */
+       /* create default unbound and ordered wq attrs */
        for (i = 0; i < NR_STD_WORKER_POOLS; i++) {
                struct workqueue_attrs *attrs;
 
                BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL)));
                attrs->nice = std_nice[i];
                unbound_std_wq_attrs[i] = attrs;
+
+               /*
+                * An ordered wq should have only one pwq as ordering is
+                * guaranteed by max_active which is enforced by pwqs.
+                * Turn off NUMA so that dfl_pwq is used for all nodes.
+                */
+               BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL)));
+               attrs->nice = std_nice[i];
+               attrs->no_numa = true;
+               ordered_wq_attrs[i] = attrs;
        }
 
        system_wq = alloc_workqueue("events", 0, 0);
index db25707aa41bc021b8174391091178b85258d466..6982094a7e74aa8c5daea87f90878174a8d746c1 100644 (file)
@@ -761,6 +761,15 @@ config PANIC_ON_OOPS_VALUE
        default 0 if !PANIC_ON_OOPS
        default 1 if PANIC_ON_OOPS
 
+config PANIC_TIMEOUT
+       int "panic timeout"
+       default 0
+       help
+         Set the timeout value (in seconds) until a reboot occurs when the
+         the kernel panics. If n = 0, then we wait forever. A timeout
+         value n > 0 will wait n seconds before rebooting, while a timeout
+         value n < 0 will reboot immediately.
+
 config SCHED_DEBUG
        bool "Collect scheduler debugging info"
        depends on DEBUG_KERNEL && PROC_FS
index 5b4b8886435ec77c7f51ff0221b3bc01558e5798..b8d848fb13772b93c5731115e8e776712c4fb593 100644 (file)
@@ -65,13 +65,17 @@ static int populate_dir(struct kobject *kobj)
 
 static int create_dir(struct kobject *kobj)
 {
+       const struct kobj_ns_type_operations *ops;
        int error;
 
        error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
-       if (!error) {
-               error = populate_dir(kobj);
-               if (error)
-                       sysfs_remove_dir(kobj);
+       if (error)
+               return error;
+
+       error = populate_dir(kobj);
+       if (error) {
+               sysfs_remove_dir(kobj);
+               return error;
        }
 
        /*
@@ -80,7 +84,20 @@ static int create_dir(struct kobject *kobj)
         */
        sysfs_get(kobj->sd);
 
-       return error;
+       /*
+        * If @kobj has ns_ops, its children need to be filtered based on
+        * their namespace tags.  Enable namespace support on @kobj->sd.
+        */
+       ops = kobj_child_ns_ops(kobj);
+       if (ops) {
+               BUG_ON(ops->type <= KOBJ_NS_TYPE_NONE);
+               BUG_ON(ops->type >= KOBJ_NS_TYPES);
+               BUG_ON(!kobj_ns_type_registered(ops->type));
+
+               kernfs_enable_ns(kobj->sd);
+       }
+
+       return 0;
 }
 
 static int get_kobj_path_length(struct kobject *kobj)
index d2b123f8456b22479681d4512fbb8c1e445a0158..f07a40d33871e2b9414ea40b53ee154108932d4e 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/export.h>
 #include <linux/lockref.h>
+#include <linux/mutex.h>
 
 #if USE_CMPXCHG_LOCKREF
 
 # define cmpxchg64_relaxed cmpxchg64
 #endif
 
-/*
- * Allow architectures to override the default cpu_relax() within CMPXCHG_LOOP.
- * This is useful for architectures with an expensive cpu_relax().
- */
-#ifndef arch_mutex_cpu_relax
-# define arch_mutex_cpu_relax() cpu_relax()
-#endif
-
 /*
  * Note that the "cmpxchg()" reloads the "old" value for the
  * failure case.
index 5a7d58fb883bfa1c4917e48d251cd132c8d9baf9..523918b8c6dcbef6968c37e2fa38ee87a3b2518c 100644 (file)
@@ -98,27 +98,24 @@ int init_emergency_isa_pool(void)
 static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
 {
        unsigned char *vfrom;
-       struct bio_vec *tovec, *fromvec;
-       int i;
-
-       bio_for_each_segment(tovec, to, i) {
-               fromvec = from->bi_io_vec + i;
-
-               /*
-                * not bounced
-                */
-               if (tovec->bv_page == fromvec->bv_page)
-                       continue;
-
-               /*
-                * fromvec->bv_offset and fromvec->bv_len might have been
-                * modified by the block layer, so use the original copy,
-                * bounce_copy_vec already uses tovec->bv_len
-                */
-               vfrom = page_address(fromvec->bv_page) + tovec->bv_offset;
+       struct bio_vec tovec, *fromvec = from->bi_io_vec;
+       struct bvec_iter iter;
+
+       bio_for_each_segment(tovec, to, iter) {
+               if (tovec.bv_page != fromvec->bv_page) {
+                       /*
+                        * fromvec->bv_offset and fromvec->bv_len might have
+                        * been modified by the block layer, so use the original
+                        * copy, bounce_copy_vec already uses tovec->bv_len
+                        */
+                       vfrom = page_address(fromvec->bv_page) +
+                               tovec.bv_offset;
+
+                       bounce_copy_vec(&tovec, vfrom);
+                       flush_dcache_page(tovec.bv_page);
+               }
 
-               bounce_copy_vec(tovec, vfrom);
-               flush_dcache_page(tovec->bv_page);
+               fromvec++;
        }
 }
 
@@ -201,13 +198,14 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
 {
        struct bio *bio;
        int rw = bio_data_dir(*bio_orig);
-       struct bio_vec *to, *from;
+       struct bio_vec *to, from;
+       struct bvec_iter iter;
        unsigned i;
 
        if (force)
                goto bounce;
-       bio_for_each_segment(from, *bio_orig, i)
-               if (page_to_pfn(from->bv_page) > queue_bounce_pfn(q))
+       bio_for_each_segment(from, *bio_orig, iter)
+               if (page_to_pfn(from.bv_page) > queue_bounce_pfn(q))
                        goto bounce;
 
        return;
index f1a0ae6e11b86b3020c90d7241ba12d47d2bbaa8..7aa0d405b14865fcffbc484dddf5703ffadd0ab5 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/swapops.h>
 #include <linux/spinlock.h>
 #include <linux/eventfd.h>
+#include <linux/poll.h>
 #include <linux/sort.h>
 #include <linux/fs.h>
 #include <linux/seq_file.h>
@@ -55,6 +56,7 @@
 #include <linux/cpu.h>
 #include <linux/oom.h>
 #include <linux/lockdep.h>
+#include <linux/file.h>
 #include "internal.h"
 #include <net/sock.h>
 #include <net/ip.h>
@@ -227,6 +229,46 @@ struct mem_cgroup_eventfd_list {
        struct eventfd_ctx *eventfd;
 };
 
+/*
+ * cgroup_event represents events which userspace want to receive.
+ */
+struct mem_cgroup_event {
+       /*
+        * memcg which the event belongs to.
+        */
+       struct mem_cgroup *memcg;
+       /*
+        * eventfd to signal userspace about the event.
+        */
+       struct eventfd_ctx *eventfd;
+       /*
+        * Each of these stored in a list by the cgroup.
+        */
+       struct list_head list;
+       /*
+        * register_event() callback will be used to add new userspace
+        * waiter for changes related to this event.  Use eventfd_signal()
+        * on eventfd to send notification to userspace.
+        */
+       int (*register_event)(struct mem_cgroup *memcg,
+                             struct eventfd_ctx *eventfd, const char *args);
+       /*
+        * unregister_event() callback will be called when userspace closes
+        * the eventfd or on cgroup removing.  This callback must be set,
+        * if you want provide notification functionality.
+        */
+       void (*unregister_event)(struct mem_cgroup *memcg,
+                                struct eventfd_ctx *eventfd);
+       /*
+        * All fields below needed to unregister event when
+        * userspace closes eventfd.
+        */
+       poll_table pt;
+       wait_queue_head_t *wqh;
+       wait_queue_t wait;
+       struct work_struct remove;
+};
+
 static void mem_cgroup_threshold(struct mem_cgroup *memcg);
 static void mem_cgroup_oom_notify(struct mem_cgroup *memcg);
 
@@ -331,6 +373,10 @@ struct mem_cgroup {
        atomic_t        numainfo_updating;
 #endif
 
+       /* List of events which userspace want to receive */
+       struct list_head event_list;
+       spinlock_t event_list_lock;
+
        struct mem_cgroup_per_node *nodeinfo[0];
        /* WARNING: nodeinfo must be the last member here */
 };
@@ -490,11 +536,6 @@ struct cgroup_subsys_state *vmpressure_to_css(struct vmpressure *vmpr)
        return &container_of(vmpr, struct mem_cgroup, vmpressure)->css;
 }
 
-struct vmpressure *css_to_vmpressure(struct cgroup_subsys_state *css)
-{
-       return &mem_cgroup_from_css(css)->vmpressure;
-}
-
 static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
 {
        return (memcg == root_mem_cgroup);
@@ -5648,13 +5689,11 @@ static void mem_cgroup_oom_notify(struct mem_cgroup *memcg)
                mem_cgroup_oom_notify_cb(iter);
 }
 
-static int mem_cgroup_usage_register_event(struct cgroup_subsys_state *css,
-       struct cftype *cft, struct eventfd_ctx *eventfd, const char *args)
+static int __mem_cgroup_usage_register_event(struct mem_cgroup *memcg,
+       struct eventfd_ctx *eventfd, const char *args, enum res_type type)
 {
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
        struct mem_cgroup_thresholds *thresholds;
        struct mem_cgroup_threshold_ary *new;
-       enum res_type type = MEMFILE_TYPE(cft->private);
        u64 threshold, usage;
        int i, size, ret;
 
@@ -5731,13 +5770,23 @@ unlock:
        return ret;
 }
 
-static void mem_cgroup_usage_unregister_event(struct cgroup_subsys_state *css,
-       struct cftype *cft, struct eventfd_ctx *eventfd)
+static int mem_cgroup_usage_register_event(struct mem_cgroup *memcg,
+       struct eventfd_ctx *eventfd, const char *args)
+{
+       return __mem_cgroup_usage_register_event(memcg, eventfd, args, _MEM);
+}
+
+static int memsw_cgroup_usage_register_event(struct mem_cgroup *memcg,
+       struct eventfd_ctx *eventfd, const char *args)
+{
+       return __mem_cgroup_usage_register_event(memcg, eventfd, args, _MEMSWAP);
+}
+
+static void __mem_cgroup_usage_unregister_event(struct mem_cgroup *memcg,
+       struct eventfd_ctx *eventfd, enum res_type type)
 {
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
        struct mem_cgroup_thresholds *thresholds;
        struct mem_cgroup_threshold_ary *new;
-       enum res_type type = MEMFILE_TYPE(cft->private);
        u64 usage;
        int i, j, size;
 
@@ -5810,14 +5859,23 @@ unlock:
        mutex_unlock(&memcg->thresholds_lock);
 }
 
-static int mem_cgroup_oom_register_event(struct cgroup_subsys_state *css,
-       struct cftype *cft, struct eventfd_ctx *eventfd, const char *args)
+static void mem_cgroup_usage_unregister_event(struct mem_cgroup *memcg,
+       struct eventfd_ctx *eventfd)
+{
+       return __mem_cgroup_usage_unregister_event(memcg, eventfd, _MEM);
+}
+
+static void memsw_cgroup_usage_unregister_event(struct mem_cgroup *memcg,
+       struct eventfd_ctx *eventfd)
+{
+       return __mem_cgroup_usage_unregister_event(memcg, eventfd, _MEMSWAP);
+}
+
+static int mem_cgroup_oom_register_event(struct mem_cgroup *memcg,
+       struct eventfd_ctx *eventfd, const char *args)
 {
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
        struct mem_cgroup_eventfd_list *event;
-       enum res_type type = MEMFILE_TYPE(cft->private);
 
-       BUG_ON(type != _OOM_TYPE);
        event = kmalloc(sizeof(*event), GFP_KERNEL);
        if (!event)
                return -ENOMEM;
@@ -5835,14 +5893,10 @@ static int mem_cgroup_oom_register_event(struct cgroup_subsys_state *css,
        return 0;
 }
 
-static void mem_cgroup_oom_unregister_event(struct cgroup_subsys_state *css,
-       struct cftype *cft, struct eventfd_ctx *eventfd)
+static void mem_cgroup_oom_unregister_event(struct mem_cgroup *memcg,
+       struct eventfd_ctx *eventfd)
 {
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
        struct mem_cgroup_eventfd_list *ev, *tmp;
-       enum res_type type = MEMFILE_TYPE(cft->private);
-
-       BUG_ON(type != _OOM_TYPE);
 
        spin_lock(&memcg_oom_lock);
 
@@ -5959,13 +6013,233 @@ static void kmem_cgroup_css_offline(struct mem_cgroup *memcg)
 }
 #endif
 
+/*
+ * DO NOT USE IN NEW FILES.
+ *
+ * "cgroup.event_control" implementation.
+ *
+ * This is way over-engineered.  It tries to support fully configurable
+ * events for each user.  Such level of flexibility is completely
+ * unnecessary especially in the light of the planned unified hierarchy.
+ *
+ * Please deprecate this and replace with something simpler if at all
+ * possible.
+ */
+
+/*
+ * Unregister event and free resources.
+ *
+ * Gets called from workqueue.
+ */
+static void memcg_event_remove(struct work_struct *work)
+{
+       struct mem_cgroup_event *event =
+               container_of(work, struct mem_cgroup_event, remove);
+       struct mem_cgroup *memcg = event->memcg;
+
+       remove_wait_queue(event->wqh, &event->wait);
+
+       event->unregister_event(memcg, event->eventfd);
+
+       /* Notify userspace the event is going away. */
+       eventfd_signal(event->eventfd, 1);
+
+       eventfd_ctx_put(event->eventfd);
+       kfree(event);
+       css_put(&memcg->css);
+}
+
+/*
+ * Gets called on POLLHUP on eventfd when user closes it.
+ *
+ * Called with wqh->lock held and interrupts disabled.
+ */
+static int memcg_event_wake(wait_queue_t *wait, unsigned mode,
+                           int sync, void *key)
+{
+       struct mem_cgroup_event *event =
+               container_of(wait, struct mem_cgroup_event, wait);
+       struct mem_cgroup *memcg = event->memcg;
+       unsigned long flags = (unsigned long)key;
+
+       if (flags & POLLHUP) {
+               /*
+                * If the event has been detached at cgroup removal, we
+                * can simply return knowing the other side will cleanup
+                * for us.
+                *
+                * We can't race against event freeing since the other
+                * side will require wqh->lock via remove_wait_queue(),
+                * which we hold.
+                */
+               spin_lock(&memcg->event_list_lock);
+               if (!list_empty(&event->list)) {
+                       list_del_init(&event->list);
+                       /*
+                        * We are in atomic context, but cgroup_event_remove()
+                        * may sleep, so we have to call it in workqueue.
+                        */
+                       schedule_work(&event->remove);
+               }
+               spin_unlock(&memcg->event_list_lock);
+       }
+
+       return 0;
+}
+
+static void memcg_event_ptable_queue_proc(struct file *file,
+               wait_queue_head_t *wqh, poll_table *pt)
+{
+       struct mem_cgroup_event *event =
+               container_of(pt, struct mem_cgroup_event, pt);
+
+       event->wqh = wqh;
+       add_wait_queue(wqh, &event->wait);
+}
+
+/*
+ * DO NOT USE IN NEW FILES.
+ *
+ * Parse input and register new cgroup event handler.
+ *
+ * Input must be in format '<event_fd> <control_fd> <args>'.
+ * Interpretation of args is defined by control file implementation.
+ */
+static int memcg_write_event_control(struct cgroup_subsys_state *css,
+                                    struct cftype *cft, const char *buffer)
+{
+       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+       struct mem_cgroup_event *event;
+       struct cgroup_subsys_state *cfile_css;
+       unsigned int efd, cfd;
+       struct fd efile;
+       struct fd cfile;
+       const char *name;
+       char *endp;
+       int ret;
+
+       efd = simple_strtoul(buffer, &endp, 10);
+       if (*endp != ' ')
+               return -EINVAL;
+       buffer = endp + 1;
+
+       cfd = simple_strtoul(buffer, &endp, 10);
+       if ((*endp != ' ') && (*endp != '\0'))
+               return -EINVAL;
+       buffer = endp + 1;
+
+       event = kzalloc(sizeof(*event), GFP_KERNEL);
+       if (!event)
+               return -ENOMEM;
+
+       event->memcg = memcg;
+       INIT_LIST_HEAD(&event->list);
+       init_poll_funcptr(&event->pt, memcg_event_ptable_queue_proc);
+       init_waitqueue_func_entry(&event->wait, memcg_event_wake);
+       INIT_WORK(&event->remove, memcg_event_remove);
+
+       efile = fdget(efd);
+       if (!efile.file) {
+               ret = -EBADF;
+               goto out_kfree;
+       }
+
+       event->eventfd = eventfd_ctx_fileget(efile.file);
+       if (IS_ERR(event->eventfd)) {
+               ret = PTR_ERR(event->eventfd);
+               goto out_put_efile;
+       }
+
+       cfile = fdget(cfd);
+       if (!cfile.file) {
+               ret = -EBADF;
+               goto out_put_eventfd;
+       }
+
+       /* the process need read permission on control file */
+       /* AV: shouldn't we check that it's been opened for read instead? */
+       ret = inode_permission(file_inode(cfile.file), MAY_READ);
+       if (ret < 0)
+               goto out_put_cfile;
+
+       /*
+        * Determine the event callbacks and set them in @event.  This used
+        * to be done via struct cftype but cgroup core no longer knows
+        * about these events.  The following is crude but the whole thing
+        * is for compatibility anyway.
+        *
+        * DO NOT ADD NEW FILES.
+        */
+       name = cfile.file->f_dentry->d_name.name;
+
+       if (!strcmp(name, "memory.usage_in_bytes")) {
+               event->register_event = mem_cgroup_usage_register_event;
+               event->unregister_event = mem_cgroup_usage_unregister_event;
+       } else if (!strcmp(name, "memory.oom_control")) {
+               event->register_event = mem_cgroup_oom_register_event;
+               event->unregister_event = mem_cgroup_oom_unregister_event;
+       } else if (!strcmp(name, "memory.pressure_level")) {
+               event->register_event = vmpressure_register_event;
+               event->unregister_event = vmpressure_unregister_event;
+       } else if (!strcmp(name, "memory.memsw.usage_in_bytes")) {
+               event->register_event = memsw_cgroup_usage_register_event;
+               event->unregister_event = memsw_cgroup_usage_unregister_event;
+       } else {
+               ret = -EINVAL;
+               goto out_put_cfile;
+       }
+
+       /*
+        * Verify @cfile should belong to @css.  Also, remaining events are
+        * automatically removed on cgroup destruction but the removal is
+        * asynchronous, so take an extra ref on @css.
+        */
+       rcu_read_lock();
+
+       ret = -EINVAL;
+       cfile_css = css_from_dir(cfile.file->f_dentry->d_parent,
+                                &mem_cgroup_subsys);
+       if (cfile_css == css && css_tryget(css))
+               ret = 0;
+
+       rcu_read_unlock();
+       if (ret)
+               goto out_put_cfile;
+
+       ret = event->register_event(memcg, event->eventfd, buffer);
+       if (ret)
+               goto out_put_css;
+
+       efile.file->f_op->poll(efile.file, &event->pt);
+
+       spin_lock(&memcg->event_list_lock);
+       list_add(&event->list, &memcg->event_list);
+       spin_unlock(&memcg->event_list_lock);
+
+       fdput(cfile);
+       fdput(efile);
+
+       return 0;
+
+out_put_css:
+       css_put(css);
+out_put_cfile:
+       fdput(cfile);
+out_put_eventfd:
+       eventfd_ctx_put(event->eventfd);
+out_put_efile:
+       fdput(efile);
+out_kfree:
+       kfree(event);
+
+       return ret;
+}
+
 static struct cftype mem_cgroup_files[] = {
        {
                .name = "usage_in_bytes",
                .private = MEMFILE_PRIVATE(_MEM, RES_USAGE),
                .read = mem_cgroup_read,
-               .register_event = mem_cgroup_usage_register_event,
-               .unregister_event = mem_cgroup_usage_unregister_event,
        },
        {
                .name = "max_usage_in_bytes",
@@ -6005,6 +6279,12 @@ static struct cftype mem_cgroup_files[] = {
                .write_u64 = mem_cgroup_hierarchy_write,
                .read_u64 = mem_cgroup_hierarchy_read,
        },
+       {
+               .name = "cgroup.event_control",         /* XXX: for compat */
+               .write_string = memcg_write_event_control,
+               .flags = CFTYPE_NO_PREFIX,
+               .mode = S_IWUGO,
+       },
        {
                .name = "swappiness",
                .read_u64 = mem_cgroup_swappiness_read,
@@ -6019,14 +6299,10 @@ static struct cftype mem_cgroup_files[] = {
                .name = "oom_control",
                .read_map = mem_cgroup_oom_control_read,
                .write_u64 = mem_cgroup_oom_control_write,
-               .register_event = mem_cgroup_oom_register_event,
-               .unregister_event = mem_cgroup_oom_unregister_event,
                .private = MEMFILE_PRIVATE(_OOM_TYPE, OOM_CONTROL),
        },
        {
                .name = "pressure_level",
-               .register_event = vmpressure_register_event,
-               .unregister_event = vmpressure_unregister_event,
        },
 #ifdef CONFIG_NUMA
        {
@@ -6074,8 +6350,6 @@ static struct cftype memsw_cgroup_files[] = {
                .name = "memsw.usage_in_bytes",
                .private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
                .read = mem_cgroup_read,
-               .register_event = mem_cgroup_usage_register_event,
-               .unregister_event = mem_cgroup_usage_unregister_event,
        },
        {
                .name = "memsw.max_usage_in_bytes",
@@ -6265,6 +6539,8 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
        mutex_init(&memcg->thresholds_lock);
        spin_lock_init(&memcg->move_lock);
        vmpressure_init(&memcg->vmpressure);
+       INIT_LIST_HEAD(&memcg->event_list);
+       spin_lock_init(&memcg->event_list_lock);
 
        return &memcg->css;
 
@@ -6340,6 +6616,19 @@ static void mem_cgroup_invalidate_reclaim_iterators(struct mem_cgroup *memcg)
 static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+       struct mem_cgroup_event *event, *tmp;
+
+       /*
+        * Unregister events and notify userspace.
+        * Notify userspace about cgroup removing only after rmdir of cgroup
+        * directory to avoid race between userspace and kernelspace.
+        */
+       spin_lock(&memcg->event_list_lock);
+       list_for_each_entry_safe(event, tmp, &memcg->event_list, list) {
+               list_del_init(&event->list);
+               schedule_work(&event->remove);
+       }
+       spin_unlock(&memcg->event_list_lock);
 
        kmem_cgroup_css_offline(memcg);
 
index 8c79a4764be0c99a1d573d174e2d247e90079519..f14eded987fac8276e3e3da5ff11d260a8ba44cf 100644 (file)
@@ -31,13 +31,13 @@ static struct bio *get_swap_bio(gfp_t gfp_flags,
 
        bio = bio_alloc(gfp_flags, 1);
        if (bio) {
-               bio->bi_sector = map_swap_page(page, &bio->bi_bdev);
-               bio->bi_sector <<= PAGE_SHIFT - 9;
+               bio->bi_iter.bi_sector = map_swap_page(page, &bio->bi_bdev);
+               bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
                bio->bi_io_vec[0].bv_page = page;
                bio->bi_io_vec[0].bv_len = PAGE_SIZE;
                bio->bi_io_vec[0].bv_offset = 0;
                bio->bi_vcnt = 1;
-               bio->bi_size = PAGE_SIZE;
+               bio->bi_iter.bi_size = PAGE_SIZE;
                bio->bi_end_io = end_io;
        }
        return bio;
@@ -62,7 +62,7 @@ void end_swap_bio_write(struct bio *bio, int err)
                printk(KERN_ALERT "Write-error on swap-device (%u:%u:%Lu)\n",
                                imajor(bio->bi_bdev->bd_inode),
                                iminor(bio->bi_bdev->bd_inode),
-                               (unsigned long long)bio->bi_sector);
+                               (unsigned long long)bio->bi_iter.bi_sector);
                ClearPageReclaim(page);
        }
        end_page_writeback(page);
@@ -80,7 +80,7 @@ void end_swap_bio_read(struct bio *bio, int err)
                printk(KERN_ALERT "Read-error on swap-device (%u:%u:%Lu)\n",
                                imajor(bio->bi_bdev->bd_inode),
                                iminor(bio->bi_bdev->bd_inode),
-                               (unsigned long long)bio->bi_sector);
+                               (unsigned long long)bio->bi_iter.bi_sector);
                goto out;
        }
 
index e0f62837c3f4873ea2d54c14845c30cb888a386b..196970a4541f0c07108eff49b7cb8d12fd930b06 100644 (file)
@@ -278,8 +278,7 @@ void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio)
 
 /**
  * vmpressure_register_event() - Bind vmpressure notifications to an eventfd
- * @css:       css that is interested in vmpressure notifications
- * @cft:       cgroup control files handle
+ * @memcg:     memcg that is interested in vmpressure notifications
  * @eventfd:   eventfd context to link notifications with
  * @args:      event arguments (used to set up a pressure level threshold)
  *
@@ -289,15 +288,12 @@ void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio)
  * threshold (one of vmpressure_str_levels, i.e. "low", "medium", or
  * "critical").
  *
- * This function should not be used directly, just pass it to (struct
- * cftype).register_event, and then cgroup core will handle everything by
- * itself.
+ * To be used as memcg event method.
  */
-int vmpressure_register_event(struct cgroup_subsys_state *css,
-                             struct cftype *cft, struct eventfd_ctx *eventfd,
-                             const char *args)
+int vmpressure_register_event(struct mem_cgroup *memcg,
+                             struct eventfd_ctx *eventfd, const char *args)
 {
-       struct vmpressure *vmpr = css_to_vmpressure(css);
+       struct vmpressure *vmpr = memcg_to_vmpressure(memcg);
        struct vmpressure_event *ev;
        int level;
 
@@ -325,23 +321,19 @@ int vmpressure_register_event(struct cgroup_subsys_state *css,
 
 /**
  * vmpressure_unregister_event() - Unbind eventfd from vmpressure
- * @css:       css handle
- * @cft:       cgroup control files handle
+ * @memcg:     memcg handle
  * @eventfd:   eventfd context that was used to link vmpressure with the @cg
  *
  * This function does internal manipulations to detach the @eventfd from
  * the vmpressure notifications, and then frees internal resources
  * associated with the @eventfd (but the @eventfd itself is not freed).
  *
- * This function should not be used directly, just pass it to (struct
- * cftype).unregister_event, and then cgroup core will handle everything
- * by itself.
+ * To be used as memcg event method.
  */
-void vmpressure_unregister_event(struct cgroup_subsys_state *css,
-                                struct cftype *cft,
+void vmpressure_unregister_event(struct mem_cgroup *memcg,
                                 struct eventfd_ctx *eventfd)
 {
-       struct vmpressure *vmpr = css_to_vmpressure(css);
+       struct vmpressure *vmpr = memcg_to_vmpressure(memcg);
        struct vmpressure_event *ev;
 
        mutex_lock(&vmpr->events_lock);
index ee8fd6bd4035b28697db6dacaf3453a3d94a72a3..a5e4d2dcb03e8c98eae243e1dd1b82cea68bd227 100644 (file)
@@ -1011,9 +1011,6 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
        if (err < 0)
                goto destroy_tagpool;
 
-       if (!clnt->trans_mod)
-               clnt->trans_mod = v9fs_get_trans_by_name("virtio");
-
        if (!clnt->trans_mod)
                clnt->trans_mod = v9fs_get_default_trans();
 
index 9321a77630675dacbca66949e7e2e0f75d25deed..b7bd7f2961bf60f49258bd60a702eadd8d651773 100644 (file)
@@ -1048,7 +1048,7 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
 static struct p9_trans_module p9_tcp_trans = {
        .name = "tcp",
        .maxsize = MAX_SOCK_BUF,
-       .def = 1,
+       .def = 0,
        .create = p9_fd_create_tcp,
        .close = p9_fd_close,
        .request = p9_fd_request,
index 9c5a1aa34d1253c725af29889d83759946af37c3..cd1e1ede73a45c2516091263c937f45024616c4e 100644 (file)
@@ -698,7 +698,7 @@ static struct p9_trans_module p9_virtio_trans = {
         * page in zero copy.
         */
        .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3),
-       .def = 0,
+       .def = 1,
        .owner = THIS_MODULE,
 };
 
index 6ccc4eb9e55e4958f3eb070894a7668b05c98b5b..03e83558a41100b8caed44da2f9f3a9ef35d32d2 100644 (file)
@@ -1275,15 +1275,17 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
                hci_setup_link_policy(req);
 
        if (lmp_le_capable(hdev)) {
-               /* If the controller has a public BD_ADDR, then by
-                * default use that one. If this is a LE only
-                * controller without one, default to the random
-                * address.
-                */
-               if (bacmp(&hdev->bdaddr, BDADDR_ANY))
-                       hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
-               else
-                       hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
+               if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
+                       /* If the controller has a public BD_ADDR, then
+                        * by default use that one. If this is a LE only
+                        * controller without a public address, default
+                        * to the random address.
+                        */
+                       if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+                               hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
+                       else
+                               hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
+               }
 
                hci_set_le_support(req);
        }
index 5935f748c0f9a6fe71cb3c0fe8baeaedb7019c37..5fb3df66c2cd5bda5b0ba7fa6cfda11565dbcde3 100644 (file)
@@ -486,7 +486,10 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev,
 
        BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
-       if (!rp->status)
+       if (rp->status)
+               return;
+
+       if (test_bit(HCI_SETUP, &hdev->dev_flags))
                memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
 }
 
@@ -538,12 +541,6 @@ static void hci_cc_read_local_features(struct hci_dev *hdev,
 
        if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
                hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
-
-       BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
-              hdev->features[0][0], hdev->features[0][1],
-              hdev->features[0][2], hdev->features[0][3],
-              hdev->features[0][4], hdev->features[0][5],
-              hdev->features[0][6], hdev->features[0][7]);
 }
 
 static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
@@ -1782,7 +1779,9 @@ static u8 hci_to_mgmt_reason(u8 err)
 static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_disconn_complete *ev = (void *) skb->data;
+       u8 reason = hci_to_mgmt_reason(ev->reason);
        struct hci_conn *conn;
+       u8 type;
 
        BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
 
@@ -1792,43 +1791,38 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
        if (!conn)
                goto unlock;
 
-       if (ev->status == 0)
-               conn->state = BT_CLOSED;
+       if (ev->status) {
+               mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+                                      conn->dst_type, ev->status);
+               goto unlock;
+       }
 
-       if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
-           (conn->type == ACL_LINK || conn->type == LE_LINK)) {
-               if (ev->status) {
-                       mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
-                                              conn->dst_type, ev->status);
-               } else {
-                       u8 reason = hci_to_mgmt_reason(ev->reason);
+       conn->state = BT_CLOSED;
 
-                       mgmt_device_disconnected(hdev, &conn->dst, conn->type,
-                                                conn->dst_type, reason);
-               }
-       }
+       if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
+               mgmt_device_disconnected(hdev, &conn->dst, conn->type,
+                                        conn->dst_type, reason);
 
-       if (ev->status == 0) {
-               u8 type = conn->type;
+       if (conn->type == ACL_LINK && conn->flush_key)
+               hci_remove_link_key(hdev, &conn->dst);
 
-               if (type == ACL_LINK && conn->flush_key)
-                       hci_remove_link_key(hdev, &conn->dst);
-               hci_proto_disconn_cfm(conn, ev->reason);
-               hci_conn_del(conn);
+       type = conn->type;
 
-               /* Re-enable advertising if necessary, since it might
-                * have been disabled by the connection. From the
-                * HCI_LE_Set_Advertise_Enable command description in
-                * the core specification (v4.0):
-                * "The Controller shall continue advertising until the Host
-                * issues an LE_Set_Advertise_Enable command with
-                * Advertising_Enable set to 0x00 (Advertising is disabled)
-                * or until a connection is created or until the Advertising
-                * is timed out due to Directed Advertising."
-                */
-               if (type == LE_LINK)
-                       mgmt_reenable_advertising(hdev);
-       }
+       hci_proto_disconn_cfm(conn, ev->reason);
+       hci_conn_del(conn);
+
+       /* Re-enable advertising if necessary, since it might
+        * have been disabled by the connection. From the
+        * HCI_LE_Set_Advertise_Enable command description in
+        * the core specification (v4.0):
+        * "The Controller shall continue advertising until the Host
+        * issues an LE_Set_Advertise_Enable command with
+        * Advertising_Enable set to 0x00 (Advertising is disabled)
+        * or until a connection is created or until the Advertising
+        * is timed out due to Directed Advertising."
+        */
+       if (type == LE_LINK)
+               mgmt_reenable_advertising(hdev);
 
 unlock:
        hci_dev_unlock(hdev);
index 074d83690a414c8e668499d7f7e7c86215c563ea..a03ca3ca91bfa77e2663a09f90ce2271addb2331 100644 (file)
@@ -1264,7 +1264,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
 
                if (cp->val == 0x02) {
                        /* Limited discoverable mode */
-                       hci_cp.num_iac = 2;
+                       hci_cp.num_iac = min_t(u8, hdev->num_iac, 2);
                        hci_cp.iac_lap[0] = 0x00;       /* LIAC */
                        hci_cp.iac_lap[1] = 0x8b;
                        hci_cp.iac_lap[2] = 0x9e;
@@ -4595,6 +4595,9 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
        struct mgmt_ev_device_disconnected ev;
        struct sock *sk = NULL;
 
+       if (link_type != ACL_LINK && link_type != LE_LINK)
+               return;
+
        mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);
 
        bacpy(&ev.addr.bdaddr, bdaddr);
@@ -4613,6 +4616,8 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
 void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
                            u8 link_type, u8 addr_type, u8 status)
 {
+       u8 bdaddr_type = link_to_bdaddr(link_type, addr_type);
+       struct mgmt_cp_disconnect *cp;
        struct mgmt_rp_disconnect rp;
        struct pending_cmd *cmd;
 
@@ -4623,8 +4628,16 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
        if (!cmd)
                return;
 
+       cp = cmd->param;
+
+       if (bacmp(bdaddr, &cp->addr.bdaddr))
+               return;
+
+       if (cp->addr.type != bdaddr_type)
+               return;
+
        bacpy(&rp.addr.bdaddr, bdaddr);
-       rp.addr.type = link_to_bdaddr(link_type, addr_type);
+       rp.addr.type = bdaddr_type;
 
        cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
                     mgmt_status(status), &rp, sizeof(rp));
index 4b07acb8293c3df3542e2a1661a6ae07bcfa6596..f99352d1aa4308bfa54296306189912b0a708b22 100644 (file)
@@ -257,11 +257,11 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
        return 0;
 }
 
-static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
+static void smp_failure(struct l2cap_conn *conn, u8 reason)
 {
        struct hci_conn *hcon = conn->hcon;
 
-       if (send)
+       if (reason)
                smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
                             &reason);
 
@@ -406,7 +406,7 @@ static void confirm_work(struct work_struct *work)
        return;
 
 error:
-       smp_failure(conn, reason, 1);
+       smp_failure(conn, reason);
 }
 
 static void random_work(struct work_struct *work)
@@ -490,7 +490,7 @@ static void random_work(struct work_struct *work)
        return;
 
 error:
-       smp_failure(conn, reason, 1);
+       smp_failure(conn, reason);
 }
 
 static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
@@ -555,10 +555,10 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
                break;
        case MGMT_OP_USER_PASSKEY_NEG_REPLY:
        case MGMT_OP_USER_CONFIRM_NEG_REPLY:
-               smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1);
+               smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
                return 0;
        default:
-               smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1);
+               smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
                return -EOPNOTSUPP;
        }
 
@@ -895,7 +895,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
                break;
 
        case SMP_CMD_PAIRING_FAIL:
-               smp_failure(conn, skb->data[0], 0);
+               smp_failure(conn, 0);
                reason = 0;
                err = -EPERM;
                break;
@@ -941,7 +941,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 
 done:
        if (reason)
-               smp_failure(conn, reason, 1);
+               smp_failure(conn, reason);
 
        kfree_skb(skb);
        return err;
index 4a5df7b1cc9ff5652185e0248cf5a4df4006effd..18c039b95c22459f8d669ee2598c411c1b615141 100644 (file)
@@ -777,13 +777,12 @@ static void ceph_msg_data_bio_cursor_init(struct ceph_msg_data_cursor *cursor,
 
        bio = data->bio;
        BUG_ON(!bio);
-       BUG_ON(!bio->bi_vcnt);
 
        cursor->resid = min(length, data->bio_length);
        cursor->bio = bio;
-       cursor->vector_index = 0;
-       cursor->vector_offset = 0;
-       cursor->last_piece = length <= bio->bi_io_vec[0].bv_len;
+       cursor->bvec_iter = bio->bi_iter;
+       cursor->last_piece =
+               cursor->resid <= bio_iter_len(bio, cursor->bvec_iter);
 }
 
 static struct page *ceph_msg_data_bio_next(struct ceph_msg_data_cursor *cursor,
@@ -792,71 +791,63 @@ static struct page *ceph_msg_data_bio_next(struct ceph_msg_data_cursor *cursor,
 {
        struct ceph_msg_data *data = cursor->data;
        struct bio *bio;
-       struct bio_vec *bio_vec;
-       unsigned int index;
+       struct bio_vec bio_vec;
 
        BUG_ON(data->type != CEPH_MSG_DATA_BIO);
 
        bio = cursor->bio;
        BUG_ON(!bio);
 
-       index = cursor->vector_index;
-       BUG_ON(index >= (unsigned int) bio->bi_vcnt);
+       bio_vec = bio_iter_iovec(bio, cursor->bvec_iter);
 
-       bio_vec = &bio->bi_io_vec[index];
-       BUG_ON(cursor->vector_offset >= bio_vec->bv_len);
-       *page_offset = (size_t) (bio_vec->bv_offset + cursor->vector_offset);
+       *page_offset = (size_t) bio_vec.bv_offset;
        BUG_ON(*page_offset >= PAGE_SIZE);
        if (cursor->last_piece) /* pagelist offset is always 0 */
                *length = cursor->resid;
        else
-               *length = (size_t) (bio_vec->bv_len - cursor->vector_offset);
+               *length = (size_t) bio_vec.bv_len;
        BUG_ON(*length > cursor->resid);
        BUG_ON(*page_offset + *length > PAGE_SIZE);
 
-       return bio_vec->bv_page;
+       return bio_vec.bv_page;
 }
 
 static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor,
                                        size_t bytes)
 {
        struct bio *bio;
-       struct bio_vec *bio_vec;
-       unsigned int index;
+       struct bio_vec bio_vec;
 
        BUG_ON(cursor->data->type != CEPH_MSG_DATA_BIO);
 
        bio = cursor->bio;
        BUG_ON(!bio);
 
-       index = cursor->vector_index;
-       BUG_ON(index >= (unsigned int) bio->bi_vcnt);
-       bio_vec = &bio->bi_io_vec[index];
+       bio_vec = bio_iter_iovec(bio, cursor->bvec_iter);
 
        /* Advance the cursor offset */
 
        BUG_ON(cursor->resid < bytes);
        cursor->resid -= bytes;
-       cursor->vector_offset += bytes;
-       if (cursor->vector_offset < bio_vec->bv_len)
+
+       bio_advance_iter(bio, &cursor->bvec_iter, bytes);
+
+       if (bytes < bio_vec.bv_len)
                return false;   /* more bytes to process in this segment */
-       BUG_ON(cursor->vector_offset != bio_vec->bv_len);
 
        /* Move on to the next segment, and possibly the next bio */
 
-       if (++index == (unsigned int) bio->bi_vcnt) {
+       if (!cursor->bvec_iter.bi_size) {
                bio = bio->bi_next;
-               index = 0;
+               cursor->bvec_iter = bio->bi_iter;
        }
        cursor->bio = bio;
-       cursor->vector_index = index;
-       cursor->vector_offset = 0;
 
        if (!cursor->last_piece) {
                BUG_ON(!cursor->resid);
                BUG_ON(!bio);
                /* A short read is OK, so use <= rather than == */
-               if (cursor->resid <= bio->bi_io_vec[index].bv_len)
+               if (cursor->resid <= bio_iter_len(bio, cursor->bvec_iter))
                        cursor->last_piece = true;
        }
 
index 618c6a8a911b65c9a406ba5d7d0e221cb124960e..dd32e34c1e2c9481aa2db3c37437ef0d85ba5277 100644 (file)
@@ -72,7 +72,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
            __get_user(kmsg->msg_flags, &umsg->msg_flags))
                return -EFAULT;
        if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
-               return -EINVAL;
+               kmsg->msg_namelen = sizeof(struct sockaddr_storage);
        kmsg->msg_name = compat_ptr(tmp1);
        kmsg->msg_iov = compat_ptr(tmp2);
        kmsg->msg_control = compat_ptr(tmp3);
index 003f5bb3acd25f4dc696255c56ac1985eae58a62..4bdab152187826f364f0acff43dca1db8d0dc938 100644 (file)
@@ -288,7 +288,8 @@ void hsr_addr_subst_dest(struct hsr_priv *hsr_priv, struct ethhdr *ethhdr,
 static bool seq_nr_after(u16 a, u16 b)
 {
        /* Remove inconsistency where
-        * seq_nr_after(a, b) == seq_nr_before(a, b) */
+        * seq_nr_after(a, b) == seq_nr_before(a, b)
+        */
        if ((int) b - a == 32768)
                return false;
 
index 5325af85eea670f5c865367fc991eaf9b907cd98..01a5261ac7a5520230fb0d2e147ffd3cf0a930ec 100644 (file)
@@ -23,6 +23,8 @@ static const struct nla_policy hsr_policy[IFLA_HSR_MAX + 1] = {
        [IFLA_HSR_SLAVE1]               = { .type = NLA_U32 },
        [IFLA_HSR_SLAVE2]               = { .type = NLA_U32 },
        [IFLA_HSR_MULTICAST_SPEC]       = { .type = NLA_U8 },
+       [IFLA_HSR_SUPERVISION_ADDR]     = { .type = NLA_BINARY, .len = ETH_ALEN },
+       [IFLA_HSR_SEQ_NR]               = { .type = NLA_U16 },
 };
 
 
@@ -59,6 +61,31 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,
        return hsr_dev_finalize(dev, link, multicast_spec);
 }
 
+static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+       struct hsr_priv *hsr_priv;
+
+       hsr_priv = netdev_priv(dev);
+
+       if (hsr_priv->slave[0])
+               if (nla_put_u32(skb, IFLA_HSR_SLAVE1, hsr_priv->slave[0]->ifindex))
+                       goto nla_put_failure;
+
+       if (hsr_priv->slave[1])
+               if (nla_put_u32(skb, IFLA_HSR_SLAVE2, hsr_priv->slave[1]->ifindex))
+                       goto nla_put_failure;
+
+       if (nla_put(skb, IFLA_HSR_SUPERVISION_ADDR, ETH_ALEN,
+                   hsr_priv->sup_multicast_addr) ||
+           nla_put_u16(skb, IFLA_HSR_SEQ_NR, hsr_priv->sequence_nr))
+               goto nla_put_failure;
+
+       return 0;
+
+nla_put_failure:
+       return -EMSGSIZE;
+}
+
 static struct rtnl_link_ops hsr_link_ops __read_mostly = {
        .kind           = "hsr",
        .maxtype        = IFLA_HSR_MAX,
@@ -66,6 +93,7 @@ static struct rtnl_link_ops hsr_link_ops __read_mostly = {
        .priv_size      = sizeof(struct hsr_priv),
        .setup          = hsr_dev_setup,
        .newlink        = hsr_newlink,
+       .fill_info      = hsr_fill_info,
 };
 
 
index 3f858266fa7e33a0941a135ec8a36b36278fdfce..ddf32a6bc415c28f0b9639514dd86eb11b18ce85 100644 (file)
@@ -386,7 +386,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf
 /*
  *     Handle MSG_ERRQUEUE
  */
-int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
+int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
 {
        struct sock_exterr_skb *serr;
        struct sk_buff *skb, *skb2;
@@ -423,6 +423,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
                                                   serr->addr_offset);
                sin->sin_port = serr->port;
                memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
+               *addr_len = sizeof(*sin);
        }
 
        memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
index 876c6ca2d8f9e77a28f1e629aa6523df1ee8f42f..242e7f4ed6f44ff5765966388618152e2721fa87 100644 (file)
@@ -772,7 +772,7 @@ int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                err = PTR_ERR(rt);
                rt = NULL;
                if (err == -ENETUNREACH)
-                       IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
+                       IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
                goto out;
        }
 
@@ -841,10 +841,11 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
        if (flags & MSG_ERRQUEUE) {
                if (family == AF_INET) {
-                       return ip_recv_error(sk, msg, len);
+                       return ip_recv_error(sk, msg, len, addr_len);
 #if IS_ENABLED(CONFIG_IPV6)
                } else if (family == AF_INET6) {
-                       return pingv6_ops.ipv6_recv_error(sk, msg, len);
+                       return pingv6_ops.ipv6_recv_error(sk, msg, len,
+                                                         addr_len);
 #endif
                }
        }
index ce848461acbb07f6b758dc900225c7aff16ac690..46d6a1c923a8741776fa1de1cdd727b6cba72294 100644 (file)
 const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly;
 const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly;
 
-/*
- *     Add a protocol handler to the hash tables
- */
-
 int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
        if (!prot->netns_ok) {
@@ -55,10 +51,6 @@ int inet_add_offload(const struct net_offload *prot, unsigned char protocol)
 }
 EXPORT_SYMBOL(inet_add_offload);
 
-/*
- *     Remove a protocol from the hash tables.
- */
-
 int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
        int ret;
index 5cb8ddb505ee8911461ec92a5c74feef0b441e00..23c3e5b5bb53f9e6f40ebbe8de4afd1683f9d7e5 100644 (file)
@@ -697,7 +697,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                goto out;
 
        if (flags & MSG_ERRQUEUE) {
-               err = ip_recv_error(sk, msg, len);
+               err = ip_recv_error(sk, msg, len, addr_len);
                goto out;
        }
 
index 59a6f8b90cd9d7c9ca51bbcd2cc424153d6571df..06721392475105fec441b2d97b3c72e6927b7e54 100644 (file)
@@ -177,7 +177,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        if (IS_ERR(rt)) {
                err = PTR_ERR(rt);
                if (err == -ENETUNREACH)
-                       IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
+                       IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
                return err;
        }
 
index 03e9154f7e687efef63c91878e33427672bc4036..269a89ecd2f441857f76c23d80e4f4c1e3cc0fdd 100644 (file)
@@ -60,7 +60,6 @@ EXPORT_SYMBOL(tcp_destroy_cgroup);
 static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
 {
        struct cg_proto *cg_proto;
-       u64 old_lim;
        int i;
        int ret;
 
@@ -71,7 +70,6 @@ static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
        if (val > RES_COUNTER_MAX)
                val = RES_COUNTER_MAX;
 
-       old_lim = res_counter_read_u64(&cg_proto->memory_allocated, RES_LIMIT);
        ret = res_counter_set_limit(&cg_proto->memory_allocated, val);
        if (ret)
                return ret;
index a2b68a108eae69170c8d915be778c9aeebf0f371..05606353c7e7cb026096acaf598a8685b84b85c9 100644 (file)
@@ -274,33 +274,32 @@ static struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *
 {
        const struct iphdr *iph = skb_gro_network_header(skb);
        __wsum wsum;
-       __sum16 sum;
+
+       /* Don't bother verifying checksum if we're going to flush anyway. */
+       if (NAPI_GRO_CB(skb)->flush)
+               goto skip_csum;
+
+       wsum = skb->csum;
 
        switch (skb->ip_summed) {
+       case CHECKSUM_NONE:
+               wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
+                                   0);
+
+               /* fall through */
+
        case CHECKSUM_COMPLETE:
                if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr,
-                                 skb->csum)) {
+                                 wsum)) {
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                        break;
                }
-flush:
+
                NAPI_GRO_CB(skb)->flush = 1;
                return NULL;
-
-       case CHECKSUM_NONE:
-               wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
-                                         skb_gro_len(skb), IPPROTO_TCP, 0);
-               sum = csum_fold(skb_checksum(skb,
-                                            skb_gro_offset(skb),
-                                            skb_gro_len(skb),
-                                            wsum));
-               if (sum)
-                       goto flush;
-
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
-               break;
        }
 
+skip_csum:
        return tcp_gro_receive(head, skb);
 }
 
index 5944d7d668dd91da21e945eac748bbbbbb11d67a..44f6a20fa29df830c1208e825816eaa11785f1ab 100644 (file)
@@ -999,7 +999,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                        err = PTR_ERR(rt);
                        rt = NULL;
                        if (err == -ENETUNREACH)
-                               IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
+                               IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
                        goto out;
                }
 
@@ -1098,6 +1098,9 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
        struct udp_sock *up = udp_sk(sk);
        int ret;
 
+       if (flags & MSG_SENDPAGE_NOTLAST)
+               flags |= MSG_MORE;
+
        if (!up->pending) {
                struct msghdr msg = {   .msg_flags = flags|MSG_MORE };
 
@@ -1236,7 +1239,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        bool slow;
 
        if (flags & MSG_ERRQUEUE)
-               return ip_recv_error(sk, msg, len);
+               return ip_recv_error(sk, msg, len, addr_len);
 
 try_again:
        skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
index a454b0ff57c7c67a91e2e5c887609e7a65e5a910..8dfe1f4d3c1a4e5f1e90be1603a2c84311f3a95b 100644 (file)
@@ -318,7 +318,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu)
 /*
  *     Handle MSG_ERRQUEUE
  */
-int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
+int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct sock_exterr_skb *serr;
@@ -369,6 +369,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                                               &sin->sin6_addr);
                        sin->sin6_scope_id = 0;
                }
+               *addr_len = sizeof(*sin);
        }
 
        memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
@@ -377,6 +378,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
        if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
                sin->sin6_family = AF_INET6;
                sin->sin6_flowinfo = 0;
+               sin->sin6_port = 0;
                if (skb->protocol == htons(ETH_P_IPV6)) {
                        sin->sin6_addr = ipv6_hdr(skb)->saddr;
                        if (np->rxopt.all)
@@ -423,7 +425,8 @@ EXPORT_SYMBOL_GPL(ipv6_recv_error);
 /*
  *     Handle IPV6_RECVPATHMTU
  */
-int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
+int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
+                    int *addr_len)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct sk_buff *skb;
@@ -457,6 +460,7 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
                sin->sin6_port = 0;
                sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id;
                sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr;
+               *addr_len = sizeof(*sin);
        }
 
        put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info);
index 59df872e2f4d62f68b583ff40218d68c5d5189df..4acdb63495dbe2484de9d278b810401e6d26fc6a 100644 (file)
@@ -116,8 +116,8 @@ static int ip6_finish_output2(struct sk_buff *skb)
        }
        rcu_read_unlock_bh();
 
-       IP6_INC_STATS_BH(dev_net(dst->dev),
-                        ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
+       IP6_INC_STATS(dev_net(dst->dev),
+                     ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
        kfree_skb(skb);
        return -EINVAL;
 }
index 8815e31a87fed4ba51ebd78a6724df8a3a436b85..a83243c3d656f553b6ccec94451e26e28cd1e743 100644 (file)
@@ -57,7 +57,8 @@ static struct inet_protosw pingv6_protosw = {
 
 
 /* Compatibility glue so we can support IPv6 when it's compiled as a module */
-static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
+static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
+                                int *addr_len)
 {
        return -EAFNOSUPPORT;
 }
index 22d1bd4670dab741b2417051b45370b4a75b42a3..e048cf1bb6a234bb1c0eac0987d8e093a733f2f1 100644 (file)
@@ -36,10 +36,6 @@ int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol
 }
 EXPORT_SYMBOL(inet6_add_protocol);
 
-/*
- *     Remove a protocol from the hash tables.
- */
-
 int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol)
 {
        int ret;
index e24ff1df0401288e4e810cf79ec3ea20d86a06c0..7fb4e14c467f60b4a65236b04fda13c6b5b9107d 100644 (file)
@@ -466,10 +466,10 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
                return -EOPNOTSUPP;
 
        if (flags & MSG_ERRQUEUE)
-               return ipv6_recv_error(sk, msg, len);
+               return ipv6_recv_error(sk, msg, len, addr_len);
 
        if (np->rxpmtu && np->rxopt.bits.rxpmtu)
-               return ipv6_recv_rxpmtu(sk, msg, len);
+               return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
 
        skb = skb_recv_datagram(sk, flags, noblock, &err);
        if (!skb)
index 1b4a4a95367552c8cc22d19850b0779eee87cdc6..366fbba3359ab790e1b22917931acdbdb1daebf3 100644 (file)
@@ -478,14 +478,44 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
        dev_put(dev);
 }
 
+/* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH
+ * if sufficient data bytes are available
+ */
+static int ipip6_err_gen_icmpv6_unreach(struct sk_buff *skb)
+{
+       const struct iphdr *iph = (const struct iphdr *) skb->data;
+       struct rt6_info *rt;
+       struct sk_buff *skb2;
+
+       if (!pskb_may_pull(skb, iph->ihl * 4 + sizeof(struct ipv6hdr) + 8))
+               return 1;
+
+       skb2 = skb_clone(skb, GFP_ATOMIC);
+
+       if (!skb2)
+               return 1;
+
+       skb_dst_drop(skb2);
+       skb_pull(skb2, iph->ihl * 4);
+       skb_reset_network_header(skb2);
+
+       rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, 0);
+
+       if (rt && rt->dst.dev)
+               skb2->dev = rt->dst.dev;
+
+       icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
+
+       if (rt)
+               ip6_rt_put(rt);
+
+       kfree_skb(skb2);
+
+       return 0;
+}
 
 static int ipip6_err(struct sk_buff *skb, u32 info)
 {
-
-/* All the routers (except for Linux) return only
-   8 bytes of packet payload. It means, that precise relaying of
-   ICMP in the real Internet is absolutely infeasible.
- */
        const struct iphdr *iph = (const struct iphdr *)skb->data;
        const int type = icmp_hdr(skb)->type;
        const int code = icmp_hdr(skb)->code;
@@ -500,7 +530,6 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
        case ICMP_DEST_UNREACH:
                switch (code) {
                case ICMP_SR_FAILED:
-               case ICMP_PORT_UNREACH:
                        /* Impossible event. */
                        return 0;
                default:
@@ -545,6 +574,9 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
                goto out;
 
        err = 0;
+       if (!ipip6_err_gen_icmpv6_unreach(skb))
+               goto out;
+
        if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
                goto out;
 
@@ -919,7 +951,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
                if (!new_skb) {
                        ip_rt_put(rt);
                        dev->stats.tx_dropped++;
-                       dev_kfree_skb(skb);
+                       kfree_skb(skb);
                        return NETDEV_TX_OK;
                }
                if (skb->sk)
@@ -945,7 +977,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 tx_error_icmp:
        dst_link_failure(skb);
 tx_error:
-       dev_kfree_skb(skb);
+       kfree_skb(skb);
 out:
        dev->stats.tx_errors++;
        return NETDEV_TX_OK;
@@ -985,7 +1017,7 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
 
 tx_err:
        dev->stats.tx_errors++;
-       dev_kfree_skb(skb);
+       kfree_skb(skb);
        return NETDEV_TX_OK;
 
 }
index c1097c79890070e3d04517cecb7f0b263c0a4fc7..6d18157dc32c5e6fadf7798d26cdd665e18cb541 100644 (file)
@@ -37,34 +37,32 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
 {
        const struct ipv6hdr *iph = skb_gro_network_header(skb);
        __wsum wsum;
-       __sum16 sum;
+
+       /* Don't bother verifying checksum if we're going to flush anyway. */
+       if (NAPI_GRO_CB(skb)->flush)
+               goto skip_csum;
+
+       wsum = skb->csum;
 
        switch (skb->ip_summed) {
+       case CHECKSUM_NONE:
+               wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
+                                   wsum);
+
+               /* fall through */
+
        case CHECKSUM_COMPLETE:
                if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
-                                 skb->csum)) {
+                                 wsum)) {
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                        break;
                }
-flush:
+
                NAPI_GRO_CB(skb)->flush = 1;
                return NULL;
-
-       case CHECKSUM_NONE:
-               wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
-                                                   skb_gro_len(skb),
-                                                   IPPROTO_TCP, 0));
-               sum = csum_fold(skb_checksum(skb,
-                                            skb_gro_offset(skb),
-                                            skb_gro_len(skb),
-                                            wsum));
-               if (sum)
-                       goto flush;
-
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
-               break;
        }
 
+skip_csum:
        return tcp_gro_receive(head, skb);
 }
 
index 81eb8cf8389b6a5af55f7b2994d7dbefe3d732bf..bcd5699313c38139306d06f733cb1ba130a1503c 100644 (file)
@@ -393,10 +393,10 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
        bool slow;
 
        if (flags & MSG_ERRQUEUE)
-               return ipv6_recv_error(sk, msg, len);
+               return ipv6_recv_error(sk, msg, len, addr_len);
 
        if (np->rxpmtu && np->rxopt.bits.rxpmtu)
-               return ipv6_recv_rxpmtu(sk, msg, len);
+               return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
 
 try_again:
        skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
index cfd65304be60ae8937449a8c1e4cf77406c11305..d9b437e5500795219339c85a8aab8a0301cc77b9 100644 (file)
@@ -665,7 +665,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
                *addr_len = sizeof(*lsa);
 
        if (flags & MSG_ERRQUEUE)
-               return ipv6_recv_error(sk, msg, len);
+               return ipv6_recv_error(sk, msg, len, addr_len);
 
        skb = skb_recv_datagram(sk, flags, noblock, &err);
        if (!skb)
index 95667b088c5b73cd0e95e8c1753ed76acec9dca0..364ce0c5962fd48c85ea23b71b2d1dd463082575 100644 (file)
@@ -1368,7 +1368,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
                        changed |=
                              ieee80211_mps_set_sta_local_pm(sta,
                                                             params->local_pm);
-               ieee80211_bss_info_change_notify(sdata, changed);
+               ieee80211_mbss_info_change_notify(sdata, changed);
 #endif
        }
 
@@ -2488,8 +2488,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
-       if (sdata->vif.type != NL80211_IFTYPE_STATION &&
-           sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
+       if (sdata->vif.type != NL80211_IFTYPE_STATION)
                return -EOPNOTSUPP;
 
        if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
@@ -3120,9 +3119,17 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
                    params->chandef.chan->band)
                        return -EINVAL;
 
+               ifmsh->chsw_init = true;
+               if (!ifmsh->pre_value)
+                       ifmsh->pre_value = 1;
+               else
+                       ifmsh->pre_value++;
+
                err = ieee80211_mesh_csa_beacon(sdata, params, true);
-               if (err < 0)
+               if (err < 0) {
+                       ifmsh->chsw_init = false;
                        return err;
+               }
                break;
 #endif
        default:
index 29dc505be125c3c19737f8f6cee911492c52727c..4aea4e7911135133818e66a1439b111d14e6147e 100644 (file)
@@ -1228,6 +1228,7 @@ struct ieee80211_csa_ie {
        u8 mode;
        u8 count;
        u8 ttl;
+       u16 pre_value;
 };
 
 /* Parsed Information Elements */
index ff101ea1d9ae1e208deb5d6fe1d67c1677b398c2..36c3a4cbcabf66b2a0864414b3c23ea2896b7c4e 100644 (file)
@@ -1325,7 +1325,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
                sdata->vif.bss_conf.bssid = NULL;
                break;
        case NL80211_IFTYPE_AP_VLAN:
-               break;
        case NL80211_IFTYPE_P2P_DEVICE:
                sdata->vif.bss_conf.bssid = sdata->vif.addr;
                break;
index 21d5d44444d04c82fc73c9fd6dee3f58ab56e512..7d1c3ac48ed941866170afdf387def183690d612 100644 (file)
@@ -940,6 +940,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
                wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
                            result);
 
+       local->hw.conf.flags = IEEE80211_CONF_IDLE;
+
        ieee80211_led_init(local);
 
        rtnl_lock();
@@ -1047,6 +1049,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 
        cancel_work_sync(&local->restart_work);
        cancel_work_sync(&local->reconfig_filter);
+       flush_work(&local->sched_scan_stopped_work);
 
        ieee80211_clear_tx_pending(local);
        rate_control_deinitialize(local);
index 896fe3bd599e9bedd5db13dbc8ed04ab76e5bd88..ba105257d03f1cffc4398f42c52e67b1e8d3eaaa 100644 (file)
@@ -943,14 +943,19 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
                 params.chandef.chan->center_freq);
 
        params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT;
-       if (beacon)
+       if (beacon) {
                ifmsh->chsw_ttl = csa_ie.ttl - 1;
-       else
-               ifmsh->chsw_ttl = 0;
+               if (ifmsh->pre_value >= csa_ie.pre_value)
+                       return false;
+               ifmsh->pre_value = csa_ie.pre_value;
+       }
 
-       if (ifmsh->chsw_ttl > 0)
+       if (ifmsh->chsw_ttl < ifmsh->mshcfg.dot11MeshTTL) {
                if (ieee80211_mesh_csa_beacon(sdata, &params, false) < 0)
                        return false;
+       } else {
+               return false;
+       }
 
        sdata->csa_radar_required = params.radar_required;
 
@@ -1163,7 +1168,6 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
        offset_ttl = (len < 42) ? 7 : 10;
        *(pos + offset_ttl) -= 1;
        *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
-       sdata->u.mesh.chsw_ttl = *(pos + offset_ttl);
 
        memcpy(mgmt_fwd, mgmt, len);
        eth_broadcast_addr(mgmt_fwd->da);
@@ -1182,7 +1186,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
        u16 pre_value;
        bool fwd_csa = true;
        size_t baselen;
-       u8 *pos, ttl;
+       u8 *pos;
 
        if (mgmt->u.action.u.measurement.action_code !=
            WLAN_ACTION_SPCT_CHL_SWITCH)
@@ -1193,8 +1197,8 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
                           u.action.u.chan_switch.variable);
        ieee802_11_parse_elems(pos, len - baselen, false, &elems);
 
-       ttl = elems.mesh_chansw_params_ie->mesh_ttl;
-       if (!--ttl)
+       ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl;
+       if (!--ifmsh->chsw_ttl)
                fwd_csa = false;
 
        pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value);
index d7504ab61a34c7ef6a51f8adce10e58c021408d0..b3a3ce316656ce8406859a3cdc325fa262e024a5 100644 (file)
@@ -1910,6 +1910,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
        if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
                already = true;
 
+       ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
+
        mutex_unlock(&sdata->local->mtx);
 
        if (already)
index 5d60779a0c1be89e987b2cd478af865ec806d4bb..4096ff6cc24fe8a5c3505411c5b232e0d800e050 100644 (file)
@@ -226,7 +226,7 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
                nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
 
        nsecs += minstrel_mcs_groups[group].duration[rate];
-       tp = 1000000 * ((mr->probability * 1000) / nsecs);
+       tp = 1000000 * ((prob * 1000) / nsecs);
 
        mr->cur_tp = MINSTREL_TRUNC(tp);
 }
@@ -277,13 +277,15 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
                        if (!(mg->supported & BIT(i)))
                                continue;
 
+                       index = MCS_GROUP_RATES * group + i;
+
                        /* initialize rates selections starting indexes */
                        if (!mg_rates_valid) {
                                mg->max_tp_rate = mg->max_tp_rate2 =
                                        mg->max_prob_rate = i;
                                if (!mi_rates_valid) {
                                        mi->max_tp_rate = mi->max_tp_rate2 =
-                                               mi->max_prob_rate = i;
+                                               mi->max_prob_rate = index;
                                        mi_rates_valid = true;
                                }
                                mg_rates_valid = true;
@@ -291,7 +293,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
 
                        mr = &mg->rates[i];
                        mr->retry_updated = false;
-                       index = MCS_GROUP_RATES * group + i;
                        minstrel_calc_rate_ewma(mr);
                        minstrel_ht_calc_tp(mi, group, i);
 
index caecef870c0e44e3562cdc0a874bcfd233fc77a1..2b0debb0422b91d89a0a7982b94726f3b9ceae11 100644 (file)
@@ -911,7 +911,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
        u16 sc;
        u8 tid, ack_policy;
 
-       if (!ieee80211_is_data_qos(hdr->frame_control))
+       if (!ieee80211_is_data_qos(hdr->frame_control) ||
+           is_multicast_ether_addr(hdr->addr1))
                goto dont_reorder;
 
        /*
index 5ad66a83ef7f4d4525de163c2c2f1fe9d6931a04..bcc4833d7542b91e1b754ed490d1dedcaee559c1 100644 (file)
@@ -1088,6 +1088,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
 
        trace_api_sched_scan_stopped(local);
 
-       ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work);
+       schedule_work(&local->sched_scan_stopped_work);
 }
 EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
index a40da20b32e074a3923f844edf104eca33a6134c..6ab00907008461fb14d551b2633a8dbcd4fef623 100644 (file)
@@ -78,6 +78,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
        if (elems->mesh_chansw_params_ie) {
                csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl;
                csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags;
+               csa_ie->pre_value = le16_to_cpu(
+                               elems->mesh_chansw_params_ie->mesh_pre_value);
        }
 
        new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
index 592a18171f95e9ec5273b03307235dff2bd1c946..9f9b9bd3fd44798e7030fb3a44c46da962cfd7ba 100644 (file)
@@ -2278,17 +2278,15 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
 {
        struct ieee80211_local *local =
                container_of(work, struct ieee80211_local, radar_detected_work);
-       struct cfg80211_chan_def chandef;
+       struct cfg80211_chan_def chandef = local->hw.conf.chandef;
 
        ieee80211_dfs_cac_cancel(local);
 
        if (local->use_chanctx)
                /* currently not handled */
                WARN_ON(1);
-       else {
-               chandef = local->hw.conf.chandef;
+       else
                cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
-       }
 }
 
 void ieee80211_radar_detected(struct ieee80211_hw *hw)
@@ -2459,14 +2457,9 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
                          WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
                put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */
                pos += 2;
-               if (!ifmsh->pre_value)
-                       ifmsh->pre_value = 1;
-               else
-                       ifmsh->pre_value++;
                pre_value = cpu_to_le16(ifmsh->pre_value);
                memcpy(pos, &pre_value, 2);             /* Precedence Value */
                pos += 2;
-               ifmsh->chsw_init = true;
        }
 
        ieee80211_tx_skb(sdata, skb);
index 4518a57aa5febb14db1c1d750f217102dd8fd2a9..713671ae45aff688e693d6087ae4d8ce9e986f48 100644 (file)
@@ -74,9 +74,12 @@ static struct list_head family_ht[GENL_FAM_TAB_SIZE];
  * Bit 17 is marked as already used since the VFS quota code
  * also abused this API and relied on family == group ID, we
  * cater to that by giving it a static family and group ID.
+ * Bit 18 is marked as already used since the PMCRAID driver
+ * did the same thing as the VFS quota code (maybe copied?)
  */
 static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) |
-                                     BIT(GENL_ID_VFS_DQUOT);
+                                     BIT(GENL_ID_VFS_DQUOT) |
+                                     BIT(GENL_ID_PMCRAID);
 static unsigned long *mc_groups = &mc_group_start;
 static unsigned long mc_groups_longs = 1;
 
@@ -139,6 +142,7 @@ static u16 genl_generate_id(void)
 
        for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) {
                if (id_gen_idx != GENL_ID_VFS_DQUOT &&
+                   id_gen_idx != GENL_ID_PMCRAID &&
                    !genl_family_find_byid(id_gen_idx))
                        return id_gen_idx;
                if (++id_gen_idx > GENL_MAX_ID)
@@ -214,7 +218,7 @@ static int genl_validate_assign_mc_groups(struct genl_family *family)
 {
        int first_id;
        int n_groups = family->n_mcgrps;
-       int err, i;
+       int err = 0, i;
        bool groups_allocated = false;
 
        if (!n_groups)
@@ -236,9 +240,12 @@ static int genl_validate_assign_mc_groups(struct genl_family *family)
        } else if (strcmp(family->name, "NET_DM") == 0) {
                first_id = 1;
                BUG_ON(n_groups != 1);
-       } else if (strcmp(family->name, "VFS_DQUOT") == 0) {
+       } else if (family->id == GENL_ID_VFS_DQUOT) {
                first_id = GENL_ID_VFS_DQUOT;
                BUG_ON(n_groups != 1);
+       } else if (family->id == GENL_ID_PMCRAID) {
+               first_id = GENL_ID_PMCRAID;
+               BUG_ON(n_groups != 1);
        } else {
                groups_allocated = true;
                err = genl_allocate_reserve_groups(n_groups, &first_id);
index ac27c86ef6d11e00c2ecb1512b09bbda73c3eefc..ba2548bd85bf7d42b26e25ae9a2626b729fc8be9 100644 (file)
@@ -439,9 +439,9 @@ static void prb_shutdown_retire_blk_timer(struct packet_sock *po,
 
        pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc;
 
-       spin_lock(&rb_queue->lock);
+       spin_lock_bh(&rb_queue->lock);
        pkc->delete_blk_timer = 1;
-       spin_unlock(&rb_queue->lock);
+       spin_unlock_bh(&rb_queue->lock);
 
        prb_del_retire_blk_timer(pkc);
 }
index 75c94e59a3bd3889cd87460afe87ac611eeb024e..bccd52b36e97be79d446e233dedc960fe65d5f16 100644 (file)
@@ -215,10 +215,10 @@ static bool loss_4state(struct netem_sched_data *q)
                if (rnd < clg->a4) {
                        clg->state = 4;
                        return true;
-               } else if (clg->a4 < rnd && rnd < clg->a1) {
+               } else if (clg->a4 < rnd && rnd < clg->a1 + clg->a4) {
                        clg->state = 3;
                        return true;
-               } else if (clg->a1 < rnd)
+               } else if (clg->a1 + clg->a4 < rnd)
                        clg->state = 1;
 
                break;
@@ -268,10 +268,11 @@ static bool loss_gilb_ell(struct netem_sched_data *q)
                        clg->state = 2;
                if (net_random() < clg->a4)
                        return true;
+               break;
        case 2:
                if (net_random() < clg->a2)
                        clg->state = 1;
-               if (clg->a3 > net_random())
+               if (net_random() > clg->a3)
                        return true;
        }
 
index 68f98595819c1224f7e64ad368ad51155ff07fea..a6090051c5dbe3d0a9aee6a2921b91397dbdc363 100644 (file)
@@ -21,6 +21,7 @@
 #include <net/netlink.h>
 #include <net/sch_generic.h>
 #include <net/pkt_sched.h>
+#include <net/tcp.h>
 
 
 /*     Simple Token Bucket Filter.
@@ -117,6 +118,22 @@ struct tbf_sched_data {
 };
 
 
+/*
+ * Return length of individual segments of a gso packet,
+ * including all headers (MAC, IP, TCP/UDP)
+ */
+static unsigned int skb_gso_seglen(const struct sk_buff *skb)
+{
+       unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
+       const struct skb_shared_info *shinfo = skb_shinfo(skb);
+
+       if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
+               hdr_len += tcp_hdrlen(skb);
+       else
+               hdr_len += sizeof(struct udphdr);
+       return hdr_len + shinfo->gso_size;
+}
+
 /* GSO packet is too big, segment it so that tbf can transmit
  * each segment in time
  */
@@ -136,12 +153,8 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch)
        while (segs) {
                nskb = segs->next;
                segs->next = NULL;
-               if (likely(segs->len <= q->max_size)) {
-                       qdisc_skb_cb(segs)->pkt_len = segs->len;
-                       ret = qdisc_enqueue(segs, q->qdisc);
-               } else {
-                       ret = qdisc_reshape_fail(skb, sch);
-               }
+               qdisc_skb_cb(segs)->pkt_len = segs->len;
+               ret = qdisc_enqueue(segs, q->qdisc);
                if (ret != NET_XMIT_SUCCESS) {
                        if (net_xmit_drop_count(ret))
                                sch->qstats.drops++;
@@ -163,7 +176,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        int ret;
 
        if (qdisc_pkt_len(skb) > q->max_size) {
-               if (skb_is_gso(skb))
+               if (skb_is_gso(skb) && skb_gso_seglen(skb) <= q->max_size)
                        return tbf_segment(skb, sch);
                return qdisc_reshape_fail(skb, sch);
        }
@@ -319,6 +332,11 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
        if (max_size < 0)
                goto done;
 
+       if (max_size < psched_mtu(qdisc_dev(sch)))
+               pr_warn_ratelimited("sch_tbf: burst %u is lower than device %s mtu (%u) !\n",
+                                   max_size, qdisc_dev(sch)->name,
+                                   psched_mtu(qdisc_dev(sch)));
+
        if (q->qdisc != &noop_qdisc) {
                err = fifo_set_limit(q->qdisc, qopt->limit);
                if (err)
index e650978daf279abe9b1277dabb22f2e865c64a7a..0e2644d0a773710d149639ab3aa777c6313a7737 100644 (file)
@@ -474,10 +474,11 @@ int sctp_packet_transmit(struct sctp_packet *packet)
                         * for a given destination transport address.
                         */
 
-                       if (!tp->rto_pending) {
+                       if (!chunk->resent && !tp->rto_pending) {
                                chunk->rtt_in_progress = 1;
                                tp->rto_pending = 1;
                        }
+
                        has_data = 1;
                }
 
index 94df7587786992fa0a6341caaed284beb1df42e0..f51ba985a36eaaf0b021adba700cf16d42394e6f 100644 (file)
@@ -446,6 +446,8 @@ void sctp_retransmit_mark(struct sctp_outq *q,
                                transport->rto_pending = 0;
                        }
 
+                       chunk->resent = 1;
+
                        /* Move the chunk to the retransmit queue. The chunks
                         * on the retransmit queue are always kept in order.
                         */
@@ -1375,6 +1377,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
                                 * instance).
                                 */
                                if (!tchunk->tsn_gap_acked &&
+                                   !tchunk->resent &&
                                    tchunk->rtt_in_progress) {
                                        tchunk->rtt_in_progress = 0;
                                        rtt = jiffies - tchunk->sent_at;
@@ -1391,7 +1394,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
                         */
                        if (!tchunk->tsn_gap_acked) {
                                tchunk->tsn_gap_acked = 1;
-                               *highest_new_tsn_in_sack = tsn;
+                               if (TSN_lt(*highest_new_tsn_in_sack, tsn))
+                                       *highest_new_tsn_in_sack = tsn;
                                bytes_acked += sctp_data_size(tchunk);
                                if (!tchunk->transport)
                                        migrate_bytes += sctp_data_size(tchunk);
index 0b18693f2be6deb2f6f6b6bbf99aa131c767e830..e83c416708af5554f89c98723bba150b8750b3f0 100644 (file)
@@ -1973,7 +1973,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
        if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
                return -EFAULT;
        if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
-               return -EINVAL;
+               kmsg->msg_namelen = sizeof(struct sockaddr_storage);
        return 0;
 }
 
index aff959e5a1b360e7cb467cade7f7d617544b3909..00a65ba3aeaa3061bc4d256239df7b74efd1ecf4 100644 (file)
@@ -451,6 +451,9 @@ int wiphy_register(struct wiphy *wiphy)
        int i;
        u16 ifmodes = wiphy->interface_modes;
 
+       /* support for 5/10 MHz is broken due to nl80211 API mess - disable */
+       wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ;
+
 #ifdef CONFIG_PM
        if (WARN_ON(wiphy->wowlan &&
                    (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
index 9d797df56649c5a47fdf1f61e665ee31e4b77e7c..89737ee2669a8de9bc8f02aa1c392052369d210b 100644 (file)
@@ -262,7 +262,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 
        /* try to find an IBSS channel if none requested ... */
        if (!wdev->wext.ibss.chandef.chan) {
-               wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
+               struct ieee80211_channel *new_chan = NULL;
 
                for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
                        struct ieee80211_supported_band *sband;
@@ -278,18 +278,19 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
                                        continue;
                                if (chan->flags & IEEE80211_CHAN_DISABLED)
                                        continue;
-                               wdev->wext.ibss.chandef.chan = chan;
-                               wdev->wext.ibss.chandef.center_freq1 =
-                                       chan->center_freq;
+                               new_chan = chan;
                                break;
                        }
 
-                       if (wdev->wext.ibss.chandef.chan)
+                       if (new_chan)
                                break;
                }
 
-               if (!wdev->wext.ibss.chandef.chan)
+               if (!new_chan)
                        return -EINVAL;
+
+               cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan,
+                                       NL80211_CHAN_NO_HT);
        }
 
        /* don't join -- SSID is not there */
@@ -363,9 +364,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
                return err;
 
        if (chan) {
-               wdev->wext.ibss.chandef.chan = chan;
-               wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
-               wdev->wext.ibss.chandef.center_freq1 = freq;
+               cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan,
+                                       NL80211_CHAN_NO_HT);
                wdev->wext.ibss.channel_fixed = true;
        } else {
                /* cfg80211_ibss_wext_join will pick one if needed */
index a1eb21073176115a587f9eb1edf5d36dba582484..138dc3bb8b67d8c345531a95ce0c8342271ce79e 100644 (file)
@@ -2687,7 +2687,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
        hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                             NL80211_CMD_NEW_KEY);
        if (!hdr)
-               return -ENOBUFS;
+               goto nla_put_failure;
 
        cookie.msg = msg;
        cookie.idx = key_idx;
@@ -5349,6 +5349,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
                                err = -EINVAL;
                                goto out_free;
                        }
+
+                       if (!wiphy->bands[band])
+                               continue;
+
                        err = ieee80211_get_ratemask(wiphy->bands[band],
                                                     nla_data(attr),
                                                     nla_len(attr),
@@ -9633,8 +9637,9 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
            nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
                goto nla_put_failure;
 
-       if (req->flags)
-               nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags);
+       if (req->flags &&
+           nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
+               goto nla_put_failure;
 
        return 0;
  nla_put_failure:
@@ -11093,6 +11098,8 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
                struct nlattr *reasons;
 
                reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
+               if (!reasons)
+                       goto free_msg;
 
                if (wakeup->disconnect &&
                    nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
@@ -11118,16 +11125,18 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
                                wakeup->pattern_idx))
                        goto free_msg;
 
-               if (wakeup->tcp_match)
-                       nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH);
+               if (wakeup->tcp_match &&
+                   nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
+                       goto free_msg;
 
-               if (wakeup->tcp_connlost)
-                       nla_put_flag(msg,
-                                    NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST);
+               if (wakeup->tcp_connlost &&
+                   nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
+                       goto free_msg;
 
-               if (wakeup->tcp_nomoretokens)
-                       nla_put_flag(msg,
-                               NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS);
+               if (wakeup->tcp_nomoretokens &&
+                   nla_put_flag(msg,
+                                NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
+                       goto free_msg;
 
                if (wakeup->packet) {
                        u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
@@ -11263,24 +11272,29 @@ void cfg80211_ft_event(struct net_device *netdev,
                return;
 
        hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
-       if (!hdr) {
-               nlmsg_free(msg);
-               return;
-       }
+       if (!hdr)
+               goto out;
 
-       nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
-       nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
-       nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap);
-       if (ft_event->ies)
-               nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies);
-       if (ft_event->ric_ies)
-               nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
-                       ft_event->ric_ies);
+       if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+           nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+           nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
+               goto out;
+
+       if (ft_event->ies &&
+           nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
+               goto out;
+       if (ft_event->ric_ies &&
+           nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
+                   ft_event->ric_ies))
+               goto out;
 
        genlmsg_end(msg, hdr);
 
        genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
                                NL80211_MCGRP_MLME, GFP_KERNEL);
+       return;
+ out:
+       nlmsg_free(msg);
 }
 EXPORT_SYMBOL(cfg80211_ft_event);
 
index 90e521fde35fa827cf5008838024ef1bf1d03a88..65014e1495bf1751beef070887d53ed3d2a0f4cb 100644 (file)
@@ -172,8 +172,15 @@ fi
 
 # Install the maintainer scripts
 # Note: hook scripts under /etc/kernel are also executed by official Debian
-# kernel packages, as well as kernel packages built using make-kpkg
+# kernel packages, as well as kernel packages built using make-kpkg.
+# make-kpkg sets $INITRD to indicate whether an initramfs is wanted, and
+# so do we; recent versions of dracut and initramfs-tools will obey this.
 debhookdir=${KDEB_HOOKDIR:-/etc/kernel}
+if grep -q '^CONFIG_BLK_DEV_INITRD=y' $KCONFIG_CONFIG; then
+       want_initrd=Yes
+else
+       want_initrd=No
+fi
 for script in postinst postrm preinst prerm ; do
        mkdir -p "$tmpdir$debhookdir/$script.d"
        cat <<EOF > "$tmpdir/DEBIAN/$script"
@@ -184,6 +191,9 @@ set -e
 # Pass maintainer script parameters to hook scripts
 export DEB_MAINT_PARAMS="\$*"
 
+# Tell initramfs builder whether it's wanted
+export INITRD=$want_initrd
+
 test -d $debhookdir/$script.d && run-parts --arg="$version" --arg="/$installed_image_path" $debhookdir/$script.d
 exit 0
 EOF
index 5f7a8b663cb9c9eb59b32f4ce63076a6a86914cc..7941fbdfb050e573120f36b770ae8321130d8d01 100644 (file)
 #include <tools/be_byteshift.h>
 #include <tools/le_byteshift.h>
 
+#ifndef EM_ARCOMPACT
+#define EM_ARCOMPACT   93
+#endif
+
 #ifndef EM_AARCH64
 #define EM_AARCH64     183
 #endif
@@ -268,6 +272,7 @@ do_file(char const *const fname)
        case EM_S390:
                custom_sort = sort_relative_table;
                break;
+       case EM_ARCOMPACT:
        case EM_ARM:
        case EM_AARCH64:
        case EM_MIPS:
index 77ca965ab684e67e2809dc16f024728d8df41c70..b4af4ebc5be284d7f2665a5266be6a5bf267a683 100644 (file)
@@ -13,9 +13,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/err.h>
-#include <linux/sched.h>
 #include <linux/rbtree.h>
-#include <linux/cred.h>
 #include <linux/key-type.h>
 #include <linux/digsig.h>
 
 
 static struct key *keyring[INTEGRITY_KEYRING_MAX];
 
-#ifdef CONFIG_IMA_TRUSTED_KEYRING
-static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
-       ".evm",
-       ".module",
-       ".ima",
-};
-#else
 static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
        "_evm",
        "_module",
        "_ima",
 };
-#endif
 
 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
                            const char *digest, int digestlen)
@@ -45,7 +35,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
 
        if (!keyring[id]) {
                keyring[id] =
-                   request_key(&key_type_keyring, keyring_name[id], NULL);
+                       request_key(&key_type_keyring, keyring_name[id], NULL);
                if (IS_ERR(keyring[id])) {
                        int err = PTR_ERR(keyring[id]);
                        pr_err("no %s keyring: %d\n", keyring_name[id], err);
@@ -66,21 +56,3 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
 
        return -EOPNOTSUPP;
 }
-
-int integrity_init_keyring(const unsigned int id)
-{
-       const struct cred *cred = current_cred();
-       const struct user_struct *user = cred->user;
-
-       keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
-                                   KGIDT_INIT(0), cred,
-                                   ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
-                                    KEY_USR_VIEW | KEY_USR_READ),
-                                   KEY_ALLOC_NOT_IN_QUOTA, user->uid_keyring);
-       if (!IS_ERR(keyring[id]))
-               set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags);
-       else
-               pr_info("Can't allocate %s keyring (%ld)\n",
-                       keyring_name[id], PTR_ERR(keyring[id]));
-       return 0;
-}
index dad8d4ca2437fd608b73218993b23c3275c65b8d..81a27971d884215bc20e71d756f6778893ae1d67 100644 (file)
@@ -123,11 +123,3 @@ config IMA_APPRAISE
          For more information on integrity appraisal refer to:
          <http://linux-ima.sourceforge.net>
          If unsure, say N.
-
-config IMA_TRUSTED_KEYRING
-       bool "Require all keys on the _ima keyring be signed"
-       depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING
-       default y
-       help
-          This option requires that all keys added to the _ima
-          keyring be signed by a key on the system trusted keyring.
index bf03c6a16cc83ace2f47a3ea7571ef79a63ed1d9..9636e17c9f5d709ae735d60bccddd3d2bc481470 100644 (file)
@@ -26,7 +26,8 @@
 
 #include "../integrity.h"
 
-enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
+enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
+                    IMA_SHOW_ASCII };
 enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
 
 /* digest size for IMA, fits SHA1 or MD5 */
@@ -97,7 +98,8 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
                           const char *op, struct inode *inode,
                           const unsigned char *filename);
 int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
-int ima_calc_field_array_hash(struct ima_field_data *field_data, int num_fields,
+int ima_calc_field_array_hash(struct ima_field_data *field_data,
+                             struct ima_template_desc *desc, int num_fields,
                              struct ima_digest_data *hash);
 int __init ima_calc_boot_aggregate(struct ima_digest_data *hash);
 void ima_add_violation(struct file *file, const unsigned char *filename,
index 0e7540863fc299687877ae4591961b13b60fcaa9..80374842fe0bb4cfef8a7dec8144eeff5278d408 100644 (file)
@@ -94,6 +94,7 @@ int ima_store_template(struct ima_template_entry *entry,
                /* this function uses default algo */
                hash.hdr.algo = HASH_ALGO_SHA1;
                result = ima_calc_field_array_hash(&entry->template_data[0],
+                                                  entry->template_desc,
                                                   num_fields, &hash.hdr);
                if (result < 0) {
                        integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
index 46353ee517f6f321a738b067584d7e62dd8872fe..734e9468aca01c9a3724a57136f6d8bf371951f3 100644 (file)
@@ -381,14 +381,3 @@ int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
        }
        return result;
 }
-
-#ifdef CONFIG_IMA_TRUSTED_KEYRING
-static int __init init_ima_keyring(void)
-{
-       int ret;
-
-       ret = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
-       return 0;
-}
-late_initcall(init_ima_keyring);
-#endif
index 676e0292dfecf6744b720b8a7e103415b924cc37..fdf60def52e90c93799e7d6ff6298ab4dd68c6d3 100644 (file)
@@ -140,6 +140,7 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
  * Calculate the hash of template data
  */
 static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data,
+                                        struct ima_template_desc *td,
                                         int num_fields,
                                         struct ima_digest_data *hash,
                                         struct crypto_shash *tfm)
@@ -160,9 +161,13 @@ static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data,
                return rc;
 
        for (i = 0; i < num_fields; i++) {
-               rc = crypto_shash_update(&desc.shash,
-                                        (const u8 *) &field_data[i].len,
-                                        sizeof(field_data[i].len));
+               if (strcmp(td->name, IMA_TEMPLATE_IMA_NAME) != 0) {
+                       rc = crypto_shash_update(&desc.shash,
+                                               (const u8 *) &field_data[i].len,
+                                               sizeof(field_data[i].len));
+                       if (rc)
+                               break;
+               }
                rc = crypto_shash_update(&desc.shash, field_data[i].data,
                                         field_data[i].len);
                if (rc)
@@ -175,7 +180,8 @@ static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data,
        return rc;
 }
 
-int ima_calc_field_array_hash(struct ima_field_data *field_data, int num_fields,
+int ima_calc_field_array_hash(struct ima_field_data *field_data,
+                             struct ima_template_desc *desc, int num_fields,
                              struct ima_digest_data *hash)
 {
        struct crypto_shash *tfm;
@@ -185,7 +191,8 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data, int num_fields,
        if (IS_ERR(tfm))
                return PTR_ERR(tfm);
 
-       rc = ima_calc_field_array_hash_tfm(field_data, num_fields, hash, tfm);
+       rc = ima_calc_field_array_hash_tfm(field_data, desc, num_fields,
+                                          hash, tfm);
 
        ima_free_tfm(tfm);
 
index d47a7c86a21d0d94f6c41933fd18311e553dafce..db01125926bdb1e696165389bcdd26117e9d25fc 100644 (file)
@@ -120,6 +120,7 @@ static int ima_measurements_show(struct seq_file *m, void *v)
        struct ima_template_entry *e;
        int namelen;
        u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX;
+       bool is_ima_template = false;
        int i;
 
        /* get entry */
@@ -145,14 +146,21 @@ static int ima_measurements_show(struct seq_file *m, void *v)
        ima_putc(m, e->template_desc->name, namelen);
 
        /* 5th:  template length (except for 'ima' template) */
-       if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
+       if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0)
+               is_ima_template = true;
+
+       if (!is_ima_template)
                ima_putc(m, &e->template_data_len,
                         sizeof(e->template_data_len));
 
        /* 6th:  template specific data */
        for (i = 0; i < e->template_desc->num_fields; i++) {
-               e->template_desc->fields[i]->field_show(m, IMA_SHOW_BINARY,
-                                                       &e->template_data[i]);
+               enum ima_show_type show = IMA_SHOW_BINARY;
+               struct ima_template_field *field = e->template_desc->fields[i];
+
+               if (is_ima_template && strcmp(field->field_id, "d") == 0)
+                       show = IMA_SHOW_BINARY_NO_FIELD_LEN;
+               field->field_show(m, show, &e->template_data[i]);
        }
        return 0;
 }
index 4e5da990630beca2c179894db96fd9f20d31bc17..635695f6a185a1d24ee3d1bfb05d4f7ebe8cedb0 100644 (file)
@@ -90,7 +90,7 @@ static struct ima_template_field *lookup_template_field(const char *field_id)
        return NULL;
 }
 
-static int template_fmt_size(char *template_fmt)
+static int template_fmt_size(const char *template_fmt)
 {
        char c;
        int template_fmt_len = strlen(template_fmt);
@@ -106,22 +106,29 @@ static int template_fmt_size(char *template_fmt)
        return j + 1;
 }
 
-static int template_desc_init_fields(char *template_fmt,
+static int template_desc_init_fields(const char *template_fmt,
                                     struct ima_template_field ***fields,
                                     int *num_fields)
 {
-       char *c, *template_fmt_ptr = template_fmt;
+       char *c, *template_fmt_copy, *template_fmt_ptr;
        int template_num_fields = template_fmt_size(template_fmt);
        int i, result = 0;
 
        if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX)
                return -EINVAL;
 
+       /* copying is needed as strsep() modifies the original buffer */
+       template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL);
+       if (template_fmt_copy == NULL)
+               return -ENOMEM;
+
        *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
        if (*fields == NULL) {
                result = -ENOMEM;
                goto out;
        }
+
+       template_fmt_ptr = template_fmt_copy;
        for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL &&
             i < template_num_fields; i++) {
                struct ima_template_field *f = lookup_template_field(c);
@@ -133,10 +140,12 @@ static int template_desc_init_fields(char *template_fmt,
                (*fields)[i] = f;
        }
        *num_fields = i;
-       return 0;
 out:
-       kfree(*fields);
-       *fields = NULL;
+       if (result < 0) {
+               kfree(*fields);
+               *fields = NULL;
+       }
+       kfree(template_fmt_copy);
        return result;
 }
 
index 6d66ad6ed265f8f6422c0d9d7f7a64aa732f0779..c38adcc910fbb91f2c6f34255c3940b257bd7f35 100644 (file)
@@ -109,9 +109,12 @@ static void ima_show_template_data_binary(struct seq_file *m,
                                          enum data_formats datafmt,
                                          struct ima_field_data *field_data)
 {
-       ima_putc(m, &field_data->len, sizeof(u32));
+       if (show != IMA_SHOW_BINARY_NO_FIELD_LEN)
+               ima_putc(m, &field_data->len, sizeof(u32));
+
        if (!field_data->len)
                return;
+
        ima_putc(m, field_data->data, field_data->len);
 }
 
@@ -125,6 +128,7 @@ static void ima_show_template_field_data(struct seq_file *m,
                ima_show_template_data_ascii(m, show, datafmt, field_data);
                break;
        case IMA_SHOW_BINARY:
+       case IMA_SHOW_BINARY_NO_FIELD_LEN:
                ima_show_template_data_binary(m, show, datafmt, field_data);
                break;
        default:
index b9e7c133734a2dc5796fe98f5c15f8c81ebc5d26..2fb5e53e927f2bf5432a34af1251c89f359d90f7 100644 (file)
@@ -137,19 +137,12 @@ static inline int integrity_digsig_verify(const unsigned int id,
 #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
 int asymmetric_verify(struct key *keyring, const char *sig,
                      int siglen, const char *data, int datalen);
-
-int integrity_init_keyring(const unsigned int id);
 #else
 static inline int asymmetric_verify(struct key *keyring, const char *sig,
                                    int siglen, const char *data, int datalen)
 {
        return -EOPNOTSUPP;
 }
-
-static int integrity_init_keyring(const unsigned int id)
-{
-       return 0;
-}
 #endif
 
 #ifdef CONFIG_INTEGRITY_AUDIT
index d3226892ad6b44953fd4d980d65874ac40535768..9048777228e2f058430f10636a7d9de74233c550 100644 (file)
@@ -434,17 +434,14 @@ static void queue_out_packet(struct amdtp_out_stream *s, unsigned int cycle)
                return;
        index = s->packet_index;
 
+       /* this module generate empty packet for 'no data' */
        syt = calculate_syt(s, cycle);
-       if (!(s->flags & CIP_BLOCKING)) {
+       if (!(s->flags & CIP_BLOCKING))
                data_blocks = calculate_data_blocks(s);
-       } else {
-               if (syt != 0xffff) {
-                       data_blocks = s->syt_interval;
-               } else {
-                       data_blocks = 0;
-                       syt = 0xffffff;
-               }
-       }
+       else if (syt != 0xffff)
+               data_blocks = s->syt_interval;
+       else
+               data_blocks = 0;
 
        buffer = s->buffer.packets[index].buffer;
        buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
index 57bcd31fcc123c38cd293cab40b52310734698a2..c0aa64941cee0bd927450a6b69314d14f2f02bce 100644 (file)
@@ -1019,7 +1019,7 @@ static void dice_proc_read(struct snd_info_entry *entry,
 
        if (dice_proc_read_mem(dice, &tx_rx_header, sections[2], 2) < 0)
                return;
-       quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.tx));
+       quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.tx) / 4);
        for (stream = 0; stream < tx_rx_header.number; ++stream) {
                if (dice_proc_read_mem(dice, &buf.tx, sections[2] + 2 +
                                       stream * tx_rx_header.size,
@@ -1045,7 +1045,7 @@ static void dice_proc_read(struct snd_info_entry *entry,
 
        if (dice_proc_read_mem(dice, &tx_rx_header, sections[4], 2) < 0)
                return;
-       quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.rx));
+       quadlets = min_t(u32, tx_rx_header.size, sizeof(buf.rx) / 4);
        for (stream = 0; stream < tx_rx_header.number; ++stream) {
                if (dice_proc_read_mem(dice, &buf.rx, sections[4] + 2 +
                                       stream * tx_rx_header.size,
index 46ed9e8ae0fde718525da786a5b79a27a043c372..3a0504dfeb8a4e97341353ccee28365ef3fb3983 100644 (file)
@@ -254,6 +254,7 @@ config SND_CS46XX
        tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
        select SND_RAWMIDI
        select SND_AC97_CODEC
+       select FW_LOADER
        help
          Say Y here to include support for Cirrus Logic CS4610/CS4612/
          CS4614/CS4615/CS4622/CS4624/CS4630/CS4280 chips.
index fc339ef0a0ae439a87087753a4bfaf6e28de9742..c49a082c378b6c711e36d74187ef742318be56ce 100644 (file)
@@ -1716,9 +1716,14 @@ struct snd_cs46xx {
        struct snd_pcm *pcm_rear;
        struct snd_pcm *pcm_center_lfe;
        struct snd_pcm *pcm_iec958;
+
+#define CS46XX_DSP_MODULES     5
+       struct dsp_module_desc *modules[CS46XX_DSP_MODULES];
 #else /* for compatibility */
        struct snd_cs46xx_pcm *playback_pcm;
        unsigned int play_ctl;
+
+       struct ba1_struct *ba1;
 #endif
 
 #ifdef CONFIG_PM_SLEEP
diff --git a/sound/pci/cs46xx/cs46xx_image.h b/sound/pci/cs46xx/cs46xx_image.h
deleted file mode 100644 (file)
index dc93f62..0000000
+++ /dev/null
@@ -1,3468 +0,0 @@
-struct BA1struct {
-       struct {
-               unsigned long offset;
-               unsigned long size;
-       } memory[BA1_MEMORY_COUNT];
-       u32 map[BA1_DWORD_SIZE];
-};
-
-
-static struct BA1struct BA1Struct = {
-{{ 0x00000000, 0x00003000 },{ 0x00010000, 0x00003800 },{ 0x00020000, 0x00007000 }},
-{0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000163,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00200040,0x00008010,0x00000000,
-0x00000000,0x80000001,0x00000001,0x00060000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00900080,0x00000173,0x00000000,
-0x00000000,0x00000010,0x00800000,0x00900000,
-0xf2c0000f,0x00000200,0x00000000,0x00010600,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000163,0x330300c2,
-0x06000000,0x00000000,0x80008000,0x80008000,
-0x3fc0000f,0x00000301,0x00010400,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00b00000,0x00d0806d,0x330480c3,
-0x04800000,0x00000001,0x00800001,0x0000ffff,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x066a0600,0x06350070,0x0000929d,0x929d929d,
-0x00000000,0x0000735a,0x00000600,0x00000000,
-0x929d735a,0x8734abfe,0x00010000,0x735a735a,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000804f,0x000000c3,
-0x05000000,0x00a00010,0x00000000,0x80008000,
-0x00000000,0x00000000,0x00000700,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000080,0x00a00000,0x0000809a,0x000000c2,
-0x07400000,0x00000000,0x80008000,0xffffffff,
-0x00c80028,0x00005555,0x00000000,0x000107a0,
-0x00c80028,0x000000c2,0x06800000,0x00000000,
-0x06e00080,0x00300000,0x000080bb,0x000000c9,
-0x07a00000,0x04000000,0x80008000,0xffffffff,
-0x00c80028,0x00005555,0x00000000,0x00000780,
-0x00c80028,0x000000c5,0xff800000,0x00000000,
-0x00640080,0x00c00000,0x00008197,0x000000c9,
-0x07800000,0x04000000,0x80008000,0xffffffff,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000805e,0x000000c1,
-0x00000000,0x00800000,0x80008000,0x80008000,
-0x00020000,0x0000ffff,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x929d0600,0x929d929d,0x929d929d,0x929d0000,
-0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0x00100635,0x060b013f,0x00000004,
-0x00000001,0x007a0002,0x00000000,0x066e0610,
-0x0105929d,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
-0x00000000,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0x929d929d,0x00000000,0x06400136,
-0x0000270f,0x00010000,0x007a0000,0x00000000,
-0x068e0645,0x0105929d,0x929d929d,0x929d929d,
-0x929d929d,0x929d929d,0xa431ac75,0x0001735a,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0x735a0100,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00010004,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00001705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00009705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00011705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00019705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00021705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00029705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00031705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00039705,0x00001400,0x000a411e,0x00001003,
-0x000fe19e,0x00001003,0x0009c730,0x00001003,
-0x0008e19c,0x00001003,0x000083c1,0x00093040,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00009705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00011705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00019705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00021705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00029705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00031705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00039705,0x00001400,0x000a211e,0x00001003,
-0x0000a730,0x00001008,0x000e2730,0x00001002,
-0x0000a731,0x00001002,0x0000a731,0x00001002,
-0x0000a731,0x00001002,0x0000a731,0x00001002,
-0x0000a731,0x00001002,0x0000a731,0x00001002,
-0x00000000,0x00000000,0x000f619c,0x00001003,
-0x0007f801,0x000c0000,0x00000037,0x00001000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x000c0000,0x00000000,0x00000000,
-0x0000373c,0x00001000,0x00000000,0x00000000,
-0x000ee19c,0x00001003,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000273c,0x00001000,
-0x00000033,0x00001000,0x000e679e,0x00001003,
-0x00007705,0x00001400,0x000ac71e,0x00001003,
-0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000a730,0x00001003,
-0x00000033,0x00001000,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x000c0000,
-0x00000032,0x00001000,0x0000273d,0x00001000,
-0x0004a730,0x00001003,0x00000f41,0x00097140,
-0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-0x00000000,0x00000000,0x0001bf05,0x0003fc40,
-0x00002725,0x000aa400,0x00013705,0x00093a00,
-0x0000002e,0x0009d6c0,0x00038630,0x00001004,
-0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
-0x00000000,0x000c70e0,0x0007d182,0x0002c640,
-0x00000630,0x00001004,0x000799b8,0x0002c6c0,
-0x00031705,0x00092240,0x00039f05,0x000932c0,
-0x0003520a,0x00000000,0x00040731,0x0000100b,
-0x00010705,0x000b20c0,0x00000000,0x000eba44,
-0x00032108,0x000c60c4,0x00065208,0x000c2917,
-0x000406b0,0x00001007,0x00012f05,0x00036880,
-0x0002818e,0x000c0000,0x0004410a,0x00000000,
-0x00040630,0x00001007,0x00029705,0x000c0000,
-0x00000000,0x00000000,0x00003fc1,0x0003fc40,
-0x000037c1,0x00091b40,0x00003fc1,0x000911c0,
-0x000037c1,0x000957c0,0x00003fc1,0x000951c0,
-0x000037c1,0x00000000,0x00003fc1,0x000991c0,
-0x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
-0x000037c1,0x00000000,0x0001ccc1,0x000915c0,
-0x0001c441,0x0009d800,0x0009cdc1,0x00091240,
-0x0001c541,0x00091d00,0x0009cfc1,0x00095240,
-0x0001c741,0x00095c80,0x000e8ca9,0x00099240,
-0x000e85ad,0x00095640,0x00069ca9,0x00099d80,
-0x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
-0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
-0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
-0x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
-0x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
-0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
-0x0006fca9,0x00002500,0x000fb208,0x000c59a0,
-0x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
-0x000683ad,0x00095241,0x00020f05,0x000991c1,
-0x00000000,0x00000000,0x00086f88,0x00001000,
-0x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
-0x0009de81,0x000bd300,0x0009d601,0x000b1700,
-0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
-0x000a0f81,0x000bd740,0x00020701,0x000b5c80,
-0x000a1681,0x000b97c0,0x00021601,0x00002500,
-0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
-0x00021681,0x00002d00,0x00020f81,0x000bd800,
-0x000a0701,0x000b5bc0,0x00021601,0x00003500,
-0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
-0x00021681,0x00003d00,0x00020f81,0x000b1d00,
-0x000a0701,0x000b1fc0,0x00021601,0x00020500,
-0x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
-0x00021681,0x00020d00,0x00020f81,0x000bde80,
-0x000a0701,0x000bdfc0,0x00021601,0x00021500,
-0x00020f81,0x000b9341,0x00020701,0x000b53c1,
-0x00021681,0x00021d00,0x000a0f81,0x000d0380,
-0x0000b601,0x000b15c0,0x00007b01,0x00000000,
-0x00007b81,0x000bd1c0,0x00007b01,0x00000000,
-0x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
-0x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
-0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
-0x0007e488,0x000d7e45,0x00000000,0x000d7a44,
-0x0007e48a,0x00000000,0x00011f05,0x00084080,
-0x00000000,0x00000000,0x00001705,0x000b3540,
-0x00008a01,0x000bf040,0x00007081,0x000bb5c0,
-0x00055488,0x00000000,0x0000d482,0x0003fc40,
-0x0003fc88,0x00000000,0x0001e401,0x000b3a00,
-0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
-0x000c86b0,0x00001007,0x00008281,0x000bb240,
-0x0000b801,0x000b7140,0x00007888,0x00000000,
-0x0000073c,0x00001000,0x0007f188,0x000c0000,
-0x00000000,0x00000000,0x00055288,0x000c555c,
-0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
-0x0000fa88,0x00000000,0x00000032,0x00001000,
-0x0000073d,0x00001000,0x0007f188,0x000c0000,
-0x00000000,0x00000000,0x0008c01c,0x00001003,
-0x00002705,0x00001008,0x0008b201,0x000c1392,
-0x0000ba01,0x00000000,0x00008731,0x00001400,
-0x0004c108,0x000fe0c4,0x00057488,0x00000000,
-0x000a6388,0x00001001,0x0008b334,0x000bc141,
-0x0003020e,0x00000000,0x000886b0,0x00001008,
-0x00003625,0x000c5dfa,0x000a638a,0x00001001,
-0x0008020e,0x00001002,0x0008a6b0,0x00001008,
-0x0007f301,0x00000000,0x00000000,0x00000000,
-0x00002725,0x000a8c40,0x000000ae,0x00000000,
-0x000d8630,0x00001008,0x00000000,0x000c74e0,
-0x0007d182,0x0002d640,0x000a8630,0x00001008,
-0x000799b8,0x0002d6c0,0x0000748a,0x000c3ec5,
-0x0007420a,0x000c0000,0x00062208,0x000c4117,
-0x00070630,0x00001009,0x00000000,0x000c0000,
-0x0001022e,0x00000000,0x0003a630,0x00001009,
-0x00000000,0x000c0000,0x00000036,0x00001000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x0002a730,0x00001008,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0002a730,0x00001008,
-0x00000033,0x00001000,0x0002a705,0x00001008,
-0x00007a01,0x000c0000,0x000e6288,0x000d550a,
-0x0006428a,0x00000000,0x00060730,0x0000100a,
-0x00000000,0x000c0000,0x00000000,0x00000000,
-0x0007aab0,0x00034880,0x00078fb0,0x0000100b,
-0x00057488,0x00000000,0x00033b94,0x00081140,
-0x000183ae,0x00000000,0x000786b0,0x0000100b,
-0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
-0x00042731,0x00001003,0x0007aab0,0x00034880,
-0x00048fb0,0x0000100a,0x00057488,0x00000000,
-0x00033b94,0x00081140,0x000183ae,0x00000000,
-0x000806b0,0x0000100b,0x00022f05,0x00000000,
-0x00007401,0x00091140,0x00048f05,0x000951c0,
-0x00042731,0x00001003,0x0000473d,0x00001000,
-0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
-0x000fe19e,0x00001003,0x00000000,0x00000000,
-0x0008e19c,0x00001003,0x000083c1,0x00093040,
-0x00000f41,0x00097140,0x0000a841,0x0009b240,
-0x0000a0c1,0x0009f040,0x0001c641,0x00093540,
-0x0001cec1,0x0009b5c0,0x00000000,0x000fdc44,
-0x00055208,0x00000000,0x00010705,0x000a2880,
-0x0000a23a,0x00093a00,0x0003fc8a,0x000df6c5,
-0x0004ef0a,0x000c0000,0x00012f05,0x00036880,
-0x00065308,0x000c2997,0x000d86b0,0x0000100a,
-0x0004410a,0x000d40c7,0x00000000,0x00000000,
-0x00080730,0x00001004,0x00056f0a,0x000ea105,
-0x00000000,0x00000000,0x0000473d,0x00001000,
-0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
-0x0000273d,0x00001000,0x00000000,0x000eba44,
-0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
-0x00000734,0x00001000,0x00010705,0x000a6880,
-0x00006a88,0x000c75c4,0x00000000,0x000e5084,
-0x00000000,0x000eba44,0x00087401,0x000e4782,
-0x00000734,0x00001000,0x00010705,0x000a6880,
-0x00006a88,0x000c75c4,0x0007c108,0x000c0000,
-0x0007e721,0x000bed40,0x00005f25,0x000badc0,
-0x0003ba97,0x000beb80,0x00065590,0x000b2e00,
-0x00033217,0x00003ec0,0x00065590,0x000b8e40,
-0x0003ed80,0x000491c0,0x00073fb0,0x00074c80,
-0x000283a0,0x0000100c,0x000ee388,0x00042970,
-0x00008301,0x00021ef2,0x000b8f14,0x0000000f,
-0x000c4d8d,0x0000001b,0x000d6dc2,0x000e06c6,
-0x000032ac,0x000c3916,0x0004edc2,0x00074c80,
-0x00078898,0x00001000,0x00038894,0x00000032,
-0x000c4d8d,0x00092e1b,0x000d6dc2,0x000e06c6,
-0x0004edc2,0x000c1956,0x0000722c,0x00034a00,
-0x00041705,0x0009ed40,0x00058730,0x00001400,
-0x000d7488,0x000c3a00,0x00048f05,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000}
- };
index 1b66efd9b728e153506106cf3917b17c73ec87b3..f18e5878f58b42a195df536aedde6d80a3897700 100644 (file)
@@ -54,7 +54,9 @@
 #include <linux/gameport.h>
 #include <linux/mutex.h>
 #include <linux/export.h>
-
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/vmalloc.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -330,13 +332,146 @@ int snd_cs46xx_download(struct snd_cs46xx *chip,
        return 0;
 }
 
+static inline void memcpy_le32(void *dst, const void *src, unsigned int len)
+{
+#ifdef __LITTLE_ENDIAN
+       memcpy(dst, src, len);
+#else
+       u32 *_dst = dst;
+       const __le32 *_src = src;
+       len /= 4;
+       while (len-- > 0)
+               *_dst++ = le32_to_cpu(*_src++);
+#endif
+}
+
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 
-#include "imgs/cwc4630.h"
-#include "imgs/cwcasync.h"
-#include "imgs/cwcsnoop.h"
-#include "imgs/cwcbinhack.h"
-#include "imgs/cwcdma.h"
+static const char *module_names[CS46XX_DSP_MODULES] = {
+       "cwc4630", "cwcasync", "cwcsnoop", "cwcbinhack", "cwcdma"
+};
+
+MODULE_FIRMWARE("cs46xx/cwc4630");
+MODULE_FIRMWARE("cs46xx/cwcasync");
+MODULE_FIRMWARE("cs46xx/cwcsnoop");
+MODULE_FIRMWARE("cs46xx/cwcbinhack");
+MODULE_FIRMWARE("cs46xx/cwcdma");
+
+static void free_module_desc(struct dsp_module_desc *module)
+{
+       if (!module)
+               return;
+       kfree(module->module_name);
+       kfree(module->symbol_table.symbols);
+       if (module->segments) {
+               int i;
+               for (i = 0; i < module->nsegments; i++)
+                       kfree(module->segments[i].data);
+               kfree(module->segments);
+       }
+}
+
+/* firmware binary format:
+ * le32 nsymbols;
+ * struct {
+ *     le32 address;
+ *     char symbol_name[DSP_MAX_SYMBOL_NAME];
+ *     le32 symbol_type;
+ * } symbols[nsymbols];
+ * le32 nsegments;
+ * struct {
+ *     le32 segment_type;
+ *     le32 offset;
+ *     le32 size;
+ *     le32 data[size];
+ * } segments[nsegments];
+ */
+
+static int load_firmware(struct snd_cs46xx *chip,
+                        struct dsp_module_desc **module_ret,
+                        const char *fw_name)
+{
+       int i, err;
+       unsigned int nums, fwlen, fwsize;
+       const __le32 *fwdat;
+       struct dsp_module_desc *module = NULL;
+       const struct firmware *fw;
+       char fw_path[32];
+
+       sprintf(fw_path, "cs46xx/%s", fw_name);
+       err = request_firmware(&fw, fw_path, &chip->pci->dev);
+       if (err < 0)
+               return err;
+       fwsize = fw->size / 4;
+       if (fwsize < 2) {
+               err = -EINVAL;
+               goto error;
+       }
+
+       err = -ENOMEM;
+       module = kzalloc(sizeof(*module), GFP_KERNEL);
+       if (!module)
+               goto error;
+       module->module_name = kstrdup(fw_name, GFP_KERNEL);
+       if (!module->module_name)
+               goto error;
+
+       fwlen = 0;
+       fwdat = (const __le32 *)fw->data;
+       nums = module->symbol_table.nsymbols = le32_to_cpu(fwdat[fwlen++]);
+       if (nums >= 40)
+               goto error_inval;
+       module->symbol_table.symbols =
+               kcalloc(nums, sizeof(struct dsp_symbol_entry), GFP_KERNEL);
+       if (!module->symbol_table.symbols)
+               goto error;
+       for (i = 0; i < nums; i++) {
+               struct dsp_symbol_entry *entry =
+                       &module->symbol_table.symbols[i];
+               if (fwlen + 2 + DSP_MAX_SYMBOL_NAME / 4 > fwsize)
+                       goto error_inval;
+               entry->address = le32_to_cpu(fwdat[fwlen++]);
+               memcpy(entry->symbol_name, &fwdat[fwlen], DSP_MAX_SYMBOL_NAME - 1);
+               fwlen += DSP_MAX_SYMBOL_NAME / 4;
+               entry->symbol_type = le32_to_cpu(fwdat[fwlen++]);
+       }
+
+       if (fwlen >= fwsize)
+               goto error_inval;
+       nums = module->nsegments = le32_to_cpu(fwdat[fwlen++]);
+       if (nums > 10)
+               goto error_inval;
+       module->segments =
+               kcalloc(nums, sizeof(struct dsp_segment_desc), GFP_KERNEL);
+       if (!module->segments)
+               goto error;
+       for (i = 0; i < nums; i++) {
+               struct dsp_segment_desc *entry = &module->segments[i];
+               if (fwlen + 3 > fwsize)
+                       goto error_inval;
+               entry->segment_type = le32_to_cpu(fwdat[fwlen++]);
+               entry->offset = le32_to_cpu(fwdat[fwlen++]);
+               entry->size = le32_to_cpu(fwdat[fwlen++]);
+               if (fwlen + entry->size > fwsize)
+                       goto error_inval;
+               entry->data = kmalloc(entry->size * 4, GFP_KERNEL);
+               if (!entry->data)
+                       goto error;
+               memcpy_le32(entry->data, &fwdat[fwlen], entry->size * 4);
+               fwlen += entry->size;
+       }
+
+       *module_ret = module;
+       release_firmware(fw);
+       return 0;
+
+ error_inval:
+       err = -EINVAL;
+ error:
+       free_module_desc(module);
+       release_firmware(fw);
+       return err;
+}
 
 int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
                          unsigned long offset,
@@ -361,20 +496,63 @@ int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
 
 #else /* old DSP image */
 
-#include "cs46xx_image.h"
+struct ba1_struct {
+       struct {
+               u32 offset;
+               u32 size;
+       } memory[BA1_MEMORY_COUNT];
+       u32 map[BA1_DWORD_SIZE];
+};
+
+MODULE_FIRMWARE("cs46xx/ba1");
+
+static int load_firmware(struct snd_cs46xx *chip)
+{
+       const struct firmware *fw;
+       int i, size, err;
+
+       err = request_firmware(&fw, "cs46xx/ba1", &chip->pci->dev);
+       if (err < 0)
+               return err;
+       if (fw->size != sizeof(*chip->ba1)) {
+               err = -EINVAL;
+               goto error;
+       }
+
+       chip->ba1 = vmalloc(sizeof(*chip->ba1));
+       if (!chip->ba1) {
+               err = -ENOMEM;
+               goto error;
+       }
+
+       memcpy_le32(chip->ba1, fw->data, sizeof(*chip->ba1));
+
+       /* sanity check */
+       size = 0;
+       for (i = 0; i < BA1_MEMORY_COUNT; i++)
+               size += chip->ba1->memory[i].size;
+       if (size > BA1_DWORD_SIZE * 4)
+               err = -EINVAL;
+
+ error:
+       release_firmware(fw);
+       return err;
+}
 
 int snd_cs46xx_download_image(struct snd_cs46xx *chip)
 {
        int idx, err;
-       unsigned long offset = 0;
+       unsigned int offset = 0;
+       struct ba1_struct *ba1 = chip->ba1;
 
        for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
-               if ((err = snd_cs46xx_download(chip,
-                                              &BA1Struct.map[offset],
-                                              BA1Struct.memory[idx].offset,
-                                              BA1Struct.memory[idx].size)) < 0)
+               err = snd_cs46xx_download(chip,
+                                         &ba1->map[offset],
+                                         ba1->memory[idx].offset,
+                                         ba1->memory[idx].size);
+               if (err < 0)
                        return err;
-               offset += BA1Struct.memory[idx].size >> 2;
+               offset += ba1->memory[idx].size >> 2;
        }       
        return 0;
 }
@@ -2798,6 +2976,10 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
                cs46xx_dsp_spos_destroy(chip);
                chip->dsp_spos_instance = NULL;
        }
+       for (idx = 0; idx < CS46XX_DSP_MODULES; idx++)
+               free_module_desc(chip->modules[idx]);
+#else
+       vfree(chip->ba1);
 #endif
        
 #ifdef CONFIG_PM_SLEEP
@@ -3067,6 +3249,11 @@ static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
 int snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
 {      
        unsigned int tmp;
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+       int i;
+#endif
+       int err;
+
        /*
         *  Reset the processor.
         */
@@ -3075,45 +3262,33 @@ int snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
         *  Download the image to the processor.
         */
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-#if 0
-       if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) {
-               snd_printk(KERN_ERR "image download error\n");
-               return -EIO;
-       }
-#endif
-
-       if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) {
-               snd_printk(KERN_ERR "image download error [cwc4630]\n");
-               return -EIO;
-       }
-
-       if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) {
-               snd_printk(KERN_ERR "image download error [cwcasync]\n");
-               return -EIO;
-       }
-
-       if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) {
-               snd_printk(KERN_ERR "image download error [cwcsnoop]\n");
-               return -EIO;
-       }
-
-       if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) {
-               snd_printk(KERN_ERR "image download error [cwcbinhack]\n");
-               return -EIO;
-       }
-
-       if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) {
-               snd_printk(KERN_ERR "image download error [cwcdma]\n");
-               return -EIO;
+       for (i = 0; i < CS46XX_DSP_MODULES; i++) {
+               err = load_firmware(chip, &chip->modules[i], module_names[i]);
+               if (err < 0) {
+                       snd_printk(KERN_ERR "firmware load error [%s]\n",
+                                  module_names[i]);
+                       return err;
+               }
+               err = cs46xx_dsp_load_module(chip, chip->modules[i]);
+               if (err < 0) {
+                       snd_printk(KERN_ERR "image download error [%s]\n",
+                                  module_names[i]);
+                       return err;
+               }
        }
 
        if (cs46xx_dsp_scb_and_task_init(chip) < 0)
                return -EIO;
 #else
+       err = load_firmware(chip);
+       if (err < 0)
+               return err;
+
        /* old image */
-       if (snd_cs46xx_download_image(chip) < 0) {
+       err = snd_cs46xx_download_image(chip);
+       if (err < 0) {
                snd_printk(KERN_ERR "image download error\n");
-               return -EIO;
+               return err;
        }
 
        /*
diff --git a/sound/pci/cs46xx/imgs/cwc4630.h b/sound/pci/cs46xx/imgs/cwc4630.h
deleted file mode 100644 (file)
index 37c4f13..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-/* generated from cwc4630.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwc4630_H__
-#define __HEADER_cwc4630_H__
-
-static struct dsp_symbol_entry cwc4630_symbols[] = {
-  { 0x0000, "BEGINADDRESS",0x00 },
-  { 0x8000, "EXECCHILD",0x03 },
-  { 0x8001, "EXECCHILD_98",0x03 },
-  { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
-  { 0x8008, "EXECSIBLING",0x03 },
-  { 0x800a, "EXECSIBLING_298",0x03 },
-  { 0x800b, "EXECSIBLING_2IND1",0x03 },
-  { 0x8010, "TIMINGMASTER",0x03 },
-  { 0x804f, "S16_CODECINPUTTASK",0x03 },
-  { 0x805e, "PCMSERIALINPUTTASK",0x03 },
-  { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
-  { 0x809a, "S16_MIX",0x03 },
-  { 0x80bb, "S16_UPSRC",0x03 },
-  { 0x813b, "MIX3_EXP",0x03 },
-  { 0x8164, "DECIMATEBYPOW2",0x03 },
-  { 0x8197, "VARIDECIMATE",0x03 },
-  { 0x81f2, "_3DINPUTTASK",0x03 },
-  { 0x820a, "_3DPRLGCINPTASK",0x03 },
-  { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
-  { 0x8242, "_3DOUTPUTTASK",0x03 },
-  { 0x82c4, "HRTF_MORPH_TASK",0x03 },
-  { 0x82c6, "WAIT4DATA",0x03 },
-  { 0x82fa, "PROLOGIC",0x03 },
-  { 0x8496, "DECORRELATOR",0x03 },
-  { 0x84a4, "STEREO2MONO",0x03 },
-  { 0x0070, "SPOSCB",0x02 },
-  { 0x0107, "TASKTREETHREAD",0x03 },
-  { 0x013c, "TASKTREEHEADERCODE",0x03 },
-  { 0x0145, "FGTASKTREEHEADERCODE",0x03 },
-  { 0x0169, "NULLALGORITHM",0x03 },
-  { 0x016d, "HFGEXECCHILD",0x03 },
-  { 0x016e, "HFGEXECCHILD_98",0x03 },
-  { 0x0170, "HFGEXECCHILD_PUSH1IND",0x03 },
-  { 0x0173, "HFGEXECSIBLING",0x03 },
-  { 0x0175, "HFGEXECSIBLING_298",0x03 },
-  { 0x0176, "HFGEXECSIBLING_2IND1",0x03 },
-  { 0x0179, "S16_CODECOUTPUTTASK",0x03 },
-  { 0x0194, "#CODE_END",0x00 },
-}; /* cwc4630 symbols */
-
-static u32 cwc4630_code[] = {
-/* BEGINADDRESS */
-/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003,
-/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003,
-/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003,
-/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003,
-/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003,
-/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003,
-/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003,
-/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003,
-/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003,
-/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040,
-/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003,
-/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003,
-/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003,
-/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003,
-/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003,
-/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003,
-/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003,
-/* 0040 */ 0x0001a730,0x00001008,0x000e2730,0x00001002,
-/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003,
-/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000,
-/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000,
-/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000,
-/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000,
-/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003,
-/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003,
-/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
-/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003,
-/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000,
-/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000,
-/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000,
-/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140,
-/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40,
-/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00,
-/* 007C */ 0x0000002e,0x0009d6c0,0x0002ef8a,0x00000000,
-/* 007E */ 0x00040630,0x00001004,0x0004ef0a,0x000eb785,
-/* 0080 */ 0x0003fc8a,0x00000000,0x00000000,0x000c70e0,
-/* 0082 */ 0x0007d182,0x0002c640,0x00008630,0x00001004,
-/* 0084 */ 0x000799b8,0x0002c6c0,0x00031705,0x00092240,
-/* 0086 */ 0x00039f05,0x000932c0,0x0003520a,0x00000000,
-/* 0088 */ 0x00070731,0x0000100b,0x00010705,0x000b20c0,
-/* 008A */ 0x00000000,0x000eba44,0x00032108,0x000c60c4,
-/* 008C */ 0x00065208,0x000c2917,0x000486b0,0x00001007,
-/* 008E */ 0x00012f05,0x00036880,0x0002818e,0x000c0000,
-/* 0090 */ 0x0004410a,0x00000000,0x00048630,0x00001007,
-/* 0092 */ 0x00029705,0x000c0000,0x00000000,0x00000000,
-/* 0094 */ 0x00003fc1,0x0003fc40,0x000037c1,0x00091b40,
-/* 0096 */ 0x00003fc1,0x000911c0,0x000037c1,0x000957c0,
-/* 0098 */ 0x00003fc1,0x000951c0,0x000037c1,0x00000000,
-/* 009A */ 0x00003fc1,0x000991c0,0x000037c1,0x00000000,
-/* 009C */ 0x00003fc1,0x0009d1c0,0x000037c1,0x00000000,
-/* 009E */ 0x0001ccc1,0x000915c0,0x0001c441,0x0009d800,
-/* 00A0 */ 0x0009cdc1,0x00091240,0x0001c541,0x00091d00,
-/* 00A2 */ 0x0009cfc1,0x00095240,0x0001c741,0x00095c80,
-/* 00A4 */ 0x000e8ca9,0x00099240,0x000e85ad,0x00095640,
-/* 00A6 */ 0x00069ca9,0x00099d80,0x000e952d,0x00099640,
-/* 00A8 */ 0x000eaca9,0x0009d6c0,0x000ea5ad,0x00091a40,
-/* 00AA */ 0x0006bca9,0x0009de80,0x000eb52d,0x00095a40,
-/* 00AC */ 0x000ecca9,0x00099ac0,0x000ec5ad,0x0009da40,
-/* 00AE */ 0x000edca9,0x0009d300,0x000a6e0a,0x00001000,
-/* 00B0 */ 0x000ed52d,0x00091e40,0x000eeca9,0x00095ec0,
-/* 00B2 */ 0x000ee5ad,0x00099e40,0x0006fca9,0x00002500,
-/* 00B4 */ 0x000fb208,0x000c59a0,0x000ef52d,0x0009de40,
-/* 00B6 */ 0x00068ca9,0x000912c1,0x000683ad,0x00095241,
-/* 00B8 */ 0x00020f05,0x000991c1,0x00000000,0x00000000,
-/* 00BA */ 0x00086f88,0x00001000,0x0009cf81,0x000b5340,
-/* 00BC */ 0x0009c701,0x000b92c0,0x0009de81,0x000bd300,
-/* 00BE */ 0x0009d601,0x000b1700,0x0001fd81,0x000b9d80,
-/* 00C0 */ 0x0009f501,0x000b57c0,0x000a0f81,0x000bd740,
-/* 00C2 */ 0x00020701,0x000b5c80,0x000a1681,0x000b97c0,
-/* 00C4 */ 0x00021601,0x00002500,0x000a0701,0x000b9b40,
-/* 00C6 */ 0x000a0f81,0x000b1bc0,0x00021681,0x00002d00,
-/* 00C8 */ 0x00020f81,0x000bd800,0x000a0701,0x000b5bc0,
-/* 00CA */ 0x00021601,0x00003500,0x000a0f81,0x000b5f40,
-/* 00CC */ 0x000a0701,0x000bdbc0,0x00021681,0x00003d00,
-/* 00CE */ 0x00020f81,0x000b1d00,0x000a0701,0x000b1fc0,
-/* 00D0 */ 0x00021601,0x00020500,0x00020f81,0x000b1341,
-/* 00D2 */ 0x000a0701,0x000b9fc0,0x00021681,0x00020d00,
-/* 00D4 */ 0x00020f81,0x000bde80,0x000a0701,0x000bdfc0,
-/* 00D6 */ 0x00021601,0x00021500,0x00020f81,0x000b9341,
-/* 00D8 */ 0x00020701,0x000b53c1,0x00021681,0x00021d00,
-/* 00DA */ 0x000a0f81,0x000d0380,0x0000b601,0x000b15c0,
-/* 00DC */ 0x00007b01,0x00000000,0x00007b81,0x000bd1c0,
-/* 00DE */ 0x00007b01,0x00000000,0x00007b81,0x000b91c0,
-/* 00E0 */ 0x00007b01,0x000b57c0,0x00007b81,0x000b51c0,
-/* 00E2 */ 0x00007b01,0x000b1b40,0x00007b81,0x000b11c0,
-/* 00E4 */ 0x00087b01,0x000c3dc0,0x0007e488,0x000d7e45,
-/* 00E6 */ 0x00000000,0x000d7a44,0x0007e48a,0x00000000,
-/* 00E8 */ 0x00011f05,0x00084080,0x00000000,0x00000000,
-/* 00EA */ 0x00001705,0x000b3540,0x00008a01,0x000bf040,
-/* 00EC */ 0x00007081,0x000bb5c0,0x00055488,0x00000000,
-/* 00EE */ 0x0000d482,0x0003fc40,0x0003fc88,0x00000000,
-/* 00F0 */ 0x0001e401,0x000b3a00,0x0001ec81,0x000bd6c0,
-/* 00F2 */ 0x0002ef88,0x000e7784,0x00056f08,0x00000000,
-/* 00F4 */ 0x000d86b0,0x00001007,0x00008281,0x000bb240,
-/* 00F6 */ 0x0000b801,0x000b7140,0x00007888,0x00000000,
-/* 00F8 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000,
-/* 00FA */ 0x00000000,0x00000000,0x00055288,0x000c555c,
-/* 00FC */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
-/* 00FE */ 0x0000fa88,0x00000000,0x00000032,0x00001000,
-/* 0100 */ 0x0000073d,0x00001000,0x0007f188,0x000c0000,
-/* 0102 */ 0x00000000,0x00000000,0x0008c01c,0x00001003,
-/* 0104 */ 0x00002705,0x00001008,0x0008b201,0x000c1392,
-/* 0106 */ 0x0000ba01,0x00000000,
-/* TASKTREETHREAD */
-/* 0107 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4,
-/* 0109 */ 0x00057488,0x00000000,0x000a6388,0x00001001,
-/* 010B */ 0x0008b334,0x000bc141,0x0003020e,0x00000000,
-/* 010D */ 0x000986b0,0x00001008,0x00003625,0x000c5dfa,
-/* 010F */ 0x000a638a,0x00001001,0x0008020e,0x00001002,
-/* 0111 */ 0x0009a6b0,0x00001008,0x0007f301,0x00000000,
-/* 0113 */ 0x00000000,0x00000000,0x00002725,0x000a8c40,
-/* 0115 */ 0x000000ae,0x00000000,0x000e8630,0x00001008,
-/* 0117 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640,
-/* 0119 */ 0x000b8630,0x00001008,0x000799b8,0x0002d6c0,
-/* 011B */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000,
-/* 011D */ 0x00062208,0x000c4117,0x000a0630,0x00001009,
-/* 011F */ 0x00000000,0x000c0000,0x0001022e,0x00000000,
-/* 0121 */ 0x0006a630,0x00001009,0x00000032,0x00001000,
-/* 0123 */ 0x000ca21c,0x00001003,0x00005a02,0x00000000,
-/* 0125 */ 0x0001a630,0x00001009,0x00000000,0x000c0000,
-/* 0127 */ 0x00000036,0x00001000,0x00000000,0x00000000,
-/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012B */ 0x00000000,0x00000000,0x0003a730,0x00001008,
-/* 012D */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 012F */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0131 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0133 */ 0x0003a730,0x00001008,0x00000033,0x00001000,
-/* 0135 */ 0x0003a705,0x00001008,0x00007a01,0x000c0000,
-/* 0137 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000,
-/* 0139 */ 0x00090730,0x0000100a,0x00000000,0x000c0000,
-/* 013B */ 0x00000000,0x00000000,
-/* TASKTREEHEADERCODE */
-/* 013C */ 0x0007aab0,0x00034880,0x000a8fb0,0x0000100b,
-/* 013E */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 0140 */ 0x000183ae,0x00000000,0x000a86b0,0x0000100b,
-/* 0142 */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
-/* 0144 */ 0x00042731,0x00001003,
-/* FGTASKTREEHEADERCODE */
-/* 0145 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100a,
-/* 0147 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 0149 */ 0x000183ae,0x00000000,0x000b06b0,0x0000100b,
-/* 014B */ 0x00022f05,0x00000000,0x00007401,0x00091140,
-/* 014D */ 0x00048f05,0x000951c0,0x00042731,0x00001003,
-/* 014F */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 0151 */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003,
-/* 0153 */ 0x00000000,0x00000000,0x0008e19c,0x00001003,
-/* 0155 */ 0x000083c1,0x00093040,0x00000f41,0x00097140,
-/* 0157 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0159 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 015B */ 0x00000000,0x000fdc44,0x00055208,0x00000000,
-/* 015D */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00,
-/* 015F */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000,
-/* 0161 */ 0x00012f05,0x00036880,0x00065308,0x000c2997,
-/* 0163 */ 0x000086b0,0x0000100b,0x0004410a,0x000d40c7,
-/* 0165 */ 0x00000000,0x00000000,0x00088730,0x00001004,
-/* 0167 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000,
-/* NULLALGORITHM */
-/* 0169 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 016B */ 0x00080000,0x000bffc7,0x0000273d,0x00001000,
-/* HFGEXECCHILD */
-/* 016D */ 0x00000000,0x000eba44,
-/* HFGEXECCHILD_98 */
-/* 016E */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
-/* HFGEXECCHILD_PUSH1IND */
-/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 0172 */ 0x00006a88,0x000c75c4,
-/* HFGEXECSIBLING */
-/* 0173 */ 0x00000000,0x000e5084,0x00000000,0x000eba44,
-/* HFGEXECSIBLING_298 */
-/* 0175 */ 0x00087401,0x000e4782,
-/* HFGEXECSIBLING_2IND1 */
-/* 0176 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 0178 */ 0x00006a88,0x000c75c4,
-/* S16_CODECOUTPUTTASK */
-/* 0179 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40,
-/* 017B */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80,
-/* 017D */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0,
-/* 017F */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0,
-/* 0181 */ 0x00073fb0,0x00074c80,0x000583a0,0x0000100c,
-/* 0183 */ 0x000ee388,0x00042970,0x00008301,0x00021ef2,
-/* 0185 */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b,
-/* 0187 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916,
-/* 0189 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000,
-/* 018B */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b,
-/* 018D */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956,
-/* 018F */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40,
-/* 0191 */ 0x00058730,0x00001400,0x000d7488,0x000c3a00,
-/* 0193 */ 0x00048f05,0x00000000
-};
-/* #CODE_END */
-
-static u32 cwc4630_parameter[] = {
-/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000
-}; /* #PARAMETER_END */
-
-
-static struct dsp_segment_desc cwc4630_segments[] = {
-  { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000328, cwc4630_code },
-  { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000080, cwc4630_parameter },
-};
-
-static struct dsp_module_desc cwc4630_module = {
-  "cwc4630",
-  {
-    38,
-    cwc4630_symbols
-  },
-  2,
-  cwc4630_segments,
-};
-
-#endif /* __HEADER_cwc4630_H__ */
diff --git a/sound/pci/cs46xx/imgs/cwcasync.h b/sound/pci/cs46xx/imgs/cwcasync.h
deleted file mode 100644 (file)
index 70e63e1..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* generated from cwcasync.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwcasync_H__
-#define __HEADER_cwcasync_H__
-
-static struct dsp_symbol_entry cwcasync_symbols[] = {
-  { 0x8000, "EXECCHILD",0x03 },
-  { 0x8001, "EXECCHILD_98",0x03 },
-  { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
-  { 0x8008, "EXECSIBLING",0x03 },
-  { 0x800a, "EXECSIBLING_298",0x03 },
-  { 0x800b, "EXECSIBLING_2IND1",0x03 },
-  { 0x8010, "TIMINGMASTER",0x03 },
-  { 0x804f, "S16_CODECINPUTTASK",0x03 },
-  { 0x805e, "PCMSERIALINPUTTASK",0x03 },
-  { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
-  { 0x809a, "S16_MIX",0x03 },
-  { 0x80bb, "S16_UPSRC",0x03 },
-  { 0x813b, "MIX3_EXP",0x03 },
-  { 0x8164, "DECIMATEBYPOW2",0x03 },
-  { 0x8197, "VARIDECIMATE",0x03 },
-  { 0x81f2, "_3DINPUTTASK",0x03 },
-  { 0x820a, "_3DPRLGCINPTASK",0x03 },
-  { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
-  { 0x8242, "_3DOUTPUTTASK",0x03 },
-  { 0x82c4, "HRTF_MORPH_TASK",0x03 },
-  { 0x82c6, "WAIT4DATA",0x03 },
-  { 0x82fa, "PROLOGIC",0x03 },
-  { 0x8496, "DECORRELATOR",0x03 },
-  { 0x84a4, "STEREO2MONO",0x03 },
-  { 0x0000, "OVERLAYBEGINADDRESS",0x00 },
-  { 0x0000, "SPIOWRITE",0x03 },
-  { 0x000d, "S16_ASYNCCODECINPUTTASK",0x03 },
-  { 0x0043, "SPDIFITASK",0x03 },
-  { 0x007b, "SPDIFOTASK",0x03 },
-  { 0x0097, "ASYNCHFGTXCODE",0x03 },
-  { 0x00be, "ASYNCHFGRXCODE",0x03 },
-  { 0x00db, "#CODE_END",0x00 },
-}; /* cwcasync symbols */
-
-static u32 cwcasync_code[] = {
-/* OVERLAYBEGINADDRESS */
-/* 0000 */ 0x00002731,0x00001400,0x00003725,0x000a8440,
-/* 0002 */ 0x000000ae,0x00000000,0x00060630,0x00001000,
-/* 0004 */ 0x00000000,0x000c7560,0x00075282,0x0002d640,
-/* 0006 */ 0x00021705,0x00000000,0x00072ab8,0x0002d6c0,
-/* 0008 */ 0x00020630,0x00001000,0x000c74c2,0x000d4b82,
-/* 000A */ 0x000475c2,0x00000000,0x0003430a,0x000c0000,
-/* 000C */ 0x00042730,0x00001400,
-/* S16_ASYNCCODECINPUTTASK */
-/* 000D */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x00000000,
-/* 000F */ 0x000fa418,0x0000101f,0x0005d402,0x0001c500,
-/* 0011 */ 0x000f0630,0x00001000,0x00004418,0x00001380,
-/* 0013 */ 0x000e243d,0x000d394a,0x00049705,0x00000000,
-/* 0015 */ 0x0007d530,0x000b4240,0x000e00f2,0x00001000,
-/* 0017 */ 0x00009134,0x000ca20a,0x00004c90,0x00001000,
-/* 0019 */ 0x0005d705,0x00000000,0x00004f25,0x00098240,
-/* 001B */ 0x00004725,0x00000000,0x0000e48a,0x00000000,
-/* 001D */ 0x00027295,0x0009c2c0,0x0003df25,0x00000000,
-/* 001F */ 0x000e8030,0x00001001,0x0005f718,0x000ac600,
-/* 0021 */ 0x0007cf30,0x000c2a01,0x00082630,0x00001001,
-/* 0023 */ 0x000504a0,0x00001001,0x00029314,0x000bcb80,
-/* 0025 */ 0x0003cf25,0x000b0e00,0x0004f5c0,0x00000000,
-/* 0027 */ 0x00049118,0x000d888a,0x0007dd02,0x000c6efa,
-/* 0029 */ 0x00000000,0x00000000,0x0004f5c0,0x00069c80,
-/* 002B */ 0x0000d402,0x00000000,0x000e8630,0x00001001,
-/* 002D */ 0x00079130,0x00000000,0x00049118,0x00090e00,
-/* 002F */ 0x0006c10a,0x00000000,0x00000000,0x000c0000,
-/* 0031 */ 0x0007cf30,0x00030580,0x00005725,0x00000000,
-/* 0033 */ 0x000d84a0,0x00001001,0x00029314,0x000b4780,
-/* 0035 */ 0x0003cf25,0x000b8600,0x00000000,0x00000000,
-/* 0037 */ 0x00000000,0x000c0000,0x00000000,0x00042c80,
-/* 0039 */ 0x0001dec1,0x000e488c,0x00031114,0x00000000,
-/* 003B */ 0x0004f5c2,0x00000000,0x0003640a,0x00000000,
-/* 003D */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
-/* 003F */ 0x00007001,0x00000000,0x00000734,0x00001000,
-/* 0041 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
-/* SPDIFITASK */
-/* 0043 */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x000d5384,
-/* 0045 */ 0x0007e48a,0x00000000,0x00067718,0x00001000,
-/* 0047 */ 0x0007a418,0x00001000,0x0007221a,0x00000000,
-/* 0049 */ 0x0005d402,0x00014500,0x000b8630,0x00001002,
-/* 004B */ 0x00004418,0x00001780,0x000e243d,0x000d394a,
-/* 004D */ 0x00049705,0x00000000,0x0007d530,0x000b4240,
-/* 004F */ 0x000ac0f2,0x00001002,0x00014414,0x00000000,
-/* 0051 */ 0x00004c90,0x00001000,0x0005d705,0x00000000,
-/* 0053 */ 0x00004f25,0x00098240,0x00004725,0x00000000,
-/* 0055 */ 0x0000e48a,0x00000000,0x00027295,0x0009c2c0,
-/* 0057 */ 0x0007df25,0x00000000,0x000ac030,0x00001003,
-/* 0059 */ 0x0005f718,0x000fe798,0x00029314,0x000bcb80,
-/* 005B */ 0x00000930,0x000b0e00,0x0004f5c0,0x000de204,
-/* 005D */ 0x000884a0,0x00001003,0x0007cf25,0x000e3560,
-/* 005F */ 0x00049118,0x00000000,0x00049118,0x000d888a,
-/* 0061 */ 0x0007dd02,0x000c6efa,0x0000c434,0x00030040,
-/* 0063 */ 0x000fda82,0x000c2312,0x000fdc0e,0x00001001,
-/* 0065 */ 0x00083402,0x000c2b92,0x000706b0,0x00001003,
-/* 0067 */ 0x00075a82,0x00000000,0x0000d625,0x000b0940,
-/* 0069 */ 0x0000840e,0x00001002,0x0000aabc,0x000c511e,
-/* 006B */ 0x00078730,0x00001003,0x0000aaf4,0x000e910a,
-/* 006D */ 0x0004628a,0x00000000,0x00006aca,0x00000000,
-/* 006F */ 0x00000930,0x00000000,0x0004f5c0,0x00069c80,
-/* 0071 */ 0x00046ac0,0x00000000,0x0003c40a,0x000fc898,
-/* 0073 */ 0x00049118,0x00090e00,0x0006c10a,0x00000000,
-/* 0075 */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
-/* 0077 */ 0x00007001,0x00000000,0x00000734,0x00001000,
-/* 0079 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
-/* SPDIFOTASK */
-/* 007B */ 0x0006a108,0x000c0000,0x0004f4c0,0x000c3245,
-/* 007D */ 0x0000a418,0x00001000,0x0003a20a,0x00000000,
-/* 007F */ 0x00004418,0x00001380,0x000e243d,0x000d394a,
-/* 0081 */ 0x000c9705,0x000def92,0x0008c030,0x00001004,
-/* 0083 */ 0x0005f718,0x000fe798,0x00000000,0x000c0000,
-/* 0085 */ 0x00005725,0x00000000,0x000704a0,0x00001004,
-/* 0087 */ 0x00029314,0x000b4780,0x0003cf25,0x000b8600,
-/* 0089 */ 0x00000000,0x00000000,0x00000000,0x000c0000,
-/* 008B */ 0x00000000,0x00042c80,0x0001dec1,0x000e488c,
-/* 008D */ 0x00031114,0x00000000,0x0004f5c2,0x00000000,
-/* 008F */ 0x0004a918,0x00098600,0x0006c28a,0x00000000,
-/* 0091 */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
-/* 0093 */ 0x00007001,0x00000000,0x00000734,0x00001000,
-/* 0095 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
-/* ASYNCHFGTXCODE */
-/* 0097 */ 0x0002a880,0x000b4e40,0x00042214,0x000e5548,
-/* 0099 */ 0x000542bf,0x00000000,0x00000000,0x000481c0,
-/* 009B */ 0x00000000,0x00000000,0x00000000,0x00000030,
-/* 009D */ 0x0000072d,0x000fbf8a,0x00077f94,0x000ea7df,
-/* 009F */ 0x0002ac95,0x000d3145,0x00002731,0x00001400,
-/* 00A1 */ 0x00006288,0x000c71c4,0x00014108,0x000e6044,
-/* 00A3 */ 0x00035408,0x00000000,0x00025418,0x000a0ec0,
-/* 00A5 */ 0x0001443d,0x000ca21e,0x00046595,0x000d730c,
-/* 00A7 */ 0x0006538e,0x00000000,0x00064630,0x00001005,
-/* 00A9 */ 0x000e7b0e,0x000df782,0x000746b0,0x00001005,
-/* 00AB */ 0x00036f05,0x000c0000,0x00043695,0x000d598c,
-/* 00AD */ 0x0005331a,0x000f2185,0x00000000,0x00000000,
-/* 00AF */ 0x000007ae,0x000bdb00,0x00040630,0x00001400,
-/* 00B1 */ 0x0005e708,0x000c0000,0x0007ef30,0x000b1c00,
-/* 00B3 */ 0x000d86a0,0x00001005,0x00066408,0x000c0000,
-/* 00B5 */ 0x00000000,0x00000000,0x00021843,0x00000000,
-/* 00B7 */ 0x00000cac,0x00062c00,0x00001dac,0x00063400,
-/* 00B9 */ 0x00002cac,0x0006cc80,0x000db943,0x000e5ca1,
-/* 00BB */ 0x00000000,0x00000000,0x0006680a,0x000f3205,
-/* 00BD */ 0x00042730,0x00001400,
-/* ASYNCHFGRXCODE */
-/* 00BE */ 0x00014108,0x000f2204,0x00025418,0x000a2ec0,
-/* 00C0 */ 0x00015dbd,0x00038100,0x00015dbc,0x00000000,
-/* 00C2 */ 0x0005e415,0x00034880,0x0001258a,0x000d730c,
-/* 00C4 */ 0x0006538e,0x000baa40,0x00060630,0x00001006,
-/* 00C6 */ 0x00067b0e,0x000ac380,0x0003ef05,0x00000000,
-/* 00C8 */ 0x0000f734,0x0001c300,0x000586b0,0x00001400,
-/* 00CA */ 0x000b6f05,0x000c3a00,0x00048f05,0x00000000,
-/* 00CC */ 0x0005b695,0x0008c380,0x0002058e,0x00000000,
-/* 00CE */ 0x000500b0,0x00001400,0x0002b318,0x000e998d,
-/* 00D0 */ 0x0006430a,0x00000000,0x00000000,0x000ef384,
-/* 00D2 */ 0x00004725,0x000c0000,0x00000000,0x000f3204,
-/* 00D4 */ 0x00004f25,0x000c0000,0x00080000,0x000e5ca1,
-/* 00D6 */ 0x000cb943,0x000e5ca1,0x0004b943,0x00000000,
-/* 00D8 */ 0x00040730,0x00001400,0x000cb943,0x000e5ca1,
-/* 00DA */ 0x0004b943,0x00000000
-};
-/* #CODE_END */
-
-static struct dsp_segment_desc cwcasync_segments[] = {
-  { SEGTYPE_SP_PROGRAM, 0x00000000, 0x000001b6, cwcasync_code },
-};
-
-static struct dsp_module_desc cwcasync_module = {
-  "cwcasync",
-  {
-    32,
-    cwcasync_symbols
-  },
-  1,
-  cwcasync_segments,
-};
-
-#endif /* __HEADER_cwcasync_H__ */
diff --git a/sound/pci/cs46xx/imgs/cwcbinhack.h b/sound/pci/cs46xx/imgs/cwcbinhack.h
deleted file mode 100644 (file)
index f4d9368..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* generated by Benny 
-   MODIFY ON YOUR OWN RISK */
-
-#ifndef __HEADER_cwcbinhack_H__
-#define __HEADER_cwcbinhack_H__
-
-static struct dsp_symbol_entry cwcbinhack_symbols[] = {
-  { 0x02c8, "OVERLAYBEGINADDRESS",0x00 },
-  { 0x02c8, "MAGICSNOOPTASK",0x03 },
-  { 0x0308, "#CODE_END",0x00 },
-}; /* cwcbinhack symbols */
-
-static u32 cwcbinhack_code[] = {
-  /* 0x02c8 */
-  0x0007bfb0,0x000bc240,0x00000c2e,0x000c6084, /* 1 */
-  0x000b8630,0x00001016,0x00006408,0x000efb84, /* 2 */
-  0x00016008,0x00000000,0x0001c088,0x000c0000, /* 3 */
-  0x000fc908,0x000e3392,0x0005f488,0x000efb84, /* 4 */
-  0x0001d402,0x000b2e00,0x0003d418,0x00001000, /* 5 */
-  0x0008d574,0x000c4293,0x00065625,0x000ea30e, /* 6 */
-  0x00096c01,0x000c6f92,0x0001a58a,0x000c6085, /* 7 */
-  0x00002f43,0x00000000,0x000e03a0,0x00001016, /* 8 */
-  0x0005e608,0x000c0000,0x00000000,0x00000000, /* 9 */
-  0x000ca108,0x000dcca1,0x00003bac,0x000c3205, /* 10 */
-  0x00073843,0x00000000,0x00010730,0x00001017, /* 11 */
-  0x0001600a,0x000c0000,0x00057488,0x00000000, /* 12 */
-  0x00000000,0x000e5084,0x00000000,0x000eba44, /* 13 */
-  0x00087401,0x000e4782,0x00000734,0x00001000, /* 14 */
-  0x00010705,0x000a6880,0x00006a88,0x000c75c4, /* 15 */
-  0x00000000,0x00000000,0x00000000,0x00000000, /* 16 */
-};
-/* #CODE_END */
-
-static struct dsp_segment_desc cwcbinhack_segments[] = {
-  { SEGTYPE_SP_PROGRAM, 0x00000000, 64, cwcbinhack_code },
-};
-
-static struct dsp_module_desc cwcbinhack_module = {
-  "cwcbinhack",
-  {
-    3,
-    cwcbinhack_symbols
-  },
-  1,
-  cwcbinhack_segments,
-};
-
-#endif /* __HEADER_cwcbinhack_H__ */
diff --git a/sound/pci/cs46xx/imgs/cwcdma.asp b/sound/pci/cs46xx/imgs/cwcdma.asp
deleted file mode 100644 (file)
index a65e119..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-// 
-//  Copyright(c) by Benny Sjostrand (benny@hostmobility.com)
-//
-//  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
-//
-
-
-//
-// This code runs inside the DSP (cs4610, cs4612, cs4624, or cs4630),
-// to compile it you need a tool named SPASM 3.0 and DSP code owned by 
-// Cirrus Logic(R). The SPASM program will generate a object file (cwcdma.osp),
-// the "ospparser"  tool will genereate the cwcdma.h file it's included from
-// the cs46xx_lib.c file.
-//
-//
-// The purpose of this code is very simple: make it possible to tranfser
-// the samples 'as they are' with no alteration from a PCMreader
-// SCB (DMA from host) to any other SCB. This is useful for AC3 through SPDIF.
-// SRC (source rate converters) task always alters the samples in somehow,
-// however it's from 48khz -> 48khz.
-// The alterations are not audible, but AC3 wont work. 
-//
-//        ...
-//         |
-// +---------------+
-// | AsynchFGTxSCB |
-// +---------------+
-//        |
-//    subListPtr
-//        |
-// +--------------+
-// |   DMAReader  |
-// +--------------+
-//        |
-//    subListPtr
-//        |
-// +-------------+
-// | PCMReader   |
-// +-------------+
-// (DMA from host)
-//
-
-struct dmaSCB
-  {
-    long  dma_reserved1[3];
-
-    short dma_reserved2:dma_outBufPtr;
-
-    short dma_unused1:dma_unused2;
-
-    long  dma_reserved3[4];
-
-    short dma_subListPtr:dma_nextSCB;
-    short dma_SPBptr:dma_entryPoint;
-
-    long  dma_strmRsConfig;
-    long  dma_strmBufPtr;
-
-    long  dma_reserved4;
-
-    VolumeControl s2m_volume;
-  };
-
-#export DMAReader
-void DMAReader()
-{
-  execChild();
-  r2 = r0->dma_subListPtr;
-  r1 = r0->nextSCB;
-       
-  rsConfig01 = r2->strmRsConfig;
-  // Load rsConfig for input buffer
-
-  rsDMA01 = r2->basicReq.daw,       ,                   tb = Z(0 - rf);
-  // Load rsDMA in case input buffer is a DMA buffer    Test to see if there is any data to transfer
-
-  if (tb) goto execSibling_2ind1 after {
-      r5 = rf + (-1);
-      r6 = r1->dma_entryPoint;           // r6 = entry point of sibling task
-      r1 = r1->dma_SPBptr,               // r1 = pointer to sibling task's SPB
-          ,   ind = r6;                  // Load entry point of sibling task
-  }
-
-  rsConfig23 = r0->dma_strmRsConfig;
-  // Load rsConfig for output buffer (never a DMA buffer)
-
-  r4 = r0->dma_outBufPtr;
-
-  rsa0 = r2->strmBufPtr;
-  // rsa0 = input buffer pointer                        
-
-  for (i = r5; i >= 0; --i)
-    after {
-      rsa2 = r4;
-      // rsa2 = output buffer pointer
-
-      nop;
-      nop;
-    }
-  //*****************************
-  // TODO: cycles to this point *
-  //*****************************
-    {
-      acc0 =  (rsd0 = *rsa0++1);
-      // get sample
-
-      nop;  // Those "nop"'s are really uggly, but there's
-      nop;  // something with DSP's pipelines which I don't
-      nop;  // understand, resulting this code to fail without
-            // having those "nop"'s (Benny)
-
-      rsa0?reqDMA = r2;
-      // Trigger DMA transfer on input stream, 
-      // if needed to replenish input buffer
-
-      nop;
-      // Yet another magic "nop" to make stuff work
-
-      ,,r98 = acc0 $+>> 0;
-      // store sample in ALU
-
-      nop;
-      // latency on load register.
-      // (this one is understandable)
-
-      *rsa2++1 = r98;
-      // store sample in output buffer
-
-      nop; // The same story
-      nop; // as above again ...
-      nop;
-    }
-  // TODO: cycles per loop iteration
-
-  r2->strmBufPtr = rsa0,,   ;
-  // Update the modified buffer pointers
-
-  r4 = rsa2;
-  // Load output pointer position into r4
-
-  r2 = r0->nextSCB;
-  // Sibling task
-
-  goto execSibling_2ind1 // takes 6 cycles
-    after {
-      r98 = r2->thisSPB:entryPoint;
-      // Load child routine entry and data address 
-
-      r1 = r9;
-      // r9 is r2->thisSPB
-
-      r0->dma_outBufPtr = r4,,
-      // Store updated output buffer pointer
-
-      ind = r8;
-      // r8 is r2->entryPoint
-    }
-}
diff --git a/sound/pci/cs46xx/imgs/cwcdma.h b/sound/pci/cs46xx/imgs/cwcdma.h
deleted file mode 100644 (file)
index 7ff0d45..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* generated from cwcdma.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwcdma_H__
-#define __HEADER_cwcdma_H__
-
-static struct dsp_symbol_entry cwcdma_symbols[] = {
-  { 0x8000, "EXECCHILD",0x03 },
-  { 0x8001, "EXECCHILD_98",0x03 },
-  { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
-  { 0x8008, "EXECSIBLING",0x03 },
-  { 0x800a, "EXECSIBLING_298",0x03 },
-  { 0x800b, "EXECSIBLING_2IND1",0x03 },
-  { 0x8010, "TIMINGMASTER",0x03 },
-  { 0x804f, "S16_CODECINPUTTASK",0x03 },
-  { 0x805e, "PCMSERIALINPUTTASK",0x03 },
-  { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
-  { 0x809a, "S16_MIX",0x03 },
-  { 0x80bb, "S16_UPSRC",0x03 },
-  { 0x813b, "MIX3_EXP",0x03 },
-  { 0x8164, "DECIMATEBYPOW2",0x03 },
-  { 0x8197, "VARIDECIMATE",0x03 },
-  { 0x81f2, "_3DINPUTTASK",0x03 },
-  { 0x820a, "_3DPRLGCINPTASK",0x03 },
-  { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
-  { 0x8242, "_3DOUTPUTTASK",0x03 },
-  { 0x82c4, "HRTF_MORPH_TASK",0x03 },
-  { 0x82c6, "WAIT4DATA",0x03 },
-  { 0x82fa, "PROLOGIC",0x03 },
-  { 0x8496, "DECORRELATOR",0x03 },
-  { 0x84a4, "STEREO2MONO",0x03 },
-  { 0x0000, "OVERLAYBEGINADDRESS",0x00 },
-  { 0x0000, "DMAREADER",0x03 },
-  { 0x0018, "#CODE_END",0x00 },
-}; /* cwcdma symbols */
-
-static u32 cwcdma_code[] = {
-/* OVERLAYBEGINADDRESS */
-/* 0000 */ 0x00002731,0x00001400,0x0004c108,0x000e5044,
-/* 0002 */ 0x0005f608,0x00000000,0x000007ae,0x000be300,
-/* 0004 */ 0x00058630,0x00001400,0x0007afb0,0x000e9584,
-/* 0006 */ 0x00007301,0x000a9840,0x0005e708,0x000cd104,
-/* 0008 */ 0x00067008,0x00000000,0x000902a0,0x00001000,
-/* 000A */ 0x00012a01,0x000c0000,0x00000000,0x00000000,
-/* 000C */ 0x00021843,0x000c0000,0x00000000,0x000c0000,
-/* 000E */ 0x0000e101,0x000c0000,0x00000cac,0x00000000,
-/* 0010 */ 0x00080000,0x000e5ca1,0x00000000,0x000c0000,
-/* 0012 */ 0x00000000,0x00000000,0x00000000,0x00092c00,
-/* 0014 */ 0x000122c1,0x000e5084,0x00058730,0x00001400,
-/* 0016 */ 0x000d7488,0x000e4782,0x00007401,0x0001c100
-};
-
-/* #CODE_END */
-
-static struct dsp_segment_desc cwcdma_segments[] = {
-  { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000030, cwcdma_code },
-};
-
-static struct dsp_module_desc cwcdma_module = {
-  "cwcdma",
-  {
-    27,
-    cwcdma_symbols
-  },
-  1,
-  cwcdma_segments,
-};
-
-#endif /* __HEADER_cwcdma_H__ */
diff --git a/sound/pci/cs46xx/imgs/cwcsnoop.h b/sound/pci/cs46xx/imgs/cwcsnoop.h
deleted file mode 100644 (file)
index 6929d0a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* generated from cwcsnoop.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwcsnoop_H__
-#define __HEADER_cwcsnoop_H__
-
-static struct dsp_symbol_entry cwcsnoop_symbols[] = {
-  { 0x0500, "OVERLAYBEGINADDRESS",0x00 },
-  { 0x0500, "OUTPUTSNOOP",0x03 },
-  { 0x051f, "#CODE_END",0x00 },
-}; /* cwcsnoop symbols */
-
-static u32 cwcsnoop_code[] = {
-/* 0000 */ 0x0007bfb0,0x000b4e40,0x0007c088,0x000c0617,
-/* 0002 */ 0x00049705,0x00000000,0x00080630,0x00001028,
-/* 0004 */ 0x00076408,0x000efb84,0x00066008,0x00000000,
-/* 0006 */ 0x0007c908,0x000c0000,0x00046725,0x000efa44,
-/* 0008 */ 0x0005f708,0x00000000,0x0001d402,0x000b2e00,
-/* 000A */ 0x0003d418,0x00001000,0x0008d574,0x000c4293,
-/* 000C */ 0x00065625,0x000ea30e,0x00096c01,0x000c6f92,
-/* 000E */ 0x0006a58a,0x000f6085,0x00002f43,0x00000000,
-/* 0010 */ 0x000a83a0,0x00001028,0x0005e608,0x000c0000,
-/* 0012 */ 0x00000000,0x00000000,0x000ca108,0x000dcca1,
-/* 0014 */ 0x00003bac,0x000fb205,0x00073843,0x00000000,
-/* 0016 */ 0x000d8730,0x00001028,0x0006600a,0x000c0000,
-/* 0018 */ 0x00057488,0x00000000,0x00000000,0x000e5084,
-/* 001A */ 0x00000000,0x000eba44,0x00087401,0x000e4782,
-/* 001C */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 001E */ 0x00006a88,0x000c75c4
-};
-/* #CODE_END */
-
-static struct dsp_segment_desc cwcsnoop_segments[] = {
-  { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000003e, cwcsnoop_code },
-};
-
-static struct dsp_module_desc cwcsnoop_module = {
-  "cwcsnoop",
-  {
-    3,
-    cwcsnoop_symbols
-  },
-  1,
-  cwcsnoop_segments,
-};
-
-#endif /* __HEADER_cwcsnoop_H__ */
index c091438286a39c3fc5d6fdf1c79fb653ea2cdf31..5a40c652df413f31112b2d72ee1bc7e1913df955 100644 (file)
@@ -3,7 +3,6 @@ snd-hda-intel-objs := hda_intel.o
 snd-hda-intel-$(CONFIG_SND_HDA_I915) +=        hda_i915.o
 
 snd-hda-codec-y := hda_codec.o hda_jack.o hda_auto_parser.o
-snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
 snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
 snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
 snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
@@ -12,6 +11,7 @@ snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
 CFLAGS_hda_codec.o := -I$(src)
 CFLAGS_hda_intel.o := -I$(src)
 
+snd-hda-codec-generic-objs :=  hda_generic.o
 snd-hda-codec-realtek-objs :=  patch_realtek.o
 snd-hda-codec-cmedia-objs :=   patch_cmedia.o
 snd-hda-codec-analog-objs :=   patch_analog.o
@@ -28,6 +28,9 @@ snd-hda-codec-hdmi-objs :=    patch_hdmi.o hda_eld.o
 obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
 
 # codec drivers (note: CONFIG_SND_HDA_CODEC_XXX are booleans)
+ifdef CONFIG_SND_HDA_GENERIC
+obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-generic.o
+endif
 ifdef CONFIG_SND_HDA_CODEC_REALTEK
 obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-realtek.o
 endif
index 69178c4f4113fad7fb3111b57d49247c8f2ebe5c..5b7622034eeef914ca42160f449de87aff8a6f26 100644 (file)
@@ -96,19 +96,29 @@ EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
 
 #ifdef CONFIG_PM
 #define codec_in_pm(codec)     ((codec)->in_pm)
+static void hda_suspend_work(struct work_struct *work);
+static void hda_resume_work(struct work_struct *work);
 static void hda_power_work(struct work_struct *work);
 static void hda_keep_power_on(struct hda_codec *codec);
 #define hda_codec_is_power_on(codec)   ((codec)->power_on)
-static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up)
+
+static void hda_call_pm_notify(struct hda_codec *codec, bool power_up)
 {
+       struct hda_bus *bus = codec->bus;
+
+       if ((power_up && codec->pm_up_notified) ||
+           (!power_up && !codec->pm_up_notified))
+               return;
        if (bus->ops.pm_notify)
                bus->ops.pm_notify(bus, power_up);
+       codec->pm_up_notified = power_up;
 }
+
 #else
 #define codec_in_pm(codec)     0
 static inline void hda_keep_power_on(struct hda_codec *codec) {}
 #define hda_codec_is_power_on(codec)   1
-#define hda_call_pm_notify(bus, state) {}
+#define hda_call_pm_notify(codec, state) {}
 #endif
 
 /**
@@ -831,6 +841,12 @@ static int snd_hda_bus_free(struct hda_bus *bus)
                bus->ops.private_free(bus);
        if (bus->workq)
                destroy_workqueue(bus->workq);
+
+#ifdef CONFIG_PM
+       if (bus->pm_wq)
+               destroy_workqueue(bus->pm_wq);
+#endif
+
        kfree(bus);
        return 0;
 }
@@ -875,6 +891,9 @@ int snd_hda_bus_new(struct snd_card *card,
                .dev_register = snd_hda_bus_dev_register,
                .dev_free = snd_hda_bus_dev_free,
        };
+#ifdef CONFIG_PM
+       char wqname[16];
+#endif
 
        if (snd_BUG_ON(!temp))
                return -EINVAL;
@@ -911,6 +930,16 @@ int snd_hda_bus_new(struct snd_card *card,
                return -ENOMEM;
        }
 
+#ifdef CONFIG_PM
+       sprintf(wqname, "hda-pm-wq-%d", card->number);
+       bus->pm_wq = create_workqueue(wqname);
+       if (!bus->pm_wq) {
+               snd_printk(KERN_ERR "cannot create PM workqueue\n");
+               snd_hda_bus_free(bus);
+               return -ENOMEM;
+       }
+#endif
+
        err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
        if (err < 0) {
                snd_hda_bus_free(bus);
@@ -945,9 +974,6 @@ find_codec_preset(struct hda_codec *codec)
        const struct hda_codec_preset *preset;
        unsigned int mod_requested = 0;
 
-       if (is_generic_config(codec))
-               return NULL; /* use the generic parser */
-
  again:
        mutex_lock(&preset_mutex);
        list_for_each_entry(tbl, &hda_preset_tables, list) {
@@ -1329,6 +1355,28 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
        return p;
 }
 
+/*
+ * Dynamic symbol binding for the codec parsers
+ */
+#ifdef MODULE
+#define load_parser_sym(sym)           ((int (*)(struct hda_codec *))symbol_request(sym))
+#define unload_parser_addr(addr)       symbol_put_addr(addr)
+#else
+#define load_parser_sym(sym)           (sym)
+#define unload_parser_addr(addr)       do {} while (0)
+#endif
+
+#define load_parser(codec, sym) \
+       ((codec)->parser = load_parser_sym(sym))
+
+static void unload_parser(struct hda_codec *codec)
+{
+       if (codec->parser) {
+               unload_parser_addr(codec->parser);
+               codec->parser = NULL;
+       }
+}
+
 /*
  * codec destructor
  */
@@ -1352,10 +1400,8 @@ static void snd_hda_codec_free(struct hda_codec *codec)
        codec->bus->caddr_tbl[codec->addr] = NULL;
        if (codec->patch_ops.free)
                codec->patch_ops.free(codec);
-#ifdef CONFIG_PM
-       if (!codec->pm_down_notified) /* cancel leftover refcounts */
-               hda_call_pm_notify(codec->bus, false);
-#endif
+       hda_call_pm_notify(codec, false); /* cancel leftover refcounts */
+       unload_parser(codec);
        module_put(codec->owner);
        free_hda_cache(&codec->amp_cache);
        free_hda_cache(&codec->cmd_cache);
@@ -1363,6 +1409,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
        kfree(codec->chip_name);
        kfree(codec->modelname);
        kfree(codec->wcaps);
+       codec->bus->num_codecs--;
        kfree(codec);
 }
 
@@ -1424,16 +1471,18 @@ int snd_hda_codec_new(struct hda_bus *bus,
        INIT_LIST_HEAD(&codec->conn_list);
 
        INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
+       codec->depop_delay = -1;
 
 #ifdef CONFIG_PM
        spin_lock_init(&codec->power_lock);
        INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
+       INIT_WORK(&codec->suspend_work, hda_suspend_work);
+       INIT_WORK(&codec->resume_work, hda_resume_work);
        /* snd_hda_codec_new() marks the codec as power-up, and leave it as is.
         * the caller has to power down appropriatley after initialization
         * phase.
         */
        hda_keep_power_on(codec);
-       hda_call_pm_notify(bus, true);
 #endif
 
        if (codec->bus->modelname) {
@@ -1445,6 +1494,11 @@ int snd_hda_codec_new(struct hda_bus *bus,
        }
 
        list_add_tail(&codec->list, &bus->codec_list);
+       bus->num_codecs++;
+#ifdef CONFIG_PM
+       workqueue_set_max_active(bus->pm_wq, bus->num_codecs);
+#endif
+
        bus->caddr_tbl[codec_addr] = codec;
 
        codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
@@ -1486,11 +1540,14 @@ int snd_hda_codec_new(struct hda_bus *bus,
 #ifdef CONFIG_PM
        codec->d3_stop_clk = snd_hda_codec_get_supported_ps(codec, fg,
                                        AC_PWRST_CLKSTOP);
-       if (!codec->d3_stop_clk)
-               bus->power_keep_link_on = 1;
 #endif
        codec->epss = snd_hda_codec_get_supported_ps(codec, fg,
                                        AC_PWRST_EPSS);
+#ifdef CONFIG_PM
+       if (!codec->d3_stop_clk || !codec->epss)
+               bus->power_keep_link_on = 1;
+#endif
+
 
        /* power-up all before initialization */
        hda_set_power_state(codec, AC_PWRST_D0);
@@ -1537,6 +1594,31 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec)
 EXPORT_SYMBOL_HDA(snd_hda_codec_update_widgets);
 
 
+#ifdef CONFIG_SND_HDA_CODEC_HDMI
+/* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */
+static bool is_likely_hdmi_codec(struct hda_codec *codec)
+{
+       hda_nid_t nid = codec->start_nid;
+       int i;
+
+       for (i = 0; i < codec->num_nodes; i++, nid++) {
+               unsigned int wcaps = get_wcaps(codec, nid);
+               switch (get_wcaps_type(wcaps)) {
+               case AC_WID_AUD_IN:
+                       return false; /* HDMI parser supports only HDMI out */
+               case AC_WID_AUD_OUT:
+                       if (!(wcaps & AC_WCAP_DIGITAL))
+                               return false;
+                       break;
+               }
+       }
+       return true;
+}
+#else
+/* no HDMI codec parser support */
+#define is_likely_hdmi_codec(codec)    false
+#endif /* CONFIG_SND_HDA_CODEC_HDMI */
+
 /**
  * snd_hda_codec_configure - (Re-)configure the HD-audio codec
  * @codec: the HDA codec
@@ -1548,6 +1630,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_update_widgets);
  */
 int snd_hda_codec_configure(struct hda_codec *codec)
 {
+       int (*patch)(struct hda_codec *) = NULL;
        int err;
 
        codec->preset = find_codec_preset(codec);
@@ -1557,29 +1640,40 @@ int snd_hda_codec_configure(struct hda_codec *codec)
                        return err;
        }
 
-       if (is_generic_config(codec)) {
-               err = snd_hda_parse_generic_codec(codec);
-               goto patched;
-       }
-       if (codec->preset && codec->preset->patch) {
-               err = codec->preset->patch(codec);
-               goto patched;
+       if (!is_generic_config(codec) && codec->preset)
+               patch = codec->preset->patch;
+       if (!patch) {
+               unload_parser(codec); /* to be sure */
+               if (is_likely_hdmi_codec(codec))
+                       patch = load_parser(codec, snd_hda_parse_hdmi_codec);
+#ifdef CONFIG_SND_HDA_GENERIC
+               if (!patch)
+                       patch = load_parser(codec, snd_hda_parse_generic_codec);
+#endif
+               if (!patch) {
+                       printk(KERN_ERR "hda-codec: No codec parser is available\n");
+                       return -ENODEV;
+               }
        }
 
-       /* call the default parser */
-       err = snd_hda_parse_generic_codec(codec);
-       if (err < 0)
-               printk(KERN_ERR "hda-codec: No codec parser is available\n");
+       err = patch(codec);
+       if (err < 0) {
+               unload_parser(codec);
+               return err;
+       }
 
- patched:
-       if (!err && codec->patch_ops.unsol_event)
+       if (codec->patch_ops.unsol_event) {
                err = init_unsol_queue(codec->bus);
+               if (err < 0)
+                       return err;
+       }
+
        /* audio codec should override the mixer name */
-       if (!err && (codec->afg || !*codec->bus->card->mixername))
+       if (codec->afg || !*codec->bus->card->mixername)
                snprintf(codec->bus->card->mixername,
                         sizeof(codec->bus->card->mixername),
                         "%s %s", codec->vendor_name, codec->chip_name);
-       return err;
+       return 0;
 }
 EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
 
@@ -2610,6 +2704,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
        codec->preset = NULL;
        codec->slave_dig_outs = NULL;
        codec->spdif_status_reset = 0;
+       unload_parser(codec);
        module_put(codec->owner);
        codec->owner = NULL;
 
@@ -3881,8 +3976,10 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
 
        /* this delay seems necessary to avoid click noise at power-down */
        if (power_state == AC_PWRST_D3) {
-               /* transition time less than 10ms for power down */
-               msleep(codec->epss ? 10 : 100);
+               if (codec->depop_delay < 0)
+                       msleep(codec->epss ? 10 : 100);
+               else if (codec->depop_delay > 0)
+                       msleep(codec->depop_delay);
                flags = HDA_RW_NO_RESPONSE_FALLBACK;
        }
 
@@ -4000,10 +4097,6 @@ static void hda_call_codec_resume(struct hda_codec *codec)
         * in the resume / power-save sequence
         */
        hda_keep_power_on(codec);
-       if (codec->pm_down_notified) {
-               codec->pm_down_notified = 0;
-               hda_call_pm_notify(codec->bus, true);
-       }
        hda_set_power_state(codec, AC_PWRST_D0);
        restore_shutup_pins(codec);
        hda_exec_init_verbs(codec);
@@ -4877,11 +4970,8 @@ static void hda_power_work(struct work_struct *work)
        spin_unlock(&codec->power_lock);
 
        state = hda_call_codec_suspend(codec, true);
-       if (!codec->pm_down_notified &&
-           !bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK)) {
-               codec->pm_down_notified = 1;
-               hda_call_pm_notify(bus, false);
-       }
+       if (!bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK))
+               hda_call_pm_notify(codec, false);
 }
 
 static void hda_keep_power_on(struct hda_codec *codec)
@@ -4891,6 +4981,7 @@ static void hda_keep_power_on(struct hda_codec *codec)
        codec->power_on = 1;
        codec->power_jiffies = jiffies;
        spin_unlock(&codec->power_lock);
+       hda_call_pm_notify(codec, true);
 }
 
 /* update the power on/off account with the current jiffies */
@@ -4910,8 +5001,6 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
 /* call this with codec->power_lock held! */
 static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
 {
-       struct hda_bus *bus = codec->bus;
-
        /* Return if power_on or transitioning to power_on, unless currently
         * powering down. */
        if ((codec->power_on || codec->power_transition > 0) &&
@@ -4938,11 +5027,6 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
        codec->power_transition = 1; /* avoid reentrance */
        spin_unlock(&codec->power_lock);
 
-       if (codec->pm_down_notified) {
-               codec->pm_down_notified = 0;
-               hda_call_pm_notify(bus, true);
-       }
-
        hda_call_codec_resume(codec);
 
        spin_lock(&codec->power_lock);
@@ -5036,6 +5120,22 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
        return 0;
 }
 EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power);
+
+static void hda_suspend_work(struct work_struct *work)
+{
+       struct hda_codec *codec =
+               container_of(work, struct hda_codec, suspend_work);
+
+       hda_call_codec_suspend(codec, false);
+}
+
+static void hda_resume_work(struct work_struct *work)
+{
+       struct hda_codec *codec =
+               container_of(work, struct hda_codec, resume_work);
+
+       hda_call_codec_resume(codec);
+}
 #endif
 
 /*
@@ -5611,9 +5711,17 @@ int snd_hda_suspend(struct hda_bus *bus)
 
        list_for_each_entry(codec, &bus->codec_list, list) {
                cancel_delayed_work_sync(&codec->jackpoll_work);
-               if (hda_codec_is_power_on(codec))
-                       hda_call_codec_suspend(codec, false);
+               if (hda_codec_is_power_on(codec)) {
+                       if (bus->num_codecs > 1)
+                               queue_work(bus->pm_wq, &codec->suspend_work);
+                       else
+                               hda_call_codec_suspend(codec, false);
+               }
        }
+
+       if (bus->num_codecs > 1)
+               flush_workqueue(bus->pm_wq);
+
        return 0;
 }
 EXPORT_SYMBOL_HDA(snd_hda_suspend);
@@ -5629,8 +5737,15 @@ int snd_hda_resume(struct hda_bus *bus)
        struct hda_codec *codec;
 
        list_for_each_entry(codec, &bus->codec_list, list) {
-               hda_call_codec_resume(codec);
+               if (bus->num_codecs > 1)
+                       queue_work(bus->pm_wq, &codec->resume_work);
+               else
+                       hda_call_codec_resume(codec);
        }
+
+       if (bus->num_codecs > 1)
+               flush_workqueue(bus->pm_wq);
+
        return 0;
 }
 EXPORT_SYMBOL_HDA(snd_hda_resume);
index 77db69480c195cde15ee64dd13bb18b2f81aa2de..3ab4834761a8443b5bbfa71e22ca7e0bd2fb0dac 100644 (file)
@@ -673,6 +673,7 @@ struct hda_bus {
 
        /* codec linked list */
        struct list_head codec_list;
+       unsigned int num_codecs;
        /* link caddr -> codec */
        struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
 
@@ -683,6 +684,9 @@ struct hda_bus {
        struct hda_bus_unsolicited *unsol;
        char workq_name[16];
        struct workqueue_struct *workq; /* common workqueue for codecs */
+#ifdef CONFIG_PM
+       struct workqueue_struct *pm_wq; /* workqueue to parallel codec PM */
+#endif
 
        /* assigned PCMs */
        DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
@@ -698,7 +702,6 @@ struct hda_bus {
        unsigned int in_reset:1;        /* during reset operation */
        unsigned int power_keep_link_on:1; /* don't power off HDA link */
        unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
-       unsigned int avoid_link_reset:1; /* don't reset link at runtime PM */
 
        int primary_dig_out_type;       /* primary digital out PCM type */
 };
@@ -835,6 +838,7 @@ struct hda_codec {
        /* detected preset */
        const struct hda_codec_preset *preset;
        struct module *owner;
+       int (*parser)(struct hda_codec *codec);
        const char *vendor_name;        /* codec vendor name */
        const char *chip_name;          /* codec chip name */
        const char *modelname;  /* model name for preset */
@@ -908,7 +912,7 @@ struct hda_codec {
 #ifdef CONFIG_PM
        unsigned int power_on :1;       /* current (global) power-state */
        unsigned int d3_stop_clk:1;     /* support D3 operation without BCLK */
-       unsigned int pm_down_notified:1; /* PM notified to controller */
+       unsigned int pm_up_notified:1;  /* PM notified to controller */
        unsigned int in_pm:1;           /* suspend/resume being performed */
        int power_transition;   /* power-state in transition */
        int power_count;        /* current (global) power refcount */
@@ -917,6 +921,9 @@ struct hda_codec {
        unsigned long power_off_acct;
        unsigned long power_jiffies;
        spinlock_t power_lock;
+       /* tasks to parallel multi-codec suspend/resume */
+       struct work_struct suspend_work;
+       struct work_struct resume_work;
 #endif
 
        /* filter the requested power state per nid */
@@ -937,6 +944,8 @@ struct hda_codec {
        struct snd_array jacks;
 #endif
 
+       int depop_delay; /* depop delay in ms, -1 for default delay time */
+
        /* fix-up list */
        int fixup_id;
        const struct hda_fixup *fixup_list;
index 3067ed4fe3b2f7fdb7edfca13e2b14575b9707a1..2729e881541d1139d0d5492aeb4abfcc2147b7a9 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/bitops.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include "hda_codec.h"
@@ -2506,12 +2507,8 @@ static int create_out_jack_modes(struct hda_codec *codec, int num_pins,
 
        for (i = 0; i < num_pins; i++) {
                hda_nid_t pin = pins[i];
-               if (pin == spec->hp_mic_pin) {
-                       int ret = create_hp_mic_jack_mode(codec, pin);
-                       if (ret < 0)
-                               return ret;
+               if (pin == spec->hp_mic_pin)
                        continue;
-               }
                if (get_out_jack_num_items(codec, pin) > 1) {
                        struct snd_kcontrol_new *knew;
                        char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
@@ -2764,7 +2761,7 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol,
                        val &= ~(AC_PINCTL_VREFEN | PIN_HP);
                        val |= get_vref_idx(vref_caps, idx) | PIN_IN;
                } else
-                       val = snd_hda_get_default_vref(codec, nid);
+                       val = snd_hda_get_default_vref(codec, nid) | PIN_IN;
        }
        snd_hda_set_pin_ctl_cache(codec, nid, val);
        call_hp_automute(codec, NULL);
@@ -2784,9 +2781,6 @@ static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin)
        struct hda_gen_spec *spec = codec->spec;
        struct snd_kcontrol_new *knew;
 
-       if (get_out_jack_num_items(codec, pin) <= 1 &&
-           get_in_jack_num_items(codec, pin) <= 1)
-               return 0; /* no need */
        knew = snd_hda_gen_add_kctl(spec, "Headphone Mic Jack Mode",
                                    &hp_mic_jack_mode_enum);
        if (!knew)
@@ -2815,6 +2809,42 @@ static int add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx)
        return 0;
 }
 
+/* return true if either a volume or a mute amp is found for the given
+ * aamix path; the amp has to be either in the mixer node or its direct leaf
+ */
+static bool look_for_mix_leaf_ctls(struct hda_codec *codec, hda_nid_t mix_nid,
+                                  hda_nid_t pin, unsigned int *mix_val,
+                                  unsigned int *mute_val)
+{
+       int idx, num_conns;
+       const hda_nid_t *list;
+       hda_nid_t nid;
+
+       idx = snd_hda_get_conn_index(codec, mix_nid, pin, true);
+       if (idx < 0)
+               return false;
+
+       *mix_val = *mute_val = 0;
+       if (nid_has_volume(codec, mix_nid, HDA_INPUT))
+               *mix_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
+       if (nid_has_mute(codec, mix_nid, HDA_INPUT))
+               *mute_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
+       if (*mix_val && *mute_val)
+               return true;
+
+       /* check leaf node */
+       num_conns = snd_hda_get_conn_list(codec, mix_nid, &list);
+       if (num_conns < idx)
+               return false;
+       nid = list[idx];
+       if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT))
+               *mix_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+       if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT))
+               *mute_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+
+       return *mix_val || *mute_val;
+}
+
 /* create input playback/capture controls for the given pin */
 static int new_analog_input(struct hda_codec *codec, int input_idx,
                            hda_nid_t pin, const char *ctlname, int ctlidx,
@@ -2822,12 +2852,11 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,
 {
        struct hda_gen_spec *spec = codec->spec;
        struct nid_path *path;
-       unsigned int val;
+       unsigned int mix_val, mute_val;
        int err, idx;
 
-       if (!nid_has_volume(codec, mix_nid, HDA_INPUT) &&
-           !nid_has_mute(codec, mix_nid, HDA_INPUT))
-               return 0; /* no need for analog loopback */
+       if (!look_for_mix_leaf_ctls(codec, mix_nid, pin, &mix_val, &mute_val))
+               return 0;
 
        path = snd_hda_add_new_path(codec, pin, mix_nid, 0);
        if (!path)
@@ -2836,20 +2865,18 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,
        spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path);
 
        idx = path->idx[path->depth - 1];
-       if (nid_has_volume(codec, mix_nid, HDA_INPUT)) {
-               val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
-               err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, val);
+       if (mix_val) {
+               err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, mix_val);
                if (err < 0)
                        return err;
-               path->ctls[NID_PATH_VOL_CTL] = val;
+               path->ctls[NID_PATH_VOL_CTL] = mix_val;
        }
 
-       if (nid_has_mute(codec, mix_nid, HDA_INPUT)) {
-               val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
-               err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, val);
+       if (mute_val) {
+               err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, mute_val);
                if (err < 0)
                        return err;
-               path->ctls[NID_PATH_MUTE_CTL] = val;
+               path->ctls[NID_PATH_MUTE_CTL] = mute_val;
        }
 
        path->active = true;
@@ -4383,6 +4410,17 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
        if (err < 0)
                return err;
 
+       /* create "Headphone Mic Jack Mode" if no input selection is
+        * available (or user specifies add_jack_modes hint)
+        */
+       if (spec->hp_mic_pin &&
+           (spec->auto_mic || spec->input_mux.num_items == 1 ||
+            spec->add_jack_modes)) {
+               err = create_hp_mic_jack_mode(codec, spec->hp_mic_pin);
+               if (err < 0)
+                       return err;
+       }
+
        if (spec->add_jack_modes) {
                if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
                        err = create_out_jack_modes(codec, cfg->line_outs,
@@ -5291,3 +5329,6 @@ error:
        return err;
 }
 EXPORT_SYMBOL_HDA(snd_hda_parse_generic_codec);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic HD-audio codec parser");
index 7a09404579a73ac729ad437c358f38ac3b2b807b..dfdb96603636bdfb7162825ca7f9e62757845ef5 100644 (file)
@@ -2994,8 +2994,7 @@ static int azx_runtime_suspend(struct device *dev)
                  STATESTS_INT_MASK);
 
        azx_stop_chip(chip);
-       if (!chip->bus->avoid_link_reset)
-               azx_enter_link_reset(chip);
+       azx_enter_link_reset(chip);
        azx_clear_irq_pending(chip);
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
                hda_display_power(false);
@@ -3979,7 +3978,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* Panther Point */
        { PCI_DEVICE(0x8086, 0x1e20),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Lynx Point */
        { PCI_DEVICE(0x8086, 0x8c20),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
index d398b648bb5d1478d63e8d430d333eedda45beb3..da80c5bd7fd42ecacaa99e17befd8bef5c40099f 100644 (file)
@@ -352,14 +352,8 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
 /*
  * generic codec parser
  */
-#ifdef CONFIG_SND_HDA_GENERIC
 int snd_hda_parse_generic_codec(struct hda_codec *codec);
-#else
-static inline int snd_hda_parse_generic_codec(struct hda_codec *codec)
-{
-       return -ENODEV;
-}
-#endif
+int snd_hda_parse_hdmi_codec(struct hda_codec *codec);
 
 /*
  * generic proc interface
index c205bb1747fdf6a7d367d6ef54d718331d671c0b..1f2717f817a0142f4ef17910ffd50dafe42e4c09 100644 (file)
@@ -3244,9 +3244,29 @@ enum {
 #if IS_ENABLED(CONFIG_THINKPAD_ACPI)
 
 #include <linux/thinkpad_acpi.h>
+#include <acpi/acpi.h>
 
 static int (*led_set_func)(int, bool);
 
+static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context,
+                                void **rv)
+{
+       bool *found = context;
+       *found = true;
+       return AE_OK;
+}
+
+static bool is_thinkpad(struct hda_codec *codec)
+{
+       bool found = false;
+       if (codec->subsystem_id >> 16 != 0x17aa)
+               return false;
+       if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found)
+               return true;
+       found = false;
+       return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found;
+}
+
 static void update_tpacpi_mute_led(void *private_data, int enabled)
 {
        struct hda_codec *codec = private_data;
@@ -3279,6 +3299,8 @@ static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec,
        bool removefunc = false;
 
        if (action == HDA_FIXUP_ACT_PROBE) {
+               if (!is_thinkpad(codec))
+                       return;
                if (!led_set_func)
                        led_set_func = symbol_request(tpacpi_led_set);
                if (!led_set_func) {
@@ -3494,6 +3516,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
        SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
+       SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI),
        SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004),
        SND_PCI_QUIRK(0x1c06, 0x2012, "Lemote A1205", CXT_PINCFG_LEMOTE_A1205),
        {}
index 08407bed093e5a64d4b659f90bf236dead9ec002..4098196b2300418a9053056377fd70aa1ed69e1e 100644 (file)
@@ -1692,21 +1692,6 @@ static int hdmi_parse_codec(struct hda_codec *codec)
                }
        }
 
-#ifdef CONFIG_PM
-       /* We're seeing some problems with unsolicited hot plug events on
-        * PantherPoint after S3, if this is not enabled */
-       if (codec->vendor_id == 0x80862806)
-               codec->bus->power_keep_link_on = 1;
-       /*
-        * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
-        * can be lost and presence sense verb will become inaccurate if the
-        * HDA link is powered off at hot plug or hw initialization time.
-        */
-       else if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
-             AC_PWRST_EPSS))
-               codec->bus->power_keep_link_on = 1;
-#endif
-
        return 0;
 }
 
@@ -3213,6 +3198,15 @@ static int patch_via_hdmi(struct hda_codec *codec)
        return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
 }
 
+/*
+ * called from hda_codec.c for generic HDMI support
+ */
+int snd_hda_parse_hdmi_codec(struct hda_codec *codec)
+{
+       return patch_generic_hdmi(codec);
+}
+EXPORT_SYMBOL_HDA(snd_hda_parse_hdmi_codec);
+
 /*
  * patch entries
  */
index 5e42059f10a1fc4e5e6f127a6c6b536ae0dd537f..537991ccba28c903d6db311b5a47f586b00b548b 100644 (file)
@@ -118,7 +118,8 @@ struct alc_spec {
 
        int init_amp;
        int codec_variant;      /* flag for other variants */
-       bool has_alc5505_dsp;
+       unsigned int has_alc5505_dsp:1;
+       unsigned int no_depop_delay:1;
 
        /* for PLL fix */
        hda_nid_t pll_nid;
@@ -280,8 +281,11 @@ static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
  */
 static void alc_eapd_shutup(struct hda_codec *codec)
 {
+       struct alc_spec *spec = codec->spec;
+
        alc_auto_setup_eapd(codec, false);
-       msleep(200);
+       if (!spec->no_depop_delay)
+               msleep(200);
        snd_hda_shutup_pins(codec);
 }
 
@@ -365,6 +369,15 @@ static void alc_fixup_sku_ignore(struct hda_codec *codec,
        }
 }
 
+static void alc_fixup_no_depop_delay(struct hda_codec *codec,
+                                   const struct hda_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+
+       if (action == HDA_FIXUP_ACT_PROBE)
+               spec->no_depop_delay = 1;
+}
+
 static int alc_auto_parse_customize_define(struct hda_codec *codec)
 {
        unsigned int ass, tmp, i;
@@ -863,7 +876,10 @@ static int alc_suspend(struct hda_codec *codec)
 #ifdef CONFIG_PM
 static int alc_resume(struct hda_codec *codec)
 {
-       msleep(150); /* to avoid pop noise */
+       struct alc_spec *spec = codec->spec;
+
+       if (!spec->no_depop_delay)
+               msleep(150); /* to avoid pop noise */
        codec->patch_ops.init(codec);
        snd_hda_codec_resume_amp(codec);
        snd_hda_codec_resume_cache(codec);
@@ -903,7 +919,7 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
 }
 
 /*
- * Rename codecs appropriately from COEF value
+ * Rename codecs appropriately from COEF value or subvendor id
  */
 struct alc_codec_rename_table {
        unsigned int vendor_id;
@@ -912,6 +928,13 @@ struct alc_codec_rename_table {
        const char *name;
 };
 
+struct alc_codec_rename_pci_table {
+       unsigned int codec_vendor_id;
+       unsigned short pci_subvendor;
+       unsigned short pci_subdevice;
+       const char *name;
+};
+
 static struct alc_codec_rename_table rename_tbl[] = {
        { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
        { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
@@ -931,9 +954,20 @@ static struct alc_codec_rename_table rename_tbl[] = {
        { } /* terminator */
 };
 
+static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
+       { 0x10ec0280, 0x1028, 0, "ALC3220" },
+       { 0x10ec0282, 0x1028, 0, "ALC3221" },
+       { 0x10ec0283, 0x1028, 0, "ALC3223" },
+       { 0x10ec0292, 0x1028, 0, "ALC3226" },
+       { 0x10ec0255, 0x1028, 0, "ALC3234" },
+       { 0x10ec0668, 0x1028, 0, "ALC3661" },
+       { } /* terminator */
+};
+
 static int alc_codec_rename_from_preset(struct hda_codec *codec)
 {
        const struct alc_codec_rename_table *p;
+       const struct alc_codec_rename_pci_table *q;
 
        for (p = rename_tbl; p->vendor_id; p++) {
                if (p->vendor_id != codec->vendor_id)
@@ -941,6 +975,17 @@ static int alc_codec_rename_from_preset(struct hda_codec *codec)
                if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
                        return alc_codec_rename(codec, p->name);
        }
+
+       for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
+               if (q->codec_vendor_id != codec->vendor_id)
+                       continue;
+               if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
+                       continue;
+               if (!q->pci_subdevice ||
+                   q->pci_subdevice == codec->bus->pci->subsystem_device)
+                       return alc_codec_rename(codec, q->name);
+       }
+
        return 0;
 }
 
@@ -1782,6 +1827,8 @@ enum {
        ALC889_FIXUP_IMAC91_VREF,
        ALC882_FIXUP_INV_DMIC,
        ALC882_FIXUP_NO_PRIMARY_HP,
+       ALC887_FIXUP_ASUS_BASS,
+       ALC887_FIXUP_BASS_CHMAP,
 };
 
 static void alc889_fixup_coef(struct hda_codec *codec,
@@ -1915,6 +1962,9 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
        }
 }
 
+static void alc_fixup_bass_chmap(struct hda_codec *codec,
+                                const struct hda_fixup *fix, int action);
+
 static const struct hda_fixup alc882_fixups[] = {
        [ALC882_FIXUP_ABIT_AW9D_MAX] = {
                .type = HDA_FIXUP_PINS,
@@ -2105,6 +2155,19 @@ static const struct hda_fixup alc882_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc882_fixup_no_primary_hp,
        },
+       [ALC887_FIXUP_ASUS_BASS] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       {0x16, 0x99130130}, /* bass speaker */
+                       {}
+               },
+               .chained = true,
+               .chain_id = ALC887_FIXUP_BASS_CHMAP,
+       },
+       [ALC887_FIXUP_BASS_CHMAP] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_bass_chmap,
+       },
 };
 
 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -2138,6 +2201,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
        SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
        SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
+       SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
        SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
        SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
        SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
@@ -2272,6 +2336,7 @@ enum {
        ALC262_FIXUP_BENQ,
        ALC262_FIXUP_BENQ_T31,
        ALC262_FIXUP_INV_DMIC,
+       ALC262_FIXUP_INTEL_BAYLEYBAY,
 };
 
 static const struct hda_fixup alc262_fixups[] = {
@@ -2336,6 +2401,10 @@ static const struct hda_fixup alc262_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_inv_dmic_0x12,
        },
+       [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_no_depop_delay,
+       },
 };
 
 static const struct snd_pci_quirk alc262_fixup_tbl[] = {
@@ -2347,6 +2416,7 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
        SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
        SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
+       SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
        {}
 };
 
@@ -3798,6 +3868,7 @@ enum {
        ALC271_FIXUP_HP_GATE_MIC_JACK,
        ALC269_FIXUP_ACER_AC700,
        ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
+       ALC269VB_FIXUP_ASUS_ZENBOOK,
        ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
        ALC269VB_FIXUP_ORDISSIMO_EVE2,
        ALC283_FIXUP_CHROME_BOOK,
@@ -4075,6 +4146,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
        },
+       [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc269_fixup_limit_int_mic_boost,
+               .chained = true,
+               .chain_id = ALC269VB_FIXUP_DMIC,
+       },
        [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc269_fixup_limit_int_mic_boost,
@@ -4176,6 +4253,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS),
        SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS),
        SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
@@ -4189,8 +4267,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
        SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
-       SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
-       SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
+       SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK),
        SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
        SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
@@ -4421,7 +4499,7 @@ static int patch_alc269(struct hda_codec *codec)
        }
 
        if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
-               spec->has_alc5505_dsp = true;
+               spec->has_alc5505_dsp = 1;
                spec->init_hook = alc5505_dsp_init;
        }
 
@@ -4467,6 +4545,7 @@ enum {
        ALC861_FIXUP_AMP_VREF_0F,
        ALC861_FIXUP_NO_JACK_DETECT,
        ALC861_FIXUP_ASUS_A6RP,
+       ALC660_FIXUP_ASUS_W7J,
 };
 
 /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
@@ -4516,10 +4595,21 @@ static const struct hda_fixup alc861_fixups[] = {
                .v.func = alc861_fixup_asus_amp_vref_0f,
                .chained = true,
                .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
+       },
+       [ALC660_FIXUP_ASUS_W7J] = {
+               .type = HDA_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       /* ASUS W7J needs a magic pin setup on unused NID 0x10
+                        * for enabling outputs
+                        */
+                       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+                       { }
+               },
        }
 };
 
 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
        SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
        SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
        SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
@@ -4715,7 +4805,7 @@ static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
 };
 
 /* override the 2.1 chmap */
-static void alc662_fixup_bass_chmap(struct hda_codec *codec,
+static void alc_fixup_bass_chmap(struct hda_codec *codec,
                                    const struct hda_fixup *fix, int action)
 {
        if (action == HDA_FIXUP_ACT_BUILD) {
@@ -4923,7 +5013,7 @@ static const struct hda_fixup alc662_fixups[] = {
        },
        [ALC662_FIXUP_BASS_CHMAP] = {
                .type = HDA_FIXUP_FUNC,
-               .v.func = alc662_fixup_bass_chmap,
+               .v.func = alc_fixup_bass_chmap,
                .chained = true,
                .chain_id = ALC662_FIXUP_ASUS_MODE4
        },
@@ -4936,7 +5026,7 @@ static const struct hda_fixup alc662_fixups[] = {
        },
        [ALC662_FIXUP_BASS_1A_CHMAP] = {
                .type = HDA_FIXUP_FUNC,
-               .v.func = alc662_fixup_bass_chmap,
+               .v.func = alc_fixup_bass_chmap,
                .chained = true,
                .chain_id = ALC662_FIXUP_BASS_1A,
        },
@@ -5118,6 +5208,7 @@ static int patch_alc662(struct hda_codec *codec)
                case 0x10ec0272:
                case 0x10ec0663:
                case 0x10ec0665:
+               case 0x10ec0668:
                        set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
                        break;
                case 0x10ec0273:
@@ -5175,6 +5266,7 @@ static int patch_alc680(struct hda_codec *codec)
  */
 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
        { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
+       { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
        { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
        { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 },
        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
index d2cc0041d9d3f92803002addf12f2ca8c98900ec..088a5afbd1b94846462cc290b7ca0eceab5ffaa7 100644 (file)
@@ -2094,7 +2094,8 @@ static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
 
        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
                spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
-               codec->bus->avoid_link_reset = 1;
+               /* resetting controller clears GPIO, so we need to keep on */
+               codec->bus->power_keep_link_on = 1;
        }
 }
 
index 5138b8493051fd54c674fe26ea87d9d5fd1411c6..a5dcdec2dccca83bb1f00aee548bc2cbdf16549b 100644 (file)
@@ -33,6 +33,7 @@ config SND_SOC_GENERIC_DMAENGINE_PCM
 # All the supported SoCs
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
+source "sound/soc/bcm/Kconfig"
 source "sound/soc/blackfin/Kconfig"
 source "sound/soc/cirrus/Kconfig"
 source "sound/soc/davinci/Kconfig"
@@ -42,7 +43,7 @@ source "sound/soc/jz4740/Kconfig"
 source "sound/soc/nuc900/Kconfig"
 source "sound/soc/omap/Kconfig"
 source "sound/soc/kirkwood/Kconfig"
-source "sound/soc/mid-x86/Kconfig"
+source "sound/soc/intel/Kconfig"
 source "sound/soc/mxs/Kconfig"
 source "sound/soc/pxa/Kconfig"
 source "sound/soc/samsung/Kconfig"
index 8b9e70105dd28f5ccceabad1cd2ea414a97640a1..bf32b7a52515f6f81a8388665e4729850d179bed 100644 (file)
@@ -10,13 +10,14 @@ obj-$(CONFIG_SND_SOC)       += codecs/
 obj-$(CONFIG_SND_SOC)  += generic/
 obj-$(CONFIG_SND_SOC)  += atmel/
 obj-$(CONFIG_SND_SOC)  += au1x/
+obj-$(CONFIG_SND_SOC)  += bcm/
 obj-$(CONFIG_SND_SOC)  += blackfin/
 obj-$(CONFIG_SND_SOC)  += cirrus/
 obj-$(CONFIG_SND_SOC)  += davinci/
 obj-$(CONFIG_SND_SOC)  += dwc/
 obj-$(CONFIG_SND_SOC)  += fsl/
 obj-$(CONFIG_SND_SOC)  += jz4740/
-obj-$(CONFIG_SND_SOC)  += mid-x86/
+obj-$(CONFIG_SND_SOC)  += intel/
 obj-$(CONFIG_SND_SOC)  += mxs/
 obj-$(CONFIG_SND_SOC)  += nuc900/
 obj-$(CONFIG_SND_SOC)  += omap/
index 992ae38d5a15afda177080da1032300bcffd18ac..1b372283bd01a947c26dc4da302f9b077adfe74a 100644 (file)
@@ -97,6 +97,8 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
                goto out;
        }
 
+       snd_soc_card_set_drvdata(card, priv);
+
        card->dev = &pdev->dev;
        card->owner = THIS_MODULE;
        card->dai_link = dai;
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
new file mode 100644 (file)
index 0000000..3d82a29
--- /dev/null
@@ -0,0 +1,10 @@
+config SND_BCM2835_SOC_I2S
+       tristate "SoC Audio support for the Broadcom BCM2835 I2S module"
+       depends on ARCH_BCM2835 || COMPILE_TEST
+       select SND_SOC_DMAENGINE_PCM
+       select SND_SOC_GENERIC_DMAENGINE_PCM
+       select REGMAP_MMIO
+       help
+         Say Y or M if you want to add support for codecs attached to
+         the BCM2835 I2S interface. You will also need
+         to select the audio interfaces to support below.
diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
new file mode 100644 (file)
index 0000000..bc816b7
--- /dev/null
@@ -0,0 +1,5 @@
+# BCM2835 Platform Support
+snd-soc-bcm2835-i2s-objs := bcm2835-i2s.o
+
+obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o
+
diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c
new file mode 100644 (file)
index 0000000..f49b007
--- /dev/null
@@ -0,0 +1,886 @@
+/*
+ * ALSA SoC I2S Audio Layer for Broadcom BCM2835 SoC
+ *
+ * Author:     Florian Meier <florian.meier@koalo.de>
+ *             Copyright 2013
+ *
+ * Based on
+ *     Raspberry Pi PCM I2S ALSA Driver
+ *     Copyright (c) by Phil Poole 2013
+ *
+ *     ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor
+ *      Vladimir Barinov, <vbarinov@embeddedalley.com>
+ *     Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com>
+ *
+ *     OMAP ALSA SoC DAI driver using McBSP port
+ *     Copyright (C) 2008 Nokia Corporation
+ *     Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
+ *              Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ *     Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
+ *     Author: Timur Tabi <timur@freescale.com>
+ *     Copyright 2007-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+/* Clock registers */
+#define BCM2835_CLK_PCMCTL_REG  0x00
+#define BCM2835_CLK_PCMDIV_REG  0x04
+
+/* Clock register settings */
+#define BCM2835_CLK_PASSWD             (0x5a000000)
+#define BCM2835_CLK_PASSWD_MASK        (0xff000000)
+#define BCM2835_CLK_MASH(v)            ((v) << 9)
+#define BCM2835_CLK_FLIP               BIT(8)
+#define BCM2835_CLK_BUSY               BIT(7)
+#define BCM2835_CLK_KILL               BIT(5)
+#define BCM2835_CLK_ENAB               BIT(4)
+#define BCM2835_CLK_SRC(v)             (v)
+
+#define BCM2835_CLK_SHIFT              (12)
+#define BCM2835_CLK_DIVI(v)            ((v) << BCM2835_CLK_SHIFT)
+#define BCM2835_CLK_DIVF(v)            (v)
+#define BCM2835_CLK_DIVF_MASK          (0xFFF)
+
+enum {
+       BCM2835_CLK_MASH_0 = 0,
+       BCM2835_CLK_MASH_1,
+       BCM2835_CLK_MASH_2,
+       BCM2835_CLK_MASH_3,
+};
+
+enum {
+       BCM2835_CLK_SRC_GND = 0,
+       BCM2835_CLK_SRC_OSC,
+       BCM2835_CLK_SRC_DBG0,
+       BCM2835_CLK_SRC_DBG1,
+       BCM2835_CLK_SRC_PLLA,
+       BCM2835_CLK_SRC_PLLC,
+       BCM2835_CLK_SRC_PLLD,
+       BCM2835_CLK_SRC_HDMI,
+};
+
+/* Most clocks are not useable (freq = 0) */
+static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = {
+       [BCM2835_CLK_SRC_GND]           = 0,
+       [BCM2835_CLK_SRC_OSC]           = 19200000,
+       [BCM2835_CLK_SRC_DBG0]          = 0,
+       [BCM2835_CLK_SRC_DBG1]          = 0,
+       [BCM2835_CLK_SRC_PLLA]          = 0,
+       [BCM2835_CLK_SRC_PLLC]          = 0,
+       [BCM2835_CLK_SRC_PLLD]          = 500000000,
+       [BCM2835_CLK_SRC_HDMI]          = 0,
+};
+
+/* I2S registers */
+#define BCM2835_I2S_CS_A_REG           0x00
+#define BCM2835_I2S_FIFO_A_REG         0x04
+#define BCM2835_I2S_MODE_A_REG         0x08
+#define BCM2835_I2S_RXC_A_REG          0x0c
+#define BCM2835_I2S_TXC_A_REG          0x10
+#define BCM2835_I2S_DREQ_A_REG         0x14
+#define BCM2835_I2S_INTEN_A_REG        0x18
+#define BCM2835_I2S_INTSTC_A_REG       0x1c
+#define BCM2835_I2S_GRAY_REG           0x20
+
+/* I2S register settings */
+#define BCM2835_I2S_STBY               BIT(25)
+#define BCM2835_I2S_SYNC               BIT(24)
+#define BCM2835_I2S_RXSEX              BIT(23)
+#define BCM2835_I2S_RXF                BIT(22)
+#define BCM2835_I2S_TXE                BIT(21)
+#define BCM2835_I2S_RXD                BIT(20)
+#define BCM2835_I2S_TXD                BIT(19)
+#define BCM2835_I2S_RXR                BIT(18)
+#define BCM2835_I2S_TXW                BIT(17)
+#define BCM2835_I2S_CS_RXERR           BIT(16)
+#define BCM2835_I2S_CS_TXERR           BIT(15)
+#define BCM2835_I2S_RXSYNC             BIT(14)
+#define BCM2835_I2S_TXSYNC             BIT(13)
+#define BCM2835_I2S_DMAEN              BIT(9)
+#define BCM2835_I2S_RXTHR(v)           ((v) << 7)
+#define BCM2835_I2S_TXTHR(v)           ((v) << 5)
+#define BCM2835_I2S_RXCLR              BIT(4)
+#define BCM2835_I2S_TXCLR              BIT(3)
+#define BCM2835_I2S_TXON               BIT(2)
+#define BCM2835_I2S_RXON               BIT(1)
+#define BCM2835_I2S_EN                 (1)
+
+#define BCM2835_I2S_CLKDIS             BIT(28)
+#define BCM2835_I2S_PDMN               BIT(27)
+#define BCM2835_I2S_PDME               BIT(26)
+#define BCM2835_I2S_FRXP               BIT(25)
+#define BCM2835_I2S_FTXP               BIT(24)
+#define BCM2835_I2S_CLKM               BIT(23)
+#define BCM2835_I2S_CLKI               BIT(22)
+#define BCM2835_I2S_FSM                BIT(21)
+#define BCM2835_I2S_FSI                BIT(20)
+#define BCM2835_I2S_FLEN(v)            ((v) << 10)
+#define BCM2835_I2S_FSLEN(v)           (v)
+
+#define BCM2835_I2S_CHWEX              BIT(15)
+#define BCM2835_I2S_CHEN               BIT(14)
+#define BCM2835_I2S_CHPOS(v)           ((v) << 4)
+#define BCM2835_I2S_CHWID(v)           (v)
+#define BCM2835_I2S_CH1(v)             ((v) << 16)
+#define BCM2835_I2S_CH2(v)             (v)
+
+#define BCM2835_I2S_TX_PANIC(v)        ((v) << 24)
+#define BCM2835_I2S_RX_PANIC(v)        ((v) << 16)
+#define BCM2835_I2S_TX(v)              ((v) << 8)
+#define BCM2835_I2S_RX(v)              (v)
+
+#define BCM2835_I2S_INT_RXERR          BIT(3)
+#define BCM2835_I2S_INT_TXERR          BIT(2)
+#define BCM2835_I2S_INT_RXR            BIT(1)
+#define BCM2835_I2S_INT_TXW            BIT(0)
+
+/* I2S DMA interface */
+/* FIXME: Needs IOMMU support */
+#define BCM2835_VCMMU_SHIFT            (0x7E000000 - 0x20000000)
+
+/* General device struct */
+struct bcm2835_i2s_dev {
+       struct device                           *dev;
+       struct snd_dmaengine_dai_dma_data       dma_data[2];
+       unsigned int                            fmt;
+       unsigned int                            bclk_ratio;
+
+       struct regmap *i2s_regmap;
+       struct regmap *clk_regmap;
+};
+
+static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev)
+{
+       /* Start the clock if in master mode */
+       unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;
+
+       switch (master) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+       case SND_SOC_DAIFMT_CBS_CFM:
+               regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
+                       BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB,
+                       BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB);
+               break;
+       default:
+               break;
+       }
+}
+
+static void bcm2835_i2s_stop_clock(struct bcm2835_i2s_dev *dev)
+{
+       uint32_t clkreg;
+       int timeout = 1000;
+
+       /* Stop clock */
+       regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
+                       BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB,
+                       BCM2835_CLK_PASSWD);
+
+       /* Wait for the BUSY flag going down */
+       while (--timeout) {
+               regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg);
+               if (!(clkreg & BCM2835_CLK_BUSY))
+                       break;
+       }
+
+       if (!timeout) {
+               /* KILL the clock */
+               dev_err(dev->dev, "I2S clock didn't stop. Kill the clock!\n");
+               regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
+                       BCM2835_CLK_KILL | BCM2835_CLK_PASSWD_MASK,
+                       BCM2835_CLK_KILL | BCM2835_CLK_PASSWD);
+       }
+}
+
+static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev,
+                                   bool tx, bool rx)
+{
+       int timeout = 1000;
+       uint32_t syncval;
+       uint32_t csreg;
+       uint32_t i2s_active_state;
+       uint32_t clkreg;
+       uint32_t clk_active_state;
+       uint32_t off;
+       uint32_t clr;
+
+       off =  tx ? BCM2835_I2S_TXON : 0;
+       off |= rx ? BCM2835_I2S_RXON : 0;
+
+       clr =  tx ? BCM2835_I2S_TXCLR : 0;
+       clr |= rx ? BCM2835_I2S_RXCLR : 0;
+
+       /* Backup the current state */
+       regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg);
+       i2s_active_state = csreg & (BCM2835_I2S_RXON | BCM2835_I2S_TXON);
+
+       regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg);
+       clk_active_state = clkreg & BCM2835_CLK_ENAB;
+
+       /* Start clock if not running */
+       if (!clk_active_state) {
+               regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
+                       BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB,
+                       BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB);
+       }
+
+       /* Stop I2S module */
+       regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0);
+
+       /*
+        * Clear the FIFOs
+        * Requires at least 2 PCM clock cycles to take effect
+        */
+       regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, clr, clr);
+
+       /* Wait for 2 PCM clock cycles */
+
+       /*
+        * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back
+        * FIXME: This does not seem to work for slave mode!
+        */
+       regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &syncval);
+       syncval &= BCM2835_I2S_SYNC;
+
+       regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
+                       BCM2835_I2S_SYNC, ~syncval);
+
+       /* Wait for the SYNC flag changing it's state */
+       while (--timeout) {
+               regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg);
+               if ((csreg & BCM2835_I2S_SYNC) != syncval)
+                       break;
+       }
+
+       if (!timeout)
+               dev_err(dev->dev, "I2S SYNC error!\n");
+
+       /* Stop clock if it was not running before */
+       if (!clk_active_state)
+               bcm2835_i2s_stop_clock(dev);
+
+       /* Restore I2S state */
+       regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
+                       BCM2835_I2S_RXON | BCM2835_I2S_TXON, i2s_active_state);
+}
+
+static int bcm2835_i2s_set_dai_fmt(struct snd_soc_dai *dai,
+                                     unsigned int fmt)
+{
+       struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+       dev->fmt = fmt;
+       return 0;
+}
+
+static int bcm2835_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai,
+                                     unsigned int ratio)
+{
+       struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+       dev->bclk_ratio = ratio;
+       return 0;
+}
+
+static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream,
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
+{
+       struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+       unsigned int sampling_rate = params_rate(params);
+       unsigned int data_length, data_delay, bclk_ratio;
+       unsigned int ch1pos, ch2pos, mode, format;
+       unsigned int mash = BCM2835_CLK_MASH_1;
+       unsigned int divi, divf, target_frequency;
+       int clk_src = -1;
+       unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;
+       bool bit_master =       (master == SND_SOC_DAIFMT_CBS_CFS
+                                       || master == SND_SOC_DAIFMT_CBS_CFM);
+
+       bool frame_master =     (master == SND_SOC_DAIFMT_CBS_CFS
+                                       || master == SND_SOC_DAIFMT_CBM_CFS);
+       uint32_t csreg;
+
+       /*
+        * If a stream is already enabled,
+        * the registers are already set properly.
+        */
+       regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg);
+
+       if (csreg & (BCM2835_I2S_TXON | BCM2835_I2S_RXON))
+               return 0;
+
+       /*
+        * Adjust the data length according to the format.
+        * We prefill the half frame length with an integer
+        * divider of 2400 as explained at the clock settings.
+        * Maybe it is overwritten there, if the Integer mode
+        * does not apply.
+        */
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               data_length = 16;
+               bclk_ratio = 40;
+               break;
+       case SNDRV_PCM_FORMAT_S32_LE:
+               data_length = 32;
+               bclk_ratio = 80;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* If bclk_ratio already set, use that one. */
+       if (dev->bclk_ratio)
+               bclk_ratio = dev->bclk_ratio;
+
+       /*
+        * Clock Settings
+        *
+        * The target frequency of the bit clock is
+        *      sampling rate * frame length
+        *
+        * Integer mode:
+        * Sampling rates that are multiples of 8000 kHz
+        * can be driven by the oscillator of 19.2 MHz
+        * with an integer divider as long as the frame length
+        * is an integer divider of 19200000/8000=2400 as set up above.
+        * This is no longer possible if the sampling rate
+        * is too high (e.g. 192 kHz), because the oscillator is too slow.
+        *
+        * MASH mode:
+        * For all other sampling rates, it is not possible to
+        * have an integer divider. Approximate the clock
+        * with the MASH module that induces a slight frequency
+        * variance. To minimize that it is best to have the fastest
+        * clock here. That is PLLD with 500 MHz.
+        */
+       target_frequency = sampling_rate * bclk_ratio;
+       clk_src = BCM2835_CLK_SRC_OSC;
+       mash = BCM2835_CLK_MASH_0;
+
+       if (bcm2835_clk_freq[clk_src] % target_frequency == 0
+                       && bit_master && frame_master) {
+               divi = bcm2835_clk_freq[clk_src] / target_frequency;
+               divf = 0;
+       } else {
+               uint64_t dividend;
+
+               if (!dev->bclk_ratio) {
+                       /*
+                        * Overwrite bclk_ratio, because the
+                        * above trick is not needed or can
+                        * not be used.
+                        */
+                       bclk_ratio = 2 * data_length;
+               }
+
+               target_frequency = sampling_rate * bclk_ratio;
+
+               clk_src = BCM2835_CLK_SRC_PLLD;
+               mash = BCM2835_CLK_MASH_1;
+
+               dividend = bcm2835_clk_freq[clk_src];
+               dividend <<= BCM2835_CLK_SHIFT;
+               do_div(dividend, target_frequency);
+               divi = dividend >> BCM2835_CLK_SHIFT;
+               divf = dividend & BCM2835_CLK_DIVF_MASK;
+       }
+
+       /* Set clock divider */
+       regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, BCM2835_CLK_PASSWD
+                       | BCM2835_CLK_DIVI(divi)
+                       | BCM2835_CLK_DIVF(divf));
+
+       /* Setup clock, but don't start it yet */
+       regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, BCM2835_CLK_PASSWD
+                       | BCM2835_CLK_MASH(mash)
+                       | BCM2835_CLK_SRC(clk_src));
+
+       /* Setup the frame format */
+       format = BCM2835_I2S_CHEN;
+
+       if (data_length > 24)
+               format |= BCM2835_I2S_CHWEX;
+
+       format |= BCM2835_I2S_CHWID((data_length-8)&0xf);
+
+       switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               data_delay = 1;
+               break;
+       default:
+               /*
+                * TODO
+                * Others are possible but are not implemented at the moment.
+                */
+               dev_err(dev->dev, "%s:bad format\n", __func__);
+               return -EINVAL;
+       }
+
+       ch1pos = data_delay;
+       ch2pos = bclk_ratio / 2 + data_delay;
+
+       switch (params_channels(params)) {
+       case 2:
+               format = BCM2835_I2S_CH1(format) | BCM2835_I2S_CH2(format);
+               format |= BCM2835_I2S_CH1(BCM2835_I2S_CHPOS(ch1pos));
+               format |= BCM2835_I2S_CH2(BCM2835_I2S_CHPOS(ch2pos));
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /*
+        * Set format for both streams.
+        * We cannot set another frame length
+        * (and therefore word length) anyway,
+        * so the format will be the same.
+        */
+       regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, format);
+       regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, format);
+
+       /* Setup the I2S mode */
+       mode = 0;
+
+       if (data_length <= 16) {
+               /*
+                * Use frame packed mode (2 channels per 32 bit word)
+                * We cannot set another frame length in the second stream
+                * (and therefore word length) anyway,
+                * so the format will be the same.
+                */
+               mode |= BCM2835_I2S_FTXP | BCM2835_I2S_FRXP;
+       }
+
+       mode |= BCM2835_I2S_FLEN(bclk_ratio - 1);
+       mode |= BCM2835_I2S_FSLEN(bclk_ratio / 2);
+
+       /* Master or slave? */
+       switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               /* CPU is master */
+               break;
+       case SND_SOC_DAIFMT_CBM_CFS:
+               /*
+                * CODEC is bit clock master
+                * CPU is frame master
+                */
+               mode |= BCM2835_I2S_CLKM;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFM:
+               /*
+                * CODEC is frame master
+                * CPU is bit clock master
+                */
+               mode |= BCM2835_I2S_FSM;
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM:
+               /* CODEC is master */
+               mode |= BCM2835_I2S_CLKM;
+               mode |= BCM2835_I2S_FSM;
+               break;
+       default:
+               dev_err(dev->dev, "%s:bad master\n", __func__);
+               return -EINVAL;
+       }
+
+       /*
+        * Invert clocks?
+        *
+        * The BCM approach seems to be inverted to the classical I2S approach.
+        */
+       switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               /* None. Therefore, both for BCM */
+               mode |= BCM2835_I2S_CLKI;
+               mode |= BCM2835_I2S_FSI;
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               /* Both. Therefore, none for BCM */
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               /*
+                * Invert only frame sync. Therefore,
+                * invert only bit clock for BCM
+                */
+               mode |= BCM2835_I2S_CLKI;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               /*
+                * Invert only bit clock. Therefore,
+                * invert only frame sync for BCM
+                */
+               mode |= BCM2835_I2S_FSI;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       regmap_write(dev->i2s_regmap, BCM2835_I2S_MODE_A_REG, mode);
+
+       /* Setup the DMA parameters */
+       regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
+                       BCM2835_I2S_RXTHR(1)
+                       | BCM2835_I2S_TXTHR(1)
+                       | BCM2835_I2S_DMAEN, 0xffffffff);
+
+       regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG,
+                         BCM2835_I2S_TX_PANIC(0x10)
+                       | BCM2835_I2S_RX_PANIC(0x30)
+                       | BCM2835_I2S_TX(0x30)
+                       | BCM2835_I2S_RX(0x20), 0xffffffff);
+
+       /* Clear FIFOs */
+       bcm2835_i2s_clear_fifos(dev, true, true);
+
+       return 0;
+}
+
+static int bcm2835_i2s_prepare(struct snd_pcm_substream *substream,
+               struct snd_soc_dai *dai)
+{
+       struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+       uint32_t cs_reg;
+
+       bcm2835_i2s_start_clock(dev);
+
+       /*
+        * Clear both FIFOs if the one that should be started
+        * is not empty at the moment. This should only happen
+        * after overrun. Otherwise, hw_params would have cleared
+        * the FIFO.
+        */
+       regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &cs_reg);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
+                       && !(cs_reg & BCM2835_I2S_TXE))
+               bcm2835_i2s_clear_fifos(dev, true, false);
+       else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE
+                       && (cs_reg & BCM2835_I2S_RXD))
+               bcm2835_i2s_clear_fifos(dev, false, true);
+
+       return 0;
+}
+
+static void bcm2835_i2s_stop(struct bcm2835_i2s_dev *dev,
+               struct snd_pcm_substream *substream,
+               struct snd_soc_dai *dai)
+{
+       uint32_t mask;
+
+       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+               mask = BCM2835_I2S_RXON;
+       else
+               mask = BCM2835_I2S_TXON;
+
+       regmap_update_bits(dev->i2s_regmap,
+                       BCM2835_I2S_CS_A_REG, mask, 0);
+
+       /* Stop also the clock when not SND_SOC_DAIFMT_CONT */
+       if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT))
+               bcm2835_i2s_stop_clock(dev);
+}
+
+static int bcm2835_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+                              struct snd_soc_dai *dai)
+{
+       struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+       uint32_t mask;
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               bcm2835_i2s_start_clock(dev);
+
+               if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+                       mask = BCM2835_I2S_RXON;
+               else
+                       mask = BCM2835_I2S_TXON;
+
+               regmap_update_bits(dev->i2s_regmap,
+                               BCM2835_I2S_CS_A_REG, mask, mask);
+               break;
+
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               bcm2835_i2s_stop(dev, substream, dai);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int bcm2835_i2s_startup(struct snd_pcm_substream *substream,
+                              struct snd_soc_dai *dai)
+{
+       struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+       if (dai->active)
+               return 0;
+
+       /* Should this still be running stop it */
+       bcm2835_i2s_stop_clock(dev);
+
+       /* Enable PCM block */
+       regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
+                       BCM2835_I2S_EN, BCM2835_I2S_EN);
+
+       /*
+        * Disable STBY.
+        * Requires at least 4 PCM clock cycles to take effect.
+        */
+       regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
+                       BCM2835_I2S_STBY, BCM2835_I2S_STBY);
+
+       return 0;
+}
+
+static void bcm2835_i2s_shutdown(struct snd_pcm_substream *substream,
+               struct snd_soc_dai *dai)
+{
+       struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+       bcm2835_i2s_stop(dev, substream, dai);
+
+       /* If both streams are stopped, disable module and clock */
+       if (dai->active)
+               return;
+
+       /* Disable the module */
+       regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
+                       BCM2835_I2S_EN, 0);
+
+       /*
+        * Stopping clock is necessary, because stop does
+        * not stop the clock when SND_SOC_DAIFMT_CONT
+        */
+       bcm2835_i2s_stop_clock(dev);
+}
+
+static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = {
+       .startup        = bcm2835_i2s_startup,
+       .shutdown       = bcm2835_i2s_shutdown,
+       .prepare        = bcm2835_i2s_prepare,
+       .trigger        = bcm2835_i2s_trigger,
+       .hw_params      = bcm2835_i2s_hw_params,
+       .set_fmt        = bcm2835_i2s_set_dai_fmt,
+       .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio
+};
+
+static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai)
+{
+       struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+       snd_soc_dai_init_dma_data(dai,
+                       &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
+                       &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
+
+       return 0;
+}
+
+static struct snd_soc_dai_driver bcm2835_i2s_dai = {
+       .name   = "bcm2835-i2s",
+       .probe  = bcm2835_i2s_dai_probe,
+       .playback = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates =        SNDRV_PCM_RATE_8000_192000,
+               .formats =      SNDRV_PCM_FMTBIT_S16_LE
+                               | SNDRV_PCM_FMTBIT_S32_LE
+               },
+       .capture = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates =        SNDRV_PCM_RATE_8000_192000,
+               .formats =      SNDRV_PCM_FMTBIT_S16_LE
+                               | SNDRV_PCM_FMTBIT_S32_LE
+               },
+       .ops = &bcm2835_i2s_dai_ops,
+       .symmetric_rates = 1
+};
+
+static bool bcm2835_i2s_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case BCM2835_I2S_CS_A_REG:
+       case BCM2835_I2S_FIFO_A_REG:
+       case BCM2835_I2S_INTSTC_A_REG:
+       case BCM2835_I2S_GRAY_REG:
+               return true;
+       default:
+               return false;
+       };
+}
+
+static bool bcm2835_i2s_precious_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case BCM2835_I2S_FIFO_A_REG:
+               return true;
+       default:
+               return false;
+       };
+}
+
+static bool bcm2835_clk_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case BCM2835_CLK_PCMCTL_REG:
+               return true;
+       default:
+               return false;
+       };
+}
+
+static const struct regmap_config bcm2835_regmap_config[] = {
+       {
+               .reg_bits = 32,
+               .reg_stride = 4,
+               .val_bits = 32,
+               .max_register = BCM2835_I2S_GRAY_REG,
+               .precious_reg = bcm2835_i2s_precious_reg,
+               .volatile_reg = bcm2835_i2s_volatile_reg,
+               .cache_type = REGCACHE_RBTREE,
+       },
+       {
+               .reg_bits = 32,
+               .reg_stride = 4,
+               .val_bits = 32,
+               .max_register = BCM2835_CLK_PCMDIV_REG,
+               .volatile_reg = bcm2835_clk_volatile_reg,
+               .cache_type = REGCACHE_RBTREE,
+       },
+};
+
+static const struct snd_soc_component_driver bcm2835_i2s_component = {
+       .name           = "bcm2835-i2s-comp",
+};
+
+static int bcm2835_i2s_probe(struct platform_device *pdev)
+{
+       struct bcm2835_i2s_dev *dev;
+       int i;
+       int ret;
+       struct regmap *regmap[2];
+       struct resource *mem[2];
+
+       /* Request both ioareas */
+       for (i = 0; i <= 1; i++) {
+               void __iomem *base;
+
+               mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i);
+               base = devm_ioremap_resource(&pdev->dev, mem[i]);
+               if (IS_ERR(base))
+                       return PTR_ERR(base);
+
+               regmap[i] = devm_regmap_init_mmio(&pdev->dev, base,
+                                           &bcm2835_regmap_config[i]);
+               if (IS_ERR(regmap[i]))
+                       return PTR_ERR(regmap[i]);
+       }
+
+       dev = devm_kzalloc(&pdev->dev, sizeof(*dev),
+                          GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       dev->i2s_regmap = regmap[0];
+       dev->clk_regmap = regmap[1];
+
+       /* Set the DMA address */
+       dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =
+               (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG
+                                         + BCM2835_VCMMU_SHIFT;
+
+       dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =
+               (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG
+                                         + BCM2835_VCMMU_SHIFT;
+
+       /* Set the bus width */
+       dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width =
+               DMA_SLAVE_BUSWIDTH_4_BYTES;
+       dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width =
+               DMA_SLAVE_BUSWIDTH_4_BYTES;
+
+       /* Set burst */
+       dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2;
+       dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2;
+
+       /* BCLK ratio - use default */
+       dev->bclk_ratio = 0;
+
+       /* Store the pdev */
+       dev->dev = &pdev->dev;
+       dev_set_drvdata(&pdev->dev, dev);
+
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                       &bcm2835_i2s_component, &bcm2835_i2s_dai, 1);
+       if (ret) {
+               dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+       if (ret) {
+               dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static const struct of_device_id bcm2835_i2s_of_match[] = {
+       { .compatible = "brcm,bcm2835-i2s", },
+       {},
+};
+
+static int bcm2835_i2s_remove(struct platform_device *pdev)
+{
+       snd_dmaengine_pcm_unregister(&pdev->dev);
+       return 0;
+}
+
+static struct platform_driver bcm2835_i2s_driver = {
+       .probe          = bcm2835_i2s_probe,
+       .remove         = bcm2835_i2s_remove,
+       .driver         = {
+               .name   = "bcm2835-i2s",
+               .owner  = THIS_MODULE,
+               .of_match_table = bcm2835_i2s_of_match,
+       },
+};
+
+module_platform_driver(bcm2835_i2s_driver);
+
+MODULE_ALIAS("platform:bcm2835-i2s");
+MODULE_DESCRIPTION("BCM2835 I2S interface");
+MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
+MODULE_LICENSE("GPL v2");
index b33b45dfceec54b205c512ca01638d947df56f66..983d087aa92aa83125903dc18cd420f57c2009eb 100644 (file)
@@ -163,8 +163,10 @@ config SND_SOC_WM_HUBS
 config SND_SOC_WM_ADSP
        tristate
        default y if SND_SOC_WM5102=y
+       default y if SND_SOC_WM5110=y
        default y if SND_SOC_WM2200=y
        default m if SND_SOC_WM5102=m
+       default m if SND_SOC_WM5110=m
        default m if SND_SOC_WM2200=m
 
 config SND_SOC_AB8500_CODEC
index aea7e52cf714117a445347cbe528f6732d2bd662..12c27eb363dd13c54b9b1f9b297d02eff9643ef5 100644 (file)
@@ -413,7 +413,7 @@ static struct spi_driver ad193x_spi_driver = {
 };
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 
 static const struct regmap_config ad193x_i2c_regmap_config = {
        .val_bits = 8,
@@ -470,7 +470,7 @@ static int __init ad193x_modinit(void)
 {
        int ret;
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret =  i2c_add_driver(&ad193x_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n",
@@ -495,7 +495,7 @@ static void __exit ad193x_modexit(void)
        spi_unregister_driver(&ad193x_spi_driver);
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&ad193x_i2c_driver);
 #endif
 }
index 14a7c169d004ebf97fabbbccfd8df0434327c639..f7bf4555274982864478b43af4a710350662d7dc 100644 (file)
@@ -939,7 +939,7 @@ static struct spi_driver adav80x_spi_driver = {
 };
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static const struct regmap_config adav80x_i2c_regmap_config = {
        .val_bits = 8,
        .pad_bits = 1,
@@ -985,7 +985,7 @@ static int __init adav80x_init(void)
 {
        int ret = 0;
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&adav80x_i2c_driver);
        if (ret)
                return ret;
@@ -1001,7 +1001,7 @@ module_init(adav80x_init);
 
 static void __exit adav80x_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&adav80x_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 49cc5f6d6dba41cd1d45712fc15037d8031ddaf5..94cbe508dd3748723197f7443f5a6ed8524b2b14 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/gpio.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -30,6 +31,7 @@
 
 /* codec private data */
 struct ak4641_priv {
+       struct regmap *regmap;
        unsigned int sysclk;
        int deemph;
        int playback_fs;
@@ -38,12 +40,12 @@ struct ak4641_priv {
 /*
  * ak4641 register cache
  */
-static const u8 ak4641_reg[AK4641_CACHEREGNUM] = {
-       0x00, 0x80, 0x00, 0x80,
-       0x02, 0x00, 0x11, 0x05,
-       0x00, 0x00, 0x36, 0x10,
-       0x00, 0x00, 0x57, 0x00,
-       0x88, 0x88, 0x08, 0x08
+static const struct reg_default ak4641_reg_defaults[] = {
+       {  0, 0x00 }, {  1, 0x80 }, {  2, 0x00 }, {  3, 0x80 },
+       {  4, 0x02 }, {  5, 0x00 }, {  6, 0x11 }, {  7, 0x05 },
+       {  8, 0x00 }, {  9, 0x00 }, { 10, 0x36 }, { 11, 0x10 },
+       { 12, 0x00 }, { 13, 0x00 }, { 14, 0x57 }, { 15, 0x00 },
+       { 16, 0x88 }, { 17, 0x88 }, { 18, 0x08 }, { 19, 0x08 }
 };
 
 static const int deemph_settings[] = {44100, 0, 48000, 32000};
@@ -396,6 +398,7 @@ static int ak4641_mute(struct snd_soc_dai *dai, int mute)
 static int ak4641_set_bias_level(struct snd_soc_codec *codec,
        enum snd_soc_bias_level level)
 {
+       struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
        struct ak4641_platform_data *pdata = codec->dev->platform_data;
        int ret;
 
@@ -417,7 +420,7 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
                                gpio_set_value(pdata->gpio_npdn, 1);
                        mdelay(1);
 
-                       ret = snd_soc_cache_sync(codec);
+                       ret = regcache_sync(ak4641->regmap);
                        if (ret) {
                                dev_err(codec->dev,
                                        "Failed to sync cache: %d\n", ret);
@@ -433,7 +436,7 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
                        gpio_set_value(pdata->gpio_npdn, 0);
                if (pdata && gpio_is_valid(pdata->gpio_power))
                        gpio_set_value(pdata->gpio_power, 0);
-               codec->cache_sync = 1;
+               regcache_mark_dirty(ak4641->regmap);
                break;
        }
        codec->dapm.bias_level = level;
@@ -518,7 +521,7 @@ static int ak4641_probe(struct snd_soc_codec *codec)
 {
        int ret;
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
+       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
        if (ret != 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
                return ret;
@@ -550,12 +553,17 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
        .dapm_routes            = ak4641_audio_map,
        .num_dapm_routes        = ARRAY_SIZE(ak4641_audio_map),
        .set_bias_level         = ak4641_set_bias_level,
-       .reg_cache_size         = ARRAY_SIZE(ak4641_reg),
-       .reg_word_size          = sizeof(u8),
-       .reg_cache_default      = ak4641_reg,
-       .reg_cache_step         = 1,
 };
 
+static const struct regmap_config ak4641_regmap = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = AK4641_BTIF,
+       .reg_defaults = ak4641_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(ak4641_reg_defaults),
+       .cache_type = REGCACHE_RBTREE,
+};
 
 static int ak4641_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
@@ -569,6 +577,10 @@ static int ak4641_i2c_probe(struct i2c_client *i2c,
        if (!ak4641)
                return -ENOMEM;
 
+       ak4641->regmap = devm_regmap_init_i2c(i2c, &ak4641_regmap);
+       if (IS_ERR(ak4641->regmap))
+               return PTR_ERR(ak4641->regmap);
+
        if (pdata) {
                if (gpio_is_valid(pdata->gpio_power)) {
                        ret = gpio_request_one(pdata->gpio_power,
index 090d499bb7ebca49d34fd2ac3142b782f8f46a1b..2f861c9b1d69079ecf32740f89a939194bc80e43 100644 (file)
@@ -511,7 +511,7 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4648 = {
        .num_dapm_routes        = ARRAY_SIZE(ak4642_intercon),
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static struct of_device_id ak4642_of_match[];
 static int ak4642_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
@@ -576,7 +576,7 @@ static struct i2c_driver ak4642_i2c_driver = {
 static int __init ak4642_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&ak4642_i2c_driver);
 #endif
        return ret;
@@ -586,7 +586,7 @@ module_init(ak4642_modinit);
 
 static void __exit ak4642_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&ak4642_i2c_driver);
 #endif
 
index fea991031be18a05eab28e4922b10a2e472b5ea9..eb9f5d4d8928aee386cebfb0fbeddd0ed74654bc 100644 (file)
@@ -292,6 +292,10 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
        "AIF1RX8",
        "AIF2RX1",
        "AIF2RX2",
+       "AIF2RX3",
+       "AIF2RX4",
+       "AIF2RX5",
+       "AIF2RX6",
        "AIF3RX1",
        "AIF3RX2",
        "SLIMRX1",
@@ -395,6 +399,10 @@ int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
        0x27,
        0x28,  /* AIF2RX1 */
        0x29,
+       0x2a,
+       0x2b,
+       0x2c,
+       0x2d,
        0x30,  /* AIF3RX1 */
        0x31,
        0x38,  /* SLIMRX1 */
@@ -560,6 +568,16 @@ const struct soc_enum arizona_ng_hold =
                        4, arizona_ng_hold_text);
 EXPORT_SYMBOL_GPL(arizona_ng_hold);
 
+static const char * const arizona_in_hpf_cut_text[] = {
+       "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
+};
+
+const struct soc_enum arizona_in_hpf_cut_enum =
+       SOC_ENUM_SINGLE(ARIZONA_HPF_CONTROL, ARIZONA_IN_HPF_CUT_SHIFT,
+                       ARRAY_SIZE(arizona_in_hpf_cut_text),
+                       arizona_in_hpf_cut_text);
+EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
+
 static const char * const arizona_in_dmic_osr_text[] = {
        "1.536MHz", "3.072MHz", "6.144MHz",
 };
index 9e81b6392692cbd78e7e9ad7b263fcd00c214a1d..6641f3d641946d12629d2a4692bfaa7048d0a5d1 100644 (file)
@@ -81,7 +81,7 @@ struct arizona_priv {
        unsigned int spk_ena_pending:1;
 };
 
-#define ARIZONA_NUM_MIXER_INPUTS 99
+#define ARIZONA_NUM_MIXER_INPUTS 103
 
 extern const unsigned int arizona_mixer_tlv[];
 extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
@@ -199,6 +199,7 @@ extern const struct soc_enum arizona_lhpf3_mode;
 extern const struct soc_enum arizona_lhpf4_mode;
 
 extern const struct soc_enum arizona_ng_hold;
+extern const struct soc_enum arizona_in_hpf_cut_enum;
 extern const struct soc_enum arizona_in_dmic_osr[];
 
 extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
index f6e953454bc0856ffccb87ec6680a670d3e90cbd..ce05fd93dc748c3cc8e1405b1d50296f5e9780e3 100644 (file)
@@ -675,7 +675,7 @@ static struct spi_driver cs4271_spi_driver = {
 };
 #endif /* defined(CONFIG_SPI_MASTER) */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static const struct i2c_device_id cs4271_i2c_id[] = {
        {"cs4271", 0},
        {}
@@ -728,7 +728,7 @@ static struct i2c_driver cs4271_i2c_driver = {
        .probe          = cs4271_i2c_probe,
        .remove         = cs4271_i2c_remove,
 };
-#endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */
+#endif /* IS_ENABLED(CONFIG_I2C) */
 
 /*
  * We only register our serial bus driver here without
@@ -741,7 +741,7 @@ static int __init cs4271_modinit(void)
 {
        int ret;
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&cs4271_i2c_driver);
        if (ret) {
                pr_err("Failed to register CS4271 I2C driver: %d\n", ret);
@@ -767,7 +767,7 @@ static void __exit cs4271_modexit(void)
        spi_unregister_driver(&cs4271_spi_driver);
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&cs4271_i2c_driver);
 #endif
 }
index 8b427c97708365e5e1e40aad701f740b62c365be..0bac6d5a4ac8fac7c00e3a909f044a499f11761b 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
@@ -50,7 +50,7 @@ struct  cs42l52_private {
        u8 mclksel;
        u32 mclk;
        u8 flags;
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#if IS_ENABLED(CONFIG_INPUT)
        struct input_dev *beep;
        struct work_struct beep_work;
        int beep_rate;
@@ -233,7 +233,7 @@ static const struct soc_enum mic_bias_level_enum =
        SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0,
                        ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text);
 
-static const char * const cs42l52_mic_text[] = { "Single", "Differential" };
+static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" };
 
 static const struct soc_enum mica_enum =
        SOC_ENUM_SINGLE(CS42L52_MICA_CTL, 5,
@@ -243,12 +243,6 @@ static const struct soc_enum micb_enum =
        SOC_ENUM_SINGLE(CS42L52_MICB_CTL, 5,
                        ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
 
-static const struct snd_kcontrol_new mica_mux =
-       SOC_DAPM_ENUM("Left Mic Input Capture Mux", mica_enum);
-
-static const struct snd_kcontrol_new micb_mux =
-       SOC_DAPM_ENUM("Right Mic Input Capture Mux", micb_enum);
-
 static const char * const digital_output_mux_text[] = {"ADC", "DSP"};
 
 static const struct soc_enum digital_output_mux_enum =
@@ -531,6 +525,30 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
 
 };
 
+static const struct snd_kcontrol_new cs42l52_mica_controls[] = {
+       SOC_ENUM("MICA Select", mica_enum),
+};
+
+static const struct snd_kcontrol_new cs42l52_micb_controls[] = {
+       SOC_ENUM("MICB Select", micb_enum),
+};
+
+static int cs42l52_add_mic_controls(struct snd_soc_codec *codec)
+{
+       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l52_platform_data *pdata = &cs42l52->pdata;
+
+       if (!pdata->mica_diff_cfg)
+               snd_soc_add_codec_controls(codec, cs42l52_mica_controls,
+                                    ARRAY_SIZE(cs42l52_mica_controls));
+
+       if (!pdata->micb_diff_cfg)
+               snd_soc_add_codec_controls(codec, cs42l52_micb_controls,
+                                    ARRAY_SIZE(cs42l52_micb_controls));
+
+       return 0;
+}
+
 static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = {
 
        SND_SOC_DAPM_INPUT("AIN1L"),
@@ -550,9 +568,6 @@ static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = {
        SND_SOC_DAPM_AIF_OUT("AIFOUTR", NULL,  0,
                        SND_SOC_NOPM, 0, 0),
 
-       SND_SOC_DAPM_MUX("MICA Mux", SND_SOC_NOPM, 0, 0, &mica_mux),
-       SND_SOC_DAPM_MUX("MICB Mux", SND_SOC_NOPM, 0, 0, &micb_mux),
-
        SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L52_PWRCTL1, 1, 1),
        SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L52_PWRCTL1, 2, 1),
        SND_SOC_DAPM_PGA("PGA Left", CS42L52_PWRCTL1, 3, 1, NULL, 0),
@@ -953,7 +968,7 @@ static int cs42l52_resume(struct snd_soc_codec *codec)
        return 0;
 }
 
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#if IS_ENABLED(CONFIG_INPUT)
 static int beep_rates[] = {
        261, 522, 585, 667, 706, 774, 889, 1000,
        1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
@@ -1110,6 +1125,8 @@ static int cs42l52_probe(struct snd_soc_codec *codec)
        }
        regcache_cache_only(cs42l52->regmap, true);
 
+       cs42l52_add_mic_controls(codec);
+
        cs42l52_init_beep(codec);
 
        cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1176,6 +1193,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
        int ret;
        unsigned int devid = 0;
        unsigned int reg;
+       u32 val32;
 
        cs42l52 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l52_private),
                               GFP_KERNEL);
@@ -1189,9 +1207,39 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
                dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
                return ret;
        }
-
-       if (pdata)
+       if (pdata) {
+               cs42l52->pdata = *pdata;
+       } else {
+               pdata = devm_kzalloc(&i2c_client->dev,
+                                    sizeof(struct cs42l52_platform_data),
+                               GFP_KERNEL);
+               if (!pdata) {
+                       dev_err(&i2c_client->dev, "could not allocate pdata\n");
+                       return -ENOMEM;
+               }
+               if (i2c_client->dev.of_node) {
+                       if (of_property_read_bool(i2c_client->dev.of_node,
+                               "cirrus,mica-differential-cfg"))
+                               pdata->mica_diff_cfg = true;
+
+                       if (of_property_read_bool(i2c_client->dev.of_node,
+                               "cirrus,micb-differential-cfg"))
+                               pdata->micb_diff_cfg = true;
+
+                       if (of_property_read_u32(i2c_client->dev.of_node,
+                               "cirrus,micbias-lvl", &val32) >= 0)
+                               pdata->micbias_lvl = val32;
+
+                       if (of_property_read_u32(i2c_client->dev.of_node,
+                               "cirrus,chgfreq-divisor", &val32) >= 0)
+                               pdata->chgfreq = val32;
+
+                       pdata->reset_gpio =
+                               of_get_named_gpio(i2c_client->dev.of_node,
+                                               "cirrus,reset-gpio", 0);
+               }
                cs42l52->pdata = *pdata;
+       }
 
        if (cs42l52->pdata.reset_gpio) {
                ret = gpio_request_one(cs42l52->pdata.reset_gpio,
@@ -1227,29 +1275,18 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
                        reg & 0xFF);
 
        /* Set Platform Data */
-       if (cs42l52->pdata.mica_cfg)
+       if (cs42l52->pdata.mica_diff_cfg)
                regmap_update_bits(cs42l52->regmap, CS42L52_MICA_CTL,
                                   CS42L52_MIC_CTL_TYPE_MASK,
-                               cs42l52->pdata.mica_cfg <<
+                               cs42l52->pdata.mica_diff_cfg <<
                                CS42L52_MIC_CTL_TYPE_SHIFT);
 
-       if (cs42l52->pdata.micb_cfg)
+       if (cs42l52->pdata.micb_diff_cfg)
                regmap_update_bits(cs42l52->regmap, CS42L52_MICB_CTL,
                                   CS42L52_MIC_CTL_TYPE_MASK,
-                               cs42l52->pdata.micb_cfg <<
+                               cs42l52->pdata.micb_diff_cfg <<
                                CS42L52_MIC_CTL_TYPE_SHIFT);
 
-       if (cs42l52->pdata.mica_sel)
-               regmap_update_bits(cs42l52->regmap, CS42L52_MICA_CTL,
-                                  CS42L52_MIC_CTL_MIC_SEL_MASK,
-                               cs42l52->pdata.mica_sel <<
-                               CS42L52_MIC_CTL_MIC_SEL_SHIFT);
-       if (cs42l52->pdata.micb_sel)
-               regmap_update_bits(cs42l52->regmap, CS42L52_MICB_CTL,
-                                  CS42L52_MIC_CTL_MIC_SEL_MASK,
-                               cs42l52->pdata.micb_sel <<
-                               CS42L52_MIC_CTL_MIC_SEL_SHIFT);
-
        if (cs42l52->pdata.chgfreq)
                regmap_update_bits(cs42l52->regmap, CS42L52_CHARGE_PUMP,
                                   CS42L52_CHARGE_PUMP_MASK,
@@ -1274,6 +1311,13 @@ static int cs42l52_i2c_remove(struct i2c_client *client)
        return 0;
 }
 
+static const struct of_device_id cs42l52_of_match[] = {
+       { .compatible = "cirrus,cs42l52", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, cs42l52_of_match);
+
+
 static const struct i2c_device_id cs42l52_id[] = {
        { "cs42l52", 0 },
        { }
@@ -1284,6 +1328,7 @@ static struct i2c_driver cs42l52_i2c_driver = {
        .driver = {
                .name = "cs42l52",
                .owner = THIS_MODULE,
+               .of_match_table = cs42l52_of_match,
        },
        .id_table = cs42l52_id,
        .probe =    cs42l52_i2c_probe,
index 9c12314565024fcb80d5091a6fc57a6dddf0555b..8166dcb2e4a393300b3210d0bcdf3dab5358cba9 100644 (file)
@@ -1188,7 +1188,7 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
        .num_dapm_routes        = ARRAY_SIZE(da7210_audio_map),
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 
 static struct reg_default da7210_regmap_i2c_patch[] = {
 
@@ -1362,7 +1362,7 @@ static struct spi_driver da7210_spi_driver = {
 static int __init da7210_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&da7210_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
@@ -1378,7 +1378,7 @@ module_init(da7210_modinit);
 
 static void __exit da7210_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&da7210_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 68342b121c966aa7c90ace1384bbfbefe4737ab7..32797a8e4ee957a17a2d0fb9161766cc0db15082 100644 (file)
@@ -44,7 +44,7 @@ static struct snd_soc_dai_driver hdmi_codec_dai = {
                        SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
                        SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
                .formats = SNDRV_PCM_FMTBIT_S16_LE |
-                       SNDRV_PCM_FMTBIT_S24_LE,
+                       SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
        },
        .capture = {
                .stream_name = "Capture",
index 492644e67ace909d2f6b71c7685259955f76661d..480074d864767b14100d38d13027a8ca498e19e0 100644 (file)
@@ -730,7 +730,7 @@ static struct spi_driver ssm2602_spi_driver = {
 };
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 /*
  * ssm2602 2 wire address is determined by GPIO5
  * state during powerup.
@@ -797,7 +797,7 @@ static int __init ssm2602_modinit(void)
                return ret;
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&ssm2602_i2c_driver);
        if (ret)
                return ret;
@@ -813,7 +813,7 @@ static void __exit ssm2602_exit(void)
        spi_unregister_driver(&ssm2602_spi_driver);
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&ssm2602_i2c_driver);
 #endif
 }
index fd0a314bc209a4005e8b3488930b6b7d3215526f..726df6d43c2b69227adc503e38397f977db4f220 100644 (file)
@@ -794,7 +794,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
        .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes),
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int uda1380_i2c_probe(struct i2c_client *i2c,
                             const struct i2c_device_id *id)
 {
@@ -840,7 +840,7 @@ static struct i2c_driver uda1380_i2c_driver = {
 static int __init uda1380_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&uda1380_i2c_driver);
        if (ret != 0)
                pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
@@ -851,7 +851,7 @@ module_init(uda1380_modinit);
 
 static void __exit uda1380_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&uda1380_i2c_driver);
 #endif
 }
index c3c7396a618115d06171bb87314b363cc8ac9f6d..9eb8517470a33f2bf5c42c0013ccf1cb3bf45eae 100644 (file)
 #include <linux/mfd/arizona/registers.h>
 
 #include "arizona.h"
+#include "wm_adsp.h"
 #include "wm5110.h"
 
+#define WM5110_NUM_ADSP 4
+
 struct wm5110_priv {
        struct arizona_priv core;
        struct arizona_fll fll[2];
 };
 
+static const struct wm_adsp_region wm5110_dsp1_regions[] = {
+       { .type = WMFW_ADSP2_PM, .base = 0x100000 },
+       { .type = WMFW_ADSP2_ZM, .base = 0x180000 },
+       { .type = WMFW_ADSP2_XM, .base = 0x190000 },
+       { .type = WMFW_ADSP2_YM, .base = 0x1a8000 },
+};
+
+static const struct wm_adsp_region wm5110_dsp2_regions[] = {
+       { .type = WMFW_ADSP2_PM, .base = 0x200000 },
+       { .type = WMFW_ADSP2_ZM, .base = 0x280000 },
+       { .type = WMFW_ADSP2_XM, .base = 0x290000 },
+       { .type = WMFW_ADSP2_YM, .base = 0x2a8000 },
+};
+
+static const struct wm_adsp_region wm5110_dsp3_regions[] = {
+       { .type = WMFW_ADSP2_PM, .base = 0x300000 },
+       { .type = WMFW_ADSP2_ZM, .base = 0x380000 },
+       { .type = WMFW_ADSP2_XM, .base = 0x390000 },
+       { .type = WMFW_ADSP2_YM, .base = 0x3a8000 },
+};
+
+static const struct wm_adsp_region wm5110_dsp4_regions[] = {
+       { .type = WMFW_ADSP2_PM, .base = 0x400000 },
+       { .type = WMFW_ADSP2_ZM, .base = 0x480000 },
+       { .type = WMFW_ADSP2_XM, .base = 0x490000 },
+       { .type = WMFW_ADSP2_YM, .base = 0x4a8000 },
+};
+
+static const struct wm_adsp_region *wm5110_dsp_regions[] = {
+       wm5110_dsp1_regions,
+       wm5110_dsp2_regions,
+       wm5110_dsp3_regions,
+       wm5110_dsp4_regions,
+};
+
 static const struct reg_default wm5110_sysclk_revd_patch[] = {
        { 0x3093, 0x1001 },
        { 0x30E3, 0x1301 },
@@ -117,6 +155,25 @@ SOC_SINGLE_RANGE_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL,
 SOC_SINGLE_RANGE_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL,
                     ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
 
+SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum),
+
+SOC_SINGLE("IN1L HPF Switch", ARIZONA_IN1L_CONTROL,
+          ARIZONA_IN1L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN1R HPF Switch", ARIZONA_IN1R_CONTROL,
+          ARIZONA_IN1R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN2L HPF Switch", ARIZONA_IN2L_CONTROL,
+          ARIZONA_IN2L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN2R HPF Switch", ARIZONA_IN2R_CONTROL,
+          ARIZONA_IN2R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN3L HPF Switch", ARIZONA_IN3L_CONTROL,
+          ARIZONA_IN3L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN3R HPF Switch", ARIZONA_IN3R_CONTROL,
+          ARIZONA_IN3R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN4L HPF Switch", ARIZONA_IN4L_CONTROL,
+          ARIZONA_IN4L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN4R HPF Switch", ARIZONA_IN4R_CONTROL,
+          ARIZONA_IN4R_HPF_SHIFT, 1, 0),
+
 SOC_SINGLE_TLV("IN1L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
               ARIZONA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
 SOC_SINGLE_TLV("IN1R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1R,
@@ -220,6 +277,10 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
 SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
 SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
 
+SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
+SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
+SOC_VALUE_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]),
+
 ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
@@ -248,19 +309,6 @@ ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SPKDAT2L", ARIZONA_OUT6LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE),
 
-SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
-          ARIZONA_OUT1_OSR_SHIFT, 1, 0),
-SOC_SINGLE("HPOUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
-          ARIZONA_OUT2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("HPOUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
-          ARIZONA_OUT3_OSR_SHIFT, 1, 0),
-SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
-          ARIZONA_OUT4_OSR_SHIFT, 1, 0),
-SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
-          ARIZONA_OUT5_OSR_SHIFT, 1, 0),
-SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L,
-          ARIZONA_OUT6_OSR_SHIFT, 1, 0),
-
 SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
             ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
@@ -293,18 +341,6 @@ SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_6L,
                 ARIZONA_DAC_DIGITAL_VOLUME_6R, ARIZONA_OUT6L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
 
-SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
-                      ARIZONA_OUTPUT_PATH_CONFIG_1R,
-                      ARIZONA_OUT1L_PGA_VOL_SHIFT,
-                      0x34, 0x40, 0, ana_tlv),
-SOC_DOUBLE_R_RANGE_TLV("HPOUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
-                      ARIZONA_OUTPUT_PATH_CONFIG_2R,
-                      ARIZONA_OUT2L_PGA_VOL_SHIFT,
-                      0x34, 0x40, 0, ana_tlv),
-SOC_DOUBLE_R_RANGE_TLV("HPOUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
-                      ARIZONA_OUTPUT_PATH_CONFIG_3R,
-                      ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
-
 SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
           ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
@@ -343,6 +379,10 @@ ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE),
 
 ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("AIF2TX3", ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("AIF2TX4", ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("AIF2TX5", ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("AIF2TX6", ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE),
 
 ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
@@ -372,6 +412,22 @@ ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
 
+ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE);
+ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE);
+
+ARIZONA_MIXER_ENUMS(DSP2L, ARIZONA_DSP2LMIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(DSP2R, ARIZONA_DSP2RMIX_INPUT_1_SOURCE);
+ARIZONA_DSP_AUX_ENUMS(DSP2, ARIZONA_DSP2AUX1MIX_INPUT_1_SOURCE);
+
+ARIZONA_MIXER_ENUMS(DSP3L, ARIZONA_DSP3LMIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(DSP3R, ARIZONA_DSP3RMIX_INPUT_1_SOURCE);
+ARIZONA_DSP_AUX_ENUMS(DSP3, ARIZONA_DSP3AUX1MIX_INPUT_1_SOURCE);
+
+ARIZONA_MIXER_ENUMS(DSP4L, ARIZONA_DSP4LMIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(DSP4R, ARIZONA_DSP4RMIX_INPUT_1_SOURCE);
+ARIZONA_DSP_AUX_ENUMS(DSP4, ARIZONA_DSP4AUX1MIX_INPUT_1_SOURCE);
+
 ARIZONA_MIXER_ENUMS(Mic, ARIZONA_MICMIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(Noise, ARIZONA_NOISEMIX_INPUT_1_SOURCE);
 
@@ -402,6 +458,10 @@ ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE);
 
 ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(AIF2TX3, ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(AIF2TX4, ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(AIF2TX5, ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(AIF2TX6, ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE);
 
 ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
@@ -420,6 +480,36 @@ ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
 
+ARIZONA_MUX_ENUMS(ISRC1INT1, ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC1INT2, ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC1INT3, ARIZONA_ISRC1INT3MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC1INT4, ARIZONA_ISRC1INT4MIX_INPUT_1_SOURCE);
+
+ARIZONA_MUX_ENUMS(ISRC1DEC1, ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC1DEC2, ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC1DEC3, ARIZONA_ISRC1DEC3MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC1DEC4, ARIZONA_ISRC1DEC4MIX_INPUT_1_SOURCE);
+
+ARIZONA_MUX_ENUMS(ISRC2INT1, ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC2INT2, ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC2INT3, ARIZONA_ISRC2INT3MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC2INT4, ARIZONA_ISRC2INT4MIX_INPUT_1_SOURCE);
+
+ARIZONA_MUX_ENUMS(ISRC2DEC1, ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC2DEC2, ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC2DEC3, ARIZONA_ISRC2DEC3MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC2DEC4, ARIZONA_ISRC2DEC4MIX_INPUT_1_SOURCE);
+
+ARIZONA_MUX_ENUMS(ISRC3INT1, ARIZONA_ISRC3INT1MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC3INT2, ARIZONA_ISRC3INT2MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC3INT3, ARIZONA_ISRC3INT3MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC3INT4, ARIZONA_ISRC3INT4MIX_INPUT_1_SOURCE);
+
+ARIZONA_MUX_ENUMS(ISRC3DEC1, ARIZONA_ISRC3DEC1MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC3DEC2, ARIZONA_ISRC3DEC2MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC3DEC3, ARIZONA_ISRC3DEC3MIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ISRC3DEC4, ARIZONA_ISRC3DEC4MIX_INPUT_1_SOURCE);
+
 static const char *wm5110_aec_loopback_texts[] = {
        "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
        "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", "SPKDAT2L", "SPKDAT2R",
@@ -560,6 +650,65 @@ SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
 SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
                 NULL, 0),
 
+WM_ADSP2("DSP1", 0),
+WM_ADSP2("DSP2", 1),
+WM_ADSP2("DSP3", 2),
+WM_ADSP2("DSP4", 3),
+
+SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
+                ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT2", ARIZONA_ISRC_1_CTRL_3,
+                ARIZONA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT3", ARIZONA_ISRC_1_CTRL_3,
+                ARIZONA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT4", ARIZONA_ISRC_1_CTRL_3,
+                ARIZONA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC1DEC1", ARIZONA_ISRC_1_CTRL_3,
+                ARIZONA_ISRC1_DEC0_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC2", ARIZONA_ISRC_1_CTRL_3,
+                ARIZONA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC3", ARIZONA_ISRC_1_CTRL_3,
+                ARIZONA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC4", ARIZONA_ISRC_1_CTRL_3,
+                ARIZONA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC2INT1", ARIZONA_ISRC_2_CTRL_3,
+                ARIZONA_ISRC2_INT0_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT2", ARIZONA_ISRC_2_CTRL_3,
+                ARIZONA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT3", ARIZONA_ISRC_2_CTRL_3,
+                ARIZONA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT4", ARIZONA_ISRC_2_CTRL_3,
+                ARIZONA_ISRC2_INT3_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC2DEC1", ARIZONA_ISRC_2_CTRL_3,
+                ARIZONA_ISRC2_DEC0_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3,
+                ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC3", ARIZONA_ISRC_2_CTRL_3,
+                ARIZONA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC4", ARIZONA_ISRC_2_CTRL_3,
+                ARIZONA_ISRC2_DEC3_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC3INT1", ARIZONA_ISRC_3_CTRL_3,
+                ARIZONA_ISRC3_INT0_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3INT2", ARIZONA_ISRC_3_CTRL_3,
+                ARIZONA_ISRC3_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3INT3", ARIZONA_ISRC_3_CTRL_3,
+                ARIZONA_ISRC3_INT2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3INT4", ARIZONA_ISRC_3_CTRL_3,
+                ARIZONA_ISRC3_INT3_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC3DEC1", ARIZONA_ISRC_3_CTRL_3,
+                ARIZONA_ISRC3_DEC0_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3DEC2", ARIZONA_ISRC_3_CTRL_3,
+                ARIZONA_ISRC3_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3DEC3", ARIZONA_ISRC_3_CTRL_3,
+                ARIZONA_ISRC3_DEC2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3,
+                ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0),
+
 SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
                       ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
                       &wm5110_aec_loopback_mux),
@@ -602,11 +751,27 @@ SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
                     ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
 SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
                     ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
+                    ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
+                    ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0,
+                    ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0,
+                    ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX6_ENA_SHIFT, 0),
 
 SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
                    ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
 SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
                    ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
+                   ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
+                   ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0,
+                   ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0,
+                   ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX6_ENA_SHIFT, 0),
 
 SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
                    ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
@@ -744,6 +909,10 @@ ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
 
 ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
 ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
+ARIZONA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"),
+ARIZONA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"),
+ARIZONA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"),
+ARIZONA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"),
 
 ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
 ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
@@ -762,6 +931,41 @@ ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
 ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
 ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
 
+ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
+ARIZONA_DSP_WIDGETS(DSP2, "DSP2"),
+ARIZONA_DSP_WIDGETS(DSP3, "DSP3"),
+ARIZONA_DSP_WIDGETS(DSP4, "DSP4"),
+
+ARIZONA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
+ARIZONA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
+ARIZONA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
+ARIZONA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
+
+ARIZONA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
+ARIZONA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
+ARIZONA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
+ARIZONA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
+
+ARIZONA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
+ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
+ARIZONA_MUX_WIDGETS(ISRC2DEC3, "ISRC2DEC3"),
+ARIZONA_MUX_WIDGETS(ISRC2DEC4, "ISRC2DEC4"),
+
+ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
+ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
+ARIZONA_MUX_WIDGETS(ISRC2INT3, "ISRC2INT3"),
+ARIZONA_MUX_WIDGETS(ISRC2INT4, "ISRC2INT4"),
+
+ARIZONA_MUX_WIDGETS(ISRC3DEC1, "ISRC3DEC1"),
+ARIZONA_MUX_WIDGETS(ISRC3DEC2, "ISRC3DEC2"),
+ARIZONA_MUX_WIDGETS(ISRC3DEC3, "ISRC3DEC3"),
+ARIZONA_MUX_WIDGETS(ISRC3DEC4, "ISRC3DEC4"),
+
+ARIZONA_MUX_WIDGETS(ISRC3INT1, "ISRC3INT1"),
+ARIZONA_MUX_WIDGETS(ISRC3INT2, "ISRC3INT2"),
+ARIZONA_MUX_WIDGETS(ISRC3INT3, "ISRC3INT3"),
+ARIZONA_MUX_WIDGETS(ISRC3INT4, "ISRC3INT4"),
+
 SND_SOC_DAPM_OUTPUT("HPOUT1L"),
 SND_SOC_DAPM_OUTPUT("HPOUT1R"),
 SND_SOC_DAPM_OUTPUT("HPOUT2L"),
@@ -805,6 +1009,10 @@ SND_SOC_DAPM_OUTPUT("MICSUPP"),
        { name, "AIF1RX8", "AIF1RX8" }, \
        { name, "AIF2RX1", "AIF2RX1" }, \
        { name, "AIF2RX2", "AIF2RX2" }, \
+       { name, "AIF2RX3", "AIF2RX3" }, \
+       { name, "AIF2RX4", "AIF2RX4" }, \
+       { name, "AIF2RX5", "AIF2RX5" }, \
+       { name, "AIF2RX6", "AIF2RX6" }, \
        { name, "AIF3RX1", "AIF3RX1" }, \
        { name, "AIF3RX2", "AIF3RX2" }, \
        { name, "SLIMRX1", "SLIMRX1" }, \
@@ -830,7 +1038,55 @@ SND_SOC_DAPM_OUTPUT("MICSUPP"),
        { name, "ASRC1L", "ASRC1L" }, \
        { name, "ASRC1R", "ASRC1R" }, \
        { name, "ASRC2L", "ASRC2L" }, \
-       { name, "ASRC2R", "ASRC2R" }
+       { name, "ASRC2R", "ASRC2R" }, \
+       { name, "ISRC1DEC1", "ISRC1DEC1" }, \
+       { name, "ISRC1DEC2", "ISRC1DEC2" }, \
+       { name, "ISRC1DEC3", "ISRC1DEC3" }, \
+       { name, "ISRC1DEC4", "ISRC1DEC4" }, \
+       { name, "ISRC1INT1", "ISRC1INT1" }, \
+       { name, "ISRC1INT2", "ISRC1INT2" }, \
+       { name, "ISRC1INT3", "ISRC1INT3" }, \
+       { name, "ISRC1INT4", "ISRC1INT4" }, \
+       { name, "ISRC2DEC1", "ISRC2DEC1" }, \
+       { name, "ISRC2DEC2", "ISRC2DEC2" }, \
+       { name, "ISRC2DEC3", "ISRC2DEC3" }, \
+       { name, "ISRC2DEC4", "ISRC2DEC4" }, \
+       { name, "ISRC2INT1", "ISRC2INT1" }, \
+       { name, "ISRC2INT2", "ISRC2INT2" }, \
+       { name, "ISRC2INT3", "ISRC2INT3" }, \
+       { name, "ISRC2INT4", "ISRC2INT4" }, \
+       { name, "ISRC3DEC1", "ISRC3DEC1" }, \
+       { name, "ISRC3DEC2", "ISRC3DEC2" }, \
+       { name, "ISRC3DEC3", "ISRC3DEC3" }, \
+       { name, "ISRC3DEC4", "ISRC3DEC4" }, \
+       { name, "ISRC3INT1", "ISRC3INT1" }, \
+       { name, "ISRC3INT2", "ISRC3INT2" }, \
+       { name, "ISRC3INT3", "ISRC3INT3" }, \
+       { name, "ISRC3INT4", "ISRC3INT4" }, \
+       { name, "DSP1.1", "DSP1" }, \
+       { name, "DSP1.2", "DSP1" }, \
+       { name, "DSP1.3", "DSP1" }, \
+       { name, "DSP1.4", "DSP1" }, \
+       { name, "DSP1.5", "DSP1" }, \
+       { name, "DSP1.6", "DSP1" }, \
+       { name, "DSP2.1", "DSP2" }, \
+       { name, "DSP2.2", "DSP2" }, \
+       { name, "DSP2.3", "DSP2" }, \
+       { name, "DSP2.4", "DSP2" }, \
+       { name, "DSP2.5", "DSP2" }, \
+       { name, "DSP2.6", "DSP2" }, \
+       { name, "DSP3.1", "DSP3" }, \
+       { name, "DSP3.2", "DSP3" }, \
+       { name, "DSP3.3", "DSP3" }, \
+       { name, "DSP3.4", "DSP3" }, \
+       { name, "DSP3.5", "DSP3" }, \
+       { name, "DSP3.6", "DSP3" }, \
+       { name, "DSP4.1", "DSP4" }, \
+       { name, "DSP4.2", "DSP4" }, \
+       { name, "DSP4.3", "DSP4" }, \
+       { name, "DSP4.4", "DSP4" }, \
+       { name, "DSP4.5", "DSP4" }, \
+       { name, "DSP4.6", "DSP4" }
 
 static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
        { "AIF2 Capture", NULL, "DBVDD2" },
@@ -902,9 +1158,17 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
 
        { "AIF2 Capture", NULL, "AIF2TX1" },
        { "AIF2 Capture", NULL, "AIF2TX2" },
+       { "AIF2 Capture", NULL, "AIF2TX3" },
+       { "AIF2 Capture", NULL, "AIF2TX4" },
+       { "AIF2 Capture", NULL, "AIF2TX5" },
+       { "AIF2 Capture", NULL, "AIF2TX6" },
 
        { "AIF2RX1", NULL, "AIF2 Playback" },
        { "AIF2RX2", NULL, "AIF2 Playback" },
+       { "AIF2RX3", NULL, "AIF2 Playback" },
+       { "AIF2RX4", NULL, "AIF2 Playback" },
+       { "AIF2RX5", NULL, "AIF2 Playback" },
+       { "AIF2RX6", NULL, "AIF2 Playback" },
 
        { "AIF3 Capture", NULL, "AIF3TX1" },
        { "AIF3 Capture", NULL, "AIF3TX2" },
@@ -988,6 +1252,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
 
        ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
        ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
+       ARIZONA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"),
+       ARIZONA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"),
+       ARIZONA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"),
+       ARIZONA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"),
 
        ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
        ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
@@ -1024,6 +1292,41 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
        ARIZONA_MUX_ROUTES("ASRC2L", "ASRC2L"),
        ARIZONA_MUX_ROUTES("ASRC2R", "ASRC2R"),
 
+       ARIZONA_DSP_ROUTES("DSP1"),
+       ARIZONA_DSP_ROUTES("DSP2"),
+       ARIZONA_DSP_ROUTES("DSP3"),
+       ARIZONA_DSP_ROUTES("DSP4"),
+
+       ARIZONA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
+       ARIZONA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
+       ARIZONA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
+       ARIZONA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
+
+       ARIZONA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
+       ARIZONA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
+       ARIZONA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
+       ARIZONA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
+
+       ARIZONA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
+       ARIZONA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
+       ARIZONA_MUX_ROUTES("ISRC2INT3", "ISRC2INT3"),
+       ARIZONA_MUX_ROUTES("ISRC2INT4", "ISRC2INT4"),
+
+       ARIZONA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
+       ARIZONA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
+       ARIZONA_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"),
+       ARIZONA_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"),
+
+       ARIZONA_MUX_ROUTES("ISRC3INT1", "ISRC3INT1"),
+       ARIZONA_MUX_ROUTES("ISRC3INT2", "ISRC3INT2"),
+       ARIZONA_MUX_ROUTES("ISRC3INT3", "ISRC3INT3"),
+       ARIZONA_MUX_ROUTES("ISRC3INT4", "ISRC3INT4"),
+
+       ARIZONA_MUX_ROUTES("ISRC3DEC1", "ISRC3DEC1"),
+       ARIZONA_MUX_ROUTES("ISRC3DEC2", "ISRC3DEC2"),
+       ARIZONA_MUX_ROUTES("ISRC3DEC3", "ISRC3DEC3"),
+       ARIZONA_MUX_ROUTES("ISRC3DEC4", "ISRC3DEC4"),
+
        { "AEC Loopback", "HPOUT1L", "OUT1L" },
        { "AEC Loopback", "HPOUT1R", "OUT1R" },
        { "HPOUT1L", NULL, "OUT1L" },
@@ -1120,14 +1423,14 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
                .playback = {
                        .stream_name = "AIF2 Playback",
                        .channels_min = 1,
-                       .channels_max = 2,
+                       .channels_max = 6,
                        .rates = WM5110_RATES,
                        .formats = WM5110_FORMATS,
                },
                .capture = {
                         .stream_name = "AIF2 Capture",
                         .channels_min = 1,
-                        .channels_max = 2,
+                        .channels_max = 6,
                         .rates = WM5110_RATES,
                         .formats = WM5110_FORMATS,
                 },
@@ -1229,6 +1532,10 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
        arizona_init_spk(codec);
        arizona_init_gpio(codec);
 
+       ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 8);
+       if (ret != 0)
+               return ret;
+
        snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
 
        priv->core.arizona->dapm = &codec->dapm;
@@ -1283,7 +1590,7 @@ static int wm5110_probe(struct platform_device *pdev)
 {
        struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
        struct wm5110_priv *wm5110;
-       int i;
+       int i, ret;
 
        wm5110 = devm_kzalloc(&pdev->dev, sizeof(struct wm5110_priv),
                              GFP_KERNEL);
@@ -1294,6 +1601,24 @@ static int wm5110_probe(struct platform_device *pdev)
        wm5110->core.arizona = arizona;
        wm5110->core.num_inputs = 8;
 
+       for (i = 0; i < WM5110_NUM_ADSP; i++) {
+               wm5110->core.adsp[i].part = "wm5110";
+               wm5110->core.adsp[i].num = i + 1;
+               wm5110->core.adsp[i].type = WMFW_ADSP2;
+               wm5110->core.adsp[i].dev = arizona->dev;
+               wm5110->core.adsp[i].regmap = arizona->regmap;
+
+               wm5110->core.adsp[i].base = ARIZONA_DSP1_CONTROL_1
+                       + (0x100 * i);
+               wm5110->core.adsp[i].mem = wm5110_dsp_regions[i];
+               wm5110->core.adsp[i].num_mems
+                       = ARRAY_SIZE(wm5110_dsp1_regions);
+
+               ret = wm_adsp2_init(&wm5110->core.adsp[i], false);
+               if (ret != 0)
+                       return ret;
+       }
+
        for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++)
                wm5110->fll[i].vco_mult = 3;
 
@@ -1304,6 +1629,12 @@ static int wm5110_probe(struct platform_device *pdev)
                         ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
                         &wm5110->fll[1]);
 
+       /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */
+       regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2,
+                          ARIZONA_SAMPLE_RATE_2_MASK, 0x11);
+       regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3,
+                          ARIZONA_SAMPLE_RATE_3_MASK, 0x12);
+
        for (i = 0; i < ARRAY_SIZE(wm5110_dai); i++)
                arizona_init_dai(&wm5110->core, i);
 
index 6ed5433943eaae4716f54a75f7b4cf4d9fd83fc2..7df7d45727559e98501eef2500b3cc610ee8a4b0 100644 (file)
@@ -684,7 +684,7 @@ static struct spi_driver wm8510_spi_driver = {
 };
 #endif /* CONFIG_SPI_MASTER */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8510_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -735,7 +735,7 @@ static struct i2c_driver wm8510_i2c_driver = {
 static int __init wm8510_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8510_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register WM8510 I2C driver: %d\n",
@@ -755,7 +755,7 @@ module_init(wm8510_modinit);
 
 static void __exit wm8510_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8510_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 139bf9ac94078152470fc639816a328eac8dbfa6..74d106dc76676d5481ae367ad2c5115e8d7df32a 100644 (file)
@@ -452,7 +452,7 @@ static const struct regmap_config wm8523_regmap = {
        .volatile_reg = wm8523_volatile_register,
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8523_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -555,7 +555,7 @@ static struct i2c_driver wm8523_i2c_driver = {
 static int __init wm8523_modinit(void)
 {
        int ret;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8523_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register WM8523 I2C driver: %d\n",
@@ -568,7 +568,7 @@ module_init(wm8523_modinit);
 
 static void __exit wm8523_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8523_i2c_driver);
 #endif
 }
index 08a414b57b1ea8179819adc03dd300233f24d72e..318989acbbe5fbb97878856ccab46330422f6bdf 100644 (file)
@@ -941,7 +941,7 @@ static const struct regmap_config wm8580_regmap = {
        .volatile_reg = wm8580_volatile,
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8580_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -1003,7 +1003,7 @@ static int __init wm8580_modinit(void)
 {
        int ret = 0;
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8580_i2c_driver);
        if (ret != 0) {
                pr_err("Failed to register WM8580 I2C driver: %d\n", ret);
@@ -1016,7 +1016,7 @@ module_init(wm8580_modinit);
 
 static void __exit wm8580_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8580_i2c_driver);
 #endif
 }
index 5b428b060d418da78286a605060c4cb4c019801b..d99f948c513cd80bf56f96f6657ce20224f2fb0d 100644 (file)
@@ -469,7 +469,7 @@ static struct spi_driver wm8711_spi_driver = {
 };
 #endif /* CONFIG_SPI_MASTER */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8711_i2c_probe(struct i2c_client *client,
                            const struct i2c_device_id *id)
 {
@@ -520,7 +520,7 @@ static struct i2c_driver wm8711_i2c_driver = {
 static int __init wm8711_modinit(void)
 {
        int ret;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8711_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register WM8711 I2C driver: %d\n",
@@ -540,7 +540,7 @@ module_init(wm8711_modinit);
 
 static void __exit wm8711_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8711_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index c6a292dcded0c11eda10c5dfa8fd70e2be84ec0c..cd89033e84c08a1d290cb012cee545273b35badd 100644 (file)
@@ -320,7 +320,7 @@ static struct spi_driver wm8728_spi_driver = {
 };
 #endif /* CONFIG_SPI_MASTER */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8728_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -371,7 +371,7 @@ static struct i2c_driver wm8728_i2c_driver = {
 static int __init wm8728_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8728_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register wm8728 I2C driver: %d\n",
@@ -391,7 +391,7 @@ module_init(wm8728_modinit);
 
 static void __exit wm8728_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8728_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 456bb8c6d759176a3bf31c5f7003a6e8cfc2d799..6117107ea56029f3760ee6c76d177f4ef70c730c 100644 (file)
@@ -732,7 +732,7 @@ static struct spi_driver wm8731_spi_driver = {
 };
 #endif /* CONFIG_SPI_MASTER */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8731_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -791,7 +791,7 @@ static struct i2c_driver wm8731_i2c_driver = {
 static int __init wm8731_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8731_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n",
@@ -811,7 +811,7 @@ module_init(wm8731_modinit);
 
 static void __exit wm8731_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8731_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index b18813cc7ba9f06c87b399834abbceac5d3b9f49..2895c8d3b5e4cce600114dcab949f28b82cf2c7e 100644 (file)
@@ -500,7 +500,7 @@ static const struct regmap_config wm8741_regmap = {
        .readable_reg = wm8741_readable,
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8741_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -617,7 +617,7 @@ static int __init wm8741_modinit(void)
 {
        int ret = 0;
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8741_i2c_driver);
        if (ret != 0)
                pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
@@ -639,7 +639,7 @@ static void __exit wm8741_exit(void)
 #if defined(CONFIG_SPI_MASTER)
        spi_unregister_driver(&wm8741_spi_driver);
 #endif
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8741_i2c_driver);
 #endif
 }
index 50d5ff616232676bb094054d44a0c1076ddba0ab..78616a638a55ad4a76f11559f08c6dc4bdb708f6 100644 (file)
@@ -816,7 +816,7 @@ static struct spi_driver wm8750_spi_driver = {
 };
 #endif /* CONFIG_SPI_MASTER */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8750_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -868,7 +868,7 @@ static struct i2c_driver wm8750_i2c_driver = {
 static int __init wm8750_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8750_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n",
@@ -888,7 +888,7 @@ module_init(wm8750_modinit);
 
 static void __exit wm8750_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8750_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index d96ebf52d953e850016184f4615f2faf979a738d..be85da93a2682fb89c7c668042f772fc08ca7452 100644 (file)
@@ -1596,7 +1596,7 @@ static struct spi_driver wm8753_spi_driver = {
 };
 #endif /* CONFIG_SPI_MASTER */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8753_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -1653,7 +1653,7 @@ static struct i2c_driver wm8753_i2c_driver = {
 static int __init wm8753_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8753_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n",
@@ -1673,7 +1673,7 @@ module_init(wm8753_modinit);
 
 static void __exit wm8753_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8753_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 942d58e455f384f9b8c5cdc83363c861ff5366b5..ef824672523206a1a3f5d593647a20ae5487b941 100644 (file)
@@ -532,7 +532,7 @@ static struct spi_driver wm8776_spi_driver = {
 };
 #endif /* CONFIG_SPI_MASTER */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8776_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -584,7 +584,7 @@ static struct i2c_driver wm8776_i2c_driver = {
 static int __init wm8776_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8776_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register wm8776 I2C driver: %d\n",
@@ -604,7 +604,7 @@ module_init(wm8776_modinit);
 
 static void __exit wm8776_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8776_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 1704b1e119cb021db8fced2be8482c5da40810d9..9bc8206a68071267cbb18856dc5c9722930af147 100644 (file)
@@ -739,7 +739,7 @@ static struct spi_driver wm8804_spi_driver = {
 };
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8804_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -791,7 +791,7 @@ static int __init wm8804_modinit(void)
 {
        int ret = 0;
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8804_i2c_driver);
        if (ret) {
                printk(KERN_ERR "Failed to register wm8804 I2C driver: %d\n",
@@ -811,7 +811,7 @@ module_init(wm8804_modinit);
 
 static void __exit wm8804_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8804_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 734209e252c3c7cc049b9f982de6539154aa67ab..e98bc7038a086b39231ecbb5196fb7a40fc92d1e 100644 (file)
@@ -1288,7 +1288,7 @@ static struct spi_driver wm8900_spi_driver = {
 };
 #endif /* CONFIG_SPI_MASTER */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8900_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -1338,7 +1338,7 @@ static struct i2c_driver wm8900_i2c_driver = {
 static int __init wm8900_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8900_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register wm8900 I2C driver: %d\n",
@@ -1358,7 +1358,7 @@ module_init(wm8900_modinit);
 
 static void __exit wm8900_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8900_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index b1591c61c254ebc1f12d0a19e682e45df632ed77..b404c26c1753407c849c61fdc5ac2db5254deaf0 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/spi/spi.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 
 struct wm8940_priv {
        unsigned int sysclk;
-       enum snd_soc_control_type control_type;
+       struct regmap *regmap;
 };
 
-static int wm8940_volatile_register(struct snd_soc_codec *codec,
-                                   unsigned int reg)
+static bool wm8940_volatile_register(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case WM8940_SOFTRESET:
-               return 1;
+               return true;
        default:
-               return 0;
+               return false;
+       }
+}
+
+static bool wm8940_readable_register(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case WM8940_SOFTRESET:
+       case WM8940_POWER1:
+       case WM8940_POWER2:
+       case WM8940_POWER3:
+       case WM8940_IFACE:
+       case WM8940_COMPANDINGCTL:
+       case WM8940_CLOCK:
+       case WM8940_ADDCNTRL:
+       case WM8940_GPIO:
+       case WM8940_CTLINT:
+       case WM8940_DAC:
+       case WM8940_DACVOL:
+       case WM8940_ADC:
+       case WM8940_ADCVOL:
+       case WM8940_NOTCH1:
+       case WM8940_NOTCH2:
+       case WM8940_NOTCH3:
+       case WM8940_NOTCH4:
+       case WM8940_NOTCH5:
+       case WM8940_NOTCH6:
+       case WM8940_NOTCH7:
+       case WM8940_NOTCH8:
+       case WM8940_DACLIM1:
+       case WM8940_DACLIM2:
+       case WM8940_ALC1:
+       case WM8940_ALC2:
+       case WM8940_ALC3:
+       case WM8940_NOISEGATE:
+       case WM8940_PLLN:
+       case WM8940_PLLK1:
+       case WM8940_PLLK2:
+       case WM8940_PLLK3:
+       case WM8940_ALC4:
+       case WM8940_INPUTCTL:
+       case WM8940_PGAGAIN:
+       case WM8940_ADCBOOST:
+       case WM8940_OUTPUTCTL:
+       case WM8940_SPKMIX:
+       case WM8940_SPKVOL:
+       case WM8940_MONOMIX:
+               return true;
+       default:
+               return false;
        }
 }
 
-static u16 wm8940_reg_defaults[] = {
-       0x8940, /* Soft Reset */
-       0x0000, /* Power 1 */
-       0x0000, /* Power 2 */
-       0x0000, /* Power 3 */
-       0x0010, /* Interface Control */
-       0x0000, /* Companding Control */
-       0x0140, /* Clock Control */
-       0x0000, /* Additional Controls */
-       0x0000, /* GPIO Control */
-       0x0002, /* Auto Increment Control */
-       0x0000, /* DAC Control */
-       0x00FF, /* DAC Volume */
-       0,
-       0,
-       0x0100, /* ADC Control */
-       0x00FF, /* ADC Volume */
-       0x0000, /* Notch Filter 1 Control 1 */
-       0x0000, /* Notch Filter 1 Control 2 */
-       0x0000, /* Notch Filter 2 Control 1 */
-       0x0000, /* Notch Filter 2 Control 2 */
-       0x0000, /* Notch Filter 3 Control 1 */
-       0x0000, /* Notch Filter 3 Control 2 */
-       0x0000, /* Notch Filter 4 Control 1 */
-       0x0000, /* Notch Filter 4 Control 2 */
-       0x0032, /* DAC Limit Control 1 */
-       0x0000, /* DAC Limit Control 2 */
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0x0038, /* ALC Control 1 */
-       0x000B, /* ALC Control 2 */
-       0x0032, /* ALC Control 3 */
-       0x0000, /* Noise Gate */
-       0x0041, /* PLLN */
-       0x000C, /* PLLK1 */
-       0x0093, /* PLLK2 */
-       0x00E9, /* PLLK3 */
-       0,
-       0,
-       0x0030, /* ALC Control 4 */
-       0,
-       0x0002, /* Input Control */
-       0x0050, /* PGA Gain */
-       0,
-       0x0002, /* ADC Boost Control */
-       0,
-       0x0002, /* Output Control */
-       0x0000, /* Speaker Mixer Control */
-       0,
-       0,
-       0,
-       0x0079, /* Speaker Volume */
-       0,
-       0x0000, /* Mono Mixer Control */
+static const struct reg_default wm8940_reg_defaults[] = {
+       {  0x1, 0x0000 }, /* Power 1 */
+       {  0x2, 0x0000 }, /* Power 2 */
+       {  0x3, 0x0000 }, /* Power 3 */
+       {  0x4, 0x0010 }, /* Interface Control */
+       {  0x5, 0x0000 }, /* Companding Control */
+       {  0x6, 0x0140 }, /* Clock Control */
+       {  0x7, 0x0000 }, /* Additional Controls */
+       {  0x8, 0x0000 }, /* GPIO Control */
+       {  0x9, 0x0002 }, /* Auto Increment Control */
+       {  0xa, 0x0000 }, /* DAC Control */
+       {  0xb, 0x00FF }, /* DAC Volume */
+
+       {  0xe, 0x0100 }, /* ADC Control */
+       {  0xf, 0x00FF }, /* ADC Volume */
+       { 0x10, 0x0000 }, /* Notch Filter 1 Control 1 */
+       { 0x11, 0x0000 }, /* Notch Filter 1 Control 2 */
+       { 0x12, 0x0000 }, /* Notch Filter 2 Control 1 */
+       { 0x13, 0x0000 }, /* Notch Filter 2 Control 2 */
+       { 0x14, 0x0000 }, /* Notch Filter 3 Control 1 */
+       { 0x15, 0x0000 }, /* Notch Filter 3 Control 2 */
+       { 0x16, 0x0000 }, /* Notch Filter 4 Control 1 */
+       { 0x17, 0x0000 }, /* Notch Filter 4 Control 2 */
+       { 0x18, 0x0032 }, /* DAC Limit Control 1 */
+       { 0x19, 0x0000 }, /* DAC Limit Control 2 */
+
+       { 0x20, 0x0038 }, /* ALC Control 1 */
+       { 0x21, 0x000B }, /* ALC Control 2 */
+       { 0x22, 0x0032 }, /* ALC Control 3 */
+       { 0x23, 0x0000 }, /* Noise Gate */
+       { 0x24, 0x0041 }, /* PLLN */
+       { 0x25, 0x000C }, /* PLLK1 */
+       { 0x26, 0x0093 }, /* PLLK2 */
+       { 0x27, 0x00E9 }, /* PLLK3 */
+
+       { 0x2a, 0x0030 }, /* ALC Control 4 */
+
+       { 0x2c, 0x0002 }, /* Input Control */
+       { 0x2d, 0x0050 }, /* PGA Gain */
+
+       { 0x2f, 0x0002 }, /* ADC Boost Control */
+
+       { 0x31, 0x0002 }, /* Output Control */
+       { 0x32, 0x0000 }, /* Speaker Mixer Control */
+
+       { 0x36, 0x0079 }, /* Speaker Volume */
+
+       { 0x38, 0x0000 }, /* Mono Mixer Control */
 };
 
 static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" };
@@ -264,7 +302,7 @@ static const struct snd_soc_dapm_widget wm8940_dapm_widgets[] = {
        SND_SOC_DAPM_INPUT("AUX"),
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8940_dapm_routes[] = {
        /* Mono output mixer */
        {"Mono Mixer", "PCM Playback Switch", "DAC"},
        {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
@@ -296,21 +334,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
        {"ADC", NULL, "Boost Mixer"},
 };
 
-static int wm8940_add_widgets(struct snd_soc_codec *codec)
-{
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-       int ret;
-
-       ret = snd_soc_dapm_new_controls(dapm, wm8940_dapm_widgets,
-                                       ARRAY_SIZE(wm8940_dapm_widgets));
-       if (ret)
-               goto error_ret;
-       ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
-error_ret:
-       return ret;
-}
-
 #define wm8940_reset(c) snd_soc_write(c, WM8940_SOFTRESET, 0);
 
 static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
@@ -446,6 +469,7 @@ static int wm8940_mute(struct snd_soc_dai *dai, int mute)
 static int wm8940_set_bias_level(struct snd_soc_codec *codec,
                                 enum snd_soc_bias_level level)
 {
+       struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
        u16 val;
        u16 pwr_reg = snd_soc_read(codec, WM8940_POWER1) & 0x1F0;
        int ret = 0;
@@ -469,7 +493,7 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
                break;
        case SND_SOC_BIAS_STANDBY:
                if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-                       ret = snd_soc_cache_sync(codec);
+                       ret = regcache_sync(wm8940->regmap);
                        if (ret < 0) {
                                dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
                                return ret;
@@ -684,12 +708,11 @@ static int wm8940_resume(struct snd_soc_codec *codec)
 
 static int wm8940_probe(struct snd_soc_codec *codec)
 {
-       struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
        struct wm8940_setup_data *pdata = codec->dev->platform_data;
        int ret;
        u16 reg;
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type);
+       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
                return ret;
@@ -716,11 +739,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
                        return ret;
        }
 
-       ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls,
-                            ARRAY_SIZE(wm8940_snd_controls));
-       if (ret)
-               return ret;
-       ret = wm8940_add_widgets(codec);
        return ret;
 }
 
@@ -736,10 +754,24 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
        .suspend =      wm8940_suspend,
        .resume =       wm8940_resume,
        .set_bias_level = wm8940_set_bias_level,
-       .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults),
-       .reg_word_size = sizeof(u16),
-       .reg_cache_default = wm8940_reg_defaults,
-       .volatile_register = wm8940_volatile_register,
+       .controls =     wm8940_snd_controls,
+       .num_controls = ARRAY_SIZE(wm8940_snd_controls),
+       .dapm_widgets = wm8940_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets),
+       .dapm_routes =  wm8940_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(wm8940_dapm_routes),
+};
+
+static const struct regmap_config wm8940_regmap = {
+       .reg_bits = 8,
+       .val_bits = 16,
+
+       .max_register = WM8940_MONOMIX,
+       .reg_defaults = wm8940_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(wm8940_reg_defaults),
+
+       .readable_reg = wm8940_readable_register,
+       .volatile_reg = wm8940_volatile_register,
 };
 
 static int wm8940_i2c_probe(struct i2c_client *i2c,
@@ -753,8 +785,11 @@ static int wm8940_i2c_probe(struct i2c_client *i2c,
        if (wm8940 == NULL)
                return -ENOMEM;
 
+       wm8940->regmap = devm_regmap_init_i2c(i2c, &wm8940_regmap);
+       if (IS_ERR(wm8940->regmap))
+               return PTR_ERR(wm8940->regmap);
+
        i2c_set_clientdata(i2c, wm8940);
-       wm8940->control_type = SND_SOC_I2C;
 
        ret = snd_soc_register_codec(&i2c->dev,
                        &soc_codec_dev_wm8940, &wm8940_dai, 1);
index 543c5c2631b61827bcebca8af1926ea02b5655e9..07da601f834326b094dd2dedbef829b2f5ad7584 100644 (file)
@@ -74,7 +74,7 @@ struct wm8962_priv {
        struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES];
        struct notifier_block disable_nb[WM8962_NUM_SUPPLIES];
 
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#if IS_ENABLED(CONFIG_INPUT)
        struct input_dev *beep;
        struct work_struct beep_work;
        int beep_rate;
@@ -3108,7 +3108,7 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 }
 EXPORT_SYMBOL_GPL(wm8962_mic_detect);
 
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#if IS_ENABLED(CONFIG_INPUT)
 static int beep_rates[] = {
        500, 1000, 2000, 4000,
 };
index a2d01d10a5dd8866747b335a027ed3049c9c71d3..15f45c7bd8334971bb63235ade92a26cb82c2f57 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 
 #include "wm8974.h"
 
-static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
-       0x0000, 0x0000, 0x0000, 0x0000,
-       0x0050, 0x0000, 0x0140, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x00ff,
-       0x0000, 0x0000, 0x0100, 0x00ff,
-       0x0000, 0x0000, 0x012c, 0x002c,
-       0x002c, 0x002c, 0x002c, 0x0000,
-       0x0032, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000,
-       0x0038, 0x000b, 0x0032, 0x0000,
-       0x0008, 0x000c, 0x0093, 0x00e9,
-       0x0000, 0x0000, 0x0000, 0x0000,
-       0x0003, 0x0010, 0x0000, 0x0000,
-       0x0000, 0x0002, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0039, 0x0000,
-       0x0000,
+static const struct reg_default wm8974_reg_defaults[] = {
+       {  0, 0x0000 }, {  1, 0x0000 }, {  2, 0x0000 }, {  3, 0x0000 },
+       {  4, 0x0050 }, {  5, 0x0000 }, {  6, 0x0140 }, {  7, 0x0000 },
+       {  8, 0x0000 }, {  9, 0x0000 }, { 10, 0x0000 }, { 11, 0x00ff },
+       { 12, 0x0000 }, { 13, 0x0000 }, { 14, 0x0100 }, { 15, 0x00ff },
+       { 16, 0x0000 }, { 17, 0x0000 }, { 18, 0x012c }, { 19, 0x002c },
+       { 20, 0x002c }, { 21, 0x002c }, { 22, 0x002c }, { 23, 0x0000 },
+       { 24, 0x0032 }, { 25, 0x0000 }, { 26, 0x0000 }, { 27, 0x0000 },
+       { 28, 0x0000 }, { 29, 0x0000 }, { 30, 0x0000 }, { 31, 0x0000 },
+       { 32, 0x0038 }, { 33, 0x000b }, { 34, 0x0032 }, { 35, 0x0000 },
+       { 36, 0x0008 }, { 37, 0x000c }, { 38, 0x0093 }, { 39, 0x00e9 },
+       { 40, 0x0000 }, { 41, 0x0000 }, { 42, 0x0000 }, { 43, 0x0000 },
+       { 44, 0x0003 }, { 45, 0x0010 }, { 46, 0x0000 }, { 47, 0x0000 },
+       { 48, 0x0000 }, { 49, 0x0002 }, { 50, 0x0000 }, { 51, 0x0000 },
+       { 52, 0x0000 }, { 53, 0x0000 }, { 54, 0x0039 }, { 55, 0x0000 },
+       { 56, 0x0000 },
 };
 
 #define WM8974_POWER1_BIASEN  0x08
@@ -514,7 +515,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
                power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
 
                if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-                       snd_soc_cache_sync(codec);
+                       regcache_sync(dev_get_regmap(codec->dev, NULL));
 
                        /* Initial cap charge at VMID 5k */
                        snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
@@ -579,11 +580,20 @@ static int wm8974_resume(struct snd_soc_codec *codec)
        return 0;
 }
 
+static const struct regmap_config wm8974_regmap = {
+       .reg_bits = 7,
+       .val_bits = 9,
+
+       .max_register = WM8974_MONOMIX,
+       .reg_defaults = wm8974_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(wm8974_reg_defaults),
+};
+
 static int wm8974_probe(struct snd_soc_codec *codec)
 {
        int ret = 0;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
+       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
                return ret;
@@ -613,9 +623,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
        .suspend =      wm8974_suspend,
        .resume =       wm8974_resume,
        .set_bias_level = wm8974_set_bias_level,
-       .reg_cache_size = ARRAY_SIZE(wm8974_reg),
-       .reg_word_size = sizeof(u16),
-       .reg_cache_default = wm8974_reg,
 
        .controls = wm8974_snd_controls,
        .num_controls = ARRAY_SIZE(wm8974_snd_controls),
@@ -628,8 +635,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
 static int wm8974_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
+       struct regmap *regmap;
        int ret;
 
+       regmap = devm_regmap_init_i2c(i2c, &wm8974_regmap);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
        ret = snd_soc_register_codec(&i2c->dev,
                        &soc_codec_dev_wm8974, &wm8974_dai, 1);
 
index 18f2babe1090bf0ee061cf169c5f0f8e867dafd3..271b517911a4bc0d4d6003356afcf7a1cc317bed 100644 (file)
@@ -1148,7 +1148,7 @@ static struct spi_driver wm8985_spi_driver = {
 };
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8985_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -1201,7 +1201,7 @@ static int __init wm8985_modinit(void)
 {
        int ret = 0;
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8985_i2c_driver);
        if (ret) {
                printk(KERN_ERR "Failed to register wm8985 I2C driver: %d\n",
@@ -1221,7 +1221,7 @@ module_init(wm8985_modinit);
 
 static void __exit wm8985_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8985_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 39b9acceb595185d60821270073d9e5895305baa..a55e1c2c382edde43985e2213f0502564bf8e17b 100644 (file)
@@ -912,7 +912,7 @@ static struct spi_driver wm8988_spi_driver = {
 };
 #endif /* CONFIG_SPI_MASTER */
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8988_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -964,7 +964,7 @@ static struct i2c_driver wm8988_i2c_driver = {
 static int __init wm8988_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8988_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register WM8988 I2C driver: %d\n",
@@ -984,7 +984,7 @@ module_init(wm8988_modinit);
 
 static void __exit wm8988_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8988_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 253c88bb7a4cbdb06d3d1df2862f10e80095aaa8..0ccd4d8d043bbcf0d0f689bc947c93545d88b16b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 
 /* codec private data */
 struct wm8990_priv {
-       enum snd_soc_control_type control_type;
+       struct regmap *regmap;
        unsigned int sysclk;
        unsigned int pcmclk;
 };
 
-static int wm8990_volatile_register(struct snd_soc_codec *codec,
-                                   unsigned int reg)
+static bool wm8990_volatile_register(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case WM8990_RESET:
@@ -46,71 +46,69 @@ static int wm8990_volatile_register(struct snd_soc_codec *codec,
        }
 }
 
-static const u16 wm8990_reg[] = {
-       0x8990,     /* R0  - Reset */
-       0x0000,     /* R1  - Power Management (1) */
-       0x6000,     /* R2  - Power Management (2) */
-       0x0000,     /* R3  - Power Management (3) */
-       0x4050,     /* R4  - Audio Interface (1) */
-       0x4000,     /* R5  - Audio Interface (2) */
-       0x01C8,     /* R6  - Clocking (1) */
-       0x0000,     /* R7  - Clocking (2) */
-       0x0040,     /* R8  - Audio Interface (3) */
-       0x0040,     /* R9  - Audio Interface (4) */
-       0x0004,     /* R10 - DAC CTRL */
-       0x00C0,     /* R11 - Left DAC Digital Volume */
-       0x00C0,     /* R12 - Right DAC Digital Volume */
-       0x0000,     /* R13 - Digital Side Tone */
-       0x0100,     /* R14 - ADC CTRL */
-       0x00C0,     /* R15 - Left ADC Digital Volume */
-       0x00C0,     /* R16 - Right ADC Digital Volume */
-       0x0000,     /* R17 */
-       0x0000,     /* R18 - GPIO CTRL 1 */
-       0x1000,     /* R19 - GPIO1 & GPIO2 */
-       0x1010,     /* R20 - GPIO3 & GPIO4 */
-       0x1010,     /* R21 - GPIO5 & GPIO6 */
-       0x8000,     /* R22 - GPIOCTRL 2 */
-       0x0800,     /* R23 - GPIO_POL */
-       0x008B,     /* R24 - Left Line Input 1&2 Volume */
-       0x008B,     /* R25 - Left Line Input 3&4 Volume */
-       0x008B,     /* R26 - Right Line Input 1&2 Volume */
-       0x008B,     /* R27 - Right Line Input 3&4 Volume */
-       0x0000,     /* R28 - Left Output Volume */
-       0x0000,     /* R29 - Right Output Volume */
-       0x0066,     /* R30 - Line Outputs Volume */
-       0x0022,     /* R31 - Out3/4 Volume */
-       0x0079,     /* R32 - Left OPGA Volume */
-       0x0079,     /* R33 - Right OPGA Volume */
-       0x0003,     /* R34 - Speaker Volume */
-       0x0003,     /* R35 - ClassD1 */
-       0x0000,     /* R36 */
-       0x0100,     /* R37 - ClassD3 */
-       0x0079,     /* R38 - ClassD4 */
-       0x0000,     /* R39 - Input Mixer1 */
-       0x0000,     /* R40 - Input Mixer2 */
-       0x0000,     /* R41 - Input Mixer3 */
-       0x0000,     /* R42 - Input Mixer4 */
-       0x0000,     /* R43 - Input Mixer5 */
-       0x0000,     /* R44 - Input Mixer6 */
-       0x0000,     /* R45 - Output Mixer1 */
-       0x0000,     /* R46 - Output Mixer2 */
-       0x0000,     /* R47 - Output Mixer3 */
-       0x0000,     /* R48 - Output Mixer4 */
-       0x0000,     /* R49 - Output Mixer5 */
-       0x0000,     /* R50 - Output Mixer6 */
-       0x0180,     /* R51 - Out3/4 Mixer */
-       0x0000,     /* R52 - Line Mixer1 */
-       0x0000,     /* R53 - Line Mixer2 */
-       0x0000,     /* R54 - Speaker Mixer */
-       0x0000,     /* R55 - Additional Control */
-       0x0000,     /* R56 - AntiPOP1 */
-       0x0000,     /* R57 - AntiPOP2 */
-       0x0000,     /* R58 - MICBIAS */
-       0x0000,     /* R59 */
-       0x0008,     /* R60 - PLL1 */
-       0x0031,     /* R61 - PLL2 */
-       0x0026,     /* R62 - PLL3 */
-       0x0000,     /* R63 - Driver internal */
+static const struct reg_default wm8990_reg_defaults[] = {
+       {  1, 0x0000 },     /* R1  - Power Management (1) */
+       {  2, 0x6000 },     /* R2  - Power Management (2) */
+       {  3, 0x0000 },     /* R3  - Power Management (3) */
+       {  4, 0x4050 },     /* R4  - Audio Interface (1) */
+       {  5, 0x4000 },     /* R5  - Audio Interface (2) */
+       {  6, 0x01C8 },     /* R6  - Clocking (1) */
+       {  7, 0x0000 },     /* R7  - Clocking (2) */
+       {  8, 0x0040 },     /* R8  - Audio Interface (3) */
+       {  9, 0x0040 },     /* R9  - Audio Interface (4) */
+       { 10, 0x0004 },     /* R10 - DAC CTRL */
+       { 11, 0x00C0 },     /* R11 - Left DAC Digital Volume */
+       { 12, 0x00C0 },     /* R12 - Right DAC Digital Volume */
+       { 13, 0x0000 },     /* R13 - Digital Side Tone */
+       { 14, 0x0100 },     /* R14 - ADC CTRL */
+       { 15, 0x00C0 },     /* R15 - Left ADC Digital Volume */
+       { 16, 0x00C0 },     /* R16 - Right ADC Digital Volume */
+
+       { 18, 0x0000 },     /* R18 - GPIO CTRL 1 */
+       { 19, 0x1000 },     /* R19 - GPIO1 & GPIO2 */
+       { 20, 0x1010 },     /* R20 - GPIO3 & GPIO4 */
+       { 21, 0x1010 },     /* R21 - GPIO5 & GPIO6 */
+       { 22, 0x8000 },     /* R22 - GPIOCTRL 2 */
+       { 23, 0x0800 },     /* R23 - GPIO_POL */
+       { 24, 0x008B },     /* R24 - Left Line Input 1&2 Volume */
+       { 25, 0x008B },     /* R25 - Left Line Input 3&4 Volume */
+       { 26, 0x008B },     /* R26 - Right Line Input 1&2 Volume */
+       { 27, 0x008B },     /* R27 - Right Line Input 3&4 Volume */
+       { 28, 0x0000 },     /* R28 - Left Output Volume */
+       { 29, 0x0000 },     /* R29 - Right Output Volume */
+       { 30, 0x0066 },     /* R30 - Line Outputs Volume */
+       { 31, 0x0022 },     /* R31 - Out3/4 Volume */
+       { 32, 0x0079 },     /* R32 - Left OPGA Volume */
+       { 33, 0x0079 },     /* R33 - Right OPGA Volume */
+       { 34, 0x0003 },     /* R34 - Speaker Volume */
+       { 35, 0x0003 },     /* R35 - ClassD1 */
+
+       { 37, 0x0100 },     /* R37 - ClassD3 */
+       { 38, 0x0079 },     /* R38 - ClassD4 */
+       { 39, 0x0000 },     /* R39 - Input Mixer1 */
+       { 40, 0x0000 },     /* R40 - Input Mixer2 */
+       { 41, 0x0000 },     /* R41 - Input Mixer3 */
+       { 42, 0x0000 },     /* R42 - Input Mixer4 */
+       { 43, 0x0000 },     /* R43 - Input Mixer5 */
+       { 44, 0x0000 },     /* R44 - Input Mixer6 */
+       { 45, 0x0000 },     /* R45 - Output Mixer1 */
+       { 46, 0x0000 },     /* R46 - Output Mixer2 */
+       { 47, 0x0000 },     /* R47 - Output Mixer3 */
+       { 48, 0x0000 },     /* R48 - Output Mixer4 */
+       { 49, 0x0000 },     /* R49 - Output Mixer5 */
+       { 50, 0x0000 },     /* R50 - Output Mixer6 */
+       { 51, 0x0180 },     /* R51 - Out3/4 Mixer */
+       { 52, 0x0000 },     /* R52 - Line Mixer1 */
+       { 53, 0x0000 },     /* R53 - Line Mixer2 */
+       { 54, 0x0000 },     /* R54 - Speaker Mixer */
+       { 55, 0x0000 },     /* R55 - Additional Control */
+       { 56, 0x0000 },     /* R56 - AntiPOP1 */
+       { 57, 0x0000 },     /* R57 - AntiPOP2 */
+       { 58, 0x0000 },     /* R58 - MICBIAS */
+
+       { 60, 0x0008 },     /* R60 - PLL1 */
+       { 61, 0x0031 },     /* R61 - PLL2 */
+       { 62, 0x0026 },     /* R62 - PLL3 */
 };
 
 #define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0)
@@ -376,32 +374,6 @@ SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
  * _DAPM_ Controls
  */
 
-static int inmixer_event(struct snd_soc_dapm_widget *w,
-       struct snd_kcontrol *kcontrol, int event)
-{
-       u16 reg, fakepower;
-
-       reg = snd_soc_read(w->codec, WM8990_POWER_MANAGEMENT_2);
-       fakepower = snd_soc_read(w->codec, WM8990_INTDRIVBITS);
-
-       if (fakepower & ((1 << WM8990_INMIXL_PWR_BIT) |
-               (1 << WM8990_AINLMUX_PWR_BIT))) {
-               reg |= WM8990_AINL_ENA;
-       } else {
-               reg &= ~WM8990_AINL_ENA;
-       }
-
-       if (fakepower & ((1 << WM8990_INMIXR_PWR_BIT) |
-               (1 << WM8990_AINRMUX_PWR_BIT))) {
-               reg |= WM8990_AINR_ENA;
-       } else {
-               reg &= ~WM8990_AINR_ENA;
-       }
-       snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg);
-
-       return 0;
-}
-
 static int outmixer_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
@@ -656,6 +628,11 @@ SND_SOC_DAPM_INPUT("RIN1"),
 SND_SOC_DAPM_INPUT("RIN2"),
 SND_SOC_DAPM_INPUT("Internal ADC Source"),
 
+SND_SOC_DAPM_SUPPLY("INL", WM8990_POWER_MANAGEMENT_2, WM8990_AINL_ENA_BIT, 0,
+                   NULL, 0),
+SND_SOC_DAPM_SUPPLY("INR", WM8990_POWER_MANAGEMENT_2, WM8990_AINR_ENA_BIT, 0,
+                   NULL, 0),
+
 /* DACs */
 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8990_POWER_MANAGEMENT_2,
        WM8990_ADCL_ENA_BIT, 0),
@@ -677,26 +654,20 @@ SND_SOC_DAPM_MIXER("RIN34 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_RIN34_ENA_BIT,
        ARRAY_SIZE(wm8990_dapm_rin34_pga_controls)),
 
 /* INMIXL */
-SND_SOC_DAPM_MIXER_E("INMIXL", WM8990_INTDRIVBITS, WM8990_INMIXL_PWR_BIT, 0,
+SND_SOC_DAPM_MIXER("INMIXL", SND_SOC_NOPM, 0, 0,
        &wm8990_dapm_inmixl_controls[0],
-       ARRAY_SIZE(wm8990_dapm_inmixl_controls),
-       inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+       ARRAY_SIZE(wm8990_dapm_inmixl_controls)),
 
 /* AINLMUX */
-SND_SOC_DAPM_MUX_E("AINLMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0,
-       &wm8990_dapm_ainlmux_controls, inmixer_event,
-       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_MUX("AINLMUX", SND_SOC_NOPM, 0, 0, &wm8990_dapm_ainlmux_controls),
 
 /* INMIXR */
-SND_SOC_DAPM_MIXER_E("INMIXR", WM8990_INTDRIVBITS, WM8990_INMIXR_PWR_BIT, 0,
+SND_SOC_DAPM_MIXER("INMIXR", SND_SOC_NOPM, 0, 0,
        &wm8990_dapm_inmixr_controls[0],
-       ARRAY_SIZE(wm8990_dapm_inmixr_controls),
-       inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+       ARRAY_SIZE(wm8990_dapm_inmixr_controls)),
 
 /* AINRMUX */
-SND_SOC_DAPM_MUX_E("AINRMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0,
-       &wm8990_dapm_ainrmux_controls, inmixer_event,
-       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_MUX("AINRMUX", SND_SOC_NOPM, 0, 0, &wm8990_dapm_ainrmux_controls),
 
 /* Output Side */
 /* DACs */
@@ -787,7 +758,7 @@ SND_SOC_DAPM_OUTPUT("RON"),
 SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8990_dapm_routes[] = {
        /* Make DACs turn on when playing even if not mixed into any outputs */
        {"Internal DAC Sink", NULL, "Left DAC"},
        {"Internal DAC Sink", NULL, "Right DAC"},
@@ -796,6 +767,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
        {"Left ADC", NULL, "Internal ADC Source"},
        {"Right ADC", NULL, "Internal ADC Source"},
 
+       {"AINLMUX", NULL, "INL"},
+       {"INMIXL", NULL, "INL"},
+       {"AINRMUX", NULL, "INR"},
+       {"INMIXR", NULL, "INR"},
+
        /* Input Side */
        /* LIN12 PGA */
        {"LIN12 PGA", "LIN1 Switch", "LIN1"},
@@ -912,18 +888,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
        {"RON", NULL, "RONMIX"},
 };
 
-static int wm8990_add_widgets(struct snd_soc_codec *codec)
-{
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-       snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets,
-                                 ARRAY_SIZE(wm8990_dapm_widgets));
-       /* set up the WM8990 audio map */
-       snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
-       return 0;
-}
-
 /* PLL divisors */
 struct _pll_div {
        u32 div2;
@@ -1148,6 +1112,7 @@ static int wm8990_mute(struct snd_soc_dai *dai, int mute)
 static int wm8990_set_bias_level(struct snd_soc_codec *codec,
        enum snd_soc_bias_level level)
 {
+       struct wm8990_priv *wm8990 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
        switch (level) {
@@ -1162,7 +1127,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_STANDBY:
                if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-                       ret = snd_soc_cache_sync(codec);
+                       ret = regcache_sync(wm8990->regmap);
                        if (ret < 0) {
                                dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
                                return ret;
@@ -1259,6 +1224,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
 
                /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
                snd_soc_write(codec, WM8990_ANTIPOP2, 0x0);
+
+               regcache_mark_dirty(wm8990->regmap);
                break;
        }
 
@@ -1327,7 +1294,7 @@ static int wm8990_probe(struct snd_soc_codec *codec)
 {
        int ret;
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
        if (ret < 0) {
                printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
                return ret;
@@ -1350,10 +1317,6 @@ static int wm8990_probe(struct snd_soc_codec *codec)
        snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
        snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
 
-       snd_soc_add_codec_controls(codec, wm8990_snd_controls,
-                               ARRAY_SIZE(wm8990_snd_controls));
-       wm8990_add_widgets(codec);
-
        return 0;
 }
 
@@ -1370,13 +1333,25 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
        .suspend =      wm8990_suspend,
        .resume =       wm8990_resume,
        .set_bias_level = wm8990_set_bias_level,
-       .reg_cache_size = ARRAY_SIZE(wm8990_reg),
-       .reg_word_size = sizeof(u16),
-       .reg_cache_default = wm8990_reg,
-       .volatile_register = wm8990_volatile_register,
+       .controls =     wm8990_snd_controls,
+       .num_controls = ARRAY_SIZE(wm8990_snd_controls),
+       .dapm_widgets = wm8990_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(wm8990_dapm_widgets),
+       .dapm_routes =  wm8990_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(wm8990_dapm_routes),
+};
+
+static const struct regmap_config wm8990_regmap = {
+       .reg_bits = 8,
+       .val_bits = 16,
+
+       .max_register = WM8990_PLL3,
+       .volatile_reg = wm8990_volatile_register,
+       .reg_defaults = wm8990_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(wm8990_reg_defaults),
+       .cache_type = REGCACHE_RBTREE,
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static int wm8990_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -1418,29 +1393,8 @@ static struct i2c_driver wm8990_i2c_driver = {
        .remove =   wm8990_i2c_remove,
        .id_table = wm8990_i2c_id,
 };
-#endif
 
-static int __init wm8990_modinit(void)
-{
-       int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-       ret = i2c_add_driver(&wm8990_i2c_driver);
-       if (ret != 0) {
-               printk(KERN_ERR "Failed to register wm8990 I2C driver: %d\n",
-                      ret);
-       }
-#endif
-       return ret;
-}
-module_init(wm8990_modinit);
-
-static void __exit wm8990_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-       i2c_del_driver(&wm8990_i2c_driver);
-#endif
-}
-module_exit(wm8990_exit);
+module_i2c_driver(wm8990_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8990 driver");
 MODULE_AUTHOR("Liam Girdwood");
index 77c98a4bfe9cdf34876e30866e73046d50748c85..0e9c78040c4c5cbfd1c7c6d5cc9cf844e5d95333 100644 (file)
@@ -78,7 +78,6 @@
 #define WM8990_PLL1                             0x3C
 #define WM8990_PLL2                             0x3D
 #define WM8990_PLL3                             0x3E
-#define WM8990_INTDRIVBITS                     0x3F
 
 #define WM8990_EXT_ACCESS_ENA                  0x75
 #define WM8990_EXT_CTL1                                0x7a
  */
 #define WM8990_PLLK2_MASK                       0x00FF  /* PLLK2 - [7:0] */
 
-/*
- * R63 (0x3F) - Internal Driver Bits
- */
-#define WM8990_INMIXL_PWR_BIT                  0
-#define WM8990_AINLMUX_PWR_BIT                 1
-#define WM8990_INMIXR_PWR_BIT                  2
-#define WM8990_AINRMUX_PWR_BIT                 3
-
 #define WM8990_MCLK_DIV 0
 #define WM8990_DACCLK_DIV 1
 #define WM8990_ADCCLK_DIV 2
index 3a39df7a38295a36a28d7865405cb7c0096089d1..dba0306c42a5c54aa459cc4fe1593b08c92a5abf 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include "wm8991.h"
 
 struct wm8991_priv {
-       enum snd_soc_control_type control_type;
+       struct regmap *regmap;
        unsigned int pcmclk;
 };
 
-static const u16 wm8991_reg_defs[] = {
-       0x8991,     /* R0  - Reset */
-       0x0000,     /* R1  - Power Management (1) */
-       0x6000,     /* R2  - Power Management (2) */
-       0x0000,     /* R3  - Power Management (3) */
-       0x4050,     /* R4  - Audio Interface (1) */
-       0x4000,     /* R5  - Audio Interface (2) */
-       0x01C8,     /* R6  - Clocking (1) */
-       0x0000,     /* R7  - Clocking (2) */
-       0x0040,     /* R8  - Audio Interface (3) */
-       0x0040,     /* R9  - Audio Interface (4) */
-       0x0004,     /* R10 - DAC CTRL */
-       0x00C0,     /* R11 - Left DAC Digital Volume */
-       0x00C0,     /* R12 - Right DAC Digital Volume */
-       0x0000,     /* R13 - Digital Side Tone */
-       0x0100,     /* R14 - ADC CTRL */
-       0x00C0,     /* R15 - Left ADC Digital Volume */
-       0x00C0,     /* R16 - Right ADC Digital Volume */
-       0x0000,     /* R17 */
-       0x0000,     /* R18 - GPIO CTRL 1 */
-       0x1000,     /* R19 - GPIO1 & GPIO2 */
-       0x1010,     /* R20 - GPIO3 & GPIO4 */
-       0x1010,     /* R21 - GPIO5 & GPIO6 */
-       0x8000,     /* R22 - GPIOCTRL 2 */
-       0x0800,     /* R23 - GPIO_POL */
-       0x008B,     /* R24 - Left Line Input 1&2 Volume */
-       0x008B,     /* R25 - Left Line Input 3&4 Volume */
-       0x008B,     /* R26 - Right Line Input 1&2 Volume */
-       0x008B,     /* R27 - Right Line Input 3&4 Volume */
-       0x0000,     /* R28 - Left Output Volume */
-       0x0000,     /* R29 - Right Output Volume */
-       0x0066,     /* R30 - Line Outputs Volume */
-       0x0022,     /* R31 - Out3/4 Volume */
-       0x0079,     /* R32 - Left OPGA Volume */
-       0x0079,     /* R33 - Right OPGA Volume */
-       0x0003,     /* R34 - Speaker Volume */
-       0x0003,     /* R35 - ClassD1 */
-       0x0000,     /* R36 */
-       0x0100,     /* R37 - ClassD3 */
-       0x0000,     /* R38 */
-       0x0000,     /* R39 - Input Mixer1 */
-       0x0000,     /* R40 - Input Mixer2 */
-       0x0000,     /* R41 - Input Mixer3 */
-       0x0000,     /* R42 - Input Mixer4 */
-       0x0000,     /* R43 - Input Mixer5 */
-       0x0000,     /* R44 - Input Mixer6 */
-       0x0000,     /* R45 - Output Mixer1 */
-       0x0000,     /* R46 - Output Mixer2 */
-       0x0000,     /* R47 - Output Mixer3 */
-       0x0000,     /* R48 - Output Mixer4 */
-       0x0000,     /* R49 - Output Mixer5 */
-       0x0000,     /* R50 - Output Mixer6 */
-       0x0180,     /* R51 - Out3/4 Mixer */
-       0x0000,     /* R52 - Line Mixer1 */
-       0x0000,     /* R53 - Line Mixer2 */
-       0x0000,     /* R54 - Speaker Mixer */
-       0x0000,     /* R55 - Additional Control */
-       0x0000,     /* R56 - AntiPOP1 */
-       0x0000,     /* R57 - AntiPOP2 */
-       0x0000,     /* R58 - MICBIAS */
-       0x0000,     /* R59 */
-       0x0008,     /* R60 - PLL1 */
-       0x0031,     /* R61 - PLL2 */
-       0x0026,     /* R62 - PLL3 */
+static const struct reg_default wm8991_reg_defaults[] = {
+       {  1, 0x0000 },     /* R1  - Power Management (1) */
+       {  2, 0x6000 },     /* R2  - Power Management (2) */
+       {  3, 0x0000 },     /* R3  - Power Management (3) */
+       {  4, 0x4050 },     /* R4  - Audio Interface (1) */
+       {  5, 0x4000 },     /* R5  - Audio Interface (2) */
+       {  6, 0x01C8 },     /* R6  - Clocking (1) */
+       {  7, 0x0000 },     /* R7  - Clocking (2) */
+       {  8, 0x0040 },     /* R8  - Audio Interface (3) */
+       {  9, 0x0040 },     /* R9  - Audio Interface (4) */
+       { 10, 0x0004 },     /* R10 - DAC CTRL */
+       { 11, 0x00C0 },     /* R11 - Left DAC Digital Volume */
+       { 12, 0x00C0 },     /* R12 - Right DAC Digital Volume */
+       { 13, 0x0000 },     /* R13 - Digital Side Tone */
+       { 14, 0x0100 },     /* R14 - ADC CTRL */
+       { 15, 0x00C0 },     /* R15 - Left ADC Digital Volume */
+       { 16, 0x00C0 },     /* R16 - Right ADC Digital Volume */
+
+       { 18, 0x0000 },     /* R18 - GPIO CTRL 1 */
+       { 19, 0x1000 },     /* R19 - GPIO1 & GPIO2 */
+       { 20, 0x1010 },     /* R20 - GPIO3 & GPIO4 */
+       { 21, 0x1010 },     /* R21 - GPIO5 & GPIO6 */
+       { 22, 0x8000 },     /* R22 - GPIOCTRL 2 */
+       { 23, 0x0800 },     /* R23 - GPIO_POL */
+       { 24, 0x008B },     /* R24 - Left Line Input 1&2 Volume */
+       { 25, 0x008B },     /* R25 - Left Line Input 3&4 Volume */
+       { 26, 0x008B },     /* R26 - Right Line Input 1&2 Volume */
+       { 27, 0x008B },     /* R27 - Right Line Input 3&4 Volume */
+       { 28, 0x0000 },     /* R28 - Left Output Volume */
+       { 29, 0x0000 },     /* R29 - Right Output Volume */
+       { 30, 0x0066 },     /* R30 - Line Outputs Volume */
+       { 31, 0x0022 },     /* R31 - Out3/4 Volume */
+       { 32, 0x0079 },     /* R32 - Left OPGA Volume */
+       { 33, 0x0079 },     /* R33 - Right OPGA Volume */
+       { 34, 0x0003 },     /* R34 - Speaker Volume */
+       { 35, 0x0003 },     /* R35 - ClassD1 */
+
+       { 37, 0x0100 },     /* R37 - ClassD3 */
+
+       { 39, 0x0000 },     /* R39 - Input Mixer1 */
+       { 40, 0x0000 },     /* R40 - Input Mixer2 */
+       { 41, 0x0000 },     /* R41 - Input Mixer3 */
+       { 42, 0x0000 },     /* R42 - Input Mixer4 */
+       { 43, 0x0000 },     /* R43 - Input Mixer5 */
+       { 44, 0x0000 },     /* R44 - Input Mixer6 */
+       { 45, 0x0000 },     /* R45 - Output Mixer1 */
+       { 46, 0x0000 },     /* R46 - Output Mixer2 */
+       { 47, 0x0000 },     /* R47 - Output Mixer3 */
+       { 48, 0x0000 },     /* R48 - Output Mixer4 */
+       { 49, 0x0000 },     /* R49 - Output Mixer5 */
+       { 50, 0x0000 },     /* R50 - Output Mixer6 */
+       { 51, 0x0180 },     /* R51 - Out3/4 Mixer */
+       { 52, 0x0000 },     /* R52 - Line Mixer1 */
+       { 53, 0x0000 },     /* R53 - Line Mixer2 */
+       { 54, 0x0000 },     /* R54 - Speaker Mixer */
+       { 55, 0x0000 },     /* R55 - Additional Control */
+       { 56, 0x0000 },     /* R56 - AntiPOP1 */
+       { 57, 0x0000 },     /* R57 - AntiPOP2 */
+       { 58, 0x0000 },     /* R58 - MICBIAS */
+
+       { 60, 0x0008 },     /* R60 - PLL1 */
+       { 61, 0x0031 },     /* R61 - PLL2 */
+       { 62, 0x0026 },     /* R62 - PLL3 */
 };
 
-#define wm8991_reset(c) snd_soc_write(c, WM8991_RESET, 0)
+static bool wm8991_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case WM8991_RESET:
+               return true;
+       default:
+               return false;
+       }
+}
 
 static const unsigned int rec_mix_tlv[] = {
        TLV_DB_RANGE_HEAD(1),
@@ -374,30 +382,6 @@ static const struct snd_kcontrol_new wm8991_snd_controls[] = {
 /*
  * _DAPM_ Controls
  */
-static int inmixer_event(struct snd_soc_dapm_widget *w,
-                        struct snd_kcontrol *kcontrol, int event)
-{
-       u16 reg, fakepower;
-
-       reg = snd_soc_read(w->codec, WM8991_POWER_MANAGEMENT_2);
-       fakepower = snd_soc_read(w->codec, WM8991_INTDRIVBITS);
-
-       if (fakepower & ((1 << WM8991_INMIXL_PWR_BIT) |
-                        (1 << WM8991_AINLMUX_PWR_BIT)))
-               reg |= WM8991_AINL_ENA;
-       else
-               reg &= ~WM8991_AINL_ENA;
-
-       if (fakepower & ((1 << WM8991_INMIXR_PWR_BIT) |
-                        (1 << WM8991_AINRMUX_PWR_BIT)))
-               reg |= WM8991_AINR_ENA;
-       else
-               reg &= ~WM8991_AINR_ENA;
-
-       snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg);
-       return 0;
-}
-
 static int outmixer_event(struct snd_soc_dapm_widget *w,
                          struct snd_kcontrol *kcontrol, int event)
 {
@@ -655,6 +639,11 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
        SND_SOC_DAPM_INPUT("RIN2"),
        SND_SOC_DAPM_INPUT("Internal ADC Source"),
 
+       SND_SOC_DAPM_SUPPLY("INL", WM8991_POWER_MANAGEMENT_2,
+                           WM8991_AINL_ENA_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("INR", WM8991_POWER_MANAGEMENT_2,
+                           WM8991_AINR_ENA_BIT, 0, NULL, 0),
+
        /* DACs */
        SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8991_POWER_MANAGEMENT_2,
                WM8991_ADCL_ENA_BIT, 0),
@@ -676,26 +665,22 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
                ARRAY_SIZE(wm8991_dapm_rin34_pga_controls)),
 
        /* INMIXL */
-       SND_SOC_DAPM_MIXER_E("INMIXL", WM8991_INTDRIVBITS, WM8991_INMIXL_PWR_BIT, 0,
+       SND_SOC_DAPM_MIXER("INMIXL", SND_SOC_NOPM, 0, 0,
                &wm8991_dapm_inmixl_controls[0],
-               ARRAY_SIZE(wm8991_dapm_inmixl_controls),
-               inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+               ARRAY_SIZE(wm8991_dapm_inmixl_controls)),
 
        /* AINLMUX */
-       SND_SOC_DAPM_MUX_E("AINLMUX", WM8991_INTDRIVBITS, WM8991_AINLMUX_PWR_BIT, 0,
-               &wm8991_dapm_ainlmux_controls, inmixer_event,
-               SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_MUX("AINLMUX", SND_SOC_NOPM, 0, 0,
+               &wm8991_dapm_ainlmux_controls),
 
        /* INMIXR */
-       SND_SOC_DAPM_MIXER_E("INMIXR", WM8991_INTDRIVBITS, WM8991_INMIXR_PWR_BIT, 0,
+       SND_SOC_DAPM_MIXER("INMIXR", SND_SOC_NOPM, 0, 0,
                &wm8991_dapm_inmixr_controls[0],
-               ARRAY_SIZE(wm8991_dapm_inmixr_controls),
-               inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+               ARRAY_SIZE(wm8991_dapm_inmixr_controls)),
 
        /* AINRMUX */
-       SND_SOC_DAPM_MUX_E("AINRMUX", WM8991_INTDRIVBITS, WM8991_AINRMUX_PWR_BIT, 0,
-               &wm8991_dapm_ainrmux_controls, inmixer_event,
-               SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_MUX("AINRMUX", SND_SOC_NOPM, 0, 0,
+               &wm8991_dapm_ainrmux_controls),
 
        /* Output Side */
        /* DACs */
@@ -787,7 +772,7 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
        SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8991_dapm_routes[] = {
        /* Make DACs turn on when playing even if not mixed into any outputs */
        {"Internal DAC Sink", NULL, "Left DAC"},
        {"Internal DAC Sink", NULL, "Right DAC"},
@@ -797,6 +782,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
        {"Right ADC", NULL, "Internal ADC Source"},
 
        /* Input Side */
+       {"INMIXL", NULL, "INL"},
+       {"AINLMUX", NULL, "INL"},
+       {"INMIXR", NULL, "INR"},
+       {"AINRMUX", NULL, "INR"},
        /* LIN12 PGA */
        {"LIN12 PGA", "LIN1 Switch", "LIN1"},
        {"LIN12 PGA", "LIN2 Switch", "LIN2"},
@@ -1129,6 +1118,7 @@ static int wm8991_mute(struct snd_soc_dai *dai, int mute)
 static int wm8991_set_bias_level(struct snd_soc_codec *codec,
                                 enum snd_soc_bias_level level)
 {
+       struct wm8991_priv *wm8991 = snd_soc_codec_get_drvdata(codec);
        u16 val;
 
        switch (level) {
@@ -1144,7 +1134,7 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_STANDBY:
                if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-                       snd_soc_cache_sync(codec);
+                       regcache_sync(wm8991->regmap);
                        /* Enable all output discharge bits */
                        snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
                                      WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
@@ -1232,7 +1222,7 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec,
 
                /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
                snd_soc_write(codec, WM8991_ANTIPOP2, 0x0);
-               codec->cache_sync = 1;
+               regcache_mark_dirty(wm8991->regmap);
                break;
        }
 
@@ -1266,44 +1256,14 @@ static int wm8991_probe(struct snd_soc_codec *codec)
 
        wm8991 = snd_soc_codec_get_drvdata(codec);
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8991->control_type);
+       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
                return ret;
        }
 
-       ret = wm8991_reset(codec);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset\n");
-               return ret;
-       }
-
        wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-       snd_soc_update_bits(codec, WM8991_AUDIO_INTERFACE_4,
-                           WM8991_ALRCGPIO1, WM8991_ALRCGPIO1);
-
-       snd_soc_update_bits(codec, WM8991_GPIO1_GPIO2,
-                           WM8991_GPIO1_SEL_MASK, 1);
-
-       snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_1,
-                           WM8991_VREF_ENA | WM8991_VMID_MODE_MASK,
-                           WM8991_VREF_ENA | WM8991_VMID_MODE_MASK);
-
-       snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_2,
-                           WM8991_OPCLK_ENA, WM8991_OPCLK_ENA);
-
-       snd_soc_write(codec, WM8991_DAC_CTRL, 0);
-       snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
-       snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
-
-       snd_soc_add_codec_controls(codec, wm8991_snd_controls,
-                            ARRAY_SIZE(wm8991_snd_controls));
-
-       snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets,
-                                 ARRAY_SIZE(wm8991_dapm_widgets));
-       snd_soc_dapm_add_routes(&codec->dapm, audio_map,
-                               ARRAY_SIZE(audio_map));
        return 0;
 }
 
@@ -1352,24 +1312,77 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
        .suspend = wm8991_suspend,
        .resume = wm8991_resume,
        .set_bias_level = wm8991_set_bias_level,
-       .reg_cache_size = WM8991_MAX_REGISTER + 1,
-       .reg_word_size = sizeof(u16),
-       .reg_cache_default = wm8991_reg_defs
+       .controls = wm8991_snd_controls,
+       .num_controls = ARRAY_SIZE(wm8991_snd_controls),
+       .dapm_widgets = wm8991_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets),
+       .dapm_routes = wm8991_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes),
+};
+
+static const struct regmap_config wm8991_regmap = {
+       .reg_bits = 8,
+       .val_bits = 16,
+
+       .max_register = WM8991_PLL3,
+       .volatile_reg = wm8991_volatile,
+       .reg_defaults = wm8991_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(wm8991_reg_defaults),
+       .cache_type = REGCACHE_RBTREE,
 };
 
 static int wm8991_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct wm8991_priv *wm8991;
+       unsigned int val;
        int ret;
 
        wm8991 = devm_kzalloc(&i2c->dev, sizeof(*wm8991), GFP_KERNEL);
        if (!wm8991)
                return -ENOMEM;
 
-       wm8991->control_type = SND_SOC_I2C;
+       wm8991->regmap = devm_regmap_init_i2c(i2c, &wm8991_regmap);
+       if (IS_ERR(wm8991->regmap))
+               return PTR_ERR(wm8991->regmap);
+
        i2c_set_clientdata(i2c, wm8991);
 
+       ret = regmap_read(wm8991->regmap, WM8991_RESET, &val);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to read device ID: %d\n", ret);
+               return ret;
+       }
+       if (val != 0x8991) {
+               dev_err(&i2c->dev, "Device with ID %x is not a WM8991\n", val);
+               return -EINVAL;
+       }
+
+       ret = regmap_write(wm8991->regmap, WM8991_RESET, 0);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
+               return ret;
+       }
+
+       regmap_update_bits(wm8991->regmap, WM8991_AUDIO_INTERFACE_4,
+                          WM8991_ALRCGPIO1, WM8991_ALRCGPIO1);
+
+       regmap_update_bits(wm8991->regmap, WM8991_GPIO1_GPIO2,
+                          WM8991_GPIO1_SEL_MASK, 1);
+
+       regmap_update_bits(wm8991->regmap, WM8991_POWER_MANAGEMENT_1,
+                          WM8991_VREF_ENA | WM8991_VMID_MODE_MASK,
+                          WM8991_VREF_ENA | WM8991_VMID_MODE_MASK);
+
+       regmap_update_bits(wm8991->regmap, WM8991_POWER_MANAGEMENT_2,
+                          WM8991_OPCLK_ENA, WM8991_OPCLK_ENA);
+
+       regmap_write(wm8991->regmap, WM8991_DAC_CTRL, 0);
+       regmap_write(wm8991->regmap, WM8991_LEFT_OUTPUT_VOLUME,
+                    0x50 | (1<<8));
+       regmap_write(wm8991->regmap, WM8991_RIGHT_OUTPUT_VOLUME,
+                    0x50 | (1<<8));
+
        ret = snd_soc_register_codec(&i2c->dev,
                                     &soc_codec_dev_wm8991, &wm8991_dai, 1);
 
index 07707d8d7e20e8ef2625f4986c3b24f70285bc5a..08ed383303c02b94e13d62a4fd4a2aa782bf969a 100644 (file)
@@ -76,7 +76,6 @@
 #define WM8991_PLL1                             0x3C
 #define WM8991_PLL2                             0x3D
 #define WM8991_PLL3                             0x3E
-#define WM8991_INTDRIVBITS                     0x3F
 
 #define WM8991_REGISTER_COUNT                   60
 #define WM8991_MAX_REGISTER                     0x3F
  */
 #define WM8991_PLLK2_MASK                       0x00FF  /* PLLK2 - [7:0] */
 
-/*
- * R63 (0x3F) - Internal Driver Bits
- */
-#define WM8991_INMIXL_PWR_BIT                  0
-#define WM8991_AINLMUX_PWR_BIT                 1
-#define WM8991_INMIXR_PWR_BIT                  2
-#define WM8991_AINRMUX_PWR_BIT                 3
-
 #define WM8991_MCLK_DIV 0
 #define WM8991_DACCLK_DIV 1
 #define WM8991_ADCCLK_DIV 2
index 86426a117b07923dd4f89aa4811cb5d5dc21b907..b9be9cbc460391d4530e970e3c77a0521109c2a2 100644 (file)
@@ -4077,12 +4077,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
        wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT,
                           wm8994_temp_shut, "Thermal shutdown", codec);
 
-       ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
-                                wm_hubs_dcs_done, "DC servo done",
-                                &wm8994->hubs);
-       if (ret == 0)
-               wm8994->hubs.dcs_done_irq = true;
-
        switch (control->type) {
        case WM8994:
                if (wm8994->micdet_irq) {
@@ -4313,6 +4307,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
        }
 
        wm_hubs_add_analogue_routes(codec, 0, 0);
+       ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
+                                wm_hubs_dcs_done, "DC servo done",
+                                &wm8994->hubs);
+       if (ret == 0)
+               wm8994->hubs.dcs_done_irq = true;
        snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
 
        switch (control->type) {
index da2899e6c4018fae6cd0a2411b58027f4048b6e4..4300caff17838b59d195ba629b1e0c94b3eb3574 100644 (file)
@@ -2293,7 +2293,7 @@ static struct spi_driver wm8995_spi_driver = {
 };
 #endif
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm8995_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -2350,7 +2350,7 @@ static int __init wm8995_modinit(void)
 {
        int ret = 0;
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        ret = i2c_add_driver(&wm8995_i2c_driver);
        if (ret) {
                printk(KERN_ERR "Failed to register wm8995 I2C driver: %d\n",
@@ -2371,7 +2371,7 @@ module_init(wm8995_modinit);
 
 static void __exit wm8995_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
        i2c_del_driver(&wm8995_i2c_driver);
 #endif
 #if defined(CONFIG_SPI_MASTER)
index 630b3d776ec27133cd54f2c3dd440ae304c83417..0982c1d38ec458205628b2fdd52ccc87a499db97 100644 (file)
@@ -1326,7 +1326,7 @@ static const struct regmap_config wm9081_regmap = {
        .cache_type = REGCACHE_RBTREE,
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if IS_ENABLED(CONFIG_I2C)
 static int wm9081_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
index 46ec0e9744d4b88b50cc922cfdc65a0b4247e567..b42f9af163c81248fe55c152d46f1a632f5884db 100644 (file)
@@ -1286,6 +1286,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
                                        reg = wm_adsp_region_to_reg(mem,
                                                                    reg);
                                        reg += offset;
+                                       break;
                                }
                        }
 
index 35e277379b86ce80d56737e3e0c05a5b3772fb2c..42c6eaeccfd4883d8bc5066833ed43564a3c98f3 100644 (file)
@@ -143,6 +143,7 @@ struct fsl_ssi_private {
        bool ssi_on_imx;
        bool imx_ac97;
        bool use_dma;
+       bool use_dual_fifo;
        struct clk *clk;
        struct snd_dmaengine_dai_dma_data dma_params_tx;
        struct snd_dmaengine_dai_dma_data dma_params_rx;
@@ -321,6 +322,36 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
        return ret;
 }
 
+static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
+{
+       struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+
+       /*
+        * Setup the clock control register
+        */
+       write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
+                       &ssi->stccr);
+       write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
+                       &ssi->srccr);
+
+       /*
+        * Enable AC97 mode and startup the SSI
+        */
+       write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV,
+                       &ssi->sacnt);
+       write_ssi(0xff, &ssi->saccdis);
+       write_ssi(0x300, &ssi->saccen);
+
+       /*
+        * Enable SSI, Transmit and Receive. AC97 has to communicate with the
+        * codec before a stream is started.
+        */
+       write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN |
+                       CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
+
+       write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
+}
+
 static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
 {
        struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
@@ -387,30 +418,13 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
         * because it is also running without an active substream. Normally SSI
         * is only enabled when there is a substream.
         */
-       if (ssi_private->imx_ac97) {
-               /*
-                * Setup the clock control register
-                */
-               write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
-                               &ssi->stccr);
-               write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
-                               &ssi->srccr);
-
-               /*
-                * Enable AC97 mode and startup the SSI
-                */
-               write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV,
-                               &ssi->sacnt);
-               write_ssi(0xff, &ssi->saccdis);
-               write_ssi(0x300, &ssi->saccen);
-
-               /*
-                * Enable SSI, Transmit and Receive
-                */
-               write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN |
-                               CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
+       if (ssi_private->imx_ac97)
+               fsl_ssi_setup_ac97(ssi_private);
 
-               write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
+       if (ssi_private->use_dual_fifo) {
+               write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1);
+               write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1);
+               write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN);
        }
 
        return 0;
@@ -480,6 +494,15 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
                ssi_private->second_stream = substream;
        }
 
+       /* When using dual fifo mode, it is safer to ensure an even period
+        * size. If appearing to an odd number while DMA always starts its
+        * task from fifo0, fifo1 would be neglected at the end of each
+        * period. But SSI would still access fifo1 with an invalid data.
+        */
+       if (ssi_private->use_dual_fifo)
+               snd_pcm_hw_constraint_step(substream->runtime, 0,
+                               SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
+
        return 0;
 }
 
@@ -947,7 +970,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
                ssi_private->fifo_depth = 8;
 
        if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) {
-               u32 dma_events[2];
+               u32 dma_events[2], dmas[4];
                ssi_private->ssi_on_imx = true;
 
                ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
@@ -1001,6 +1024,15 @@ static int fsl_ssi_probe(struct platform_device *pdev)
                        dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
                imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
                        dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
+               if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4)
+                               && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
+                       ssi_private->use_dual_fifo = true;
+                       /* When using dual fifo mode, we need to keep watermark
+                        * as even numbers due to dma script limitation.
+                        */
+                       ssi_private->dma_params_tx.maxburst &= ~0x1;
+                       ssi_private->dma_params_rx.maxburst &= ~0x1;
+               }
        } else if (ssi_private->use_dma) {
                /* The 'name' should not have any slashes in it. */
                ret = devm_request_irq(&pdev->dev, ssi_private->irq,
index d34d91743e3ffe95f9e4823bafdd33d78875b6c3..0b18f654b41340908d022003485d8a88c5e0c94e 100644 (file)
         SNDRV_PCM_FMTBIT_S24_LE | \
         SNDRV_PCM_FMTBIT_S32_LE)
 
+#define KIRKWOOD_SPDIF_FORMATS \
+       (SNDRV_PCM_FMTBIT_S16_LE | \
+        SNDRV_PCM_FMTBIT_S24_LE)
+
 static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
                unsigned int fmt)
 {
@@ -244,15 +248,15 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
                                   ctl);
        }
 
-       if (dai->id == 0)
-               ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN;      /* i2s */
-       else
-               ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN;        /* spdif */
-
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
                /* configure */
                ctl = priv->ctl_play;
+               if (dai->id == 0)
+                       ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN;      /* i2s */
+               else
+                       ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN;        /* spdif */
+
                value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
                writel(value, priv->io + KIRKWOOD_PLAYCTL);
 
@@ -449,14 +453,14 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai[2] = {
                .channels_max = 2,
                .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
                                SNDRV_PCM_RATE_96000,
-               .formats = KIRKWOOD_I2S_FORMATS,
+               .formats = KIRKWOOD_SPDIF_FORMATS,
        },
        .capture = {
                .channels_min = 1,
                .channels_max = 2,
                .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
                                SNDRV_PCM_RATE_96000,
-               .formats = KIRKWOOD_I2S_FORMATS,
+               .formats = KIRKWOOD_SPDIF_FORMATS,
        },
        .ops = &kirkwood_i2s_dai_ops,
     },
@@ -493,7 +497,7 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
                .rates = SNDRV_PCM_RATE_8000_192000 |
                         SNDRV_PCM_RATE_CONTINUOUS |
                         SNDRV_PCM_RATE_KNOT,
-               .formats = KIRKWOOD_I2S_FORMATS,
+               .formats = KIRKWOOD_SPDIF_FORMATS,
        },
        .capture = {
                .channels_min = 1,
@@ -501,7 +505,7 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
                .rates = SNDRV_PCM_RATE_8000_192000 |
                         SNDRV_PCM_RATE_CONTINUOUS |
                         SNDRV_PCM_RATE_KNOT,
-               .formats = KIRKWOOD_I2S_FORMATS,
+               .formats = KIRKWOOD_SPDIF_FORMATS,
        },
        .ops = &kirkwood_i2s_dai_ops,
     },
index 83433fdea32ad790f839edd357c14824def13c07..86c75384c3c87dd0e4c9109f737122b1888ad295 100644 (file)
@@ -36,10 +36,10 @@ static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
 
        if (mcbsp->pdata->reg_size == 2) {
                ((u16 *)mcbsp->reg_cache)[reg] = (u16)val;
-               __raw_writew((u16)val, addr);
+               writew_relaxed((u16)val, addr);
        } else {
                ((u32 *)mcbsp->reg_cache)[reg] = val;
-               __raw_writel(val, addr);
+               writel_relaxed(val, addr);
        }
 }
 
@@ -48,22 +48,22 @@ static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
        void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
 
        if (mcbsp->pdata->reg_size == 2) {
-               return !from_cache ? __raw_readw(addr) :
+               return !from_cache ? readw_relaxed(addr) :
                                     ((u16 *)mcbsp->reg_cache)[reg];
        } else {
-               return !from_cache ? __raw_readl(addr) :
+               return !from_cache ? readl_relaxed(addr) :
                                     ((u32 *)mcbsp->reg_cache)[reg];
        }
 }
 
 static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
 {
-       __raw_writel(val, mcbsp->st_data->io_base_st + reg);
+       writel_relaxed(val, mcbsp->st_data->io_base_st + reg);
 }
 
 static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
 {
-       return __raw_readl(mcbsp->st_data->io_base_st + reg);
+       return readl_relaxed(mcbsp->st_data->io_base_st + reg);
 }
 
 #define MCBSP_READ(mcbsp, reg) \
index 12e566be3793e61eb4fdd7d9ac47a23d638bc260..1bd531d718f953c3a2cd0e533e0f4340d3713892 100644 (file)
@@ -61,12 +61,12 @@ struct omap_dmic {
 
 static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
 {
-       __raw_writel(val, dmic->io_base + reg);
+       writel_relaxed(val, dmic->io_base + reg);
 }
 
 static inline int omap_dmic_read(struct omap_dmic *dmic, u16 reg)
 {
-       return __raw_readl(dmic->io_base + reg);
+       return readl_relaxed(dmic->io_base + reg);
 }
 
 static inline void omap_dmic_start(struct omap_dmic *dmic)
index cd9ee167959dcc0b34512ffdf32d26208d506c31..2f5b1536477e8895238d21f400f21370a14f3041 100644 (file)
@@ -74,12 +74,12 @@ struct omap_mcpdm {
 
 static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val)
 {
-       __raw_writel(val, mcpdm->io_base + reg);
+       writel_relaxed(val, mcpdm->io_base + reg);
 }
 
 static inline int omap_mcpdm_read(struct omap_mcpdm *mcpdm, u16 reg)
 {
-       return __raw_readl(mcpdm->io_base + reg);
+       return readl_relaxed(mcpdm->io_base + reg);
 }
 
 #ifdef DEBUG
index 14011d90d70af3180f4eeedee2fa254a6d5fde25..ff60e11ecb564674bdffbe8814392fe1b2b01065 100644 (file)
@@ -37,6 +37,7 @@ config SND_SOC_SH4_SIU
 config SND_SOC_RCAR
        tristate "R-Car series SRU/SCU/SSIU/SSI support"
        select SND_SIMPLE_CARD
+       select REGMAP
        help
          This option enables R-Car SUR/SCU/SSIU/SSI sound support
 
index 61212ee97c28269a0cd245e424636c4f38efc4c7..bf066f73ef054e2b7c21c021bb333deb2496daff 100644 (file)
  */
 #include "rsnd.h"
 
-struct rsnd_gen_ops {
-       int (*probe)(struct platform_device *pdev,
-                    struct rcar_snd_info *info,
-                    struct rsnd_priv *priv);
-       void (*remove)(struct platform_device *pdev,
-                     struct rsnd_priv *priv);
-       int (*path_init)(struct rsnd_priv *priv,
-                        struct rsnd_dai *rdai,
-                        struct rsnd_dai_stream *io);
-       int (*path_exit)(struct rsnd_priv *priv,
-                        struct rsnd_dai *rdai,
-                        struct rsnd_dai_stream *io);
-};
-
 struct rsnd_gen {
        void __iomem *base[RSND_BASE_MAX];
 
@@ -86,12 +72,28 @@ static struct regmap_bus rsnd_regmap_bus = {
        .val_format_endian_default      = REGMAP_ENDIAN_NATIVE,
 };
 
+static int rsnd_is_accessible_reg(struct rsnd_priv *priv,
+                                 struct rsnd_gen *gen, enum rsnd_reg reg)
+{
+       if (!gen->regs[reg]) {
+               struct device *dev = rsnd_priv_to_dev(priv);
+
+               dev_err(dev, "unsupported register access %x\n", reg);
+               return 0;
+       }
+
+       return 1;
+}
+
 u32 rsnd_read(struct rsnd_priv *priv,
              struct rsnd_mod *mod, enum rsnd_reg reg)
 {
        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
        u32 val;
 
+       if (!rsnd_is_accessible_reg(priv, gen, reg))
+               return 0;
+
        regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
 
        return val;
@@ -103,6 +105,9 @@ void rsnd_write(struct rsnd_priv *priv,
 {
        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
 
+       if (!rsnd_is_accessible_reg(priv, gen, reg))
+               return;
+
        regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
 }
 
@@ -111,21 +116,48 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
 {
        struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
 
+       if (!rsnd_is_accessible_reg(priv, gen, reg))
+               return;
+
        regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
                                  mask, data);
 }
 
-/*
- *             Gen2
- *             will be filled in the future
- */
+static int rsnd_gen_regmap_init(struct rsnd_priv *priv,
+                               struct rsnd_gen  *gen,
+                               struct reg_field *regf)
+{
+       int i;
+       struct device *dev = rsnd_priv_to_dev(priv);
+       struct regmap_config regc;
 
-/*
- *             Gen1
- */
-static int rsnd_gen1_path_init(struct rsnd_priv *priv,
-                              struct rsnd_dai *rdai,
-                              struct rsnd_dai_stream *io)
+       memset(&regc, 0, sizeof(regc));
+       regc.reg_bits = 32;
+       regc.val_bits = 32;
+
+       gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, &regc);
+       if (IS_ERR(gen->regmap)) {
+               dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap));
+               return PTR_ERR(gen->regmap);
+       }
+
+       for (i = 0; i < RSND_REG_MAX; i++) {
+               gen->regs[i] = NULL;
+               if (!regf[i].reg)
+                       continue;
+
+               gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]);
+               if (IS_ERR(gen->regs[i]))
+                       return PTR_ERR(gen->regs[i]);
+
+       }
+
+       return 0;
+}
+
+int rsnd_gen_path_init(struct rsnd_priv *priv,
+                      struct rsnd_dai *rdai,
+                      struct rsnd_dai_stream *io)
 {
        struct rsnd_mod *mod;
        int ret;
@@ -163,9 +195,9 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv,
        return ret;
 }
 
-static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
-                              struct rsnd_dai *rdai,
-                              struct rsnd_dai_stream *io)
+int rsnd_gen_path_exit(struct rsnd_priv *priv,
+                      struct rsnd_dai *rdai,
+                      struct rsnd_dai_stream *io)
 {
        struct rsnd_mod *mod, *n;
        int ret = 0;
@@ -179,6 +211,94 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
        return ret;
 }
 
+/*
+ *             Gen2
+ */
+
+/* single address mapping */
+#define RSND_GEN2_S_REG(gen, reg, id, offset)                          \
+       RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, 0, 9)
+
+/* multi address mapping */
+#define RSND_GEN2_M_REG(gen, reg, id, offset, _id_offset)              \
+       RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, _id_offset, 9)
+
+static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
+{
+       struct reg_field regf[RSND_REG_MAX] = {
+               RSND_GEN2_S_REG(gen, SSIU,      SSI_MODE0,      0x800),
+               RSND_GEN2_S_REG(gen, SSIU,      SSI_MODE1,      0x804),
+               /* FIXME: it needs SSI_MODE2/3 in the future */
+               RSND_GEN2_M_REG(gen, SSIU,      INT_ENABLE,     0x18,   0x80),
+
+               RSND_GEN2_S_REG(gen, ADG,       BRRA,           0x00),
+               RSND_GEN2_S_REG(gen, ADG,       BRRB,           0x04),
+               RSND_GEN2_S_REG(gen, ADG,       SSICKR,         0x08),
+               RSND_GEN2_S_REG(gen, ADG,       AUDIO_CLK_SEL0, 0x0c),
+               RSND_GEN2_S_REG(gen, ADG,       AUDIO_CLK_SEL1, 0x10),
+               RSND_GEN2_S_REG(gen, ADG,       AUDIO_CLK_SEL2, 0x14),
+
+               RSND_GEN2_M_REG(gen, SSI,       SSICR,          0x00,   0x40),
+               RSND_GEN2_M_REG(gen, SSI,       SSISR,          0x04,   0x40),
+               RSND_GEN2_M_REG(gen, SSI,       SSITDR,         0x08,   0x40),
+               RSND_GEN2_M_REG(gen, SSI,       SSIRDR,         0x0c,   0x40),
+               RSND_GEN2_M_REG(gen, SSI,       SSIWSR,         0x20,   0x40),
+       };
+
+       return rsnd_gen_regmap_init(priv, gen, regf);
+}
+
+static int rsnd_gen2_probe(struct platform_device *pdev,
+                          struct rcar_snd_info *info,
+                          struct rsnd_priv *priv)
+{
+       struct device *dev = rsnd_priv_to_dev(priv);
+       struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+       struct resource *scu_res;
+       struct resource *adg_res;
+       struct resource *ssiu_res;
+       struct resource *ssi_res;
+       int ret;
+
+       /*
+        * map address
+        */
+       scu_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SCU);
+       adg_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_ADG);
+       ssiu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSIU);
+       ssi_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSI);
+
+       gen->base[RSND_GEN2_SCU]  = devm_ioremap_resource(dev, scu_res);
+       gen->base[RSND_GEN2_ADG]  = devm_ioremap_resource(dev, adg_res);
+       gen->base[RSND_GEN2_SSIU] = devm_ioremap_resource(dev, ssiu_res);
+       gen->base[RSND_GEN2_SSI]  = devm_ioremap_resource(dev, ssi_res);
+       if (IS_ERR(gen->base[RSND_GEN2_SCU])  ||
+           IS_ERR(gen->base[RSND_GEN2_ADG])  ||
+           IS_ERR(gen->base[RSND_GEN2_SSIU]) ||
+           IS_ERR(gen->base[RSND_GEN2_SSI]))
+               return -ENODEV;
+
+       ret = rsnd_gen2_regmap_init(priv, gen);
+       if (ret < 0)
+               return ret;
+
+       dev_dbg(dev, "Gen2 device probed\n");
+       dev_dbg(dev, "SRU  : %08x => %p\n", scu_res->start,
+               gen->base[RSND_GEN2_SCU]);
+       dev_dbg(dev, "ADG  : %08x => %p\n", adg_res->start,
+               gen->base[RSND_GEN2_ADG]);
+       dev_dbg(dev, "SSIU : %08x => %p\n", ssiu_res->start,
+               gen->base[RSND_GEN2_SSIU]);
+       dev_dbg(dev, "SSI  : %08x => %p\n", ssi_res->start,
+               gen->base[RSND_GEN2_SSI]);
+
+       return 0;
+}
+
+/*
+ *             Gen1
+ */
+
 /* single address mapping */
 #define RSND_GEN1_S_REG(gen, reg, id, offset)  \
        RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9)
@@ -189,9 +309,6 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
 
 static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
 {
-       int i;
-       struct device *dev = rsnd_priv_to_dev(priv);
-       struct regmap_config regc;
        struct reg_field regf[RSND_REG_MAX] = {
                RSND_GEN1_S_REG(gen, SRU,       SRC_ROUTE_SEL,  0x00),
                RSND_GEN1_S_REG(gen, SRU,       SRC_TMG_SEL0,   0x08),
@@ -208,9 +325,6 @@ static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
                RSND_GEN1_S_REG(gen, ADG,       SSICKR,         0x08),
                RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL0, 0x0c),
                RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL1, 0x10),
-               RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL3, 0x18),
-               RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL4, 0x1c),
-               RSND_GEN1_S_REG(gen, ADG,       AUDIO_CLK_SEL5, 0x20),
 
                RSND_GEN1_M_REG(gen, SSI,       SSICR,          0x00,   0x40),
                RSND_GEN1_M_REG(gen, SSI,       SSISR,          0x04,   0x40),
@@ -219,24 +333,7 @@ static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
                RSND_GEN1_M_REG(gen, SSI,       SSIWSR,         0x20,   0x40),
        };
 
-       memset(&regc, 0, sizeof(regc));
-       regc.reg_bits = 32;
-       regc.val_bits = 32;
-
-       gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, &regc);
-       if (IS_ERR(gen->regmap)) {
-               dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap));
-               return PTR_ERR(gen->regmap);
-       }
-
-       for (i = 0; i < RSND_REG_MAX; i++) {
-               gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]);
-               if (IS_ERR(gen->regs[i]))
-                       return PTR_ERR(gen->regs[i]);
-
-       }
-
-       return 0;
+       return rsnd_gen_regmap_init(priv, gen, regf);
 }
 
 static int rsnd_gen1_probe(struct platform_device *pdev,
@@ -281,45 +378,16 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 
 }
 
-static void rsnd_gen1_remove(struct platform_device *pdev,
-                            struct rsnd_priv *priv)
-{
-}
-
-static struct rsnd_gen_ops rsnd_gen1_ops = {
-       .probe          = rsnd_gen1_probe,
-       .remove         = rsnd_gen1_remove,
-       .path_init      = rsnd_gen1_path_init,
-       .path_exit      = rsnd_gen1_path_exit,
-};
-
 /*
  *             Gen
  */
-int rsnd_gen_path_init(struct rsnd_priv *priv,
-                      struct rsnd_dai *rdai,
-                      struct rsnd_dai_stream *io)
-{
-       struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
-
-       return gen->ops->path_init(priv, rdai, io);
-}
-
-int rsnd_gen_path_exit(struct rsnd_priv *priv,
-                      struct rsnd_dai *rdai,
-                      struct rsnd_dai_stream *io)
-{
-       struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
-
-       return gen->ops->path_exit(priv, rdai, io);
-}
-
 int rsnd_gen_probe(struct platform_device *pdev,
                   struct rcar_snd_info *info,
                   struct rsnd_priv *priv)
 {
        struct device *dev = rsnd_priv_to_dev(priv);
        struct rsnd_gen *gen;
+       int ret;
 
        gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
        if (!gen) {
@@ -327,23 +395,21 @@ int rsnd_gen_probe(struct platform_device *pdev,
                return -ENOMEM;
        }
 
+       priv->gen = gen;
+
+       ret = -ENODEV;
        if (rsnd_is_gen1(priv))
-               gen->ops = &rsnd_gen1_ops;
+               ret = rsnd_gen1_probe(pdev, info, priv);
+       else if (rsnd_is_gen2(priv))
+               ret = rsnd_gen2_probe(pdev, info, priv);
 
-       if (!gen->ops) {
+       if (ret < 0)
                dev_err(dev, "unknown generation R-Car sound device\n");
-               return -ENODEV;
-       }
-
-       priv->gen = gen;
 
-       return gen->ops->probe(pdev, info, priv);
+       return ret;
 }
 
 void rsnd_gen_remove(struct platform_device *pdev,
                     struct rsnd_priv *priv)
 {
-       struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
-
-       gen->ops->remove(pdev, priv);
 }
index 9e463e50e7e62b81fabeaeecf39f50de4206eeaf..bff7b9e5306656a55e6686142f4602be5c859b8a 100644 (file)
@@ -31,7 +31,7 @@
  * see gen1/gen2 for detail
  */
 enum rsnd_reg {
-       /* SRU/SCU */
+       /* SRU/SCU/SSIU */
        RSND_REG_SRC_ROUTE_SEL,
        RSND_REG_SRC_TMG_SEL0,
        RSND_REG_SRC_TMG_SEL1,
@@ -41,6 +41,7 @@ enum rsnd_reg {
        RSND_REG_SSI_MODE1,
        RSND_REG_BUSIF_MODE,
        RSND_REG_BUSIF_ADINR,
+       RSND_REG_INT_ENABLE,
 
        /* ADG */
        RSND_REG_BRRA,
@@ -49,9 +50,6 @@ enum rsnd_reg {
        RSND_REG_AUDIO_CLK_SEL0,
        RSND_REG_AUDIO_CLK_SEL1,
        RSND_REG_AUDIO_CLK_SEL2,
-       RSND_REG_AUDIO_CLK_SEL3,
-       RSND_REG_AUDIO_CLK_SEL4,
-       RSND_REG_AUDIO_CLK_SEL5,
 
        /* SSI */
        RSND_REG_SSICR,
@@ -174,11 +172,11 @@ struct rsnd_dai {
        struct rsnd_dai_stream playback;
        struct rsnd_dai_stream capture;
 
-       int clk_master:1;
-       int bit_clk_inv:1;
-       int frm_clk_inv:1;
-       int sys_delay:1;
-       int data_alignment:1;
+       unsigned int clk_master:1;
+       unsigned int bit_clk_inv:1;
+       unsigned int frm_clk_inv:1;
+       unsigned int sys_delay:1;
+       unsigned int data_alignment:1;
 };
 
 #define rsnd_dai_nr(priv) ((priv)->dai_nr)
index 5ac20cd5e00607efd0b8113fc85aec9ed97f57f4..a821b14ca8daaa4deadd9973b22ba2865dfd37f1 100644 (file)
@@ -457,6 +457,9 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
        /* enable PIO IRQ */
        ssi->cr_etc = UIEN | OIEN | DIEN;
 
+       /* enable PIO interrupt */
+       rsnd_mod_write(&ssi->mod, INT_ENABLE, 0x0f000000);
+
        rsnd_ssi_hw_start(ssi, rdai, io);
 
        dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
index 4e53d87e881d0891a3d8437881d12d41225303cc..a66783e13a9cca182e3077b3e998c804aa40ff1d 100644 (file)
@@ -3212,11 +3212,11 @@ int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
                        break;
                case 2:
                        ((u16 *)(&ucontrol->value.bytes.data))[0]
-                               &= ~params->mask;
+                               &= cpu_to_be16(~params->mask);
                        break;
                case 4:
                        ((u32 *)(&ucontrol->value.bytes.data))[0]
-                               &= ~params->mask;
+                               &= cpu_to_be32(~params->mask);
                        break;
                default:
                        return -EINVAL;
index b1d732255c0275fd06039efe36988b1a8ba3e8d2..999861942d28d4712d2e62657d0778fba3baf30b 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
 
 static void devm_component_release(struct device *dev, void *res)
 {
@@ -84,3 +85,43 @@ int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)
        return ret;
 }
 EXPORT_SYMBOL_GPL(devm_snd_soc_register_card);
+
+#ifdef CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM
+
+static void devm_dmaengine_pcm_release(struct device *dev, void *res)
+{
+       snd_dmaengine_pcm_unregister(*(struct device **)res);
+}
+
+/**
+ * devm_snd_dmaengine_pcm_register - resource managed dmaengine PCM registration
+ * @dev: The parent device for the PCM device
+ * @config: Platform specific PCM configuration
+ * @flags: Platform specific quirks
+ *
+ * Register a dmaengine based PCM device with automatic unregistration when the
+ * device is unregistered.
+ */
+int devm_snd_dmaengine_pcm_register(struct device *dev,
+       const struct snd_dmaengine_pcm_config *config, unsigned int flags)
+{
+       struct device **ptr;
+       int ret;
+
+       ptr = devres_alloc(devm_dmaengine_pcm_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return -ENOMEM;
+
+       ret = snd_dmaengine_pcm_register(dev, config, flags);
+       if (ret == 0) {
+               *ptr = dev;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(devm_snd_dmaengine_pcm_register);
+
+#endif
index 4f11d23f20621971b8806e70618ee8e4e1c3846f..aa886cca3ecf94a8ecf2c360312cd3dc3bcb4184 100644 (file)
@@ -99,14 +99,14 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
        config.val_bits = data_bits;
 
        switch (control) {
-#if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE)
+#if IS_ENABLED(CONFIG_REGMAP_I2C)
        case SND_SOC_I2C:
                codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
                                                      &config);
                break;
 #endif
 
-#if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE)
+#if IS_ENABLED(CONFIG_REGMAP_SPI)
        case SND_SOC_SPI:
                codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
                                                      &config);
index 42782c01e41320e924efb4b93c839802f0df5722..22af038dabcdf538b314d3f83469f64a11e6cb3b 100644 (file)
@@ -84,30 +84,97 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        int ret;
 
-       if (!soc_dai->driver->symmetric_rates &&
-           !rtd->dai_link->symmetric_rates)
-               return 0;
+       if (soc_dai->rate && (soc_dai->driver->symmetric_rates ||
+                               rtd->dai_link->symmetric_rates)) {
+               dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n",
+                               soc_dai->rate);
+
+               ret = snd_pcm_hw_constraint_minmax(substream->runtime,
+                                               SNDRV_PCM_HW_PARAM_RATE,
+                                               soc_dai->rate, soc_dai->rate);
+               if (ret < 0) {
+                       dev_err(soc_dai->dev,
+                               "ASoC: Unable to apply rate constraint: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
 
-       /* This can happen if multiple streams are starting simultaneously -
-        * the second can need to get its constraints before the first has
-        * picked a rate.  Complain and allow the application to carry on.
-        */
-       if (!soc_dai->rate) {
-               dev_warn(soc_dai->dev,
-                        "ASoC: Not enforcing symmetric_rates due to race\n");
-               return 0;
+       if (soc_dai->channels && (soc_dai->driver->symmetric_channels ||
+                               rtd->dai_link->symmetric_channels)) {
+               dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n",
+                               soc_dai->channels);
+
+               ret = snd_pcm_hw_constraint_minmax(substream->runtime,
+                                               SNDRV_PCM_HW_PARAM_CHANNELS,
+                                               soc_dai->channels,
+                                               soc_dai->channels);
+               if (ret < 0) {
+                       dev_err(soc_dai->dev,
+                               "ASoC: Unable to apply channel symmetry constraint: %d\n",
+                               ret);
+                       return ret;
+               }
        }
 
-       dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", soc_dai->rate);
+       if (soc_dai->sample_bits && (soc_dai->driver->symmetric_samplebits ||
+                               rtd->dai_link->symmetric_samplebits)) {
+               dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n",
+                               soc_dai->sample_bits);
 
-       ret = snd_pcm_hw_constraint_minmax(substream->runtime,
-                                          SNDRV_PCM_HW_PARAM_RATE,
-                                          soc_dai->rate, soc_dai->rate);
-       if (ret < 0) {
-               dev_err(soc_dai->dev,
-                       "ASoC: Unable to apply rate symmetry constraint: %d\n",
-                       ret);
-               return ret;
+               ret = snd_pcm_hw_constraint_minmax(substream->runtime,
+                                               SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+                                               soc_dai->sample_bits,
+                                               soc_dai->sample_bits);
+               if (ret < 0) {
+                       dev_err(soc_dai->dev,
+                               "ASoC: Unable to apply sample bits symmetry constraint: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       unsigned int rate, channels, sample_bits, symmetry;
+
+       rate = params_rate(params);
+       channels = params_channels(params);
+       sample_bits = snd_pcm_format_physical_width(params_format(params));
+
+       /* reject unmatched parameters when applying symmetry */
+       symmetry = cpu_dai->driver->symmetric_rates ||
+               codec_dai->driver->symmetric_rates ||
+               rtd->dai_link->symmetric_rates;
+       if (symmetry && cpu_dai->rate && cpu_dai->rate != rate) {
+               dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n",
+                               cpu_dai->rate, rate);
+               return -EINVAL;
+       }
+
+       symmetry = cpu_dai->driver->symmetric_channels ||
+               codec_dai->driver->symmetric_channels ||
+               rtd->dai_link->symmetric_channels;
+       if (symmetry && cpu_dai->channels && cpu_dai->channels != channels) {
+               dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n",
+                               cpu_dai->channels, channels);
+               return -EINVAL;
+       }
+
+       symmetry = cpu_dai->driver->symmetric_samplebits ||
+               codec_dai->driver->symmetric_samplebits ||
+               rtd->dai_link->symmetric_samplebits;
+       if (symmetry && cpu_dai->sample_bits && cpu_dai->sample_bits != sample_bits) {
+               dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n",
+                               cpu_dai->sample_bits, sample_bits);
+               return -EINVAL;
        }
 
        return 0;
@@ -148,12 +215,12 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
        }
 }
 
-static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw,
+static void soc_pcm_init_runtime_hw(struct snd_pcm_runtime *runtime,
        struct snd_soc_pcm_stream *codec_stream,
        struct snd_soc_pcm_stream *cpu_stream)
 {
-       hw->rate_min = max(codec_stream->rate_min, cpu_stream->rate_min);
-       hw->rate_max = max(codec_stream->rate_max, cpu_stream->rate_max);
+       struct snd_pcm_hardware *hw = &runtime->hw;
+
        hw->channels_min = max(codec_stream->channels_min,
                cpu_stream->channels_min);
        hw->channels_max = min(codec_stream->channels_max,
@@ -166,6 +233,13 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw,
        if (cpu_stream->rates
                & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
                hw->rates |= codec_stream->rates;
+
+       snd_pcm_limit_hw_rates(runtime);
+
+       hw->rate_min = max(hw->rate_min, cpu_stream->rate_min);
+       hw->rate_min = max(hw->rate_min, codec_stream->rate_min);
+       hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max);
+       hw->rate_max = min_not_zero(hw->rate_max, codec_stream->rate_max);
 }
 
 /*
@@ -235,15 +309,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 
        /* Check that the codec and cpu DAIs are compatible */
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->playback,
+               soc_pcm_init_runtime_hw(runtime, &codec_dai_drv->playback,
                        &cpu_dai_drv->playback);
        } else {
-               soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->capture,
+               soc_pcm_init_runtime_hw(runtime, &codec_dai_drv->capture,
                        &cpu_dai_drv->capture);
        }
 
        ret = -EINVAL;
-       snd_pcm_limit_hw_rates(runtime);
        if (!runtime->hw.rates) {
                printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n",
                        codec_dai->name, cpu_dai->name);
@@ -383,13 +456,6 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
        codec_dai->active--;
        codec->active--;
 
-       /* clear the corresponding DAIs rate when inactive */
-       if (!cpu_dai->active)
-               cpu_dai->rate = 0;
-
-       if (!codec_dai->active)
-               codec_dai->rate = 0;
-
        /* Muting the DAC suppresses artifacts caused during digital
         * shutdown, for example from stopping clocks.
         */
@@ -525,6 +591,10 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 
        mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
+       ret = soc_pcm_params_symmetry(substream, params);
+       if (ret)
+               goto out;
+
        if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
                ret = rtd->dai_link->ops->hw_params(substream, params);
                if (ret < 0) {
@@ -561,9 +631,16 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
                }
        }
 
-       /* store the rate for each DAIs */
+       /* store the parameters for each DAIs */
        cpu_dai->rate = params_rate(params);
+       cpu_dai->channels = params_channels(params);
+       cpu_dai->sample_bits =
+               snd_pcm_format_physical_width(params_format(params));
+
        codec_dai->rate = params_rate(params);
+       codec_dai->channels = params_channels(params);
+       codec_dai->sample_bits =
+               snd_pcm_format_physical_width(params_format(params));
 
 out:
        mutex_unlock(&rtd->pcm_mutex);
@@ -598,6 +675,19 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
 
        mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
+       /* clear the corresponding DAIs parameters when going to be inactive */
+       if (cpu_dai->active == 1) {
+               cpu_dai->rate = 0;
+               cpu_dai->channels = 0;
+               cpu_dai->sample_bits = 0;
+       }
+
+       if (codec_dai->active == 1) {
+               codec_dai->rate = 0;
+               codec_dai->channels = 0;
+               codec_dai->sample_bits = 0;
+       }
+
        /* apply codec digital mute */
        if (!codec->active)
                snd_soc_dai_digital_mute(codec_dai, 1, substream->stream);
index 4707f2b862c3762502d622d1d799944ee0e401fc..9a02141666ea9b75bb94817b9e25a97e344f96a1 100644 (file)
@@ -49,18 +49,12 @@ static const struct snd_dmaengine_pcm_config spear_dmaengine_pcm_config = {
 
 static int spear_soc_platform_probe(struct platform_device *pdev)
 {
-       return snd_dmaengine_pcm_register(&pdev->dev,
+       return devm_snd_dmaengine_pcm_register(&pdev->dev,
                &spear_dmaengine_pcm_config,
                SND_DMAENGINE_PCM_FLAG_NO_DT |
                SND_DMAENGINE_PCM_FLAG_COMPAT);
 }
 
-static int spear_soc_platform_remove(struct platform_device *pdev)
-{
-       snd_dmaengine_pcm_unregister(&pdev->dev);
-       return 0;
-}
-
 static struct platform_driver spear_pcm_driver = {
        .driver = {
                .name = "spear-pcm-audio",
@@ -68,7 +62,6 @@ static struct platform_driver spear_pcm_driver = {
        },
 
        .probe = spear_soc_platform_probe,
-       .remove = spear_soc_platform_remove,
 };
 
 module_platform_driver(spear_pcm_driver);
index 178d1bad62591565589803f52c859a2062044df2..b3b66aa98dce7d8b3f6844eb9f65a7d59a728cd8 100644 (file)
@@ -91,6 +91,8 @@ static int mop500_of_probe(struct platform_device *pdev,
        for (i = 0; i < 2; i++) {
                mop500_dai_links[i].cpu_of_node = msp_np[i];
                mop500_dai_links[i].cpu_dai_name = NULL;
+               mop500_dai_links[i].platform_of_node = msp_np[i];
+               mop500_dai_links[i].platform_name = NULL;
                mop500_dai_links[i].codec_of_node = codec_np;
                mop500_dai_links[i].codec_name = NULL;
        }
index c6fb5cce980e365f4fa84a02fa2b4254a9887e66..8d1b01ff1704ac9510e02d9be883a269809ee03b 100644 (file)
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/of.h>
 #include <linux/regulator/consumer.h>
 #include <linux/mfd/dbx500-prcmu.h>
 #include <linux/platform_data/asoc-ux500-msp.h>
 
 #include <sound/soc.h>
 #include <sound/soc-dai.h>
+#include <sound/dmaengine_pcm.h>
 
 #include "ux500_msp_i2s.h"
 #include "ux500_msp_dai.h"
@@ -654,16 +656,52 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream,
        return ret;
 }
 
+static int ux500_msp_dai_of_probe(struct snd_soc_dai *dai)
+{
+       struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
+       struct snd_dmaengine_dai_dma_data *playback_dma_data;
+       struct snd_dmaengine_dai_dma_data *capture_dma_data;
+
+       playback_dma_data = devm_kzalloc(dai->dev,
+                                        sizeof(*playback_dma_data),
+                                        GFP_KERNEL);
+       if (!playback_dma_data)
+               return -ENOMEM;
+
+       capture_dma_data = devm_kzalloc(dai->dev,
+                                       sizeof(*capture_dma_data),
+                                       GFP_KERNEL);
+       if (!capture_dma_data)
+               return -ENOMEM;
+
+       playback_dma_data->addr = drvdata->msp->playback_dma_data.tx_rx_addr;
+       capture_dma_data->addr = drvdata->msp->capture_dma_data.tx_rx_addr;
+
+       playback_dma_data->maxburst = 4;
+       capture_dma_data->maxburst = 4;
+
+       snd_soc_dai_init_dma_data(dai, playback_dma_data, capture_dma_data);
+
+       return 0;
+}
+
 static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
 {
        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
+       struct device_node *np = dai->dev->of_node;
+       int ret;
 
-       dai->playback_dma_data = &drvdata->msp->playback_dma_data;
-       dai->capture_dma_data = &drvdata->msp->capture_dma_data;
+       if (np) {
+               ret = ux500_msp_dai_of_probe(dai);
+               return ret;
+       }
 
        drvdata->msp->playback_dma_data.data_size = drvdata->slot_width;
        drvdata->msp->capture_dma_data.data_size = drvdata->slot_width;
 
+       snd_soc_dai_init_dma_data(dai,
+                                 &drvdata->msp->playback_dma_data,
+                                 &drvdata->msp->capture_dma_data);
        return 0;
 }
 
index 1ca8b08ae993d34a100b22032315b9c94ce9ec03..7f2a4acddcd7619f9ab1b17f498769d4712acf78 100644 (file)
@@ -646,6 +646,34 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
 
 }
 
+int ux500_msp_i2s_of_init_msp(struct platform_device *pdev,
+                             struct ux500_msp *msp,
+                             struct msp_i2s_platform_data **platform_data)
+{
+       struct msp_i2s_platform_data *pdata;
+
+       *platform_data = devm_kzalloc(&pdev->dev,
+                                    sizeof(struct msp_i2s_platform_data),
+                                    GFP_KERNEL);
+       pdata = *platform_data;
+       if (!pdata)
+               return -ENOMEM;
+
+       msp->playback_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
+                                       sizeof(struct stedma40_chan_cfg),
+                                       GFP_KERNEL);
+       if (!msp->playback_dma_data.dma_cfg)
+               return -ENOMEM;
+
+       msp->capture_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
+                                       sizeof(struct stedma40_chan_cfg),
+                                       GFP_KERNEL);
+       if (!msp->capture_dma_data.dma_cfg)
+               return -ENOMEM;
+
+       return 0;
+}
+
 int ux500_msp_i2s_init_msp(struct platform_device *pdev,
                        struct ux500_msp **msp_p,
                        struct msp_i2s_platform_data *platform_data)
@@ -653,30 +681,28 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
        struct resource *res = NULL;
        struct device_node *np = pdev->dev.of_node;
        struct ux500_msp *msp;
+       int ret;
 
        *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
        msp = *msp_p;
        if (!msp)
                return -ENOMEM;
 
-       if (np) {
-               if (!platform_data) {
-                       platform_data = devm_kzalloc(&pdev->dev,
-                               sizeof(struct msp_i2s_platform_data), GFP_KERNEL);
-                       if (!platform_data)
-                               return -ENOMEM;
-               }
-       } else
-               if (!platform_data)
+       if (!platform_data) {
+               if (np) {
+                       ret = ux500_msp_i2s_of_init_msp(pdev, msp,
+                                                       &platform_data);
+                       if (ret)
+                               return ret;
+               } else
                        return -EINVAL;
+       } else {
+               msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
+               msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
+               msp->id = platform_data->id;
+       }
 
-       dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
-               pdev->name, platform_data->id);
-
-       msp->id = platform_data->id;
        msp->dev = &pdev->dev;
-       msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
-       msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (res == NULL) {
index ce554de5d9dc5a131aa52e9f3d9c1da87b8ddb8c..6162f7091436557f2ed17d3570e337b9be25cf0b 100644 (file)
@@ -65,14 +65,10 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
        struct snd_pcm_substream *substream)
 {
        struct snd_soc_dai *dai = rtd->cpu_dai;
-       struct device *dev = dai->dev;
        u16 per_data_width, mem_data_width;
        struct stedma40_chan_cfg *dma_cfg;
        struct ux500_msp_dma_params *dma_params;
 
-       dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
-               snd_pcm_stream_str(substream));
-
        dma_params = snd_soc_dai_get_dma_data(dai, substream);
        dma_cfg = dma_params->dma_cfg;
 
index b9ba0fcc45df10d4151bb39f8a5d6284dc8ec23e..83aabea259d7113d82d94d870bd04ebffd64b633 100644 (file)
@@ -636,8 +636,22 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,
        if (usb_pipein(ep->pipe) ||
                        snd_usb_endpoint_implicit_feedback_sink(ep)) {
 
+               urb_packs = packs_per_ms;
+               /*
+                * Wireless devices can poll at a max rate of once per 4ms.
+                * For dataintervals less than 5, increase the packet count to
+                * allow the host controller to use bursting to fill in the
+                * gaps.
+                */
+               if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_WIRELESS) {
+                       int interval = ep->datainterval;
+                       while (interval < 5) {
+                               urb_packs <<= 1;
+                               ++interval;
+                       }
+               }
                /* make capture URBs <= 1 ms and smaller than a period */
-               urb_packs = min(max_packs_per_urb, packs_per_ms);
+               urb_packs = min(max_packs_per_urb, urb_packs);
                while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
                        urb_packs >>= 1;
                ep->nurbs = MAX_URBS;
diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
new file mode 100644 (file)
index 0000000..da8b7aa
--- /dev/null
@@ -0,0 +1,251 @@
+# liblockdep version
+LL_VERSION = 0
+LL_PATCHLEVEL = 0
+LL_EXTRAVERSION = 1
+
+# file format version
+FILE_VERSION = 1
+
+MAKEFLAGS += --no-print-directory
+
+
+# Makefiles suck: This macro sets a default value of $(2) for the
+# variable named by $(1), unless the variable has been set by
+# environment or command line. This is necessary for CC and AR
+# because make sets default values, so the simpler ?= approach
+# won't work as expected.
+define allow-override
+  $(if $(or $(findstring environment,$(origin $(1))),\
+            $(findstring command line,$(origin $(1)))),,\
+    $(eval $(1) = $(2)))
+endef
+
+# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
+$(call allow-override,CC,$(CROSS_COMPILE)gcc)
+$(call allow-override,AR,$(CROSS_COMPILE)ar)
+
+INSTALL = install
+
+# Use DESTDIR for installing into a different root directory.
+# This is useful for building a package. The program will be
+# installed in this directory as if it was the root directory.
+# Then the build tool can move it later.
+DESTDIR ?=
+DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
+
+prefix ?= /usr/local
+libdir_relative = lib
+libdir = $(prefix)/$(libdir_relative)
+bindir_relative = bin
+bindir = $(prefix)/$(bindir_relative)
+
+export DESTDIR DESTDIR_SQ INSTALL
+
+# copy a bit from Linux kbuild
+
+ifeq ("$(origin V)", "command line")
+  VERBOSE = $(V)
+endif
+ifndef VERBOSE
+  VERBOSE = 0
+endif
+
+ifeq ("$(origin O)", "command line")
+  BUILD_OUTPUT := $(O)
+endif
+
+ifeq ($(BUILD_SRC),)
+ifneq ($(BUILD_OUTPUT),)
+
+define build_output
+       $(if $(VERBOSE:1=),@)$(MAKE) -C $(BUILD_OUTPUT) \
+       BUILD_SRC=$(CURDIR) -f $(CURDIR)/Makefile $1
+endef
+
+saved-output := $(BUILD_OUTPUT)
+BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd)
+$(if $(BUILD_OUTPUT),, \
+     $(error output directory "$(saved-output)" does not exist))
+
+all: sub-make
+
+gui: force
+       $(call build_output, all_cmd)
+
+$(filter-out gui,$(MAKECMDGOALS)): sub-make
+
+sub-make: force
+       $(call build_output, $(MAKECMDGOALS))
+
+
+# Leave processing to above invocation of make
+skip-makefile := 1
+
+endif # BUILD_OUTPUT
+endif # BUILD_SRC
+
+# We process the rest of the Makefile if this is the final invocation of make
+ifeq ($(skip-makefile),)
+
+srctree                := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR))
+objtree                := $(CURDIR)
+src            := $(srctree)
+obj            := $(objtree)
+
+export prefix libdir bindir src obj
+
+# Shell quotes
+libdir_SQ = $(subst ','\'',$(libdir))
+bindir_SQ = $(subst ','\'',$(bindir))
+
+LIB_FILE = liblockdep.a liblockdep.so
+BIN_FILE = lockdep
+
+CONFIG_INCLUDES =
+CONFIG_LIBS    =
+CONFIG_FLAGS   =
+
+OBJ            = $@
+N              =
+
+export Q VERBOSE
+
+LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION)
+
+INCLUDES = -I. -I/usr/local/include -I./uinclude $(CONFIG_INCLUDES)
+
+# Set compile option CFLAGS if not set elsewhere
+CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g
+
+override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
+
+ifeq ($(VERBOSE),1)
+  Q =
+  print_compile =
+  print_app_build =
+  print_fpic_compile =
+  print_shared_lib_compile =
+  print_install =
+else
+  Q = @
+  print_compile =              echo '  CC                 '$(OBJ);
+  print_app_build =            echo '  BUILD              '$(OBJ);
+  print_fpic_compile =         echo '  CC FPIC            '$(OBJ);
+  print_shared_lib_compile =   echo '  BUILD SHARED LIB   '$(OBJ);
+  print_static_lib_build =     echo '  BUILD STATIC LIB   '$(OBJ);
+  print_install =              echo '  INSTALL     '$1'        to      $(DESTDIR_SQ)$2';
+endif
+
+do_fpic_compile =                                      \
+       ($(print_fpic_compile)                          \
+       $(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@)
+
+do_app_build =                                         \
+       ($(print_app_build)                             \
+       $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS))
+
+do_compile_shared_library =                    \
+       ($(print_shared_lib_compile)            \
+       $(CC) --shared $^ -o $@ -lpthread -ldl)
+
+do_build_static_lib =                          \
+       ($(print_static_lib_build)              \
+       $(RM) $@;  $(AR) rcs $@ $^)
+
+
+define do_compile
+       $(print_compile)                                                \
+       $(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@;
+endef
+
+$(obj)/%.o: $(src)/%.c
+       $(Q)$(call do_compile)
+
+%.o: $(src)/%.c
+       $(Q)$(call do_compile)
+
+PEVENT_LIB_OBJS = common.o lockdep.o preload.o rbtree.o
+
+ALL_OBJS = $(PEVENT_LIB_OBJS)
+
+CMD_TARGETS = $(LIB_FILE)
+
+TARGETS = $(CMD_TARGETS)
+
+
+all: all_cmd
+
+all_cmd: $(CMD_TARGETS)
+
+liblockdep.so: $(PEVENT_LIB_OBJS)
+       $(Q)$(do_compile_shared_library)
+
+liblockdep.a: $(PEVENT_LIB_OBJS)
+       $(Q)$(do_build_static_lib)
+
+$(PEVENT_LIB_OBJS): %.o: $(src)/%.c
+       $(Q)$(do_fpic_compile)
+
+## make deps
+
+all_objs := $(sort $(ALL_OBJS))
+all_deps := $(all_objs:%.o=.%.d)
+
+# let .d file also depends on the source and header files
+define check_deps
+               @set -e; $(RM) $@; \
+               $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
+               sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+               $(RM) $@.$$$$
+endef
+
+$(all_deps): .%.d: $(src)/%.c
+       $(Q)$(call check_deps)
+
+$(all_objs) : %.o : .%.d
+
+dep_includes := $(wildcard $(all_deps))
+
+ifneq ($(dep_includes),)
+ include $(dep_includes)
+endif
+
+### Detect environment changes
+TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
+
+tags:  force
+       $(RM) tags
+       find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
+       --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
+
+TAGS:  force
+       $(RM) TAGS
+       find . -name '*.[ch]' | xargs etags \
+       --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/'
+
+define do_install
+       $(print_install)                                \
+       if [ ! -d '$(DESTDIR_SQ)$2' ]; then             \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \
+       fi;                                             \
+       $(INSTALL) $1 '$(DESTDIR_SQ)$2'
+endef
+
+install_lib: all_cmd
+       $(Q)$(call do_install,$(LIB_FILE),$(libdir_SQ))
+       $(Q)$(call do_install,$(BIN_FILE),$(bindir_SQ))
+
+install: install_lib
+
+clean:
+       $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d
+       $(RM) tags TAGS
+
+endif # skip-makefile
+
+PHONY += force
+force:
+
+# Declare the contents of the .PHONY variable as phony.  We keep that
+# information in a variable so we can use it in if_changed and friends.
+.PHONY: $(PHONY)
diff --git a/tools/lib/lockdep/common.c b/tools/lib/lockdep/common.c
new file mode 100644 (file)
index 0000000..8ef602f
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stddef.h>
+#include <stdbool.h>
+#include <linux/compiler.h>
+#include <linux/lockdep.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+static __thread struct task_struct current_obj;
+
+/* lockdep wants these */
+bool debug_locks = true;
+bool debug_locks_silent;
+
+__attribute__((constructor)) static void liblockdep_init(void)
+{
+       lockdep_init();
+}
+
+__attribute__((destructor)) static void liblockdep_exit(void)
+{
+       debug_check_no_locks_held(&current_obj);
+}
+
+struct task_struct *__curr(void)
+{
+       if (current_obj.pid == 0) {
+               /* Makes lockdep output pretty */
+               prctl(PR_GET_NAME, current_obj.comm);
+               current_obj.pid = syscall(__NR_gettid);
+       }
+
+       return &current_obj;
+}
diff --git a/tools/lib/lockdep/include/liblockdep/common.h b/tools/lib/lockdep/include/liblockdep/common.h
new file mode 100644 (file)
index 0000000..0bda630
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef _LIBLOCKDEP_COMMON_H
+#define _LIBLOCKDEP_COMMON_H
+
+#include <pthread.h>
+
+#define NR_LOCKDEP_CACHING_CLASSES 2
+#define MAX_LOCKDEP_SUBCLASSES 8UL
+
+#ifndef CALLER_ADDR0
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#endif
+
+#ifndef _RET_IP_
+#define _RET_IP_ CALLER_ADDR0
+#endif
+
+#ifndef _THIS_IP_
+#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
+#endif
+
+struct lockdep_subclass_key {
+       char __one_byte;
+};
+
+struct lock_class_key {
+       struct lockdep_subclass_key subkeys[MAX_LOCKDEP_SUBCLASSES];
+};
+
+struct lockdep_map {
+       struct lock_class_key   *key;
+       struct lock_class       *class_cache[NR_LOCKDEP_CACHING_CLASSES];
+       const char              *name;
+#ifdef CONFIG_LOCK_STAT
+       int                     cpu;
+       unsigned long           ip;
+#endif
+};
+
+void lockdep_init_map(struct lockdep_map *lock, const char *name,
+                       struct lock_class_key *key, int subclass);
+void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
+                       int trylock, int read, int check,
+                       struct lockdep_map *nest_lock, unsigned long ip);
+void lock_release(struct lockdep_map *lock, int nested,
+                       unsigned long ip);
+
+#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \
+       { .name = (_name), .key = (void *)(_key), }
+
+#endif
diff --git a/tools/lib/lockdep/include/liblockdep/mutex.h b/tools/lib/lockdep/include/liblockdep/mutex.h
new file mode 100644 (file)
index 0000000..c342f70
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef _LIBLOCKDEP_MUTEX_H
+#define _LIBLOCKDEP_MUTEX_H
+
+#include <pthread.h>
+#include "common.h"
+
+struct liblockdep_pthread_mutex {
+       pthread_mutex_t mutex;
+       struct lockdep_map dep_map;
+};
+
+typedef struct liblockdep_pthread_mutex liblockdep_pthread_mutex_t;
+
+#define LIBLOCKDEP_PTHREAD_MUTEX_INITIALIZER(mtx)                      \
+               (const struct liblockdep_pthread_mutex) {               \
+       .mutex = PTHREAD_MUTEX_INITIALIZER,                             \
+       .dep_map = STATIC_LOCKDEP_MAP_INIT(#mtx, &((&(mtx))->dep_map)), \
+}
+
+static inline int __mutex_init(liblockdep_pthread_mutex_t *lock,
+                               const char *name,
+                               struct lock_class_key *key,
+                               const pthread_mutexattr_t *__mutexattr)
+{
+       lockdep_init_map(&lock->dep_map, name, key, 0);
+       return pthread_mutex_init(&lock->mutex, __mutexattr);
+}
+
+#define liblockdep_pthread_mutex_init(mutex, mutexattr)                \
+({                                                             \
+       static struct lock_class_key __key;                     \
+                                                               \
+       __mutex_init((mutex), #mutex, &__key, (mutexattr));     \
+})
+
+static inline int liblockdep_pthread_mutex_lock(liblockdep_pthread_mutex_t *lock)
+{
+       lock_acquire(&lock->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_);
+       return pthread_mutex_lock(&lock->mutex);
+}
+
+static inline int liblockdep_pthread_mutex_unlock(liblockdep_pthread_mutex_t *lock)
+{
+       lock_release(&lock->dep_map, 0, (unsigned long)_RET_IP_);
+       return pthread_mutex_unlock(&lock->mutex);
+}
+
+static inline int liblockdep_pthread_mutex_trylock(liblockdep_pthread_mutex_t *lock)
+{
+       lock_acquire(&lock->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_);
+       return pthread_mutex_trylock(&lock->mutex) == 0 ? 1 : 0;
+}
+
+static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock)
+{
+       return pthread_mutex_destroy(&lock->mutex);
+}
+
+#ifdef __USE_LIBLOCKDEP
+
+#define pthread_mutex_t         liblockdep_pthread_mutex_t
+#define pthread_mutex_init      liblockdep_pthread_mutex_init
+#define pthread_mutex_lock      liblockdep_pthread_mutex_lock
+#define pthread_mutex_unlock    liblockdep_pthread_mutex_unlock
+#define pthread_mutex_trylock   liblockdep_pthread_mutex_trylock
+#define pthread_mutex_destroy   liblockdep_pthread_mutex_destroy
+
+#endif
+
+#endif
diff --git a/tools/lib/lockdep/include/liblockdep/rwlock.h b/tools/lib/lockdep/include/liblockdep/rwlock.h
new file mode 100644 (file)
index 0000000..a680ab8
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef _LIBLOCKDEP_RWLOCK_H
+#define _LIBLOCKDEP_RWLOCK_H
+
+#include <pthread.h>
+#include "common.h"
+
+struct liblockdep_pthread_rwlock {
+       pthread_rwlock_t rwlock;
+       struct lockdep_map dep_map;
+};
+
+typedef struct liblockdep_pthread_rwlock liblockdep_pthread_rwlock_t;
+
+#define LIBLOCKDEP_PTHREAD_RWLOCK_INITIALIZER(rwl)                     \
+               (struct liblockdep_pthread_rwlock) {                    \
+       .rwlock = PTHREAD_RWLOCK_INITIALIZER,                           \
+       .dep_map = STATIC_LOCKDEP_MAP_INIT(#rwl, &((&(rwl))->dep_map)), \
+}
+
+static inline int __rwlock_init(liblockdep_pthread_rwlock_t *lock,
+                               const char *name,
+                               struct lock_class_key *key,
+                               const pthread_rwlockattr_t *attr)
+{
+       lockdep_init_map(&lock->dep_map, name, key, 0);
+
+       return pthread_rwlock_init(&lock->rwlock, attr);
+}
+
+#define liblockdep_pthread_rwlock_init(lock, attr)             \
+({                                                     \
+       static struct lock_class_key __key;             \
+                                                       \
+       __rwlock_init((lock), #lock, &__key, (attr));   \
+})
+
+static inline int liblockdep_pthread_rwlock_rdlock(liblockdep_pthread_rwlock_t *lock)
+{
+       lock_acquire(&lock->dep_map, 0, 0, 2, 2, NULL, (unsigned long)_RET_IP_);
+       return pthread_rwlock_rdlock(&lock->rwlock);
+
+}
+
+static inline int liblockdep_pthread_rwlock_unlock(liblockdep_pthread_rwlock_t *lock)
+{
+       lock_release(&lock->dep_map, 0, (unsigned long)_RET_IP_);
+       return pthread_rwlock_unlock(&lock->rwlock);
+}
+
+static inline int liblockdep_pthread_rwlock_wrlock(liblockdep_pthread_rwlock_t *lock)
+{
+       lock_acquire(&lock->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_);
+       return pthread_rwlock_wrlock(&lock->rwlock);
+}
+
+static inline int liblockdep_pthread_rwlock_tryrdlock(liblockdep_pthread_rwlock_t *lock)
+{
+       lock_acquire(&lock->dep_map, 0, 1, 2, 2, NULL, (unsigned long)_RET_IP_);
+       return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0;
+}
+
+static inline int liblockdep_pthread_rwlock_trywlock(liblockdep_pthread_rwlock_t *lock)
+{
+       lock_acquire(&lock->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_);
+       return pthread_rwlock_trywlock(&lock->rwlock) == 0 ? 1 : 0;
+}
+
+static inline int liblockdep_rwlock_destroy(liblockdep_pthread_rwlock_t *lock)
+{
+       return pthread_rwlock_destroy(&lock->rwlock);
+}
+
+#ifdef __USE_LIBLOCKDEP
+
+#define pthread_rwlock_t               liblockdep_pthread_rwlock_t
+#define pthread_rwlock_init            liblockdep_pthread_rwlock_init
+#define pthread_rwlock_rdlock          liblockdep_pthread_rwlock_rdlock
+#define pthread_rwlock_unlock          liblockdep_pthread_rwlock_unlock
+#define pthread_rwlock_wrlock          liblockdep_pthread_rwlock_wrlock
+#define pthread_rwlock_tryrdlock       liblockdep_pthread_rwlock_tryrdlock
+#define pthread_rwlock_trywlock                liblockdep_pthread_rwlock_trywlock
+#define pthread_rwlock_destroy         liblockdep_rwlock_destroy
+
+#endif
+
+#endif
diff --git a/tools/lib/lockdep/lockdep b/tools/lib/lockdep/lockdep
new file mode 100755 (executable)
index 0000000..49af9fe
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+LD_PRELOAD="./liblockdep.so $LD_PRELOAD" "$@"
diff --git a/tools/lib/lockdep/lockdep.c b/tools/lib/lockdep/lockdep.c
new file mode 100644 (file)
index 0000000..f42b7e9
--- /dev/null
@@ -0,0 +1,2 @@
+#include <linux/lockdep.h>
+#include "../../../kernel/locking/lockdep.c"
diff --git a/tools/lib/lockdep/lockdep_internals.h b/tools/lib/lockdep/lockdep_internals.h
new file mode 100644 (file)
index 0000000..29d0c95
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../kernel/locking/lockdep_internals.h"
diff --git a/tools/lib/lockdep/lockdep_states.h b/tools/lib/lockdep/lockdep_states.h
new file mode 100644 (file)
index 0000000..248d235
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../kernel/locking/lockdep_states.h"
diff --git a/tools/lib/lockdep/preload.c b/tools/lib/lockdep/preload.c
new file mode 100644 (file)
index 0000000..f8465a8
--- /dev/null
@@ -0,0 +1,447 @@
+#define _GNU_SOURCE
+#include <pthread.h>
+#include <stdio.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <sysexits.h>
+#include "include/liblockdep/mutex.h"
+#include "../../../include/linux/rbtree.h"
+
+/**
+ * struct lock_lookup - liblockdep's view of a single unique lock
+ * @orig: pointer to the original pthread lock, used for lookups
+ * @dep_map: lockdep's dep_map structure
+ * @key: lockdep's key structure
+ * @node: rb-tree node used to store the lock in a global tree
+ * @name: a unique name for the lock
+ */
+struct lock_lookup {
+       void *orig; /* Original pthread lock, used for lookups */
+       struct lockdep_map dep_map; /* Since all locks are dynamic, we need
+                                    * a dep_map and a key for each lock */
+       /*
+        * Wait, there's no support for key classes? Yup :(
+        * Most big projects wrap the pthread api with their own calls to
+        * be compatible with different locking methods. This means that
+        * "classes" will be brokes since the function that creates all
+        * locks will point to a generic locking function instead of the
+        * actual code that wants to do the locking.
+        */
+       struct lock_class_key key;
+       struct rb_node node;
+#define LIBLOCKDEP_MAX_LOCK_NAME 22
+       char name[LIBLOCKDEP_MAX_LOCK_NAME];
+};
+
+/* This is where we store our locks */
+static struct rb_root locks = RB_ROOT;
+static pthread_rwlock_t locks_rwlock = PTHREAD_RWLOCK_INITIALIZER;
+
+/* pthread mutex API */
+
+#ifdef __GLIBC__
+extern int __pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
+extern int __pthread_mutex_lock(pthread_mutex_t *mutex);
+extern int __pthread_mutex_trylock(pthread_mutex_t *mutex);
+extern int __pthread_mutex_unlock(pthread_mutex_t *mutex);
+extern int __pthread_mutex_destroy(pthread_mutex_t *mutex);
+#else
+#define __pthread_mutex_init   NULL
+#define __pthread_mutex_lock   NULL
+#define __pthread_mutex_trylock        NULL
+#define __pthread_mutex_unlock NULL
+#define __pthread_mutex_destroy        NULL
+#endif
+static int (*ll_pthread_mutex_init)(pthread_mutex_t *mutex,
+                       const pthread_mutexattr_t *attr)        = __pthread_mutex_init;
+static int (*ll_pthread_mutex_lock)(pthread_mutex_t *mutex)    = __pthread_mutex_lock;
+static int (*ll_pthread_mutex_trylock)(pthread_mutex_t *mutex) = __pthread_mutex_trylock;
+static int (*ll_pthread_mutex_unlock)(pthread_mutex_t *mutex)  = __pthread_mutex_unlock;
+static int (*ll_pthread_mutex_destroy)(pthread_mutex_t *mutex) = __pthread_mutex_destroy;
+
+/* pthread rwlock API */
+
+#ifdef __GLIBC__
+extern int __pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
+extern int __pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
+extern int __pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
+extern int __pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
+extern int __pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
+extern int __pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
+extern int __pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
+#else
+#define __pthread_rwlock_init          NULL
+#define __pthread_rwlock_destroy       NULL
+#define __pthread_rwlock_wrlock                NULL
+#define __pthread_rwlock_trywrlock     NULL
+#define __pthread_rwlock_rdlock                NULL
+#define __pthread_rwlock_tryrdlock     NULL
+#define __pthread_rwlock_unlock                NULL
+#endif
+
+static int (*ll_pthread_rwlock_init)(pthread_rwlock_t *rwlock,
+                       const pthread_rwlockattr_t *attr)               = __pthread_rwlock_init;
+static int (*ll_pthread_rwlock_destroy)(pthread_rwlock_t *rwlock)      = __pthread_rwlock_destroy;
+static int (*ll_pthread_rwlock_rdlock)(pthread_rwlock_t *rwlock)       = __pthread_rwlock_rdlock;
+static int (*ll_pthread_rwlock_tryrdlock)(pthread_rwlock_t *rwlock)    = __pthread_rwlock_tryrdlock;
+static int (*ll_pthread_rwlock_trywrlock)(pthread_rwlock_t *rwlock)    = __pthread_rwlock_trywrlock;
+static int (*ll_pthread_rwlock_wrlock)(pthread_rwlock_t *rwlock)       = __pthread_rwlock_wrlock;
+static int (*ll_pthread_rwlock_unlock)(pthread_rwlock_t *rwlock)       = __pthread_rwlock_unlock;
+
+enum { none, prepare, done, } __init_state;
+static void init_preload(void);
+static void try_init_preload(void)
+{
+       if (!__init_state != done)
+               init_preload();
+}
+
+static struct rb_node **__get_lock_node(void *lock, struct rb_node **parent)
+{
+       struct rb_node **node = &locks.rb_node;
+       struct lock_lookup *l;
+
+       *parent = NULL;
+
+       while (*node) {
+               l = rb_entry(*node, struct lock_lookup, node);
+
+               *parent = *node;
+               if (lock < l->orig)
+                       node = &l->node.rb_left;
+               else if (lock > l->orig)
+                       node = &l->node.rb_right;
+               else
+                       return node;
+       }
+
+       return node;
+}
+
+#ifndef LIBLOCKDEP_STATIC_ENTRIES
+#define LIBLOCKDEP_STATIC_ENTRIES      1024
+#endif
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+static struct lock_lookup __locks[LIBLOCKDEP_STATIC_ENTRIES];
+static int __locks_nr;
+
+static inline bool is_static_lock(struct lock_lookup *lock)
+{
+       return lock >= __locks && lock < __locks + ARRAY_SIZE(__locks);
+}
+
+static struct lock_lookup *alloc_lock(void)
+{
+       if (__init_state != done) {
+               /*
+                * Some programs attempt to initialize and use locks in their
+                * allocation path. This means that a call to malloc() would
+                * result in locks being initialized and locked.
+                *
+                * Why is it an issue for us? dlsym() below will try allocating
+                * to give us the original function. Since this allocation will
+                * result in a locking operations, we have to let pthread deal
+                * with it, but we can't! we don't have the pointer to the
+                * original API since we're inside dlsym() trying to get it
+                */
+
+               int idx = __locks_nr++;
+               if (idx >= ARRAY_SIZE(__locks)) {
+                       fprintf(stderr,
+               "LOCKDEP error: insufficient LIBLOCKDEP_STATIC_ENTRIES\n");
+                       exit(EX_UNAVAILABLE);
+               }
+               return __locks + idx;
+       }
+
+       return malloc(sizeof(struct lock_lookup));
+}
+
+static inline void free_lock(struct lock_lookup *lock)
+{
+       if (likely(!is_static_lock(lock)))
+               free(lock);
+}
+
+/**
+ * __get_lock - find or create a lock instance
+ * @lock: pointer to a pthread lock function
+ *
+ * Try to find an existing lock in the rbtree using the provided pointer. If
+ * one wasn't found - create it.
+ */
+static struct lock_lookup *__get_lock(void *lock)
+{
+       struct rb_node **node, *parent;
+       struct lock_lookup *l;
+
+       ll_pthread_rwlock_rdlock(&locks_rwlock);
+       node = __get_lock_node(lock, &parent);
+       ll_pthread_rwlock_unlock(&locks_rwlock);
+       if (*node) {
+               return rb_entry(*node, struct lock_lookup, node);
+       }
+
+       /* We didn't find the lock, let's create it */
+       l = alloc_lock();
+       if (l == NULL)
+               return NULL;
+
+       l->orig = lock;
+       /*
+        * Currently the name of the lock is the ptr value of the pthread lock,
+        * while not optimal, it makes debugging a bit easier.
+        *
+        * TODO: Get the real name of the lock using libdwarf
+        */
+       sprintf(l->name, "%p", lock);
+       lockdep_init_map(&l->dep_map, l->name, &l->key, 0);
+
+       ll_pthread_rwlock_wrlock(&locks_rwlock);
+       /* This might have changed since the last time we fetched it */
+       node = __get_lock_node(lock, &parent);
+       rb_link_node(&l->node, parent, node);
+       rb_insert_color(&l->node, &locks);
+       ll_pthread_rwlock_unlock(&locks_rwlock);
+
+       return l;
+}
+
+static void __del_lock(struct lock_lookup *lock)
+{
+       ll_pthread_rwlock_wrlock(&locks_rwlock);
+       rb_erase(&lock->node, &locks);
+       ll_pthread_rwlock_unlock(&locks_rwlock);
+       free_lock(lock);
+}
+
+int pthread_mutex_init(pthread_mutex_t *mutex,
+                       const pthread_mutexattr_t *attr)
+{
+       int r;
+
+       /*
+        * We keep trying to init our preload module because there might be
+        * code in init sections that tries to touch locks before we are
+        * initialized, in that case we'll need to manually call preload
+        * to get us going.
+        *
+        * Funny enough, kernel's lockdep had the same issue, and used
+        * (almost) the same solution. See look_up_lock_class() in
+        * kernel/locking/lockdep.c for details.
+        */
+       try_init_preload();
+
+       r = ll_pthread_mutex_init(mutex, attr);
+       if (r == 0)
+               /*
+                * We do a dummy initialization here so that lockdep could
+                * warn us if something fishy is going on - such as
+                * initializing a held lock.
+                */
+               __get_lock(mutex);
+
+       return r;
+}
+
+int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+       int r;
+
+       try_init_preload();
+
+       lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 2, NULL,
+                       (unsigned long)_RET_IP_);
+       /*
+        * Here's the thing with pthread mutexes: unlike the kernel variant,
+        * they can fail.
+        *
+        * This means that the behaviour here is a bit different from what's
+        * going on in the kernel: there we just tell lockdep that we took the
+        * lock before actually taking it, but here we must deal with the case
+        * that locking failed.
+        *
+        * To do that we'll "release" the lock if locking failed - this way
+        * we'll get lockdep doing the correct checks when we try to take
+        * the lock, and if that fails - we'll be back to the correct
+        * state by releasing it.
+        */
+       r = ll_pthread_mutex_lock(mutex);
+       if (r)
+               lock_release(&__get_lock(mutex)->dep_map, 0, (unsigned long)_RET_IP_);
+
+       return r;
+}
+
+int pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+       int r;
+
+       try_init_preload();
+
+       lock_acquire(&__get_lock(mutex)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_);
+       r = ll_pthread_mutex_trylock(mutex);
+       if (r)
+               lock_release(&__get_lock(mutex)->dep_map, 0, (unsigned long)_RET_IP_);
+
+       return r;
+}
+
+int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+       int r;
+
+       try_init_preload();
+
+       lock_release(&__get_lock(mutex)->dep_map, 0, (unsigned long)_RET_IP_);
+       /*
+        * Just like taking a lock, only in reverse!
+        *
+        * If we fail releasing the lock, tell lockdep we're holding it again.
+        */
+       r = ll_pthread_mutex_unlock(mutex);
+       if (r)
+               lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_);
+
+       return r;
+}
+
+int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+       try_init_preload();
+
+       /*
+        * Let's see if we're releasing a lock that's held.
+        *
+        * TODO: Hook into free() and add that check there as well.
+        */
+       debug_check_no_locks_freed(mutex, mutex + sizeof(*mutex));
+       __del_lock(__get_lock(mutex));
+       return ll_pthread_mutex_destroy(mutex);
+}
+
+/* This is the rwlock part, very similar to what happened with mutex above */
+int pthread_rwlock_init(pthread_rwlock_t *rwlock,
+                       const pthread_rwlockattr_t *attr)
+{
+       int r;
+
+       try_init_preload();
+
+       r = ll_pthread_rwlock_init(rwlock, attr);
+       if (r == 0)
+               __get_lock(rwlock);
+
+       return r;
+}
+
+int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
+{
+       try_init_preload();
+
+       debug_check_no_locks_freed(rwlock, rwlock + sizeof(*rwlock));
+       __del_lock(__get_lock(rwlock));
+       return ll_pthread_rwlock_destroy(rwlock);
+}
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
+{
+       int r;
+
+        init_preload();
+
+       lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 2, 2, NULL, (unsigned long)_RET_IP_);
+       r = ll_pthread_rwlock_rdlock(rwlock);
+       if (r)
+               lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_);
+
+       return r;
+}
+
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
+{
+       int r;
+
+        init_preload();
+
+       lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 2, 2, NULL, (unsigned long)_RET_IP_);
+       r = ll_pthread_rwlock_tryrdlock(rwlock);
+       if (r)
+               lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_);
+
+       return r;
+}
+
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
+{
+       int r;
+
+        init_preload();
+
+       lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_);
+       r = ll_pthread_rwlock_trywrlock(rwlock);
+       if (r)
+                lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_);
+
+       return r;
+}
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
+{
+       int r;
+
+        init_preload();
+
+       lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_);
+       r = ll_pthread_rwlock_wrlock(rwlock);
+       if (r)
+               lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_);
+
+       return r;
+}
+
+int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+{
+       int r;
+
+        init_preload();
+
+       lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_);
+       r = ll_pthread_rwlock_unlock(rwlock);
+       if (r)
+               lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_);
+
+       return r;
+}
+
+__attribute__((constructor)) static void init_preload(void)
+{
+       if (__init_state != done)
+               return;
+
+#ifndef __GLIBC__
+       __init_state = prepare;
+
+       ll_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init");
+       ll_pthread_mutex_lock = dlsym(RTLD_NEXT, "pthread_mutex_lock");
+       ll_pthread_mutex_trylock = dlsym(RTLD_NEXT, "pthread_mutex_trylock");
+       ll_pthread_mutex_unlock = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
+       ll_pthread_mutex_destroy = dlsym(RTLD_NEXT, "pthread_mutex_destroy");
+
+       ll_pthread_rwlock_init = dlsym(RTLD_NEXT, "pthread_rwlock_init");
+       ll_pthread_rwlock_destroy = dlsym(RTLD_NEXT, "pthread_rwlock_destroy");
+       ll_pthread_rwlock_rdlock = dlsym(RTLD_NEXT, "pthread_rwlock_rdlock");
+       ll_pthread_rwlock_tryrdlock = dlsym(RTLD_NEXT, "pthread_rwlock_tryrdlock");
+       ll_pthread_rwlock_wrlock = dlsym(RTLD_NEXT, "pthread_rwlock_wrlock");
+       ll_pthread_rwlock_trywrlock = dlsym(RTLD_NEXT, "pthread_rwlock_trywrlock");
+       ll_pthread_rwlock_unlock = dlsym(RTLD_NEXT, "pthread_rwlock_unlock");
+#endif
+
+       printf("%p\n", ll_pthread_mutex_trylock);fflush(stdout);
+
+       lockdep_init();
+
+       __init_state = done;
+}
diff --git a/tools/lib/lockdep/rbtree.c b/tools/lib/lockdep/rbtree.c
new file mode 100644 (file)
index 0000000..f7f4303
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../lib/rbtree.c"
diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh
new file mode 100644 (file)
index 0000000..5334ad9
--- /dev/null
@@ -0,0 +1,27 @@
+#! /bin/bash
+
+make &> /dev/null
+
+for i in `ls tests/*.c`; do
+       testname=$(basename -s .c "$i")
+       gcc -o tests/$testname -pthread -lpthread $i liblockdep.a -Iinclude -D__USE_LIBLOCKDEP &> /dev/null
+       echo -ne "$testname... "
+       if [ $(timeout 1 ./tests/$testname | wc -l) -gt 0 ]; then
+               echo "PASSED!"
+       else
+               echo "FAILED!"
+       fi
+       rm tests/$testname
+done
+
+for i in `ls tests/*.c`; do
+       testname=$(basename -s .c "$i")
+       gcc -o tests/$testname -pthread -lpthread -Iinclude $i &> /dev/null
+       echo -ne "(PRELOAD) $testname... "
+       if [ $(timeout 1 ./lockdep ./tests/$testname | wc -l) -gt 0 ]; then
+               echo "PASSED!"
+       else
+               echo "FAILED!"
+       fi
+       rm tests/$testname
+done
diff --git a/tools/lib/lockdep/tests/AA.c b/tools/lib/lockdep/tests/AA.c
new file mode 100644 (file)
index 0000000..0f782ff
--- /dev/null
@@ -0,0 +1,13 @@
+#include <liblockdep/mutex.h>
+
+void main(void)
+{
+       pthread_mutex_t a, b;
+
+       pthread_mutex_init(&a, NULL);
+       pthread_mutex_init(&b, NULL);
+
+       pthread_mutex_lock(&a);
+       pthread_mutex_lock(&b);
+       pthread_mutex_lock(&a);
+}
diff --git a/tools/lib/lockdep/tests/ABBA.c b/tools/lib/lockdep/tests/ABBA.c
new file mode 100644 (file)
index 0000000..07f0e29
--- /dev/null
@@ -0,0 +1,13 @@
+#include <liblockdep/mutex.h>
+#include "common.h"
+
+void main(void)
+{
+       pthread_mutex_t a, b;
+
+       pthread_mutex_init(&a, NULL);
+       pthread_mutex_init(&b, NULL);
+
+       LOCK_UNLOCK_2(a, b);
+       LOCK_UNLOCK_2(b, a);
+}
diff --git a/tools/lib/lockdep/tests/ABBCCA.c b/tools/lib/lockdep/tests/ABBCCA.c
new file mode 100644 (file)
index 0000000..843db09
--- /dev/null
@@ -0,0 +1,15 @@
+#include <liblockdep/mutex.h>
+#include "common.h"
+
+void main(void)
+{
+       pthread_mutex_t a, b, c;
+
+       pthread_mutex_init(&a, NULL);
+       pthread_mutex_init(&b, NULL);
+       pthread_mutex_init(&c, NULL);
+
+       LOCK_UNLOCK_2(a, b);
+       LOCK_UNLOCK_2(b, c);
+       LOCK_UNLOCK_2(c, a);
+}
diff --git a/tools/lib/lockdep/tests/ABBCCDDA.c b/tools/lib/lockdep/tests/ABBCCDDA.c
new file mode 100644 (file)
index 0000000..33620e2
--- /dev/null
@@ -0,0 +1,17 @@
+#include <liblockdep/mutex.h>
+#include "common.h"
+
+void main(void)
+{
+       pthread_mutex_t a, b, c, d;
+
+       pthread_mutex_init(&a, NULL);
+       pthread_mutex_init(&b, NULL);
+       pthread_mutex_init(&c, NULL);
+       pthread_mutex_init(&d, NULL);
+
+       LOCK_UNLOCK_2(a, b);
+       LOCK_UNLOCK_2(b, c);
+       LOCK_UNLOCK_2(c, d);
+       LOCK_UNLOCK_2(d, a);
+}
diff --git a/tools/lib/lockdep/tests/ABCABC.c b/tools/lib/lockdep/tests/ABCABC.c
new file mode 100644 (file)
index 0000000..3fee51e
--- /dev/null
@@ -0,0 +1,15 @@
+#include <liblockdep/mutex.h>
+#include "common.h"
+
+void main(void)
+{
+       pthread_mutex_t a, b, c;
+
+       pthread_mutex_init(&a, NULL);
+       pthread_mutex_init(&b, NULL);
+       pthread_mutex_init(&c, NULL);
+
+       LOCK_UNLOCK_2(a, b);
+       LOCK_UNLOCK_2(c, a);
+       LOCK_UNLOCK_2(b, c);
+}
diff --git a/tools/lib/lockdep/tests/ABCDBCDA.c b/tools/lib/lockdep/tests/ABCDBCDA.c
new file mode 100644 (file)
index 0000000..427ba56
--- /dev/null
@@ -0,0 +1,17 @@
+#include <liblockdep/mutex.h>
+#include "common.h"
+
+void main(void)
+{
+       pthread_mutex_t a, b, c, d;
+
+       pthread_mutex_init(&a, NULL);
+       pthread_mutex_init(&b, NULL);
+       pthread_mutex_init(&c, NULL);
+       pthread_mutex_init(&d, NULL);
+
+       LOCK_UNLOCK_2(a, b);
+       LOCK_UNLOCK_2(c, d);
+       LOCK_UNLOCK_2(b, c);
+       LOCK_UNLOCK_2(d, a);
+}
diff --git a/tools/lib/lockdep/tests/ABCDBDDA.c b/tools/lib/lockdep/tests/ABCDBDDA.c
new file mode 100644 (file)
index 0000000..680c6cf
--- /dev/null
@@ -0,0 +1,17 @@
+#include <liblockdep/mutex.h>
+#include "common.h"
+
+void main(void)
+{
+       pthread_mutex_t a, b, c, d;
+
+       pthread_mutex_init(&a, NULL);
+       pthread_mutex_init(&b, NULL);
+       pthread_mutex_init(&c, NULL);
+       pthread_mutex_init(&d, NULL);
+
+       LOCK_UNLOCK_2(a, b);
+       LOCK_UNLOCK_2(c, d);
+       LOCK_UNLOCK_2(b, d);
+       LOCK_UNLOCK_2(d, a);
+}
diff --git a/tools/lib/lockdep/tests/WW.c b/tools/lib/lockdep/tests/WW.c
new file mode 100644 (file)
index 0000000..d44f77d
--- /dev/null
@@ -0,0 +1,13 @@
+#include <liblockdep/rwlock.h>
+
+void main(void)
+{
+       pthread_rwlock_t a, b;
+
+       pthread_rwlock_init(&a, NULL);
+       pthread_rwlock_init(&b, NULL);
+
+       pthread_rwlock_wrlock(&a);
+       pthread_rwlock_rdlock(&b);
+       pthread_rwlock_wrlock(&a);
+}
diff --git a/tools/lib/lockdep/tests/common.h b/tools/lib/lockdep/tests/common.h
new file mode 100644 (file)
index 0000000..d89e94d
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _LIBLOCKDEP_TEST_COMMON_H
+#define _LIBLOCKDEP_TEST_COMMON_H
+
+#define LOCK_UNLOCK_2(a, b)                    \
+       do {                                    \
+               pthread_mutex_lock(&(a));       \
+               pthread_mutex_lock(&(b));       \
+               pthread_mutex_unlock(&(b));     \
+               pthread_mutex_unlock(&(a));     \
+       } while(0)
+
+#endif
diff --git a/tools/lib/lockdep/tests/unlock_balance.c b/tools/lib/lockdep/tests/unlock_balance.c
new file mode 100644 (file)
index 0000000..0bc62de
--- /dev/null
@@ -0,0 +1,12 @@
+#include <liblockdep/mutex.h>
+
+void main(void)
+{
+       pthread_mutex_t a;
+
+       pthread_mutex_init(&a, NULL);
+
+       pthread_mutex_lock(&a);
+       pthread_mutex_unlock(&a);
+       pthread_mutex_unlock(&a);
+}
diff --git a/tools/lib/lockdep/uinclude/asm/hweight.h b/tools/lib/lockdep/uinclude/asm/hweight.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/asm/sections.h b/tools/lib/lockdep/uinclude/asm/sections.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/bitops.h b/tools/lib/lockdep/uinclude/linux/bitops.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/compiler.h b/tools/lib/lockdep/uinclude/linux/compiler.h
new file mode 100644 (file)
index 0000000..7ac838a
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _LIBLOCKDEP_LINUX_COMPILER_H_
+#define _LIBLOCKDEP_LINUX_COMPILER_H_
+
+#define __used         __attribute__((__unused__))
+#define unlikely
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/debug_locks.h b/tools/lib/lockdep/uinclude/linux/debug_locks.h
new file mode 100644 (file)
index 0000000..f38eb64
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _LIBLOCKDEP_DEBUG_LOCKS_H_
+#define _LIBLOCKDEP_DEBUG_LOCKS_H_
+
+#include <stddef.h>
+#include <linux/compiler.h>
+
+#define DEBUG_LOCKS_WARN_ON(x) (x)
+
+extern bool debug_locks;
+extern bool debug_locks_silent;
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/delay.h b/tools/lib/lockdep/uinclude/linux/delay.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/export.h b/tools/lib/lockdep/uinclude/linux/export.h
new file mode 100644 (file)
index 0000000..6bdf349
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _LIBLOCKDEP_LINUX_EXPORT_H_
+#define _LIBLOCKDEP_LINUX_EXPORT_H_
+
+#define EXPORT_SYMBOL(sym)
+#define EXPORT_SYMBOL_GPL(sym)
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/ftrace.h b/tools/lib/lockdep/uinclude/linux/ftrace.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/gfp.h b/tools/lib/lockdep/uinclude/linux/gfp.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/hardirq.h b/tools/lib/lockdep/uinclude/linux/hardirq.h
new file mode 100644 (file)
index 0000000..c8f3f8f
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _LIBLOCKDEP_LINUX_HARDIRQ_H_
+#define _LIBLOCKDEP_LINUX_HARDIRQ_H_
+
+#define SOFTIRQ_BITS   0UL
+#define HARDIRQ_BITS   0UL
+#define SOFTIRQ_SHIFT  0UL
+#define HARDIRQ_SHIFT  0UL
+#define hardirq_count()        0UL
+#define softirq_count()        0UL
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/hash.h b/tools/lib/lockdep/uinclude/linux/hash.h
new file mode 100644 (file)
index 0000000..0f84798
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../include/linux/hash.h"
diff --git a/tools/lib/lockdep/uinclude/linux/interrupt.h b/tools/lib/lockdep/uinclude/linux/interrupt.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/irqflags.h b/tools/lib/lockdep/uinclude/linux/irqflags.h
new file mode 100644 (file)
index 0000000..6cc296f
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_
+#define _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_
+
+# define trace_hardirq_context(p)      0
+# define trace_softirq_context(p)      0
+# define trace_hardirqs_enabled(p)     0
+# define trace_softirqs_enabled(p)     0
+# define trace_hardirq_enter()         do { } while (0)
+# define trace_hardirq_exit()          do { } while (0)
+# define lockdep_softirq_enter()       do { } while (0)
+# define lockdep_softirq_exit()                do { } while (0)
+# define INIT_TRACE_IRQFLAGS
+
+# define stop_critical_timings() do { } while (0)
+# define start_critical_timings() do { } while (0)
+
+#define raw_local_irq_disable() do { } while (0)
+#define raw_local_irq_enable() do { } while (0)
+#define raw_local_irq_save(flags) ((flags) = 0)
+#define raw_local_irq_restore(flags) do { } while (0)
+#define raw_local_save_flags(flags) ((flags) = 0)
+#define raw_irqs_disabled_flags(flags) do { } while (0)
+#define raw_irqs_disabled() 0
+#define raw_safe_halt()
+
+#define local_irq_enable() do { } while (0)
+#define local_irq_disable() do { } while (0)
+#define local_irq_save(flags) ((flags) = 0)
+#define local_irq_restore(flags) do { } while (0)
+#define local_save_flags(flags)        ((flags) = 0)
+#define irqs_disabled() (1)
+#define irqs_disabled_flags(flags) (0)
+#define safe_halt() do { } while (0)
+
+#define trace_lock_release(x, y)
+#define trace_lock_acquire(a, b, c, d, e, f, g)
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/kallsyms.h b/tools/lib/lockdep/uinclude/linux/kallsyms.h
new file mode 100644 (file)
index 0000000..b0f2dbd
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _LIBLOCKDEP_LINUX_KALLSYMS_H_
+#define _LIBLOCKDEP_LINUX_KALLSYMS_H_
+
+#include <linux/kernel.h>
+#include <stdio.h>
+
+#define KSYM_NAME_LEN 128
+
+struct module;
+
+static inline const char *kallsyms_lookup(unsigned long addr,
+                                         unsigned long *symbolsize,
+                                         unsigned long *offset,
+                                         char **modname, char *namebuf)
+{
+       return NULL;
+}
+
+#include <execinfo.h>
+#include <stdlib.h>
+static inline void print_ip_sym(unsigned long ip)
+{
+       char **name;
+
+       name = backtrace_symbols((void **)&ip, 1);
+
+       printf("%s\n", *name);
+
+       free(name);
+}
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/kern_levels.h b/tools/lib/lockdep/uinclude/linux/kern_levels.h
new file mode 100644 (file)
index 0000000..3b9bade
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __KERN_LEVELS_H__
+#define __KERN_LEVELS_H__
+
+#define KERN_SOH       ""              /* ASCII Start Of Header */
+#define KERN_SOH_ASCII ''
+
+#define KERN_EMERG     KERN_SOH ""     /* system is unusable */
+#define KERN_ALERT     KERN_SOH ""     /* action must be taken immediately */
+#define KERN_CRIT      KERN_SOH ""     /* critical conditions */
+#define KERN_ERR       KERN_SOH ""     /* error conditions */
+#define KERN_WARNING   KERN_SOH ""     /* warning conditions */
+#define KERN_NOTICE    KERN_SOH ""     /* normal but significant condition */
+#define KERN_INFO      KERN_SOH ""     /* informational */
+#define KERN_DEBUG     KERN_SOH ""     /* debug-level messages */
+
+#define KERN_DEFAULT   KERN_SOH ""     /* the default kernel loglevel */
+
+/*
+ * Annotation for a "continued" line of log printout (only done after a
+ * line that had no enclosing \n). Only to be used by core/arch code
+ * during early bootup (a continued line is not SMP-safe otherwise).
+ */
+#define KERN_CONT      ""
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/kernel.h b/tools/lib/lockdep/uinclude/linux/kernel.h
new file mode 100644 (file)
index 0000000..a11e3c3
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef _LIBLOCKDEP_LINUX_KERNEL_H_
+#define _LIBLOCKDEP_LINUX_KERNEL_H_
+
+#include <linux/export.h>
+#include <linux/types.h>
+#include <linux/rcu.h>
+#include <linux/hardirq.h>
+#include <linux/kern_levels.h>
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({                     \
+       const typeof(((type *)0)->member) * __mptr = (ptr);     \
+       (type *)((char *)__mptr - offsetof(type, member)); })
+#endif
+
+#define max(x, y) ({                           \
+       typeof(x) _max1 = (x);                  \
+       typeof(y) _max2 = (y);                  \
+       (void) (&_max1 == &_max2);              \
+       _max1 > _max2 ? _max1 : _max2; })
+
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+#define WARN_ON(x) (x)
+#define WARN_ON_ONCE(x) (x)
+#define likely(x) (x)
+#define WARN(x, y, z) (x)
+#define uninitialized_var(x) x
+#define __init
+#define noinline
+#define list_add_tail_rcu list_add_tail
+
+#ifndef CALLER_ADDR0
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#endif
+
+#ifndef _RET_IP_
+#define _RET_IP_ CALLER_ADDR0
+#endif
+
+#ifndef _THIS_IP_
+#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
+#endif
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/kmemcheck.h b/tools/lib/lockdep/uinclude/linux/kmemcheck.h
new file mode 100644 (file)
index 0000000..94d598b
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _LIBLOCKDEP_LINUX_KMEMCHECK_H_
+#define _LIBLOCKDEP_LINUX_KMEMCHECK_H_
+
+static inline void kmemcheck_mark_initialized(void *address, unsigned int n)
+{
+}
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/linkage.h b/tools/lib/lockdep/uinclude/linux/linkage.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/list.h b/tools/lib/lockdep/uinclude/linux/list.h
new file mode 100644 (file)
index 0000000..6e9ef31
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../include/linux/list.h"
diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h
new file mode 100644 (file)
index 0000000..d0f5d6e
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef _LIBLOCKDEP_LOCKDEP_H_
+#define _LIBLOCKDEP_LOCKDEP_H_
+
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+#include <string.h>
+#include <limits.h>
+#include <linux/utsname.h>
+
+
+#define MAX_LOCK_DEPTH 2000UL
+
+#include "../../../include/linux/lockdep.h"
+
+struct task_struct {
+       u64 curr_chain_key;
+       int lockdep_depth;
+       unsigned int lockdep_recursion;
+       struct held_lock held_locks[MAX_LOCK_DEPTH];
+       gfp_t lockdep_reclaim_gfp;
+       int pid;
+       char comm[17];
+};
+
+extern struct task_struct *__curr(void);
+
+#define current (__curr())
+
+#define debug_locks_off() 1
+#define task_pid_nr(tsk) ((tsk)->pid)
+
+#define KSYM_NAME_LEN 128
+#define printk printf
+
+#define list_del_rcu list_del
+
+#define atomic_t unsigned long
+#define atomic_inc(x) ((*(x))++)
+
+static struct new_utsname *init_utsname(void)
+{
+       static struct new_utsname n = (struct new_utsname) {
+               .release = "liblockdep",
+               .version = LIBLOCKDEP_VERSION,
+       };
+
+       return &n;
+}
+
+#define print_tainted() ""
+#define static_obj(x) 1
+
+#define debug_show_all_locks()
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/module.h b/tools/lib/lockdep/uinclude/linux/module.h
new file mode 100644 (file)
index 0000000..09c7a7b
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _LIBLOCKDEP_LINUX_MODULE_H_
+#define _LIBLOCKDEP_LINUX_MODULE_H_
+
+#define module_param(name, type, perm)
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/mutex.h b/tools/lib/lockdep/uinclude/linux/mutex.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/poison.h b/tools/lib/lockdep/uinclude/linux/poison.h
new file mode 100644 (file)
index 0000000..0c27bdf
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../include/linux/poison.h"
diff --git a/tools/lib/lockdep/uinclude/linux/prefetch.h b/tools/lib/lockdep/uinclude/linux/prefetch.h
new file mode 100644 (file)
index 0000000..d73fe6f
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _LIBLOCKDEP_LINUX_PREFETCH_H_
+#define _LIBLOCKDEP_LINUX_PREFETCH_H
+
+static inline void prefetch(void *a __attribute__((unused))) { }
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/proc_fs.h b/tools/lib/lockdep/uinclude/linux/proc_fs.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/rbtree.h b/tools/lib/lockdep/uinclude/linux/rbtree.h
new file mode 100644 (file)
index 0000000..965901d
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../include/linux/rbtree.h"
diff --git a/tools/lib/lockdep/uinclude/linux/rbtree_augmented.h b/tools/lib/lockdep/uinclude/linux/rbtree_augmented.h
new file mode 100644 (file)
index 0000000..c375947
--- /dev/null
@@ -0,0 +1,2 @@
+#define __always_inline
+#include "../../../include/linux/rbtree_augmented.h"
diff --git a/tools/lib/lockdep/uinclude/linux/rcu.h b/tools/lib/lockdep/uinclude/linux/rcu.h
new file mode 100644 (file)
index 0000000..4c99fcb
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _LIBLOCKDEP_RCU_H_
+#define _LIBLOCKDEP_RCU_H_
+
+int rcu_scheduler_active;
+
+static inline int rcu_lockdep_current_cpu_online(void)
+{
+       return 1;
+}
+
+static inline int rcu_is_cpu_idle(void)
+{
+       return 1;
+}
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/seq_file.h b/tools/lib/lockdep/uinclude/linux/seq_file.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/spinlock.h b/tools/lib/lockdep/uinclude/linux/spinlock.h
new file mode 100644 (file)
index 0000000..68c1aa2
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _LIBLOCKDEP_SPINLOCK_H_
+#define _LIBLOCKDEP_SPINLOCK_H_
+
+#include <pthread.h>
+#include <stdbool.h>
+
+#define arch_spinlock_t pthread_mutex_t
+#define __ARCH_SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER
+
+static inline void arch_spin_lock(arch_spinlock_t *mutex)
+{
+       pthread_mutex_lock(mutex);
+}
+
+static inline void arch_spin_unlock(arch_spinlock_t *mutex)
+{
+       pthread_mutex_unlock(mutex);
+}
+
+static inline bool arch_spin_is_locked(arch_spinlock_t *mutex)
+{
+       return true;
+}
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/stacktrace.h b/tools/lib/lockdep/uinclude/linux/stacktrace.h
new file mode 100644 (file)
index 0000000..39aecc6
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _LIBLOCKDEP_LINUX_STACKTRACE_H_
+#define _LIBLOCKDEP_LINUX_STACKTRACE_H_
+
+#include <execinfo.h>
+
+struct stack_trace {
+       unsigned int nr_entries, max_entries;
+       unsigned long *entries;
+       int skip;
+};
+
+static inline void print_stack_trace(struct stack_trace *trace, int spaces)
+{
+       backtrace_symbols_fd((void **)trace->entries, trace->nr_entries, 1);
+}
+
+#define save_stack_trace(trace)        \
+       ((trace)->nr_entries =  \
+               backtrace((void **)(trace)->entries, (trace)->max_entries))
+
+static inline int dump_stack(void)
+{
+       void *array[64];
+       size_t size;
+
+       size = backtrace(array, 64);
+       backtrace_symbols_fd(array, size, 1);
+
+       return 0;
+}
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/stringify.h b/tools/lib/lockdep/uinclude/linux/stringify.h
new file mode 100644 (file)
index 0000000..05dfcd1
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _LIBLOCKDEP_LINUX_STRINGIFY_H_
+#define _LIBLOCKDEP_LINUX_STRINGIFY_H_
+
+#define __stringify_1(x...)    #x
+#define __stringify(x...)      __stringify_1(x)
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/types.h b/tools/lib/lockdep/uinclude/linux/types.h
new file mode 100644 (file)
index 0000000..929938f
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef _LIBLOCKDEP_LINUX_TYPES_H_
+#define _LIBLOCKDEP_LINUX_TYPES_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#define __SANE_USERSPACE_TYPES__       /* For PPC64, to get LL64 types */
+#include <asm/types.h>
+
+struct page;
+struct kmem_cache;
+
+typedef unsigned gfp_t;
+
+typedef __u64 u64;
+typedef __s64 s64;
+
+typedef __u32 u32;
+typedef __s32 s32;
+
+typedef __u16 u16;
+typedef __s16 s16;
+
+typedef __u8  u8;
+typedef __s8  s8;
+
+#ifdef __CHECKER__
+#define __bitwise__ __attribute__((bitwise))
+#else
+#define __bitwise__
+#endif
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __bitwise__
+#else
+#define __bitwise
+#endif
+
+
+typedef __u16 __bitwise __le16;
+typedef __u16 __bitwise __be16;
+typedef __u32 __bitwise __le32;
+typedef __u32 __bitwise __be32;
+typedef __u64 __bitwise __le64;
+typedef __u64 __bitwise __be64;
+
+struct list_head {
+       struct list_head *next, *prev;
+};
+
+struct hlist_head {
+       struct hlist_node *first;
+};
+
+struct hlist_node {
+       struct hlist_node *next, **pprev;
+};
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/trace/events/lock.h b/tools/lib/lockdep/uinclude/trace/events/lock.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
index 0362d575de7d185752b2a23a53845236c71510f6..900fca01bdd3fcbc8617929a822ba5d90ba47ae0 100644 (file)
@@ -1606,6 +1606,24 @@ process_arg(struct event_format *event, struct print_arg *arg, char **tok)
 static enum event_type
 process_op(struct event_format *event, struct print_arg *arg, char **tok);
 
+/*
+ * For __print_symbolic() and __print_flags, we need to completely
+ * evaluate the first argument, which defines what to print next.
+ */
+static enum event_type
+process_field_arg(struct event_format *event, struct print_arg *arg, char **tok)
+{
+       enum event_type type;
+
+       type = process_arg(event, arg, tok);
+
+       while (type == EVENT_OP) {
+               type = process_op(event, arg, tok);
+       }
+
+       return type;
+}
+
 static enum event_type
 process_cond(struct event_format *event, struct print_arg *top, char **tok)
 {
@@ -2371,7 +2389,7 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok)
                goto out_free;
        }
 
-       type = process_arg(event, field, &token);
+       type = process_field_arg(event, field, &token);
 
        /* Handle operations in the first argument */
        while (type == EVENT_OP)
@@ -2424,7 +2442,8 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
                goto out_free;
        }
 
-       type = process_arg(event, field, &token);
+       type = process_field_arg(event, field, &token);
+
        if (test_type_token(type, token, EVENT_DELIM, ","))
                goto out_free_field;
 
@@ -3446,7 +3465,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                 * is in the bottom half of the 32 bit field.
                 */
                offset &= 0xffff;
-               val = (unsigned long long)(data + offset);
+               val = (unsigned long long)((unsigned long)data + offset);
                break;
        default: /* not sure what to do there */
                return 0;
@@ -4080,6 +4099,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
        unsigned long long val;
        struct func_map *func;
        const char *saveptr;
+       struct trace_seq p;
        char *bprint_fmt = NULL;
        char format[32];
        int show_func;
@@ -4287,8 +4307,12 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
                                format[len] = 0;
                                if (!len_as_arg)
                                        len_arg = -1;
-                               print_str_arg(s, data, size, event,
+                               /* Use helper trace_seq */
+                               trace_seq_init(&p);
+                               print_str_arg(&p, data, size, event,
                                              format, len_arg, arg);
+                               trace_seq_terminate(&p);
+                               trace_seq_puts(s, p.buffer);
                                arg = arg->next;
                                break;
                        default:
index 43b42c4f4a915ad96be76c737b63feee12925de2..c407897f04359c9e253fbcb27368926419aced51 100644 (file)
@@ -57,6 +57,8 @@ OPTIONS
 -t::
 --tid=::
         Record events on existing thread ID (comma separated list).
+        This option also disables inheritance by default.  Enable it by adding
+        --inherit.
 
 -u::
 --uid=::
@@ -201,11 +203,11 @@ abort events and some memory events in precise mode on modern Intel CPUs.
 --transaction::
 Record transaction flags for transaction related events.
 
---force-per-cpu::
-Force the use of per-cpu mmaps.  By default, when tasks are specified (i.e. -p,
--t or -u options) per-thread mmaps are created.  This option overrides that and
-forces per-cpu mmaps.  A side-effect of that is that inheritance is
-automatically enabled.  Add the -i option also to disable inheritance.
+--per-thread::
+Use per-thread mmaps.  By default per-cpu mmaps are created.  This option
+overrides that and uses per-thread mmaps.  A side-effect of that is that
+inheritance is automatically disabled.  --per-thread is ignored with a warning
+if combined with -a or -C options.
 
 SEE ALSO
 --------
index e9cbfcddfa3f608ee19b2366802f7f405f78f535..cfdbb1e045b53514f919e6c96acb48d0b6df4be3 100644 (file)
@@ -203,6 +203,12 @@ OPTIONS
 --show-kernel-path::
        Try to resolve the path of [kernel.kallsyms]
 
+--show-task-events
+       Display task related events (e.g. FORK, COMM, EXIT).
+
+--show-mmap-events
+       Display mmap related events (e.g. MMAP, MMAP2).
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-script-perl[1],
index 3ff8bd4f0b4d94163d77231881b462e50bbd4e17..271dd4ed5b05bc8abf19699f1eef64f26b4f7d3b 100644 (file)
@@ -8,8 +8,7 @@ perf-timechart - Tool to visualize total system behavior during a workload
 SYNOPSIS
 --------
 [verse]
-'perf timechart' record <command>
-'perf timechart' [<options>]
+'perf timechart' [<timechart options>] {record} [<record options>]
 
 DESCRIPTION
 -----------
@@ -21,8 +20,8 @@ There are two variants of perf timechart:
   'perf timechart' to turn a trace into a Scalable Vector Graphics file,
   that can be viewed with popular SVG viewers such as 'Inkscape'.
 
-OPTIONS
--------
+TIMECHART OPTIONS
+-----------------
 -o::
 --output=::
         Select the output file (default: output.svg)
@@ -35,6 +34,9 @@ OPTIONS
 -P::
 --power-only::
         Only output the CPU power section of the diagram
+-T::
+--tasks-only::
+        Don't output processor state transitions
 -p::
 --process::
         Select the processes to display, by name or PID
@@ -54,6 +56,22 @@ $ perf timechart
 
   Written 10.2 seconds of trace to output.svg.
 
+-n::
+--proc-num::
+        Print task info for at least given number of tasks.
+
+RECORD OPTIONS
+--------------
+-P::
+--power-only::
+        Record only power-related events
+-T::
+--tasks-only::
+        Record only tasks-related events
+-g::
+--callchain::
+        Do call-graph (stack chain/backtrace) recording
+
 SEE ALSO
 --------
 linkperf:perf-record[1]
index 7de01dd7968898c18e34f40914017ae549a3f618..cdd8d4946dba8f85b6ef6f56062067dd1b2dd622 100644 (file)
@@ -50,7 +50,6 @@ Default is to monitor all CPUS.
 --count-filter=<count>::
        Only display functions with more events than this.
 
--g::
 --group::
         Put the counters into a counter group.
 
@@ -143,12 +142,12 @@ Default is to monitor all CPUS.
 --asm-raw::
        Show raw instruction encoding of assembly instructions.
 
--G::
+-g::
        Enables call-graph (stack chain/backtrace) recording.
 
 --call-graph::
        Setup and enable call-graph (stack chain/backtrace) recording,
-       implies -G.
+       implies -g.
 
 --max-stack::
        Set the stack depth limit when parsing the callchain, anything
index 4835618a5608892054de87d497e45e644fdeb0da..eefb9fb0c02f991ba00007b8885685ff248a85dc 100644 (file)
@@ -60,8 +60,11 @@ endef
 
 #
 # Needed if no target specified:
+# (Except for tags and TAGS targets. The reason is that the
+# Makefile does not treat tags/TAGS as targets but as files
+# and thus won't rebuilt them once they are in place.)
 #
-all:
+all tags TAGS:
        $(print_msg)
        $(make)
 
@@ -77,3 +80,5 @@ clean:
 %:
        $(print_msg)
        $(make)
+
+.PHONY: tags TAGS
index 7fc8f179cae74d08e2cc507031c773009723bb00..e416ccc7d83180d203e7dd0cea0f64cc49819fec 100644 (file)
@@ -840,9 +840,9 @@ ifndef NO_LIBPYTHON
                $(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'; \
                $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
 endif
-       $(call QUIET_INSTALL, bash_completion-script) \
+       $(call QUIET_INSTALL, perf_completion-script) \
                $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \
-               $(INSTALL) bash_completion '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf'
+               $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf'
        $(call QUIET_INSTALL, tests) \
                $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
                $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
index 7c8020a32784abcd6d44223dc3a5586f7ba7f3f0..65615a8bc25e7ff02a1a96f78114decd54df6212 100644 (file)
@@ -800,6 +800,7 @@ static struct perf_record record = {
                .freq                = 4000,
                .target              = {
                        .uses_mmap   = true,
+                       .default_per_cpu = true,
                },
        },
 };
@@ -842,8 +843,9 @@ const struct option record_options[] = {
        OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
        OPT_STRING('o', "output", &record.file.path, "file",
                    "output file name"),
-       OPT_BOOLEAN('i', "no-inherit", &record.opts.no_inherit,
-                   "child tasks do not inherit counters"),
+       OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
+                       &record.opts.no_inherit_set,
+                       "child tasks do not inherit counters"),
        OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
        OPT_CALLBACK('m', "mmap-pages", &record.opts.mmap_pages, "pages",
                     "number of mmap data pages",
@@ -888,8 +890,8 @@ const struct option record_options[] = {
                    "sample by weight (on special events only)"),
        OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
                    "sample transaction flags (special events only)"),
-       OPT_BOOLEAN(0, "force-per-cpu", &record.opts.target.force_per_cpu,
-                   "force the use of per-cpu mmaps"),
+       OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
+                   "use per-thread mmaps"),
        OPT_END()
 };
 
@@ -938,6 +940,9 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
                goto out_symbol_exit;
        }
 
+       if (rec->opts.target.tid && !rec->opts.no_inherit_set)
+               rec->opts.no_inherit = true;
+
        err = target__validate(&rec->opts.target);
        if (err) {
                target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
index baf17989a216137064e089d4e2f65fef07a4357f..952dce979252f5e9d71f8093d0b71f4367c0a1f5 100644 (file)
@@ -280,6 +280,30 @@ static int perf_session__check_output_opt(struct perf_session *session)
                set_print_ip_opts(&evsel->attr);
        }
 
+       /*
+        * set default for tracepoints to print symbols only
+        * if callchains are present
+        */
+       if (symbol_conf.use_callchain &&
+           !output[PERF_TYPE_TRACEPOINT].user_set) {
+               struct perf_event_attr *attr;
+
+               j = PERF_TYPE_TRACEPOINT;
+               evsel = perf_session__find_first_evtype(session, j);
+               if (evsel == NULL)
+                       goto out;
+
+               attr = &evsel->attr;
+
+               if (attr->sample_type & PERF_SAMPLE_CALLCHAIN) {
+                       output[j].fields |= PERF_OUTPUT_IP;
+                       output[j].fields |= PERF_OUTPUT_SYM;
+                       output[j].fields |= PERF_OUTPUT_DSO;
+                       set_print_ip_opts(attr);
+               }
+       }
+
+out:
        return 0;
 }
 
@@ -288,7 +312,6 @@ static void print_sample_start(struct perf_sample *sample,
                               struct perf_evsel *evsel)
 {
        struct perf_event_attr *attr = &evsel->attr;
-       const char *evname = NULL;
        unsigned long secs;
        unsigned long usecs;
        unsigned long long nsecs;
@@ -323,11 +346,6 @@ static void print_sample_start(struct perf_sample *sample,
                usecs = nsecs / NSECS_PER_USEC;
                printf("%5lu.%06lu: ", secs, usecs);
        }
-
-       if (PRINT_FIELD(EVNAME)) {
-               evname = perf_evsel__name(evsel);
-               printf("%s: ", evname ? evname : "[unknown]");
-       }
 }
 
 static bool is_bts_event(struct perf_event_attr *attr)
@@ -434,6 +452,11 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
 
        print_sample_start(sample, thread, evsel);
 
+       if (PRINT_FIELD(EVNAME)) {
+               const char *evname = perf_evsel__name(evsel);
+               printf("%s: ", evname ? evname : "[unknown]");
+       }
+
        if (is_bts_event(attr)) {
                print_sample_bts(event, sample, evsel, machine, thread);
                return;
@@ -549,6 +572,8 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 struct perf_script {
        struct perf_tool        tool;
        struct perf_session     *session;
+       bool                    show_task_events;
+       bool                    show_mmap_events;
 };
 
 static int process_attr(struct perf_tool *tool, union perf_event *event,
@@ -579,6 +604,163 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
        return perf_evsel__check_attr(evsel, scr->session);
 }
 
+static int process_comm_event(struct perf_tool *tool,
+                             union perf_event *event,
+                             struct perf_sample *sample,
+                             struct machine *machine)
+{
+       struct thread *thread;
+       struct perf_script *script = container_of(tool, struct perf_script, tool);
+       struct perf_session *session = script->session;
+       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+       int ret = -1;
+
+       thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid);
+       if (thread == NULL) {
+               pr_debug("problem processing COMM event, skipping it.\n");
+               return -1;
+       }
+
+       if (perf_event__process_comm(tool, event, sample, machine) < 0)
+               goto out;
+
+       if (!evsel->attr.sample_id_all) {
+               sample->cpu = 0;
+               sample->time = 0;
+               sample->tid = event->comm.tid;
+               sample->pid = event->comm.pid;
+       }
+       print_sample_start(sample, thread, evsel);
+       perf_event__fprintf(event, stdout);
+       ret = 0;
+
+out:
+       return ret;
+}
+
+static int process_fork_event(struct perf_tool *tool,
+                             union perf_event *event,
+                             struct perf_sample *sample,
+                             struct machine *machine)
+{
+       struct thread *thread;
+       struct perf_script *script = container_of(tool, struct perf_script, tool);
+       struct perf_session *session = script->session;
+       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+
+       if (perf_event__process_fork(tool, event, sample, machine) < 0)
+               return -1;
+
+       thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
+       if (thread == NULL) {
+               pr_debug("problem processing FORK event, skipping it.\n");
+               return -1;
+       }
+
+       if (!evsel->attr.sample_id_all) {
+               sample->cpu = 0;
+               sample->time = event->fork.time;
+               sample->tid = event->fork.tid;
+               sample->pid = event->fork.pid;
+       }
+       print_sample_start(sample, thread, evsel);
+       perf_event__fprintf(event, stdout);
+
+       return 0;
+}
+static int process_exit_event(struct perf_tool *tool,
+                             union perf_event *event,
+                             struct perf_sample *sample,
+                             struct machine *machine)
+{
+       struct thread *thread;
+       struct perf_script *script = container_of(tool, struct perf_script, tool);
+       struct perf_session *session = script->session;
+       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+
+       thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
+       if (thread == NULL) {
+               pr_debug("problem processing EXIT event, skipping it.\n");
+               return -1;
+       }
+
+       if (!evsel->attr.sample_id_all) {
+               sample->cpu = 0;
+               sample->time = 0;
+               sample->tid = event->comm.tid;
+               sample->pid = event->comm.pid;
+       }
+       print_sample_start(sample, thread, evsel);
+       perf_event__fprintf(event, stdout);
+
+       if (perf_event__process_exit(tool, event, sample, machine) < 0)
+               return -1;
+
+       return 0;
+}
+
+static int process_mmap_event(struct perf_tool *tool,
+                             union perf_event *event,
+                             struct perf_sample *sample,
+                             struct machine *machine)
+{
+       struct thread *thread;
+       struct perf_script *script = container_of(tool, struct perf_script, tool);
+       struct perf_session *session = script->session;
+       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+
+       if (perf_event__process_mmap(tool, event, sample, machine) < 0)
+               return -1;
+
+       thread = machine__findnew_thread(machine, event->mmap.pid, event->mmap.tid);
+       if (thread == NULL) {
+               pr_debug("problem processing MMAP event, skipping it.\n");
+               return -1;
+       }
+
+       if (!evsel->attr.sample_id_all) {
+               sample->cpu = 0;
+               sample->time = 0;
+               sample->tid = event->mmap.tid;
+               sample->pid = event->mmap.pid;
+       }
+       print_sample_start(sample, thread, evsel);
+       perf_event__fprintf(event, stdout);
+
+       return 0;
+}
+
+static int process_mmap2_event(struct perf_tool *tool,
+                             union perf_event *event,
+                             struct perf_sample *sample,
+                             struct machine *machine)
+{
+       struct thread *thread;
+       struct perf_script *script = container_of(tool, struct perf_script, tool);
+       struct perf_session *session = script->session;
+       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+
+       if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
+               return -1;
+
+       thread = machine__findnew_thread(machine, event->mmap2.pid, event->mmap2.tid);
+       if (thread == NULL) {
+               pr_debug("problem processing MMAP2 event, skipping it.\n");
+               return -1;
+       }
+
+       if (!evsel->attr.sample_id_all) {
+               sample->cpu = 0;
+               sample->time = 0;
+               sample->tid = event->mmap2.tid;
+               sample->pid = event->mmap2.pid;
+       }
+       print_sample_start(sample, thread, evsel);
+       perf_event__fprintf(event, stdout);
+
+       return 0;
+}
+
 static void sig_handler(int sig __maybe_unused)
 {
        session_done = 1;
@@ -590,6 +772,17 @@ static int __cmd_script(struct perf_script *script)
 
        signal(SIGINT, sig_handler);
 
+       /* override event processing functions */
+       if (script->show_task_events) {
+               script->tool.comm = process_comm_event;
+               script->tool.fork = process_fork_event;
+               script->tool.exit = process_exit_event;
+       }
+       if (script->show_mmap_events) {
+               script->tool.mmap = process_mmap_event;
+               script->tool.mmap2 = process_mmap2_event;
+       }
+
        ret = perf_session__process_events(script->session, &script->tool);
 
        if (debug_mode)
@@ -1352,6 +1545,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                    "display extended information from perf.data file"),
        OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
                    "Show the path of [kernel.kallsyms]"),
+       OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
+                   "Show the fork/comm/exit events"),
+       OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
+                   "Show the mmap events"),
        OPT_END()
        };
        const char * const script_usage[] = {
index ee0d565f83e300f57d21d465a9f65180f5a74618..dab98b50c9feb800eac1652d4c66d2cf4c691c97 100644 (file)
@@ -138,6 +138,7 @@ static const char           *post_cmd                       = NULL;
 static bool                    sync_run                        = false;
 static unsigned int            interval                        = 0;
 static unsigned int            initial_delay                   = 0;
+static unsigned int            unit_width                      = 4; /* strlen("unit") */
 static bool                    forever                         = false;
 static struct timespec         ref_time;
 static struct cpu_map          *aggr_map;
@@ -461,17 +462,17 @@ static void print_interval(void)
        if (num_print_interval == 0 && !csv_output) {
                switch (aggr_mode) {
                case AGGR_SOCKET:
-                       fprintf(output, "#           time socket cpus             counts events\n");
+                       fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
                        break;
                case AGGR_CORE:
-                       fprintf(output, "#           time core         cpus             counts events\n");
+                       fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
                        break;
                case AGGR_NONE:
-                       fprintf(output, "#           time CPU                 counts events\n");
+                       fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
                        break;
                case AGGR_GLOBAL:
                default:
-                       fprintf(output, "#           time             counts events\n");
+                       fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
                }
        }
 
@@ -516,6 +517,7 @@ static int __run_perf_stat(int argc, const char **argv)
        unsigned long long t0, t1;
        struct perf_evsel *counter;
        struct timespec ts;
+       size_t l;
        int status = 0;
        const bool forks = (argc > 0);
 
@@ -565,6 +567,10 @@ static int __run_perf_stat(int argc, const char **argv)
                        return -1;
                }
                counter->supported = true;
+
+               l = strlen(counter->unit);
+               if (l > unit_width)
+                       unit_width = l;
        }
 
        if (perf_evlist__apply_filters(evsel_list)) {
@@ -704,14 +710,25 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
 static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
 {
        double msecs = avg / 1e6;
-       const char *fmt = csv_output ? "%.6f%s%s" : "%18.6f%s%-25s";
+       const char *fmt_v, *fmt_n;
        char name[25];
 
+       fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
+       fmt_n = csv_output ? "%s" : "%-25s";
+
        aggr_printout(evsel, cpu, nr);
 
        scnprintf(name, sizeof(name), "%s%s",
                  perf_evsel__name(evsel), csv_output ? "" : " (msec)");
-       fprintf(output, fmt, msecs, csv_sep, name);
+
+       fprintf(output, fmt_v, msecs, csv_sep);
+
+       if (csv_output)
+               fprintf(output, "%s%s", evsel->unit, csv_sep);
+       else
+               fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep);
+
+       fprintf(output, fmt_n, name);
 
        if (evsel->cgrp)
                fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
@@ -908,21 +925,31 @@ static void print_ll_cache_misses(int cpu,
 static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
 {
        double total, ratio = 0.0, total2;
+       double sc =  evsel->scale;
        const char *fmt;
 
-       if (csv_output)
-               fmt = "%.0f%s%s";
-       else if (big_num)
-               fmt = "%'18.0f%s%-25s";
-       else
-               fmt = "%18.0f%s%-25s";
+       if (csv_output) {
+               fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
+       } else {
+               if (big_num)
+                       fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
+               else
+                       fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
+       }
 
        aggr_printout(evsel, cpu, nr);
 
        if (aggr_mode == AGGR_GLOBAL)
                cpu = 0;
 
-       fprintf(output, fmt, avg, csv_sep, perf_evsel__name(evsel));
+       fprintf(output, fmt, avg, csv_sep);
+
+       if (evsel->unit)
+               fprintf(output, "%-*s%s",
+                       csv_output ? 0 : unit_width,
+                       evsel->unit, csv_sep);
+
+       fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
 
        if (evsel->cgrp)
                fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
@@ -941,7 +968,10 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
 
                if (total && avg) {
                        ratio = total / avg;
-                       fprintf(output, "\n                                             #   %5.2f  stalled cycles per insn", ratio);
+                       fprintf(output, "\n");
+                       if (aggr_mode == AGGR_NONE)
+                               fprintf(output, "        ");
+                       fprintf(output, "                                                  #   %5.2f  stalled cycles per insn", ratio);
                }
 
        } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
@@ -1061,6 +1091,7 @@ static void print_aggr(char *prefix)
 {
        struct perf_evsel *counter;
        int cpu, cpu2, s, s2, id, nr;
+       double uval;
        u64 ena, run, val;
 
        if (!(aggr_map || aggr_get_id))
@@ -1087,11 +1118,17 @@ static void print_aggr(char *prefix)
                        if (run == 0 || ena == 0) {
                                aggr_printout(counter, id, nr);
 
-                               fprintf(output, "%*s%s%*s",
+                               fprintf(output, "%*s%s",
                                        csv_output ? 0 : 18,
                                        counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
-                                       csv_sep,
-                                       csv_output ? 0 : -24,
+                                       csv_sep);
+
+                               fprintf(output, "%-*s%s",
+                                       csv_output ? 0 : unit_width,
+                                       counter->unit, csv_sep);
+
+                               fprintf(output, "%*s",
+                                       csv_output ? 0 : -25,
                                        perf_evsel__name(counter));
 
                                if (counter->cgrp)
@@ -1101,11 +1138,12 @@ static void print_aggr(char *prefix)
                                fputc('\n', output);
                                continue;
                        }
+                       uval = val * counter->scale;
 
                        if (nsec_counter(counter))
-                               nsec_printout(id, nr, counter, val);
+                               nsec_printout(id, nr, counter, uval);
                        else
-                               abs_printout(id, nr, counter, val);
+                               abs_printout(id, nr, counter, uval);
 
                        if (!csv_output) {
                                print_noise(counter, 1.0);
@@ -1128,16 +1166,21 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
        struct perf_stat *ps = counter->priv;
        double avg = avg_stats(&ps->res_stats[0]);
        int scaled = counter->counts->scaled;
+       double uval;
 
        if (prefix)
                fprintf(output, "%s", prefix);
 
        if (scaled == -1) {
-               fprintf(output, "%*s%s%*s",
+               fprintf(output, "%*s%s",
                        csv_output ? 0 : 18,
                        counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
-                       csv_sep,
-                       csv_output ? 0 : -24,
+                       csv_sep);
+               fprintf(output, "%-*s%s",
+                       csv_output ? 0 : unit_width,
+                       counter->unit, csv_sep);
+               fprintf(output, "%*s",
+                       csv_output ? 0 : -25,
                        perf_evsel__name(counter));
 
                if (counter->cgrp)
@@ -1147,10 +1190,12 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
                return;
        }
 
+       uval = avg * counter->scale;
+
        if (nsec_counter(counter))
-               nsec_printout(-1, 0, counter, avg);
+               nsec_printout(-1, 0, counter, uval);
        else
-               abs_printout(-1, 0, counter, avg);
+               abs_printout(-1, 0, counter, uval);
 
        print_noise(counter, avg);
 
@@ -1177,6 +1222,7 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
 static void print_counter(struct perf_evsel *counter, char *prefix)
 {
        u64 ena, run, val;
+       double uval;
        int cpu;
 
        for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
@@ -1188,14 +1234,20 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
                        fprintf(output, "%s", prefix);
 
                if (run == 0 || ena == 0) {
-                       fprintf(output, "CPU%*d%s%*s%s%*s",
+                       fprintf(output, "CPU%*d%s%*s%s",
                                csv_output ? 0 : -4,
                                perf_evsel__cpus(counter)->map[cpu], csv_sep,
                                csv_output ? 0 : 18,
                                counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
-                               csv_sep,
-                               csv_output ? 0 : -24,
-                               perf_evsel__name(counter));
+                               csv_sep);
+
+                               fprintf(output, "%-*s%s",
+                                       csv_output ? 0 : unit_width,
+                                       counter->unit, csv_sep);
+
+                               fprintf(output, "%*s",
+                                       csv_output ? 0 : -25,
+                                       perf_evsel__name(counter));
 
                        if (counter->cgrp)
                                fprintf(output, "%s%s",
@@ -1205,10 +1257,12 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
                        continue;
                }
 
+               uval = val * counter->scale;
+
                if (nsec_counter(counter))
-                       nsec_printout(cpu, 0, counter, val);
+                       nsec_printout(cpu, 0, counter, uval);
                else
-                       abs_printout(cpu, 0, counter, val);
+                       abs_printout(cpu, 0, counter, uval);
 
                if (!csv_output) {
                        print_noise(counter, 1.0);
index 41c9bde2fb67f1418faceaaf86475a163694bdeb..680632d7e26a1a372e8e918d92947cf8726ad166 100644 (file)
@@ -41,6 +41,7 @@
 #define SUPPORT_OLD_POWER_EVENTS 1
 #define PWR_EVENT_EXIT -1
 
+static int proc_num = 15;
 
 static unsigned int    numcpus;
 static u64             min_freq;       /* Lowest CPU frequency seen */
@@ -50,16 +51,12 @@ static u64          turbo_frequency;
 static u64             first_time, last_time;
 
 static bool            power_only;
+static bool            tasks_only;
+static bool            with_backtrace;
 
 
-struct per_pid;
 struct per_pidcomm;
-
 struct cpu_sample;
-struct power_event;
-struct wake_event;
-
-struct sample_wrapper;
 
 /*
  * Datastructure layout:
@@ -124,6 +121,7 @@ struct cpu_sample {
        u64 end_time;
        int type;
        int cpu;
+       const char *backtrace;
 };
 
 static struct per_pid *all_data;
@@ -145,12 +143,12 @@ struct wake_event {
        int waker;
        int wakee;
        u64 time;
+       const char *backtrace;
 };
 
 static struct power_event    *power_events;
 static struct wake_event     *wake_events;
 
-struct process_filter;
 struct process_filter {
        char                    *name;
        int                     pid;
@@ -229,7 +227,8 @@ static void pid_exit(int pid, u64 timestamp)
 }
 
 static void
-pid_put_sample(int pid, int type, unsigned int cpu, u64 start, u64 end)
+pid_put_sample(int pid, int type, unsigned int cpu, u64 start, u64 end,
+              const char *backtrace)
 {
        struct per_pid *p;
        struct per_pidcomm *c;
@@ -252,6 +251,7 @@ pid_put_sample(int pid, int type, unsigned int cpu, u64 start, u64 end)
        sample->type = type;
        sample->next = c->samples;
        sample->cpu = cpu;
+       sample->backtrace = backtrace;
        c->samples = sample;
 
        if (sample->type == TYPE_RUNNING && end > start && start > 0) {
@@ -299,50 +299,10 @@ static int process_exit_event(struct perf_tool *tool __maybe_unused,
        return 0;
 }
 
-struct trace_entry {
-       unsigned short          type;
-       unsigned char           flags;
-       unsigned char           preempt_count;
-       int                     pid;
-       int                     lock_depth;
-};
-
 #ifdef SUPPORT_OLD_POWER_EVENTS
 static int use_old_power_events;
-struct power_entry_old {
-       struct trace_entry te;
-       u64     type;
-       u64     value;
-       u64     cpu_id;
-};
 #endif
 
-struct power_processor_entry {
-       struct trace_entry te;
-       u32     state;
-       u32     cpu_id;
-};
-
-#define TASK_COMM_LEN 16
-struct wakeup_entry {
-       struct trace_entry te;
-       char comm[TASK_COMM_LEN];
-       int   pid;
-       int   prio;
-       int   success;
-};
-
-struct sched_switch {
-       struct trace_entry te;
-       char prev_comm[TASK_COMM_LEN];
-       int  prev_pid;
-       int  prev_prio;
-       long prev_state; /* Arjan weeps. */
-       char next_comm[TASK_COMM_LEN];
-       int  next_pid;
-       int  next_prio;
-};
-
 static void c_state_start(int cpu, u64 timestamp, int state)
 {
        cpus_cstate_start_times[cpu] = timestamp;
@@ -402,23 +362,23 @@ static void p_state_change(int cpu, u64 timestamp, u64 new_freq)
                        turbo_frequency = max_freq;
 }
 
-static void
-sched_wakeup(int cpu, u64 timestamp, int pid, struct trace_entry *te)
+static void sched_wakeup(int cpu, u64 timestamp, int waker, int wakee,
+                        u8 flags, const char *backtrace)
 {
        struct per_pid *p;
-       struct wakeup_entry *wake = (void *)te;
        struct wake_event *we = zalloc(sizeof(*we));
 
        if (!we)
                return;
 
        we->time = timestamp;
-       we->waker = pid;
+       we->waker = waker;
+       we->backtrace = backtrace;
 
-       if ((te->flags & TRACE_FLAG_HARDIRQ) || (te->flags & TRACE_FLAG_SOFTIRQ))
+       if ((flags & TRACE_FLAG_HARDIRQ) || (flags & TRACE_FLAG_SOFTIRQ))
                we->waker = -1;
 
-       we->wakee = wake->pid;
+       we->wakee = wakee;
        we->next = wake_events;
        wake_events = we;
        p = find_create_pid(we->wakee);
@@ -428,27 +388,31 @@ sched_wakeup(int cpu, u64 timestamp, int pid, struct trace_entry *te)
                p->current->state = TYPE_WAITING;
        }
        if (p && p->current && p->current->state == TYPE_BLOCKED) {
-               pid_put_sample(p->pid, p->current->state, cpu, p->current->state_since, timestamp);
+               pid_put_sample(p->pid, p->current->state, cpu,
+                              p->current->state_since, timestamp, NULL);
                p->current->state_since = timestamp;
                p->current->state = TYPE_WAITING;
        }
 }
 
-static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te)
+static void sched_switch(int cpu, u64 timestamp, int prev_pid, int next_pid,
+                        u64 prev_state, const char *backtrace)
 {
        struct per_pid *p = NULL, *prev_p;
-       struct sched_switch *sw = (void *)te;
 
+       prev_p = find_create_pid(prev_pid);
 
-       prev_p = find_create_pid(sw->prev_pid);
-
-       p = find_create_pid(sw->next_pid);
+       p = find_create_pid(next_pid);
 
        if (prev_p->current && prev_p->current->state != TYPE_NONE)
-               pid_put_sample(sw->prev_pid, TYPE_RUNNING, cpu, prev_p->current->state_since, timestamp);
+               pid_put_sample(prev_pid, TYPE_RUNNING, cpu,
+                              prev_p->current->state_since, timestamp,
+                              backtrace);
        if (p && p->current) {
                if (p->current->state != TYPE_NONE)
-                       pid_put_sample(sw->next_pid, p->current->state, cpu, p->current->state_since, timestamp);
+                       pid_put_sample(next_pid, p->current->state, cpu,
+                                      p->current->state_since, timestamp,
+                                      backtrace);
 
                p->current->state_since = timestamp;
                p->current->state = TYPE_RUNNING;
@@ -457,18 +421,97 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te)
        if (prev_p->current) {
                prev_p->current->state = TYPE_NONE;
                prev_p->current->state_since = timestamp;
-               if (sw->prev_state & 2)
+               if (prev_state & 2)
                        prev_p->current->state = TYPE_BLOCKED;
-               if (sw->prev_state == 0)
+               if (prev_state == 0)
                        prev_p->current->state = TYPE_WAITING;
        }
 }
 
+static const char *cat_backtrace(union perf_event *event,
+                                struct perf_sample *sample,
+                                struct machine *machine)
+{
+       struct addr_location al;
+       unsigned int i;
+       char *p = NULL;
+       size_t p_len;
+       u8 cpumode = PERF_RECORD_MISC_USER;
+       struct addr_location tal;
+       struct ip_callchain *chain = sample->callchain;
+       FILE *f = open_memstream(&p, &p_len);
+
+       if (!f) {
+               perror("open_memstream error");
+               return NULL;
+       }
+
+       if (!chain)
+               goto exit;
+
+       if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
+               fprintf(stderr, "problem processing %d event, skipping it.\n",
+                       event->header.type);
+               goto exit;
+       }
+
+       for (i = 0; i < chain->nr; i++) {
+               u64 ip;
+
+               if (callchain_param.order == ORDER_CALLEE)
+                       ip = chain->ips[i];
+               else
+                       ip = chain->ips[chain->nr - i - 1];
+
+               if (ip >= PERF_CONTEXT_MAX) {
+                       switch (ip) {
+                       case PERF_CONTEXT_HV:
+                               cpumode = PERF_RECORD_MISC_HYPERVISOR;
+                               break;
+                       case PERF_CONTEXT_KERNEL:
+                               cpumode = PERF_RECORD_MISC_KERNEL;
+                               break;
+                       case PERF_CONTEXT_USER:
+                               cpumode = PERF_RECORD_MISC_USER;
+                               break;
+                       default:
+                               pr_debug("invalid callchain context: "
+                                        "%"PRId64"\n", (s64) ip);
+
+                               /*
+                                * It seems the callchain is corrupted.
+                                * Discard all.
+                                */
+                               free(p);
+                               p = NULL;
+                               goto exit;
+                       }
+                       continue;
+               }
+
+               tal.filtered = false;
+               thread__find_addr_location(al.thread, machine, cpumode,
+                                          MAP__FUNCTION, ip, &tal);
+
+               if (tal.sym)
+                       fprintf(f, "..... %016" PRIx64 " %s\n", ip,
+                               tal.sym->name);
+               else
+                       fprintf(f, "..... %016" PRIx64 "\n", ip);
+       }
+
+exit:
+       fclose(f);
+
+       return p;
+}
+
 typedef int (*tracepoint_handler)(struct perf_evsel *evsel,
-                                 struct perf_sample *sample);
+                                 struct perf_sample *sample,
+                                 const char *backtrace);
 
 static int process_sample_event(struct perf_tool *tool __maybe_unused,
-                               union perf_event *event __maybe_unused,
+                               union perf_event *event,
                                struct perf_sample *sample,
                                struct perf_evsel *evsel,
                                struct machine *machine __maybe_unused)
@@ -485,81 +528,97 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 
        if (evsel->handler != NULL) {
                tracepoint_handler f = evsel->handler;
-               return f(evsel, sample);
+               return f(evsel, sample, cat_backtrace(event, sample, machine));
        }
 
        return 0;
 }
 
 static int
-process_sample_cpu_idle(struct perf_evsel *evsel __maybe_unused,
-                       struct perf_sample *sample)
+process_sample_cpu_idle(struct perf_evsel *evsel,
+                       struct perf_sample *sample,
+                       const char *backtrace __maybe_unused)
 {
-       struct power_processor_entry *ppe = sample->raw_data;
+       u32 state = perf_evsel__intval(evsel, sample, "state");
+       u32 cpu_id = perf_evsel__intval(evsel, sample, "cpu_id");
 
-       if (ppe->state == (u32) PWR_EVENT_EXIT)
-               c_state_end(ppe->cpu_id, sample->time);
+       if (state == (u32)PWR_EVENT_EXIT)
+               c_state_end(cpu_id, sample->time);
        else
-               c_state_start(ppe->cpu_id, sample->time, ppe->state);
+               c_state_start(cpu_id, sample->time, state);
        return 0;
 }
 
 static int
-process_sample_cpu_frequency(struct perf_evsel *evsel __maybe_unused,
-                            struct perf_sample *sample)
+process_sample_cpu_frequency(struct perf_evsel *evsel,
+                            struct perf_sample *sample,
+                            const char *backtrace __maybe_unused)
 {
-       struct power_processor_entry *ppe = sample->raw_data;
+       u32 state = perf_evsel__intval(evsel, sample, "state");
+       u32 cpu_id = perf_evsel__intval(evsel, sample, "cpu_id");
 
-       p_state_change(ppe->cpu_id, sample->time, ppe->state);
+       p_state_change(cpu_id, sample->time, state);
        return 0;
 }
 
 static int
-process_sample_sched_wakeup(struct perf_evsel *evsel __maybe_unused,
-                           struct perf_sample *sample)
+process_sample_sched_wakeup(struct perf_evsel *evsel,
+                           struct perf_sample *sample,
+                           const char *backtrace)
 {
-       struct trace_entry *te = sample->raw_data;
+       u8 flags = perf_evsel__intval(evsel, sample, "common_flags");
+       int waker = perf_evsel__intval(evsel, sample, "common_pid");
+       int wakee = perf_evsel__intval(evsel, sample, "pid");
 
-       sched_wakeup(sample->cpu, sample->time, sample->pid, te);
+       sched_wakeup(sample->cpu, sample->time, waker, wakee, flags, backtrace);
        return 0;
 }
 
 static int
-process_sample_sched_switch(struct perf_evsel *evsel __maybe_unused,
-                           struct perf_sample *sample)
+process_sample_sched_switch(struct perf_evsel *evsel,
+                           struct perf_sample *sample,
+                           const char *backtrace)
 {
-       struct trace_entry *te = sample->raw_data;
+       int prev_pid = perf_evsel__intval(evsel, sample, "prev_pid");
+       int next_pid = perf_evsel__intval(evsel, sample, "next_pid");
+       u64 prev_state = perf_evsel__intval(evsel, sample, "prev_state");
 
-       sched_switch(sample->cpu, sample->time, te);
+       sched_switch(sample->cpu, sample->time, prev_pid, next_pid, prev_state,
+                    backtrace);
        return 0;
 }
 
 #ifdef SUPPORT_OLD_POWER_EVENTS
 static int
-process_sample_power_start(struct perf_evsel *evsel __maybe_unused,
-                          struct perf_sample *sample)
+process_sample_power_start(struct perf_evsel *evsel,
+                          struct perf_sample *sample,
+                          const char *backtrace __maybe_unused)
 {
-       struct power_entry_old *peo = sample->raw_data;
+       u64 cpu_id = perf_evsel__intval(evsel, sample, "cpu_id");
+       u64 value = perf_evsel__intval(evsel, sample, "value");
 
-       c_state_start(peo->cpu_id, sample->time, peo->value);
+       c_state_start(cpu_id, sample->time, value);
        return 0;
 }
 
 static int
 process_sample_power_end(struct perf_evsel *evsel __maybe_unused,
-                        struct perf_sample *sample)
+                        struct perf_sample *sample,
+                        const char *backtrace __maybe_unused)
 {
        c_state_end(sample->cpu, sample->time);
        return 0;
 }
 
 static int
-process_sample_power_frequency(struct perf_evsel *evsel __maybe_unused,
-                              struct perf_sample *sample)
+process_sample_power_frequency(struct perf_evsel *evsel,
+                              struct perf_sample *sample,
+                              const char *backtrace __maybe_unused)
 {
-       struct power_entry_old *peo = sample->raw_data;
+       u64 cpu_id = perf_evsel__intval(evsel, sample, "cpu_id");
+       u64 value = perf_evsel__intval(evsel, sample, "value");
 
-       p_state_change(peo->cpu_id, sample->time, peo->value);
+       p_state_change(cpu_id, sample->time, value);
        return 0;
 }
 #endif /* SUPPORT_OLD_POWER_EVENTS */
@@ -739,11 +798,12 @@ static void draw_wakeups(void)
                }
 
                if (we->waker == -1)
-                       svg_interrupt(we->time, to);
+                       svg_interrupt(we->time, to, we->backtrace);
                else if (from && to && abs(from - to) == 1)
-                       svg_wakeline(we->time, from, to);
+                       svg_wakeline(we->time, from, to, we->backtrace);
                else
-                       svg_partial_wakeline(we->time, from, task_from, to, task_to);
+                       svg_partial_wakeline(we->time, from, task_from, to,
+                                            task_to, we->backtrace);
                we = we->next;
 
                free(task_from);
@@ -796,11 +856,20 @@ static void draw_process_bars(void)
                        sample = c->samples;
                        while (sample) {
                                if (sample->type == TYPE_RUNNING)
-                                       svg_sample(Y, sample->cpu, sample->start_time, sample->end_time);
+                                       svg_running(Y, sample->cpu,
+                                                   sample->start_time,
+                                                   sample->end_time,
+                                                   sample->backtrace);
                                if (sample->type == TYPE_BLOCKED)
-                                       svg_box(Y, sample->start_time, sample->end_time, "blocked");
+                                       svg_blocked(Y, sample->cpu,
+                                                   sample->start_time,
+                                                   sample->end_time,
+                                                   sample->backtrace);
                                if (sample->type == TYPE_WAITING)
-                                       svg_waiting(Y, sample->start_time, sample->end_time);
+                                       svg_waiting(Y, sample->cpu,
+                                                   sample->start_time,
+                                                   sample->end_time,
+                                                   sample->backtrace);
                                sample = sample->next;
                        }
 
@@ -911,7 +980,7 @@ static int determine_display_tasks(u64 threshold)
                /* no exit marker, task kept running to the end */
                if (p->end_time == 0)
                        p->end_time = last_time;
-               if (p->total_time >= threshold && !power_only)
+               if (p->total_time >= threshold)
                        p->display = 1;
 
                c = p->all;
@@ -922,7 +991,7 @@ static int determine_display_tasks(u64 threshold)
                        if (c->start_time == 1)
                                c->start_time = first_time;
 
-                       if (c->total_time >= threshold && !power_only) {
+                       if (c->total_time >= threshold) {
                                c->display = 1;
                                count++;
                        }
@@ -945,15 +1014,19 @@ static void write_svg_file(const char *filename)
 {
        u64 i;
        int count;
+       int thresh = TIME_THRESH;
 
        numcpus++;
 
+       if (power_only)
+               proc_num = 0;
 
-       count = determine_display_tasks(TIME_THRESH);
-
-       /* We'd like to show at least 15 tasks; be less picky if we have fewer */
-       if (count < 15)
-               count = determine_display_tasks(TIME_THRESH / 10);
+       /* We'd like to show at least proc_num tasks;
+        * be less picky if we have fewer */
+       do {
+               count = determine_display_tasks(thresh);
+               thresh /= 10;
+       } while (!process_filter && thresh && count < proc_num);
 
        open_svg(filename, numcpus, count, first_time, last_time);
 
@@ -964,9 +1037,12 @@ static void write_svg_file(const char *filename)
                svg_cpu_box(i, max_freq, turbo_frequency);
 
        draw_cpu_usage();
-       draw_process_bars();
-       draw_c_p_states();
-       draw_wakeups();
+       if (proc_num)
+               draw_process_bars();
+       if (!tasks_only)
+               draw_c_p_states();
+       if (proc_num)
+               draw_wakeups();
 
        svg_close();
 }
@@ -1031,50 +1107,92 @@ out_delete:
 
 static int __cmd_record(int argc, const char **argv)
 {
-#ifdef SUPPORT_OLD_POWER_EVENTS
-       const char * const record_old_args[] = {
+       unsigned int rec_argc, i, j;
+       const char **rec_argv;
+       const char **p;
+       unsigned int record_elems;
+
+       const char * const common_args[] = {
                "record", "-a", "-R", "-c", "1",
+       };
+       unsigned int common_args_nr = ARRAY_SIZE(common_args);
+
+       const char * const backtrace_args[] = {
+               "-g",
+       };
+       unsigned int backtrace_args_no = ARRAY_SIZE(backtrace_args);
+
+       const char * const power_args[] = {
+               "-e", "power:cpu_frequency",
+               "-e", "power:cpu_idle",
+       };
+       unsigned int power_args_nr = ARRAY_SIZE(power_args);
+
+       const char * const old_power_args[] = {
+#ifdef SUPPORT_OLD_POWER_EVENTS
                "-e", "power:power_start",
                "-e", "power:power_end",
                "-e", "power:power_frequency",
-               "-e", "sched:sched_wakeup",
-               "-e", "sched:sched_switch",
-       };
 #endif
-       const char * const record_new_args[] = {
-               "record", "-a", "-R", "-c", "1",
-               "-e", "power:cpu_frequency",
-               "-e", "power:cpu_idle",
+       };
+       unsigned int old_power_args_nr = ARRAY_SIZE(old_power_args);
+
+       const char * const tasks_args[] = {
                "-e", "sched:sched_wakeup",
                "-e", "sched:sched_switch",
        };
-       unsigned int rec_argc, i, j;
-       const char **rec_argv;
-       const char * const *record_args = record_new_args;
-       unsigned int record_elems = ARRAY_SIZE(record_new_args);
+       unsigned int tasks_args_nr = ARRAY_SIZE(tasks_args);
 
 #ifdef SUPPORT_OLD_POWER_EVENTS
        if (!is_valid_tracepoint("power:cpu_idle") &&
            is_valid_tracepoint("power:power_start")) {
                use_old_power_events = 1;
-               record_args = record_old_args;
-               record_elems = ARRAY_SIZE(record_old_args);
+               power_args_nr = 0;
+       } else {
+               old_power_args_nr = 0;
        }
 #endif
 
-       rec_argc = record_elems + argc - 1;
+       if (power_only)
+               tasks_args_nr = 0;
+
+       if (tasks_only) {
+               power_args_nr = 0;
+               old_power_args_nr = 0;
+       }
+
+       if (!with_backtrace)
+               backtrace_args_no = 0;
+
+       record_elems = common_args_nr + tasks_args_nr +
+               power_args_nr + old_power_args_nr + backtrace_args_no;
+
+       rec_argc = record_elems + argc;
        rec_argv = calloc(rec_argc + 1, sizeof(char *));
 
        if (rec_argv == NULL)
                return -ENOMEM;
 
-       for (i = 0; i < record_elems; i++)
-               rec_argv[i] = strdup(record_args[i]);
+       p = rec_argv;
+       for (i = 0; i < common_args_nr; i++)
+               *p++ = strdup(common_args[i]);
 
-       for (j = 1; j < (unsigned int)argc; j++, i++)
-               rec_argv[i] = argv[j];
+       for (i = 0; i < backtrace_args_no; i++)
+               *p++ = strdup(backtrace_args[i]);
 
-       return cmd_record(i, rec_argv, NULL);
+       for (i = 0; i < tasks_args_nr; i++)
+               *p++ = strdup(tasks_args[i]);
+
+       for (i = 0; i < power_args_nr; i++)
+               *p++ = strdup(power_args[i]);
+
+       for (i = 0; i < old_power_args_nr; i++)
+               *p++ = strdup(old_power_args[i]);
+
+       for (j = 1; j < (unsigned int)argc; j++)
+               *p++ = argv[j];
+
+       return cmd_record(rec_argc, rec_argv, NULL);
 }
 
 static int
@@ -1090,16 +1208,20 @@ int cmd_timechart(int argc, const char **argv,
                  const char *prefix __maybe_unused)
 {
        const char *output_name = "output.svg";
-       const struct option options[] = {
+       const struct option timechart_options[] = {
        OPT_STRING('i', "input", &input_name, "file", "input file name"),
        OPT_STRING('o', "output", &output_name, "file", "output file name"),
        OPT_INTEGER('w', "width", &svg_page_width, "page width"),
        OPT_BOOLEAN('P', "power-only", &power_only, "output power data only"),
+       OPT_BOOLEAN('T', "tasks-only", &tasks_only,
+                   "output processes data only"),
        OPT_CALLBACK('p', "process", NULL, "process",
                      "process selector. Pass a pid or process name.",
                       parse_process),
        OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
                    "Look for files with symbols relative to this directory"),
+       OPT_INTEGER('n', "proc-num", &proc_num,
+                   "min. number of tasks to print"),
        OPT_END()
        };
        const char * const timechart_usage[] = {
@@ -1107,15 +1229,39 @@ int cmd_timechart(int argc, const char **argv,
                NULL
        };
 
-       argc = parse_options(argc, argv, options, timechart_usage,
+       const struct option record_options[] = {
+       OPT_BOOLEAN('P', "power-only", &power_only, "output power data only"),
+       OPT_BOOLEAN('T', "tasks-only", &tasks_only,
+                   "output processes data only"),
+       OPT_BOOLEAN('g', "callchain", &with_backtrace, "record callchain"),
+       OPT_END()
+       };
+       const char * const record_usage[] = {
+               "perf timechart record [<options>]",
+               NULL
+       };
+       argc = parse_options(argc, argv, timechart_options, timechart_usage,
                        PARSE_OPT_STOP_AT_NON_OPTION);
 
+       if (power_only && tasks_only) {
+               pr_err("-P and -T options cannot be used at the same time.\n");
+               return -1;
+       }
+
        symbol__init();
 
-       if (argc && !strncmp(argv[0], "rec", 3))
+       if (argc && !strncmp(argv[0], "rec", 3)) {
+               argc = parse_options(argc, argv, record_options, record_usage,
+                                    PARSE_OPT_STOP_AT_NON_OPTION);
+
+               if (power_only && tasks_only) {
+                       pr_err("-P and -T options cannot be used at the same time.\n");
+                       return -1;
+               }
+
                return __cmd_record(argc, argv);
-       else if (argc)
-               usage_with_options(timechart_usage, options);
+       else if (argc)
+               usage_with_options(timechart_usage, timechart_options);
 
        setup_pager();
 
index 71e6402729a8616bf9b9fe8e2141ea08ac0bbca2..03d37a76c6122d6328034322dc9c3f99830b623d 100644 (file)
@@ -634,26 +634,9 @@ repeat:
        return NULL;
 }
 
-/* Tag samples to be skipped. */
-static const char *skip_symbols[] = {
-       "intel_idle",
-       "default_idle",
-       "native_safe_halt",
-       "cpu_idle",
-       "enter_idle",
-       "exit_idle",
-       "mwait_idle",
-       "mwait_idle_with_hints",
-       "poll_idle",
-       "ppc64_runlatch_off",
-       "pseries_dedicated_idle_sleep",
-       NULL
-};
-
 static int symbol_filter(struct map *map __maybe_unused, struct symbol *sym)
 {
        const char *name = sym->name;
-       int i;
 
        /*
         * ppc64 uses function descriptors and appends a '.' to the
@@ -671,12 +654,8 @@ static int symbol_filter(struct map *map __maybe_unused, struct symbol *sym)
            strstr(name, "_text_end"))
                return 1;
 
-       for (i = 0; skip_symbols[i]; i++) {
-               if (!strcmp(skip_symbols[i], name)) {
-                       sym->ignore = true;
-                       break;
-               }
-       }
+       if (symbol__is_idle(sym))
+               sym->ignore = true;
 
        return 0;
 }
@@ -1084,7 +1063,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
                            "dump the symbol table used for profiling"),
        OPT_INTEGER('f', "count-filter", &top.count_filter,
                    "only display functions with more events than this"),
-       OPT_BOOLEAN('g', "group", &opts->group,
+       OPT_BOOLEAN(0, "group", &opts->group,
                            "put the counters into a counter group"),
        OPT_BOOLEAN('i', "no-inherit", &opts->no_inherit,
                    "child tasks do not inherit counters"),
@@ -1105,7 +1084,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
                   " abort, in_tx, transaction"),
        OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
                    "Show a column with the number of samples"),
-       OPT_CALLBACK_NOOPT('G', NULL, &top.record_opts,
+       OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
                           NULL, "enables call-graph recording",
                           &callchain_opt),
        OPT_CALLBACK(0, "call-graph", &top.record_opts,
index 8be17fc462baff466a6aa25682f804c4b5fdd1dc..e9f345e2551a18be6e5a17af51b8547f89c5ddbb 100644 (file)
@@ -2158,7 +2158,6 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv)
        size_t printed = data->printed;
        struct trace *trace = data->trace;
        struct thread_trace *ttrace = thread->priv;
-       const char *color;
        double ratio;
 
        if (ttrace == NULL)
@@ -2166,17 +2165,9 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv)
 
        ratio = (double)ttrace->nr_events / trace->nr_events * 100.0;
 
-       color = PERF_COLOR_NORMAL;
-       if (ratio > 50.0)
-               color = PERF_COLOR_RED;
-       else if (ratio > 25.0)
-               color = PERF_COLOR_GREEN;
-       else if (ratio > 5.0)
-               color = PERF_COLOR_YELLOW;
-
-       printed += color_fprintf(fp, color, " %s (%d), ", thread__comm_str(thread), thread->tid);
+       printed += fprintf(fp, " %s (%d), ", thread__comm_str(thread), thread->tid);
        printed += fprintf(fp, "%lu events, ", ttrace->nr_events);
-       printed += color_fprintf(fp, color, "%.1f%%", ratio);
+       printed += fprintf(fp, "%.1f%%", ratio);
        printed += fprintf(fp, ", %.3f msec\n", ttrace->runtime_ms);
        printed += thread__dump_stats(ttrace, trace, fp);
 
similarity index 65%
rename from tools/perf/bash_completion
rename to tools/perf/perf-completion.sh
index 62e157db2e2b01e9400f9348d671fd9ba7267104..49494882d9bb8c1a65417589b20d691b08f57538 100644 (file)
@@ -1,4 +1,4 @@
-# perf completion
+# perf bash and zsh completion
 
 # Taken from git.git's completion script.
 __my_reassemble_comp_words_by_ref()
@@ -89,37 +89,113 @@ __ltrim_colon_completions()
        fi
 }
 
-type perf &>/dev/null &&
-_perf()
+__perfcomp ()
 {
-       local cur words cword prev cmd
+       COMPREPLY=( $( compgen -W "$1" -- "$2" ) )
+}
 
-       COMPREPLY=()
-       _get_comp_words_by_ref -n =: cur words cword prev
+__perfcomp_colon ()
+{
+       __perfcomp "$1" "$2"
+       __ltrim_colon_completions $cur
+}
+
+__perf_main ()
+{
+       local cmd
 
        cmd=${words[0]}
+       COMPREPLY=()
 
        # List perf subcommands or long options
        if [ $cword -eq 1 ]; then
                if [[ $cur == --* ]]; then
-                       COMPREPLY=( $( compgen -W '--help --version \
+                       __perfcomp '--help --version \
                        --exec-path --html-path --paginate --no-pager \
-                       --perf-dir --work-tree --debugfs-dir' -- "$cur" ) )
+                       --perf-dir --work-tree --debugfs-dir' -- "$cur"
                else
                        cmds=$($cmd --list-cmds)
-                       COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
+                       __perfcomp "$cmds" "$cur"
                fi
        # List possible events for -e option
        elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
                evts=$($cmd list --raw-dump)
-               COMPREPLY=( $( compgen -W '$evts' -- "$cur" ) )
-               __ltrim_colon_completions $cur
+               __perfcomp_colon "$evts" "$cur"
        # List long option names
        elif [[ $cur == --* ]];  then
                subcmd=${words[1]}
                opts=$($cmd $subcmd --list-opts)
-               COMPREPLY=( $( compgen -W '$opts' -- "$cur" ) )
+               __perfcomp "$opts" "$cur"
        fi
+}
+
+if [[ -n ${ZSH_VERSION-} ]]; then
+       autoload -U +X compinit && compinit
+
+       __perfcomp ()
+       {
+               emulate -L zsh
+
+               local c IFS=$' \t\n'
+               local -a array
+
+               for c in ${=1}; do
+                       case $c in
+                       --*=*|*.) ;;
+                       *) c="$c " ;;
+                       esac
+                       array[${#array[@]}+1]="$c"
+               done
+
+               compset -P '*[=:]'
+               compadd -Q -S '' -a -- array && _ret=0
+       }
+
+       __perfcomp_colon ()
+       {
+               emulate -L zsh
+
+               local cur_="${2-$cur}"
+               local c IFS=$' \t\n'
+               local -a array
+
+               if [[ "$cur_" == *:* ]]; then
+                       local colon_word=${cur_%"${cur_##*:}"}
+               fi
+
+               for c in ${=1}; do
+                       case $c in
+                       --*=*|*.) ;;
+                       *) c="$c " ;;
+                       esac
+                       array[$#array+1]=${c#"$colon_word"}
+               done
+
+               compset -P '*[=:]'
+               compadd -Q -S '' -a -- array && _ret=0
+       }
+
+       _perf ()
+       {
+               local _ret=1 cur cword prev
+               cur=${words[CURRENT]}
+               prev=${words[CURRENT-1]}
+               let cword=CURRENT-1
+               emulate ksh -c __perf_main
+               let _ret && _default && _ret=0
+               return _ret
+       }
+
+       compdef _perf perf
+       return
+fi
+
+type perf &>/dev/null &&
+_perf()
+{
+       local cur words cword prev
+       _get_comp_words_by_ref -n =: cur words cword prev
+       __perf_main
 } &&
 
 complete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \
index b079304bd53daa87ca61a428f4611046741f58e6..b23fed5275149adfb1b5f826730341ef6d63f8be 100644 (file)
@@ -254,6 +254,7 @@ struct perf_record_opts {
        bool         inherit_stat;
        bool         no_delay;
        bool         no_inherit;
+       bool         no_inherit_set;
        bool         no_samples;
        bool         raw_samples;
        bool         sample_address;
index 9079a25cd643cdabaf570d19131e4cc0e4fef7f6..44edcb2edcd50b7c4696477e88f6e12176555303 100644 (file)
@@ -3,5 +3,5 @@ command = record
 args    = -i kill >/dev/null 2>&1
 
 [event:base-record]
-sample_type=259
+sample_type=263
 inherit=0
index bb788c109fe6efa4ecb2ae5784efa49cf33bca73..c77814bf01e1a7f89857ba8742ce7ec7cbcfaf5e 100644 (file)
@@ -732,8 +732,7 @@ int perf_event__preprocess_sample(const union perf_event *event,
        if (thread == NULL)
                return -1;
 
-       if (symbol_conf.comm_list &&
-           !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread)))
+       if (thread__is_filtered(thread))
                goto out_filtered;
 
        dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
index bbc746aa571663d92e989bb5f3f2703c31c9a193..76fa76431329f9b252d15e1b49b43e18d05c6c0a 100644 (file)
@@ -819,8 +819,10 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
        if (evlist->threads == NULL)
                return -1;
 
-       if (target->force_per_cpu)
-               evlist->cpus = cpu_map__new(target->cpu_list);
+       if (target->default_per_cpu)
+               evlist->cpus = target->per_thread ?
+                                       cpu_map__dummy_new() :
+                                       cpu_map__new(target->cpu_list);
        else if (target__has_task(target))
                evlist->cpus = cpu_map__dummy_new();
        else if (!target__has_cpu(target) && !target->uses_mmap)
index 46dd4c2a41ce7e0a844e0b691c134e3ce23f55e6..b5fe7f9b2e15091f5d38db1044159177d9c15f27 100644 (file)
@@ -162,6 +162,8 @@ void perf_evsel__init(struct perf_evsel *evsel,
        evsel->idx         = idx;
        evsel->attr        = *attr;
        evsel->leader      = evsel;
+       evsel->unit        = "";
+       evsel->scale       = 1.0;
        INIT_LIST_HEAD(&evsel->node);
        hists__init(&evsel->hists);
        evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
@@ -572,6 +574,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
        struct perf_evsel *leader = evsel->leader;
        struct perf_event_attr *attr = &evsel->attr;
        int track = !evsel->idx; /* only the first counter needs these */
+       bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread;
 
        attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
        attr->inherit       = !opts->no_inherit;
@@ -645,7 +648,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
                }
        }
 
-       if (target__has_cpu(&opts->target) || opts->target.force_per_cpu)
+       if (target__has_cpu(&opts->target))
                perf_evsel__set_sample_bit(evsel, CPU);
 
        if (opts->period)
@@ -653,7 +656,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
 
        if (!perf_missing_features.sample_id_all &&
            (opts->sample_time || !opts->no_inherit ||
-            target__has_cpu(&opts->target) || opts->target.force_per_cpu))
+            target__has_cpu(&opts->target) || per_cpu))
                perf_evsel__set_sample_bit(evsel, TIME);
 
        if (opts->raw_samples) {
index 1ea7c92e6e3365aebbedbed37ae728e9473dbab5..8120eeb86ac16c4c5b86c931785233e85ea4ac16 100644 (file)
@@ -68,6 +68,8 @@ struct perf_evsel {
        u32                     ids;
        struct hists            hists;
        char                    *name;
+       double                  scale;
+       const char              *unit;
        struct event_format     *tp_format;
        union {
                void            *priv;
@@ -138,6 +140,7 @@ extern const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX];
 int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result,
                                            char *bf, size_t size);
 const char *perf_evsel__name(struct perf_evsel *evsel);
+
 const char *perf_evsel__group_name(struct perf_evsel *evsel);
 int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
 
index 369c03648f8846d3da12bf96a938f6e76485fbed..1cd035708931144dccbfdb68f4c1024903e45631 100644 (file)
@@ -2078,8 +2078,10 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
                if (evsel->idx == (int) desc[i].leader_idx) {
                        evsel->leader = evsel;
                        /* {anon_group} is a dummy name */
-                       if (strcmp(desc[i].name, "{anon_group}"))
+                       if (strcmp(desc[i].name, "{anon_group}")) {
                                evsel->group_name = desc[i].name;
+                               desc[i].name = NULL;
+                       }
                        evsel->nr_members = desc[i].nr_members;
 
                        if (i >= nr_groups || nr > 0) {
@@ -2105,7 +2107,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
 
        ret = 0;
 out_free:
-       while ((int) --i >= 0)
+       for (i = 0; i < nr_groups; i++)
                free(desc[i].name);
        free(desc);
 
index 6de6f89c2a6175c96570055f57ccbb83cc8c58b5..969cb8f0d88d0c77152fec5b187b53c21cfd44ef 100644 (file)
@@ -269,9 +269,10 @@ const char *event_type(int type)
 
 
 
-static int __add_event(struct list_head *list, int *idx,
-                      struct perf_event_attr *attr,
-                      char *name, struct cpu_map *cpus)
+static struct perf_evsel *
+__add_event(struct list_head *list, int *idx,
+           struct perf_event_attr *attr,
+           char *name, struct cpu_map *cpus)
 {
        struct perf_evsel *evsel;
 
@@ -279,19 +280,19 @@ static int __add_event(struct list_head *list, int *idx,
 
        evsel = perf_evsel__new_idx(attr, (*idx)++);
        if (!evsel)
-               return -ENOMEM;
+               return NULL;
 
        evsel->cpus = cpus;
        if (name)
                evsel->name = strdup(name);
        list_add_tail(&evsel->node, list);
-       return 0;
+       return evsel;
 }
 
 static int add_event(struct list_head *list, int *idx,
                     struct perf_event_attr *attr, char *name)
 {
-       return __add_event(list, idx, attr, name, NULL);
+       return __add_event(list, idx, attr, name, NULL) ? 0 : -ENOMEM;
 }
 
 static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
@@ -633,6 +634,9 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
 {
        struct perf_event_attr attr;
        struct perf_pmu *pmu;
+       struct perf_evsel *evsel;
+       char *unit;
+       double scale;
 
        pmu = perf_pmu__find(name);
        if (!pmu)
@@ -640,7 +644,7 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
 
        memset(&attr, 0, sizeof(attr));
 
-       if (perf_pmu__check_alias(pmu, head_config))
+       if (perf_pmu__check_alias(pmu, head_config, &unit, &scale))
                return -EINVAL;
 
        /*
@@ -652,8 +656,14 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
        if (perf_pmu__config(pmu, &attr, head_config))
                return -EINVAL;
 
-       return __add_event(list, idx, &attr, pmu_event_name(head_config),
-                          pmu->cpus);
+       evsel = __add_event(list, idx, &attr, pmu_event_name(head_config),
+                           pmu->cpus);
+       if (evsel) {
+               evsel->unit = unit;
+               evsel->scale = scale;
+       }
+
+       return evsel ? 0 : -ENOMEM;
 }
 
 int parse_events__modifier_group(struct list_head *list,
index 31f404a032a90499e5d366123f3185972edf3b49..d22e3f8017dc429a67458bc18457a6de7cd9f778 100644 (file)
@@ -78,6 +78,8 @@ static int get_value(struct parse_opt_ctx_t *p,
 
        case OPTION_BOOLEAN:
                *(bool *)opt->value = unset ? false : true;
+               if (opt->set)
+                       *(bool *)opt->set = true;
                return 0;
 
        case OPTION_INCR:
@@ -224,6 +226,24 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
                        return 0;
                }
                if (!rest) {
+                       if (!prefixcmp(options->long_name, "no-")) {
+                               /*
+                                * The long name itself starts with "no-", so
+                                * accept the option without "no-" so that users
+                                * do not have to enter "no-no-" to get the
+                                * negation.
+                                */
+                               rest = skip_prefix(arg, options->long_name + 3);
+                               if (rest) {
+                                       flags |= OPT_UNSET;
+                                       goto match;
+                               }
+                               /* Abbreviated case */
+                               if (!prefixcmp(options->long_name + 3, arg)) {
+                                       flags |= OPT_UNSET;
+                                       goto is_abbreviated;
+                               }
+                       }
                        /* abbreviated? */
                        if (!strncmp(options->long_name, arg, arg_end - arg)) {
 is_abbreviated:
@@ -259,6 +279,7 @@ is_abbreviated:
                        if (!rest)
                                continue;
                }
+match:
                if (*rest) {
                        if (*rest != '=')
                                continue;
index b0241e28eaf7dd7b81469e22416e8f1e16e26c63..cbf0149cf221783aea2aeafd8643900b80e6765d 100644 (file)
@@ -82,6 +82,9 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
  *   OPTION_{BIT,SET_UINT,SET_PTR} store the {mask,integer,pointer} to put in
  *   the value when met.
  *   CALLBACKS can use it like they want.
+ *
+ * `set`::
+ *   whether an option was set by the user
  */
 struct option {
        enum parse_opt_type type;
@@ -94,6 +97,7 @@ struct option {
        int flags;
        parse_opt_cb *callback;
        intptr_t defval;
+       bool *set;
 };
 
 #define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v )
@@ -103,6 +107,10 @@ struct option {
 #define OPT_GROUP(h)                { .type = OPTION_GROUP, .help = (h) }
 #define OPT_BIT(s, l, v, h, b)      { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) }
 #define OPT_BOOLEAN(s, l, v, h)     { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = check_vtype(v, bool *), .help = (h) }
+#define OPT_BOOLEAN_SET(s, l, v, os, h) \
+       { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), \
+       .value = check_vtype(v, bool *), .help = (h), \
+       .set = check_vtype(os, bool *)}
 #define OPT_INCR(s, l, v, h)        { .type = OPTION_INCR, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h) }
 #define OPT_SET_UINT(s, l, v, h, i)  { .type = OPTION_SET_UINT, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h), .defval = (i) }
 #define OPT_SET_PTR(s, l, v, h, p)  { .type = OPTION_SET_PTR, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (p) }
index c232d8dd410bf6483ba8fcd850380bbd562f03ee..56fc10a5e288142a04bda6d4086c14763531a11f 100644 (file)
@@ -1,19 +1,23 @@
 #include <linux/list.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <dirent.h>
 #include "fs.h"
+#include <locale.h>
 #include "util.h"
 #include "pmu.h"
 #include "parse-events.h"
 #include "cpumap.h"
 
+#define UNIT_MAX_LEN   31 /* max length for event unit name */
+
 struct perf_pmu_alias {
        char *name;
        struct list_head terms;
        struct list_head list;
+       char unit[UNIT_MAX_LEN+1];
+       double scale;
 };
 
 struct perf_pmu_format {
@@ -94,7 +98,80 @@ static int pmu_format(const char *name, struct list_head *format)
        return 0;
 }
 
-static int perf_pmu__new_alias(struct list_head *list, char *name, FILE *file)
+static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
+{
+       struct stat st;
+       ssize_t sret;
+       char scale[128];
+       int fd, ret = -1;
+       char path[PATH_MAX];
+       char *lc;
+
+       snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1)
+               return -1;
+
+       if (fstat(fd, &st) < 0)
+               goto error;
+
+       sret = read(fd, scale, sizeof(scale)-1);
+       if (sret < 0)
+               goto error;
+
+       scale[sret] = '\0';
+       /*
+        * save current locale
+        */
+       lc = setlocale(LC_NUMERIC, NULL);
+
+       /*
+        * force to C locale to ensure kernel
+        * scale string is converted correctly.
+        * kernel uses default C locale.
+        */
+       setlocale(LC_NUMERIC, "C");
+
+       alias->scale = strtod(scale, NULL);
+
+       /* restore locale */
+       setlocale(LC_NUMERIC, lc);
+
+       ret = 0;
+error:
+       close(fd);
+       return ret;
+}
+
+static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
+{
+       char path[PATH_MAX];
+       ssize_t sret;
+       int fd;
+
+       snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1)
+               return -1;
+
+               sret = read(fd, alias->unit, UNIT_MAX_LEN);
+       if (sret < 0)
+               goto error;
+
+       close(fd);
+
+       alias->unit[sret] = '\0';
+
+       return 0;
+error:
+       close(fd);
+       alias->unit[0] = '\0';
+       return -1;
+}
+
+static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
 {
        struct perf_pmu_alias *alias;
        char buf[256];
@@ -110,6 +187,9 @@ static int perf_pmu__new_alias(struct list_head *list, char *name, FILE *file)
                return -ENOMEM;
 
        INIT_LIST_HEAD(&alias->terms);
+       alias->scale = 1.0;
+       alias->unit[0] = '\0';
+
        ret = parse_events_terms(&alias->terms, buf);
        if (ret) {
                free(alias);
@@ -117,7 +197,14 @@ static int perf_pmu__new_alias(struct list_head *list, char *name, FILE *file)
        }
 
        alias->name = strdup(name);
+       /*
+        * load unit name and scale if available
+        */
+       perf_pmu__parse_unit(alias, dir, name);
+       perf_pmu__parse_scale(alias, dir, name);
+
        list_add_tail(&alias->list, list);
+
        return 0;
 }
 
@@ -129,6 +216,7 @@ static int pmu_aliases_parse(char *dir, struct list_head *head)
 {
        struct dirent *evt_ent;
        DIR *event_dir;
+       size_t len;
        int ret = 0;
 
        event_dir = opendir(dir);
@@ -143,13 +231,24 @@ static int pmu_aliases_parse(char *dir, struct list_head *head)
                if (!strcmp(name, ".") || !strcmp(name, ".."))
                        continue;
 
+               /*
+                * skip .unit and .scale info files
+                * parsed in perf_pmu__new_alias()
+                */
+               len = strlen(name);
+               if (len > 5 && !strcmp(name + len - 5, ".unit"))
+                       continue;
+               if (len > 6 && !strcmp(name + len - 6, ".scale"))
+                       continue;
+
                snprintf(path, PATH_MAX, "%s/%s", dir, name);
 
                ret = -EINVAL;
                file = fopen(path, "r");
                if (!file)
                        break;
-               ret = perf_pmu__new_alias(head, name, file);
+
+               ret = perf_pmu__new_alias(head, dir, name, file);
                fclose(file);
        }
 
@@ -508,16 +607,42 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
        return NULL;
 }
 
+
+static int check_unit_scale(struct perf_pmu_alias *alias,
+                           char **unit, double *scale)
+{
+       /*
+        * Only one term in event definition can
+        * define unit and scale, fail if there's
+        * more than one.
+        */
+       if ((*unit && alias->unit) ||
+           (*scale && alias->scale))
+               return -EINVAL;
+
+       if (alias->unit)
+               *unit = alias->unit;
+
+       if (alias->scale)
+               *scale = alias->scale;
+
+       return 0;
+}
+
 /*
  * Find alias in the terms list and replace it with the terms
  * defined for the alias
  */
-int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms)
+int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
+                         char **unit, double *scale)
 {
        struct parse_events_term *term, *h;
        struct perf_pmu_alias *alias;
        int ret;
 
+       *unit   = NULL;
+       *scale  = 0;
+
        list_for_each_entry_safe(term, h, head_terms, list) {
                alias = pmu_find_alias(pmu, term);
                if (!alias)
@@ -525,6 +650,11 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms)
                ret = pmu_alias_terms(alias, &term->list);
                if (ret)
                        return ret;
+
+               ret = check_unit_scale(alias, unit, scale);
+               if (ret)
+                       return ret;
+
                list_del(&term->list);
                free(term);
        }
index 1179b26f244a31280e5454787a51a8f01ff9ac2e..9183380e203851b8fb12f0bcee499b61dcda0f58 100644 (file)
@@ -28,7 +28,8 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
 int perf_pmu__config_terms(struct list_head *formats,
                           struct perf_event_attr *attr,
                           struct list_head *head_terms);
-int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms);
+int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
+                         char **unit, double *scale);
 struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
                                  struct list_head *head_terms);
 int perf_pmu_wrap(void);
index f36d24a024453f6e2777d1bc4cfbb10fb9a3cf4a..b0b15e213df50d9624674b7f9de622a48b90b800 100644 (file)
@@ -1522,6 +1522,9 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
                        if (!node)
                                break;
 
+                       if (node->sym && node->sym->ignore)
+                               goto next;
+
                        if (print_ip)
                                printf("%c%16" PRIx64, s, node->ip);
 
@@ -1544,12 +1547,15 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
                        if (!print_oneline)
                                printf("\n");
 
-                       callchain_cursor_advance(&callchain_cursor);
-
                        stack_depth--;
+next:
+                       callchain_cursor_advance(&callchain_cursor);
                }
 
        } else {
+               if (al.sym && al.sym->ignore)
+                       return;
+
                if (print_ip)
                        printf("%16" PRIx64, sample->ip);
 
index 96c866045d60d2a17f4d969ed5e3a0a3c00933fc..8b79d3ad124629e44184b8d20474592f9346a44b 100644 (file)
@@ -95,6 +95,7 @@ void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end)
 
        total_height = (1 + rows + cpu2slot(cpus)) * SLOT_MULT;
        fprintf(svgfile, "<?xml version=\"1.0\" standalone=\"no\"?> \n");
+       fprintf(svgfile, "<!DOCTYPE svg SYSTEM \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
        fprintf(svgfile, "<svg width=\"%i\" height=\"%" PRIu64 "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n", svg_page_width, total_height);
 
        fprintf(svgfile, "<defs>\n  <style type=\"text/css\">\n    <![CDATA[\n");
@@ -128,12 +129,33 @@ void svg_box(int Yslot, u64 start, u64 end, const char *type)
                time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT, type);
 }
 
-void svg_sample(int Yslot, int cpu, u64 start, u64 end)
+static char *time_to_string(u64 duration);
+void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
+{
+       if (!svgfile)
+               return;
+
+       fprintf(svgfile, "<g>\n");
+       fprintf(svgfile, "<title>#%d blocked %s</title>\n", cpu,
+               time_to_string(end - start));
+       if (backtrace)
+               fprintf(svgfile, "<desc>Blocked on:\n%s</desc>\n", backtrace);
+       svg_box(Yslot, start, end, "blocked");
+       fprintf(svgfile, "</g>\n");
+}
+
+void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
 {
        double text_size;
        if (!svgfile)
                return;
 
+       fprintf(svgfile, "<g>\n");
+
+       fprintf(svgfile, "<title>#%d running %s</title>\n",
+               cpu, time_to_string(end - start));
+       if (backtrace)
+               fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace);
        fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"sample\"/>\n",
                time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT);
 
@@ -148,6 +170,7 @@ void svg_sample(int Yslot, int cpu, u64 start, u64 end)
                fprintf(svgfile, "<text x=\"%1.8f\" y=\"%1.8f\" font-size=\"%1.8fpt\">%i</text>\n",
                        time2pixels(start), Yslot *  SLOT_MULT + SLOT_HEIGHT - 1, text_size,  cpu + 1);
 
+       fprintf(svgfile, "</g>\n");
 }
 
 static char *time_to_string(u64 duration)
@@ -168,7 +191,7 @@ static char *time_to_string(u64 duration)
        return text;
 }
 
-void svg_waiting(int Yslot, u64 start, u64 end)
+void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
 {
        char *text;
        const char *style;
@@ -192,6 +215,9 @@ void svg_waiting(int Yslot, u64 start, u64 end)
        font_size = round_text_size(font_size);
 
        fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\">\n", time2pixels(start), Yslot * SLOT_MULT);
+       fprintf(svgfile, "<title>#%d waiting %s</title>\n", cpu, time_to_string(end - start));
+       if (backtrace)
+               fprintf(svgfile, "<desc>Waiting on:\n%s</desc>\n", backtrace);
        fprintf(svgfile, "<rect x=\"0\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n",
                time2pixels(end)-time2pixels(start), SLOT_HEIGHT, style);
        if (font_size > MIN_TEXT_SIZE)
@@ -242,6 +268,8 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
        max_freq = __max_freq;
        turbo_frequency = __turbo_freq;
 
+       fprintf(svgfile, "<g>\n");
+
        fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"cpu\"/>\n",
                time2pixels(first_time),
                time2pixels(last_time)-time2pixels(first_time),
@@ -253,6 +281,8 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
 
        fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\" font-size=\"1.25pt\">%s</text>\n",
                10+time2pixels(first_time), cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - 4, cpu_model());
+
+       fprintf(svgfile, "</g>\n");
 }
 
 void svg_process(int cpu, u64 start, u64 end, const char *type, const char *name)
@@ -264,6 +294,7 @@ void svg_process(int cpu, u64 start, u64 end, const char *type, const char *name
 
 
        fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\">\n", time2pixels(start), cpu2y(cpu));
+       fprintf(svgfile, "<title>%s %s</title>\n", name, time_to_string(end - start));
        fprintf(svgfile, "<rect x=\"0\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n",
                time2pixels(end)-time2pixels(start), SLOT_MULT+SLOT_HEIGHT, type);
        width = time2pixels(end)-time2pixels(start);
@@ -288,6 +319,8 @@ void svg_cstate(int cpu, u64 start, u64 end, int type)
                return;
 
 
+       fprintf(svgfile, "<g>\n");
+
        if (type > 6)
                type = 6;
        sprintf(style, "c%i", type);
@@ -306,6 +339,8 @@ void svg_cstate(int cpu, u64 start, u64 end, int type)
        if (width > MIN_TEXT_SIZE)
                fprintf(svgfile, "<text x=\"%4.8f\" y=\"%4.8f\" font-size=\"%3.8fpt\">C%i</text>\n",
                        time2pixels(start), cpu2y(cpu)+width, width, type);
+
+       fprintf(svgfile, "</g>\n");
 }
 
 static char *HzToHuman(unsigned long hz)
@@ -339,6 +374,8 @@ void svg_pstate(int cpu, u64 start, u64 end, u64 freq)
        if (!svgfile)
                return;
 
+       fprintf(svgfile, "<g>\n");
+
        if (max_freq)
                height = freq * 1.0 / max_freq * (SLOT_HEIGHT + SLOT_MULT);
        height = 1 + cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - height;
@@ -347,10 +384,11 @@ void svg_pstate(int cpu, u64 start, u64 end, u64 freq)
        fprintf(svgfile, "<text x=\"%4.8f\" y=\"%4.8f\" font-size=\"0.25pt\">%s</text>\n",
                time2pixels(start), height+0.9, HzToHuman(freq));
 
+       fprintf(svgfile, "</g>\n");
 }
 
 
-void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2)
+void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace)
 {
        double height;
 
@@ -358,6 +396,15 @@ void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc
                return;
 
 
+       fprintf(svgfile, "<g>\n");
+
+       fprintf(svgfile, "<title>%s wakes up %s</title>\n",
+               desc1 ? desc1 : "?",
+               desc2 ? desc2 : "?");
+
+       if (backtrace)
+               fprintf(svgfile, "<desc>%s</desc>\n", backtrace);
+
        if (row1 < row2) {
                if (row1) {
                        fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%4.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
@@ -395,9 +442,11 @@ void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc
        if (row1)
                fprintf(svgfile, "<circle  cx=\"%4.8f\" cy=\"%4.2f\" r = \"0.01\"  style=\"fill:rgb(32,255,32)\"/>\n",
                        time2pixels(start), height);
+
+       fprintf(svgfile, "</g>\n");
 }
 
-void svg_wakeline(u64 start, int row1, int row2)
+void svg_wakeline(u64 start, int row1, int row2, const char *backtrace)
 {
        double height;
 
@@ -405,6 +454,11 @@ void svg_wakeline(u64 start, int row1, int row2)
                return;
 
 
+       fprintf(svgfile, "<g>\n");
+
+       if (backtrace)
+               fprintf(svgfile, "<desc>%s</desc>\n", backtrace);
+
        if (row1 < row2)
                fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%4.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
                        time2pixels(start), row1 * SLOT_MULT + SLOT_HEIGHT,  time2pixels(start), row2 * SLOT_MULT);
@@ -417,17 +471,28 @@ void svg_wakeline(u64 start, int row1, int row2)
                height += SLOT_HEIGHT;
        fprintf(svgfile, "<circle  cx=\"%4.8f\" cy=\"%4.2f\" r = \"0.01\"  style=\"fill:rgb(32,255,32)\"/>\n",
                        time2pixels(start), height);
+
+       fprintf(svgfile, "</g>\n");
 }
 
-void svg_interrupt(u64 start, int row)
+void svg_interrupt(u64 start, int row, const char *backtrace)
 {
        if (!svgfile)
                return;
 
+       fprintf(svgfile, "<g>\n");
+
+       fprintf(svgfile, "<title>Wakeup from interrupt</title>\n");
+
+       if (backtrace)
+               fprintf(svgfile, "<desc>%s</desc>\n", backtrace);
+
        fprintf(svgfile, "<circle  cx=\"%4.8f\" cy=\"%4.2f\" r = \"0.01\"  style=\"fill:rgb(255,128,128)\"/>\n",
                        time2pixels(start), row * SLOT_MULT);
        fprintf(svgfile, "<circle  cx=\"%4.8f\" cy=\"%4.2f\" r = \"0.01\"  style=\"fill:rgb(255,128,128)\"/>\n",
                        time2pixels(start), row * SLOT_MULT + SLOT_HEIGHT);
+
+       fprintf(svgfile, "</g>\n");
 }
 
 void svg_text(int Yslot, u64 start, const char *text)
@@ -455,6 +520,7 @@ void svg_legenda(void)
        if (!svgfile)
                return;
 
+       fprintf(svgfile, "<g>\n");
        svg_legenda_box(0,      "Running", "sample");
        svg_legenda_box(100,    "Idle","c1");
        svg_legenda_box(200,    "Deeper Idle", "c3");
@@ -462,6 +528,7 @@ void svg_legenda(void)
        svg_legenda_box(550,    "Sleeping", "process2");
        svg_legenda_box(650,    "Waiting for cpu", "waiting");
        svg_legenda_box(800,    "Blocked on IO", "blocked");
+       fprintf(svgfile, "</g>\n");
 }
 
 void svg_time_grid(void)
index e0781989cc31f5d1dd004dc66c22a584d371189d..fad79ceeac1adb12470d0a7f842e4787f52f2dad 100644 (file)
@@ -5,8 +5,9 @@
 
 extern void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end);
 extern void svg_box(int Yslot, u64 start, u64 end, const char *type);
-extern void svg_sample(int Yslot, int cpu, u64 start, u64 end);
-extern void svg_waiting(int Yslot, u64 start, u64 end);
+extern void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
+extern void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
+extern void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
 extern void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency);
 
 
@@ -17,9 +18,9 @@ extern void svg_pstate(int cpu, u64 start, u64 end, u64 freq);
 
 extern void svg_time_grid(void);
 extern void svg_legenda(void);
-extern void svg_wakeline(u64 start, int row1, int row2);
-extern void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2);
-extern void svg_interrupt(u64 start, int row);
+extern void svg_wakeline(u64 start, int row1, int row2, const char *backtrace);
+extern void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace);
+extern void svg_interrupt(u64 start, int row, const char *backtrace);
 extern void svg_text(int Yslot, u64 start, const char *text);
 extern void svg_close(void);
 
index c0c36965fff0f0060b2f2a077edc17c569648bf2..360eefecb81df4de3d458085ba6cbc05dce0f0d4 100644 (file)
@@ -573,6 +573,36 @@ static u8 kallsyms2elf_type(char type)
        return isupper(type) ? STB_GLOBAL : STB_LOCAL;
 }
 
+bool symbol__is_idle(struct symbol *sym)
+{
+       const char * const idle_symbols[] = {
+               "cpu_idle",
+               "intel_idle",
+               "default_idle",
+               "native_safe_halt",
+               "enter_idle",
+               "exit_idle",
+               "mwait_idle",
+               "mwait_idle_with_hints",
+               "poll_idle",
+               "ppc64_runlatch_off",
+               "pseries_dedicated_idle_sleep",
+               NULL
+       };
+
+       int i;
+
+       if (!sym)
+               return false;
+
+       for (i = 0; idle_symbols[i]; i++) {
+               if (!strcmp(idle_symbols[i], sym->name))
+                       return true;
+       }
+
+       return false;
+}
+
 static int map__process_kallsym_symbol(void *arg, const char *name,
                                       char type, u64 start)
 {
@@ -1496,14 +1526,15 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)
 
        build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
 
+       scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s", buildid_dir,
+                 sbuild_id);
+
        /* Use /proc/kallsyms if possible */
        if (is_host) {
                DIR *d;
                int fd;
 
                /* If no cached kcore go with /proc/kallsyms */
-               scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s",
-                         buildid_dir, sbuild_id);
                d = opendir(path);
                if (!d)
                        goto proc_kallsyms;
@@ -1528,6 +1559,10 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)
                goto proc_kallsyms;
        }
 
+       /* Find kallsyms in build-id cache with kcore */
+       if (!find_matching_kcore(map, path, sizeof(path)))
+               return strdup(path);
+
        scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s",
                  buildid_dir, sbuild_id);
 
@@ -1719,7 +1754,7 @@ out_fail:
        return -1;
 }
 
-static int setup_list(struct strlist **list, const char *list_str,
+int setup_list(struct strlist **list, const char *list_str,
                      const char *list_name)
 {
        if (list_str == NULL)
index 07de8fea2f48dbc346124539e7393307b839051a..f1031a1358a1ee3bbb12b62c87dfc83497d7ff92 100644 (file)
@@ -240,6 +240,7 @@ size_t symbol__fprintf(struct symbol *sym, FILE *fp);
 bool symbol_type__is_a(char symbol_type, enum map_type map_type);
 bool symbol__restricted_filename(const char *filename,
                                 const char *restricted_filename);
+bool symbol__is_idle(struct symbol *sym);
 
 int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
                  struct symsrc *runtime_ss, symbol_filter_t filter,
@@ -273,4 +274,7 @@ void kcore_extract__delete(struct kcore_extract *kce);
 int kcore_copy(const char *from_dir, const char *to_dir);
 int compare_proc_modules(const char *from, const char *to);
 
+int setup_list(struct strlist **list, const char *list_str,
+              const char *list_name);
+
 #endif /* __PERF_SYMBOL */
index 3c778a07b7cc78de8d92ec188e9bb446c40798bd..e74c5963dc7a9db7038e4ad3f5f7de1ed490f20f 100644 (file)
@@ -55,6 +55,13 @@ enum target_errno target__validate(struct target *target)
                        ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM;
        }
 
+       /* THREAD and SYSTEM/CPU are mutually exclusive */
+       if (target->per_thread && (target->system_wide || target->cpu_list)) {
+               target->per_thread = false;
+               if (ret == TARGET_ERRNO__SUCCESS)
+                       ret = TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD;
+       }
+
        return ret;
 }
 
@@ -100,6 +107,7 @@ static const char *target__error_str[] = {
        "UID switch overriding CPU",
        "PID/TID switch overriding SYSTEM",
        "UID switch overriding SYSTEM",
+       "SYSTEM/CPU switch overriding PER-THREAD",
        "Invalid User: %s",
        "Problems obtaining information for user %s",
 };
@@ -131,7 +139,8 @@ int target__strerror(struct target *target, int errnum,
        msg = target__error_str[idx];
 
        switch (errnum) {
-       case TARGET_ERRNO__PID_OVERRIDE_CPU ... TARGET_ERRNO__UID_OVERRIDE_SYSTEM:
+       case TARGET_ERRNO__PID_OVERRIDE_CPU ...
+            TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD:
                snprintf(buf, buflen, "%s", msg);
                break;
 
index 2d0c506908926f6fce822adc45a39e76911edd10..31dd2e9a27d043fd0609bfed57ea6a0f9076c6d9 100644 (file)
@@ -12,7 +12,8 @@ struct target {
        uid_t        uid;
        bool         system_wide;
        bool         uses_mmap;
-       bool         force_per_cpu;
+       bool         default_per_cpu;
+       bool         per_thread;
 };
 
 enum target_errno {
@@ -33,6 +34,7 @@ enum target_errno {
        TARGET_ERRNO__UID_OVERRIDE_CPU,
        TARGET_ERRNO__PID_OVERRIDE_SYSTEM,
        TARGET_ERRNO__UID_OVERRIDE_SYSTEM,
+       TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD,
 
        /* for target__parse_uid() */
        TARGET_ERRNO__INVALID_UID,
index cd8e2f59271969f410daf28afdf93523699f475c..49eaf1d7d89d0554a146a272e923cd139e6cbac7 100644 (file)
@@ -70,14 +70,13 @@ int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)
        /* Override latest entry if it had no specific time coverage */
        if (!curr->start) {
                comm__override(curr, str, timestamp);
-               return 0;
+       } else {
+               new = comm__new(str, timestamp);
+               if (!new)
+                       return -ENOMEM;
+               list_add(&new->list, &thread->comm_list);
        }
 
-       new = comm__new(str, timestamp);
-       if (!new)
-               return -ENOMEM;
-
-       list_add(&new->list, &thread->comm_list);
        thread->comm_set = true;
 
        return 0;
index 897c1b2a750a278c8cecf000c892d5f6bba8f0af..5b856bf942e11fa9691c28551a88b53b4ac3d5f2 100644 (file)
@@ -6,6 +6,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include "symbol.h"
+#include <strlist.h>
 
 struct thread {
        union {
@@ -66,4 +67,15 @@ static inline void thread__set_priv(struct thread *thread, void *p)
 {
        thread->priv = p;
 }
+
+static inline bool thread__is_filtered(struct thread *thread)
+{
+       if (symbol_conf.comm_list &&
+           !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread))) {
+               return true;
+       }
+
+       return false;
+}
+
 #endif /* __PERF_THREAD_H */
index 66cace601e5721cf920c89f3b365c75f6695ce67..0f10b81e3322694df614bf23a0b1824d415b34ce 100644 (file)
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-
+#include <linux/acpi.h>
 #include <asm/io.h>
 
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-
 static int pm_tmr_ioport = 0;
 
 /*helper function to safely read acpi pm timesource*/
index 4178effd9e99ce217c2c65a34dcfe09b4eb5edfa..7b3646adb92f597cf9016c88e3c5d97e12f2b9c0 100644 (file)
@@ -87,4 +87,5 @@ Thomas Renninger <trenn@suse.de>
 .fi
 .SH "SEE ALSO"
 .LP
-cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1)
+cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1),
+cpupower\-idle\-set(1)
diff --git a/tools/power/cpupower/man/cpupower-idle-set.1 b/tools/power/cpupower/man/cpupower-idle-set.1
new file mode 100644 (file)
index 0000000..6b16072
--- /dev/null
@@ -0,0 +1,71 @@
+.TH "CPUPOWER-IDLE-SET" "1" "0.1" "" "cpupower Manual"
+.SH "NAME"
+.LP
+cpupower idle\-set \- Utility to set cpu idle state specific kernel options
+.SH "SYNTAX"
+.LP
+cpupower [ \-c cpulist ] idle\-info [\fIoptions\fP]
+.SH "DESCRIPTION"
+.LP
+The cpupower idle\-set subcommand allows to set cpu idle, also called cpu
+sleep state, specific options offered by the kernel. One example is disabling
+sleep states. This can be handy for power vs performance tuning.
+.SH "OPTIONS"
+.LP
+.TP
+\fB\-d\fR \fB\-\-disable\fR
+Disable a specific processor sleep state.
+.TP
+\fB\-e\fR \fB\-\-enable\fR
+Enable a specific processor sleep state.
+
+.SH "REMARKS"
+.LP
+Cpuidle Governors Policy on Disabling Sleep States
+
+.RS 4
+Depending on the used  cpuidle governor, implementing the kernel policy
+how to choose sleep states, subsequent sleep states on this core, might get
+disabled as well.
+
+There are two cpuidle governors ladder and menu. While the ladder
+governor is always available, if CONFIG_CPU_IDLE is selected, the
+menu governor additionally requires CONFIG_NO_HZ.
+
+The behavior and the effect of the disable variable depends on the
+implementation of a particular governor. In the ladder governor, for
+example, it is not coherent, i.e. if one is disabling a light state,
+then all deeper states are disabled as well. Likewise, if one enables a
+deep state but a lighter state still is disabled, then this has no effect.
+.RE
+.LP
+Disabling the Lightest Sleep State may not have any Affect
+
+.RS 4
+If criteria are not met to enter deeper sleep states and the lightest sleep
+state is chosen when idle, the kernel may still enter this sleep state,
+irrespective of whether it is disabled or not. This is also reflected in
+the usage count of the disabled sleep state when using the cpupower idle-info
+command.
+.RE
+.LP
+Selecting specific CPU Cores
+
+.RS 4
+By default processor sleep states of all CPU cores are set. Please refer
+to the cpupower(1) manpage in the \-\-cpu option section how to disable
+C-states of specific cores.
+.RE
+.SH "FILES"
+.nf
+\fI/sys/devices/system/cpu/cpu*/cpuidle/state*\fP
+\fI/sys/devices/system/cpu/cpuidle/*\fP
+.fi
+.SH "AUTHORS"
+.nf
+Thomas Renninger <trenn@suse.de>
+.fi
+.SH "SEE ALSO"
+.LP
+cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1),
+cpupower\-idle\-info(1)
index 5cdc600e8152efae140687df6a532933e196cf59..851c7a16ca49633f0db3fd155b15466dfc4ab4fa 100644 (file)
@@ -278,7 +278,7 @@ static char *sysfs_idlestate_get_one_string(unsigned int cpu,
 int sysfs_is_idlestate_disabled(unsigned int cpu,
                                unsigned int idlestate)
 {
-       if (sysfs_get_idlestate_count(cpu) < idlestate)
+       if (sysfs_get_idlestate_count(cpu) <= idlestate)
                return -1;
 
        if (!sysfs_idlestate_file_exists(cpu, idlestate,
@@ -303,7 +303,7 @@ int sysfs_idlestate_disable(unsigned int cpu,
        char value[SYSFS_PATH_MAX];
        int bytes_written;
 
-       if (sysfs_get_idlestate_count(cpu) < idlestate)
+       if (sysfs_get_idlestate_count(cpu) <= idlestate)
                return -1;
 
        if (!sysfs_idlestate_file_exists(cpu, idlestate,